package models import ( "fmt" "runtime" "time" "maps" "github.com/google/uuid" "github.com/tecamino/tecamino-dbm/utils" ws "github.com/tecamino/tecamino-dbm/websocket" json_dataModels "github.com/tecamino/tecamino-json_data/models" "github.com/tecamino/tecamino-logger/logging" ) type DBM struct { Datapoints Datapoint Uuids Uuids Conns *ws.ClientHandler Log *logging.Logger } var SystemDatapoints uuid.UUID func NewDBM(conns *ws.ClientHandler, log *logging.Logger) *DBM { return &DBM{ Uuids: make(Uuids), Conns: conns, Log: log, } } func (d *DBM) CreateDatapoints(sets ...json_dataModels.Set) ([]json_dataModels.Set, error) { if len(sets) == 0 { return nil, nil } dps, uuids, err := d.Datapoints.CreateDatapoints(sets...) //save uuid in seperate map for fast look up maps.Copy(d.Uuids, uuids) if err != nil { return nil, err } var ndp uint64 for _, dp := range dps { if !dp.Updated { ndp++ } } d.ModifyCountedDatapoints(ndp, false) return dps, nil } func (d *DBM) ImportDatapoints(dps ...*Datapoint) error { for _, dp := range dps { uuids, err := d.Datapoints.ImportDatapoint(dp, dp.Path) if err != nil { return err } maps.Copy(d.Uuids, uuids) d.ModifyCountedDatapoints(1, false) } return nil } func (d *DBM) UpdateDatapointValue(value any, uid uuid.UUID, path ...string) error { if uid != uuid.Nil { if _, ok := d.Uuids[uid]; !ok { return fmt.Errorf("uuid %s not found", uid.String()) } dp := d.Uuids[uid] dp.Value = dp.Type.ConvertValue(value) dp.UpdateDateTime = time.Now().UnixMilli() dp.Publish(OnChange) } if len(path) > 1 { return fmt.Errorf("only one path allowed") } return d.Datapoints.UpdateDatapointValue(value, path[0]) } func (d *DBM) RemoveDatapoint(sets ...json_dataModels.Set) (lsRemoved []json_dataModels.Set, err error) { for _, set := range sets { if set.Path == "" { if dp, ok := d.Uuids[set.Uuid]; ok { set.Path = dp.Path } } lsRemoved, err = d.Datapoints.RemoveDatapoint(d.Conns, set) if err != nil { return } d.ModifyCountedDatapoints(uint64(len(lsRemoved)), true) } return } func (d *DBM) QueryDatapoints(depth uint, uid uuid.UUID, key ...string) []*Datapoint { if uid != uuid.Nil { if _, ok := d.Uuids[uid]; !ok { return nil } dp := d.Uuids[uid] if depth == 1 { return []*Datapoint{dp} } return append([]*Datapoint{}, dp.QueryDatapoints(depth, key[0])...) } return d.Datapoints.QueryDatapoints(depth, key[0]) } func (d *DBM) GetAllDatapoints(depth uint) (dps Datapoints) { return d.Datapoints.GetAllDatapoints(0) } func (d *DBM) GetNumbersOfDatapoints() uint64 { return utils.Uint64From(d.Datapoints.Datapoints["System"].Datapoints["Datapoints"].Value) } func (d *DBM) ModifyCountedDatapoints(count uint64, countDown bool) { dp := d.QueryDatapoints(1, SystemDatapoints, "System:Datapoints") amount := dp[0].GetValueUint64() if countDown { amount -= count } else { amount += count } d.UpdateDatapointValue(amount, SystemDatapoints, "System:Datapoints") } func (d *DBM) GoSystemTime() error { path := "System:Time" typ := json_dataModels.STR rights := json_dataModels.Read _, err := d.CreateDatapoints(json_dataModels.Set{Path: path, Type: typ, Rights: rights}) if err != nil { d.Log.Error("system.GoSystemTime", err.Error()) return err } go func() { ticker := time.NewTicker(time.Second) for range ticker.C { if er := d.UpdateDatapointValue(time.Now().Format("2006-01-02 15:04:05"), uuid.Nil, path); er != nil { d.Log.Error("dmb.Handler.AddSystemDps.UpdateDatapointValue", er.Error()) } } }() return nil } func (d *DBM) GoSystemMemory() error { path := "System:UsedMemory" typ := json_dataModels.STR rights := json_dataModels.Read _, err := d.CreateDatapoints(json_dataModels.Set{Path: path, Type: typ, Rights: rights}) if err != nil { d.Log.Error("system.GoSystemMemory", err.Error()) return err } go func() { for { var m runtime.MemStats runtime.ReadMemStats(&m) mem := fmt.Sprintf("%.2f MB", float64(m.Alloc)/1024/1024) if er := d.UpdateDatapointValue(mem, uuid.Nil, path); er != nil { d.Log.Error("dmb.Handler.AddSystemDps.UpdateDatapointValue", er.Error()) } time.Sleep(time.Second) } }() return nil }