Files
tecamino-dbm/models/dbm.go

186 lines
4.2 KiB
Go

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
}