From c45724f5d8ddd519796e68235488f30da89a4bb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Thu, 30 May 2024 13:05:42 +0200 Subject: [PATCH 1/4] Fixed bug in creating new datatype --- datapoint.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datapoint.go b/datapoint.go index ff284a2..afb815e 100644 --- a/datapoint.go +++ b/datapoint.go @@ -73,7 +73,7 @@ func (dp Datapoint) Update() (err error) { // {{{ if dp.ID == 0 { _, err = service.Db.Conn.Exec( - `INSERT INTO datapoint("group", name, datatype) VALUES($1, $2, $3, $4)`, + `INSERT INTO datapoint("group", name, datatype, nodata_problem_seconds) VALUES($1, $2, $3, $4)`, dp.Group, name, dp.Datatype, From 9eecf946f8dd6a68b435c419f3282076853d9bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Thu, 30 May 2024 13:31:51 +0200 Subject: [PATCH 2/4] Configurable interval for nodata checks --- config.go | 3 ++- main.go | 6 +++++- nodata.go | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/config.go b/config.go index 150fa1d..6ac26a3 100644 --- a/config.go +++ b/config.go @@ -1,5 +1,6 @@ package main type SmonConfiguration struct { - LogFile string + LogFile string + NodataInterval int `json:"nodata_interval"` // in seconds } diff --git a/main.go b/main.go index 859e59f..085ea5c 100644 --- a/main.go +++ b/main.go @@ -38,6 +38,7 @@ var ( parsedTemplates map[string]*template.Template componentFilenames []string notificationManager notification.Manager + smonConf SmonConfiguration //go:embed sql sqlFS embed.FS @@ -88,7 +89,6 @@ func main() { // {{{ os.Exit(1) } - smonConf := SmonConfiguration{} j, _ := json.Marshal(service.Config.Application) json.Unmarshal(j, &smonConf) logFile, err = os.OpenFile(smonConf.LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600) @@ -96,6 +96,10 @@ func main() { // {{{ logger.Error("application", "error", err) return } + if smonConf.NodataInterval < 10 { + logger.Error("application → nodata_interval has to be larger or equal to 10.") + return + } service.SetDatabase(sqlProvider) service.SetStaticFS(staticFS, "static") diff --git a/nodata.go b/nodata.go index a6cba54..ea09de9 100644 --- a/nodata.go +++ b/nodata.go @@ -25,7 +25,7 @@ func nodataLoop() { var err error // TODO - should be configurable - ticker := time.NewTicker(time.Second * 5) + ticker := time.NewTicker(time.Second * time.Duration(smonConf.NodataInterval)) for { <-ticker.C datapoints, err = nodataDatapoints() From 68abb894a68542ca94dc41ac93070b7297d181ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Thu, 30 May 2024 13:32:04 +0200 Subject: [PATCH 3/4] Don't erase datapoints when used in triggers. --- datapoint.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/datapoint.go b/datapoint.go index afb815e..02acec4 100644 --- a/datapoint.go +++ b/datapoint.go @@ -283,6 +283,37 @@ func DatapointRetrieve(id int, name string) (dp Datapoint, err error) { // {{{ return } // }}} func DatapointDelete(id int) (err error) { // {{{ + var dpName string + row := service.Db.Conn.QueryRow(`SELECT name FROM public.datapoint WHERE id = $1`, id) + err = row.Scan(&dpName) + if err != nil { + err = werr.Wrap(err).WithData(id) + return + } + + var rows *sql.Rows + rows, err = service.Db.Conn.Query(`SELECT name FROM public.trigger WHERE datapoints ? $1`, dpName) + if err != nil { + err = werr.Wrap(err).WithData(dpName) + return + } + defer rows.Close() + + var triggerNames []string + var name string + for rows.Next() { + err = rows.Scan(&name) + if err != nil { + err = werr.Wrap(err) + return + } + triggerNames = append(triggerNames, name) + } + + if len(triggerNames) > 0 { + return werr.New("Datapoint '%s' used in the following triggers: %s", dpName, strings.Join(triggerNames, ", ")) + } + _, err = service.Db.Conn.Exec(`DELETE FROM datapoint WHERE id=$1`, id) if err != nil { err = werr.Wrap(err).WithData(id) From adab2ab67dc60429fe3fa4bdf44cccfe6e73a2c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20=C3=85hall?= Date: Thu, 30 May 2024 14:33:43 +0200 Subject: [PATCH 4/4] In-page addition of datapoints to triggers --- main.go | 34 ++++++++++++++++++++++++++++++++++ static/js/trigger_edit.mjs | 20 +++++++++++++++----- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/main.go b/main.go index 085ea5c..bb1df33 100644 --- a/main.go +++ b/main.go @@ -21,6 +21,7 @@ import ( "net/http" "os" "path" + "slices" "sort" "strconv" "time" @@ -138,6 +139,7 @@ func main() { // {{{ service.Register("/triggers", false, false, pageTriggers) service.Register("/trigger/edit/{id}", false, false, pageTriggerEdit) service.Register("/trigger/edit/{id}/{sectionID}", false, false, pageTriggerEdit) + service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, pageTriggerDatapointAdd) service.Register("/trigger/update/{id}", false, false, pageTriggerUpdate) service.Register("/trigger/run/{id}", false, false, pageTriggerRun) @@ -725,6 +727,38 @@ func pageTriggerEdit(w http.ResponseWriter, r *http.Request, _ *session.T) { // page.Render(w) } // }}} +func pageTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ + triggerID := r.PathValue("id") + dpName := r.PathValue("datapointName") + + id, err := strconv.Atoi(triggerID) + if err != nil { + httpError(w, werr.Wrap(err).Log()) + return + } + + var trigger Trigger + if id > 0 { + trigger, err = TriggerRetrieve(id) + if err != nil { + httpError(w, werr.Wrap(err).Log()) + return + } + } + + if !slices.Contains(trigger.Datapoints, dpName) { + trigger.Datapoints = append(trigger.Datapoints, dpName) + } + err = trigger.Update() + if err != nil { + httpError(w, werr.Wrap(err).Log()) + return + } + + j, _ := json.Marshal(struct{ OK bool }{OK: true}) + w.Header().Add("Content-Type", "application/json") + w.Write(j) +} // }}} func pageTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{ idStr := r.PathValue("id") id, err := strconv.Atoi(idStr) diff --git a/static/js/trigger_edit.mjs b/static/js/trigger_edit.mjs index d190ef1..ab90143 100644 --- a/static/js/trigger_edit.mjs +++ b/static/js/trigger_edit.mjs @@ -66,7 +66,7 @@ export class UI { }) .catch(err => alert(err)) }//}}} - chooseDatapoint() {//{{{ + async chooseDatapoint() {//{{{ const dlg = document.getElementById('dlg-datapoints') const datapoint = document.getElementById('datapoint').value const dp = this.datapoints.find(dp => dp.Name == datapoint) @@ -77,8 +77,10 @@ export class UI { } this.trigger.addDatapoint(dp) - dlg.close() - this.render() + .then(() => { + dlg.close() + this.render() + }) }//}}} deleteDatapoint(name) {//{{{ if (!confirm(`Delete ${name}?`)) { @@ -147,7 +149,15 @@ export class Trigger { }) .catch(err => alert(err)) }//}}} - addDatapoint(dp) {//{{{ - this.datapoints[dp.Name] = dp + async addDatapoint(dp) {//{{{ + return fetch(`/trigger/addDatapoint/${this.id}/${dp.Name}`) + .then(data => data.json()) + .then(json => { + if (!json.OK) { + alert(json.Error) + return + } + this.datapoints[dp.Name] = dp + }) }//}}} }