From 21e4231e24e284711cbc16117a8eeb5e49da6e6f Mon Sep 17 00:00:00 2001 From: Adrian Zuercher Date: Thu, 31 Jul 2025 12:20:49 +0200 Subject: [PATCH] add and improve remove driver function and rename datapoint --- dbm/json_data.go | 5 -- drivers/drivers.go | 3 + go.mod | 2 +- go.sum | 4 +- models/datapoint.go | 123 +++++++++++++++++++++++++++---------- models/uuids.go | 8 +-- websocket/clientHandler.go | 1 - websocket/models/client.go | 10 ++- 8 files changed, 107 insertions(+), 49 deletions(-) diff --git a/dbm/json_data.go b/dbm/json_data.go index 12a64de..5dd9e52 100644 --- a/dbm/json_data.go +++ b/dbm/json_data.go @@ -1,7 +1,6 @@ package dbm import ( - "fmt" "net/http" "github.com/gin-gonic/gin" @@ -46,10 +45,6 @@ func (d *DBMHandler) Json_Data(c *gin.Context) { } if len(payload.Set) > 0 { resp.Set, err = d.DBM.CreateDatapoints(payload.Set...) - for i, o := range resp.Set { - fmt.Println(1000, i, o) - fmt.Println(1001, o.HasChild) - } if err != nil { r := json_data.NewResponse() r.SetError() diff --git a/drivers/drivers.go b/drivers/drivers.go index e2dbb87..1d1a54b 100644 --- a/drivers/drivers.go +++ b/drivers/drivers.go @@ -3,5 +3,8 @@ package drivers type Drivers []Driver type Driver interface { + NewArtNetDriver(string) AddAddress() } + +//func Add diff --git a/go.mod b/go.mod index fb7af9c..1eeb0fb 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.3 - github.com/tecamino/tecamino-json_data v0.0.21 + github.com/tecamino/tecamino-json_data v0.0.31 github.com/tecamino/tecamino-logger v0.2.0 ) diff --git a/go.sum b/go.sum index dba797a..e1b7eb3 100644 --- a/go.sum +++ b/go.sum @@ -71,8 +71,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tecamino/tecamino-json_data v0.0.21 h1:ZRN9wyn+p6J1T4b0e9xf1HStVaAy4wb+3yZ9xn5LFc0= -github.com/tecamino/tecamino-json_data v0.0.21/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= +github.com/tecamino/tecamino-json_data v0.0.31 h1:7zFbANj1Lihr64CCCh3O+9hxxsMcEPniRJZ5NgPrS5Y= +github.com/tecamino/tecamino-json_data v0.0.31/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY= github.com/tecamino/tecamino-logger v0.2.0 h1:NPH/Gg9qRhmVoW8b39i1eXu/LEftHc74nyISpcRG+XU= github.com/tecamino/tecamino-logger v0.2.0/go.mod h1:0M1E9Uei/qw3e3WA1x3lBo1eP3H5oeYE7GjYrMahnj8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= diff --git a/models/datapoint.go b/models/datapoint.go index be3b7be..a7a3a48 100644 --- a/models/datapoint.go +++ b/models/datapoint.go @@ -2,7 +2,6 @@ package models import ( "encoding/json" - "errors" "fmt" "regexp" "strings" @@ -70,17 +69,13 @@ func (d *Datapoint) Set(path string, set json_dataModels.Set) (bool, error) { if set.Driver == nil { return changed, nil } - if set.Driver.Type == "" { - return changed, errors.New("driver type missing") - } - if set.Driver.Bus == "" { - return changed, errors.New("driver bus name missing") - } if d.Drivers == nil { - d.Drivers = json_dataModels.NewDrivers() + d.Drivers = json_dataModels.Drivers{} } - d.Drivers.AddDriver(set.Driver.Type, set.Driver.Bus, set.Driver.Address) + d.Drivers.AddDriver(set.Driver) + + changed = true d.UpdateDateTime = time.Now().UnixMilli() return changed, nil @@ -99,6 +94,27 @@ func (d *Datapoint) CreateDatapoints(uuids *Uuids, sets ...json_dataModels.Set) for _, dp := range sets { + if dp.Path == "" && dp.Uuid != uuid.Nil { + existing := uuids.GetDatapoint(dp.Uuid) + _, err := existing.Set("", dp) + if err != nil { + return nil, err + } + created = append(created, json_dataModels.Set{ + Uuid: existing.Uuid, + Path: existing.Path, + Type: existing.Type, + Value: existing.Value, + Rights: existing.ReadWrite, + Drivers: &existing.Drivers, + Updated: true, + HasChild: existing.HasChild, + }) + + existing.Publish(OnChange) + continue + } + parts := strings.Split(dp.Path, ":") current := d @@ -106,6 +122,7 @@ func (d *Datapoint) CreateDatapoints(uuids *Uuids, sets ...json_dataModels.Set) if current.Datapoints == nil { current.Datapoints = make(map[string]*Datapoint) } + if i == len(parts)-1 { // Leaf node: create or update datapoint if existing, ok := current.Datapoints[part]; ok { @@ -126,7 +143,6 @@ func (d *Datapoint) CreateDatapoints(uuids *Uuids, sets ...json_dataModels.Set) }) existing.Publish(OnChange) - } else { var uid uuid.UUID = uuid.New() if dp.Uuid != uuid.Nil { @@ -147,8 +163,8 @@ func (d *Datapoint) CreateDatapoints(uuids *Uuids, sets ...json_dataModels.Set) } //add uuid to flat map for faster lookup - uuids.AddDatapoint(current, ndp) - + renamedDps := uuids.AddDatapoint(current, ndp) + created = append(created, renamedDps...) created = append(created, json_dataModels.Set{ Uuid: ndp.Uuid, Path: ndp.Path, @@ -183,8 +199,8 @@ func (d *Datapoint) CreateDatapoints(uuids *Uuids, sets ...json_dataModels.Set) } //add uuid to flat map for faster lookup - uuids.AddDatapoint(current, newDp) - + renamedDps := uuids.AddDatapoint(current, newDp) + created = append(created, renamedDps...) created = append(created, json_dataModels.Set{ Uuid: newDp.Uuid, Path: newDp.Path, @@ -304,6 +320,8 @@ func (d *Datapoint) UpdateValue(value any) error { return nil } +// removes datapoint and its children if path is given +// if path and func (d *Datapoint) RemoveDatapoint(set json_dataModels.Set) (sets []json_dataModels.Set, err error) { parts := strings.Split(set.Path, ":") @@ -324,20 +342,35 @@ func (d *Datapoint) RemoveDatapoint(set json_dataModels.Set) (sets []json_dataMo toDelete := parts[len(parts)-1] if dp, ok := current.Datapoints[toDelete]; ok { - s, p := removeChildren(dp) - sets = append(sets, s...) - publishes = append(publishes, p...) - publishes = append(publishes, json_dataModels.Publish{ - Event: OnDelete, - Uuid: dp.Uuid, - Path: dp.Path, - }) - sets = append(sets, json_dataModels.Set{ - Uuid: dp.Uuid, - Path: dp.Path, - }) - delete(current.Datapoints, toDelete) - + //if driver information found, remoove only driver information + if set.Driver != nil { + dp.RemoveDriver(set.Driver) + publishes = append(publishes, json_dataModels.Publish{ + Event: OnChange, + Uuid: dp.Uuid, + Path: dp.Path, + Drivers: &dp.Drivers, + }) + sets = append(sets, json_dataModels.Set{ + Uuid: dp.Uuid, + Path: dp.Path, + Drivers: &dp.Drivers, + }) + } else { + s, pubs := removeChildren(dp) + sets = append(sets, s...) + publishes = append(publishes, pubs...) + publishes = append(publishes, json_dataModels.Publish{ + Event: OnDelete, + Uuid: dp.Uuid, + Path: dp.Path, + }) + sets = append(sets, json_dataModels.Set{ + Uuid: dp.Uuid, + Path: dp.Path, + }) + delete(current.Datapoints, toDelete) + } r := json_data.NewResponse() r.Publish = append(r.Publish, publishes...) @@ -442,7 +475,7 @@ func (d *Datapoint) AddSubscribtion(conn *wsModels.Client, sub json_dataModels.S } } -func (d *Datapoint) RenamePaths(oldPath string) { +func (d *Datapoint) RenamePaths(oldPath string) (renamed []json_dataModels.Set) { visited := make(map[*Datapoint]bool) if len(d.Datapoints) == 0 { @@ -451,11 +484,22 @@ func (d *Datapoint) RenamePaths(oldPath string) { for _, dp := range d.Datapoints { dp.Path = strings.Replace(dp.Path, oldPath, d.Path, 1) - dp.renameSubPaths(oldPath, d.Path, visited) + renamedDps := dp.renameSubPaths(oldPath, d.Path, visited) + renamed = append(renamed, renamedDps...) + renamed = append(renamed, json_dataModels.Set{ + Uuid: dp.Uuid, + Path: dp.Path, + Type: dp.Type, + Value: dp.Value, + Rights: dp.ReadWrite, + Drivers: &dp.Drivers, + HasChild: dp.HasChild, + }) } + return } -func (d *Datapoint) renameSubPaths(oldPath, newPath string, visited map[*Datapoint]bool) { +func (d *Datapoint) renameSubPaths(oldPath, newPath string, visited map[*Datapoint]bool) (renamed []json_dataModels.Set) { if visited[d] { return } @@ -467,14 +511,29 @@ func (d *Datapoint) renameSubPaths(oldPath, newPath string, visited map[*Datapoi for _, dp := range d.Datapoints { dp.Path = strings.Replace(dp.Path, oldPath, newPath, 1) - dp.renameSubPaths(oldPath, newPath, visited) + renamedDps := dp.renameSubPaths(oldPath, newPath, visited) + renamed = append(renamed, renamedDps...) + renamed = append(renamed, json_dataModels.Set{ + Uuid: dp.Uuid, + Path: dp.Path, + Type: dp.Type, + Value: dp.Value, + Rights: dp.ReadWrite, + Drivers: &dp.Drivers, + HasChild: dp.HasChild, + }) } + return } func (d *Datapoint) RemoveSubscribtion(client *wsModels.Client) { delete(d.Subscriptions, client) } +func (d *Datapoint) RemoveDriver(driver *json_dataModels.Driver) { + d.Drivers.RemoveDriver(driver) +} + func (d *Datapoint) Publish(eventType string) error { r := json_data.NewResponse() r.AddPublish(json_dataModels.Publish{ diff --git a/models/uuids.go b/models/uuids.go index 73070c0..ec7ff1b 100644 --- a/models/uuids.go +++ b/models/uuids.go @@ -1,8 +1,6 @@ package models import ( - "fmt" - "github.com/google/uuid" json_dataModels "github.com/tecamino/tecamino-json_data/models" ) @@ -13,7 +11,7 @@ func NewUuids() *Uuids { return &Uuids{} } -func (u *Uuids) AddDatapoint(parentDp, newDp *Datapoint) { +func (u *Uuids) AddDatapoint(parentDp, newDp *Datapoint) (renamed []json_dataModels.Set) { if odp, ok := (*u)[newDp.Uuid]; ok { if odp.Path == newDp.Path { return @@ -21,14 +19,14 @@ func (u *Uuids) AddDatapoint(parentDp, newDp *Datapoint) { newDp.Datapoints = odp.Datapoints newDp.HasChild = len(odp.Datapoints) > 0 odp.Datapoints = map[string]*Datapoint{} - newDp.RenamePaths(odp.Path) + renamed = newDp.RenamePaths(odp.Path) rmDps, _ := parentDp.RemoveDatapoint(json_dataModels.Set{Path: odp.Path}) datapoints := u.GetDatapointByPath("System:Datapoints") datapoints.UpdateValue(datapoints.Value.(uint64) - uint64(len(rmDps))) - fmt.Println(11, newDp.HasChild) } (*u)[newDp.Uuid] = newDp + return } func (u *Uuids) GetDatapoint(uuid uuid.UUID) *Datapoint { diff --git a/websocket/clientHandler.go b/websocket/clientHandler.go index 82eb4a8..7379970 100644 --- a/websocket/clientHandler.go +++ b/websocket/clientHandler.go @@ -38,7 +38,6 @@ func (cH *ClientHandler) ConnectNewClient(id string, c *gin.Context) (client *mo client, err = models.ConnectNewClient(id, c) client.OnClose = func(code int, reason string) { - fmt.Println(23, "closing", id) delete(cH.Clients, id) } diff --git a/websocket/models/client.go b/websocket/models/client.go index 952972c..5c2bb27 100644 --- a/websocket/models/client.go +++ b/websocket/models/client.go @@ -17,10 +17,10 @@ var Broadcast Clients = make(Clients) const ( // Time allowed to write a message to the peer. - writeWait = 30 * time.Second + writeWait = 10 * time.Second // Time allowed to read the next pong message from the peer. - pongWait = 40 * time.Second + pongWait = 30 * time.Second // Send pings to peer with this period. Must be less than pongWait. pingPeriod = (pongWait * 9) / 10 @@ -69,12 +69,15 @@ func ConnectNewClient(id string, c *gin.Context) (*Client, error) { Broadcast[client.Id] = client + conn.SetReadDeadline(time.Now().Add(pongWait)) + conn.SetPingHandler(func(appData string) error { if client.OnPing != nil { client.OnPing() } + + conn.SetReadDeadline(time.Now().Add(pongWait)) conn.SetWriteDeadline(time.Now().Add(writeWait)) - conn.SetReadDeadline(time.Now().Add(writeWait)) if err := client.conn.WriteControl(websocket.PongMessage, []byte(appData), time.Now().Add(pongWait)); err != nil { client.OnError(err) } @@ -166,6 +169,7 @@ func (c *Client) PingInterval(interval time.Duration) { c.OnError(err) return } + for range ticker.C { if c.OnPing != nil { c.OnPing()