GoSungrow/iSolarCloud/api/struct_data.go
2022-10-13 16:51:32 +11:00

985 lines
23 KiB
Go

package api
import (
"GoSungrow/Only"
"GoSungrow/iSolarCloud/api/apiReflect"
"encoding/json"
"fmt"
datatable "go.pennock.tech/tabular/auto"
"strings"
"time"
)
const (
PointTimeSpanInstant = "instant"
PointTimeSpanBoot = "boot"
PointTimeSpanDaily = "daily"
PointTimeSpanMonthly = "monthly"
PointTimeSpanYearly = "yearly"
PointTimeSpanTotal = "total"
)
type PointId string
type DataPointEntries []DataEntry
// type DataPoints struct {
// Map map[PointId]DataPointEntries
// }
func (de *DataPointEntries) Hide() {
for range Only.Once {
for i := range *de {
(*de)[i].Hide = true
}
}
}
type DataMap struct {
DataPoints map[PointId]DataPointEntries
Order []PointId
}
type DataEntry struct {
Point *Point `json:"point"`
Date DateTime `json:"date"`
EndPoint string `json:"endpoint"`
FullId PointId `json:"full_id"`
Parent ParentDevice `json:"parent"`
Value string `json:"value"`
ValueFloat float64 `json:"value_float"`
ValueBool bool `json:"value_bool"`
Index int `json:"index"`
Valid bool `json:"valid"`
Hide bool `json:"hide"`
}
func (de *DataEntry) IsValid() bool {
var ok bool
for range Only.Once {
if de.Point == nil {
break
}
if de.Point.Valid == false {
break
}
ok = true
}
return ok
}
func (de *DataEntry) IsNotValid() bool {
return !de.IsValid()
}
func NewDataMap() DataMap {
return DataMap {
DataPoints: make(map[PointId]DataPointEntries),
}
}
// func (dm *DataMap) Add(point string, entry DataEntry) {
// dm.Entries[point] = entry
// dm.Order = append(dm.Order, point)
// }
func (dm *DataMap) StructToPoints(ref interface{}, endpoint string, parentId string, timestamp DateTime) {
for range Only.Once {
if endpoint == "" {
endpoint = apiReflect.GetCallerPackage(2)
}
// Iterate over all available fields and read the tags value
tp := apiReflect.GetPointTags(ref, endpoint)
// fmt.Printf("TP: %v\n", tp)
for _, f := range tp {
// if strings.Contains(strings.ToLower(f.Json), "p83012") {
// fmt.Sprintf("")
// }
if f.PointIgnore {
// fmt.Printf("IGNORE: %s\n", f.PointId)
continue
}
if f.PointName == "" {
f.PointName = PointToName(PointId(f.PointId))
}
if f.PointDevice == "" {
if parentId != "" {
f.PointDevice = parentId
} else {
f.PointDevice = "virtual"
}
}
var parents ParentDevices
parents.Add(ParentDevice{Key: f.PointDevice})
// pUnit := fieldTo.Tag.Get("PointUnit")
var uv UnitValue
var ignore bool
switch f.ValueType {
case "int":
uv = SetUnitValueInteger(int64(f.Value.(int)), f.PointUnit)
case "int32":
uv = SetUnitValueInteger(int64(f.Value.(int32)), f.PointUnit)
case "int64":
uv = SetUnitValueInteger(f.Value.(int64), f.PointUnit)
case "float32":
uv = SetUnitValueFloat(float64(f.Value.(float32)), f.PointUnit)
case "float64":
uv = SetUnitValueFloat(f.Value.(float64), f.PointUnit)
case "string":
uv = SetUnitValueString(f.Value.(string), f.PointUnit)
case "bool":
v := f.Value.(bool)
uv = SetUnitValueString(fmt.Sprintf("%v", v), "binary")
case "UnitValue":
fallthrough
case "api.UnitValue":
uv = f.Value.(UnitValue)
// uv = uv.UnitValueFix()
case "[]UnitValue":
fallthrough
case "[]api.UnitValue":
// v := strings.Join(f.Value.([]string), ",")
j, err := json.Marshal(f.Value.([]UnitValue))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]UnitValue)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "Float":
fallthrough
case "api.Float":
v := f.Value.(Float)
uv = SetUnitValueFloat(v.Value(), f.PointUnit)
case "[]Float":
fallthrough
case "[]api.Float":
// v := strings.Join(f.Value.([]string), ",")
j, err := json.Marshal(f.Value.([]Float))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]Float)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "Integer":
fallthrough
case "api.Integer":
v := f.Value.(Integer).Value()
uv = SetUnitValueInteger(v, f.PointUnit)
case "[]Integer":
fallthrough
case "[]api.Integer":
j, err := json.Marshal(f.Value.([]Integer))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]Integer)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "Count":
fallthrough
case "api.Count":
v := f.Value.(Count).Value()
uv = SetUnitValueInteger(v, "counter")
case "[]Count":
fallthrough
case "[]api.Count":
j, err := json.Marshal(f.Value.([]Count))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]Count)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "Bool":
fallthrough
case "api.Bool":
v := f.Value.(Bool).String()
uv = SetUnitValueString(v, "binary")
case "[]Bool":
fallthrough
case "[]api.Bool":
j, err := json.Marshal(f.Value.([]Bool))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]Bool)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "String":
fallthrough
case "api.String":
v := f.Value.(String).String()
uv = SetUnitValueString(v, f.PointUnit)
case "[]String":
fallthrough
case "[]api.String":
j, err := json.Marshal(f.Value.([]String))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]String)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "PsKey":
fallthrough
case "api.PsKey":
v := f.Value.(PsKey).Value()
uv = SetUnitValueString(v, f.PointUnit)
case "[]PsKey":
fallthrough
case "[]api.PsKey":
j, err := json.Marshal(f.Value.([]PsKey))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]PsKey)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "DateTime":
fallthrough
case "api.DateTime":
v := f.Value.(DateTime).String()
uv = SetUnitValueString(v, "date")
case "[]DateTime":
fallthrough
case "[]api.DateTime":
j, err := json.Marshal(f.Value.([]DateTime))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]DateTime)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
case "[]string":
// v := strings.Join(f.Value.([]string), ",")
j, err := json.Marshal(f.Value.([]string))
if err != nil {
j = []byte(fmt.Sprintf("%v", f.Value.([]string)))
}
uv = SetUnitValueString(string(j), f.PointUnit)
default:
ignore = true
}
if ignore {
// fmt.Printf("IGNORE: %s.%s (%s)\n", f.Endpoint, f.PointId, f.ValueType)
continue
}
switch f.PointTimeSpan {
case "PointTimeSpanInstant":
f.PointTimeSpan = PointTimeSpanInstant
case "PointTimeSpanBoot":
f.PointTimeSpan = PointTimeSpanBoot
case "PointTimeSpanDaily":
f.PointTimeSpan = PointTimeSpanDaily
case "PointTimeSpanMonthly":
f.PointTimeSpan = PointTimeSpanMonthly
case "PointTimeSpanYearly":
f.PointTimeSpan = PointTimeSpanYearly
case "PointTimeSpanTotal":
f.PointTimeSpan = PointTimeSpanTotal
}
var now DateTime
if timestamp.IsZero() {
now = NewDateTime(time.Now().Round(5 * time.Minute).Format(DtLayoutZeroSeconds))
} else {
now = NewDateTime(timestamp.String())
}
// @TODO - Think about adding in arrays of values OR just marshal arrays into JSON.
// fullName := JoinDevicePoint(device, PointId(f.PointId))
p := Point {
Parents: parents,
Id: PointId(f.PointId),
GroupName: f.PointGroupName,
Name: f.PointName,
Unit: uv.Unit(),
TimeSpan: f.PointTimeSpan,
ValueType: f.PointValueType,
Valid: true,
States: nil,
}
// if strings.Contains(strings.ToLower(f.Json), "p83012") {
// fmt.Sprintf("")
// }
dm.AddEntry(f.Endpoint, f.PointDevice, p, now, uv.String())
if f.PointAlias != "" {
// fullName = NameDevicePoint(device, PointId(alias))
p.Id = PointId(f.PointAlias)
dm.AddEntry(f.Endpoint, f.PointDevice, p, now, uv.String())
}
}
for _, f := range tp {
// if strings.Contains(strings.ToLower(f.PointId), "p83012") {
// fmt.Sprintf("")
// }
if f.PointUnitFrom != "" {
sdp := dm.GetEntryFromPointId(f.PointUnitFrom)
if sdp == nil {
continue
}
ddp := dm.GetEntryFromPointId(f.PointId)
if ddp == nil {
continue
}
ddp.SetUnits(sdp.GetEntry(0).Value)
sdp.Hide()
}
}
}
}
const LastEntry = -1
func (de *DataPointEntries) GetEntry(index int) DataEntry {
for range Only.Once {
l := len(*de) - 1
if index > l {
index = l
break
}
if index < 0 {
index = l + index + 1
if index < 0 {
index = 0
}
}
}
return (*de)[index]
}
func (de *DataPointEntries) GetUnits() string {
var unit string
for range Only.Once {
for _, v := range *de {
unit = v.Point.Unit
break
}
}
return unit
}
func (de *DataPointEntries) SetUnits(units string) {
for range Only.Once {
for i := range *de {
(*de)[i].Point.Unit = units
}
}
}
func (dm *DataMap) GetEntry(entry string, index int) DataEntry {
var ret DataEntry
for range Only.Once {
pe := dm.DataPoints[PointId(entry)]
if pe != nil {
ret = pe.GetEntry(index)
break
}
for k, v := range dm.DataPoints {
if strings.HasSuffix(string(k), "." + entry) {
ret = v.GetEntry(index)
break
}
}
}
return ret
}
func (dm *DataMap) GetEntryFromPointId(pointId string) *DataPointEntries {
var ret *DataPointEntries
for range Only.Once {
for _, v := range dm.DataPoints {
pe := v.GetEntry(0)
if pe.IsNotValid() {
continue
}
if string(pe.Point.Id) == pointId {
ret = &v
break
}
}
}
return ret
}
func (dm *DataMap) HideEntry(pointId string) {
for range Only.Once {
de := dm.GetEntryFromPointId(pointId)
de.Hide()
}
}
func (dm *DataMap) GetFloatValue(entry string, index int) float64 {
var ret float64
for range Only.Once {
pe := dm.GetEntry(entry, index)
if pe.IsNotValid() {
fmt.Printf("ERROR: GetFloatValue('%s', '%d')\n", entry, index)
break
}
ret = pe.ValueFloat
}
return ret
}
func (dm *DataMap) LowerUpper(lowerEntry string, upperEntry string, index int) float64 {
var ret float64
for range Only.Once {
l := dm.GetEntry(lowerEntry, index)
if l.IsNotValid() {
fmt.Printf("ERROR: LowerUpper('%s', '%s', %d)\n", lowerEntry, upperEntry, index)
break
}
u := dm.GetEntry(upperEntry, index)
if u.IsNotValid() {
fmt.Printf("ERROR: LowerUpper('%s', '%s', %d)\n", lowerEntry, upperEntry, index)
break
}
if l.ValueFloat > 0 {
ret = 0 - l.ValueFloat
break
}
ret = u.ValueFloat
}
return ret
}
func (dm *DataMap) GetPercent(entry string, max string, index int) float64 {
var ret float64
for range Only.Once {
v := dm.GetEntry(entry, index)
if v.IsNotValid() {
fmt.Printf("ERROR: GetPercent('%s', '%s', %d)\n", entry, max, index)
break
}
m := dm.GetEntry(max, index)
if m.IsNotValid() {
fmt.Printf("ERROR: GetPercent('%s', '%s', %d)\n", entry, max, index)
break
}
ret = GetPercent(v.ValueFloat, m.ValueFloat)
}
return ret
}
func (dm *DataMap) GetValue(entry string, index int) float64 {
var ret float64
for range Only.Once {
v := dm.GetEntry(entry, index)
if v.IsNotValid() {
fmt.Printf("ERROR: GetValue('%s', %d)\n", entry, index)
break
}
ret = v.ValueFloat
}
return ret
}
func (dm *DataMap) AppendMap(add DataMap) {
for range Only.Once {
if dm.DataPoints == nil {
dm.DataPoints = make(map[PointId]DataPointEntries)
}
for point, de := range add.DataPoints {
if dd, ok := dm.DataPoints[point]; ok {
jde, _ := json.Marshal(de)
jdd, _ := json.Marshal(dd)
if string(jdd) != string(jde) {
fmt.Printf("DIFF ")
}
fmt.Printf("Duplicate[%s]:\n%s\n%s\n", point, jde, jdd)
continue
}
dm.DataPoints[point] = de
dm.Order = append(dm.Order, point)
if Points.Exists(point) {
fmt.Printf("EXISTS: %s\n", point)
}
Points.Add(point, *de[len(de)-1].Point)
}
}
}
func (dm *DataMap) Add(pid PointId, de DataEntry) {
for range Only.Once {
if !strings.Contains(string(pid), ".") {
pid = PointId(de.EndPoint + "." + string(pid))
}
de.Index = len(dm.Order)
dm.DataPoints[pid] = append(dm.DataPoints[pid], de)
dm.Order = append(dm.Order, pid)
if Points.Exists(pid) {
fmt.Printf("EXISTS: %s\n", pid)
}
Points.Add(pid, *de.Point)
// if ep, ok := Points[point]; ok {
// jep, _ := json.Marshal(ep)
// jde, _ := json.Marshal(ep)
// fmt.Printf("EXISTS[%s]:\n%s\n%s\n", point, jde, jep)
// continue
// }
// Points[point] = *de.Point
}
}
func (dm *DataMap) AddEntry(endpoint string, parentId string, point Point, date DateTime, value string) {
for range Only.Once {
unit := point.Unit // Save unit.
// Match to a previously defined point.
p := GetPoint(endpoint, point.Id)
if p == nil {
point = *p
}
// var parents ParentDevices
// parents.Add(ParentDevice{Key: device})
var parent ParentDevice
parent.Set(parentId)
point.Parents.Add(parent)
if point.Name == "" {
point.Name = PointToName(point.Id)
}
// fid := JoinDevicePoint(parent.Key, point.Id)
ref := SetUnitValueString(value, unit)
point.Unit = ref.Unit()
point.Valid = true
if _, ok := dm.DataPoints[point.Id]; ok {
point.Id += ".BARF"
}
// dm.Add(JoinDevicePoint(endpoint, point.Id), DataEntry {
dm.Add(JoinDevicePoint(endpoint, point.Id), DataEntry {
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, point.Id),
// FullId: JoinDevicePoint(parent.Key, point.Id),
Parent: parent,
Point: &point,
Date: date,
Value: ref.String(),
ValueFloat: ref.Value(),
})
}
}
func (dm *DataMap) AddUnitValue(endpoint string, parentId string, pid PointId, name string, groupName string, date DateTime, ref UnitValue) {
for range Only.Once {
if endpoint == "" {
endpoint = apiReflect.GetCallerPackage(2)
}
ref = ref.UnitValueFix()
if name == "" {
name = string(pid)
}
point := GetPoint(parentId, pid)
if point == nil {
// No UV found. Create one.
dm.Add(pid, CreateDataEntryUnitValue(date, endpoint, parentId, pid, name, ref))
break
}
var parent ParentDevice
parent.Set(parentId)
point.Parents.Add(parent)
if point.Unit == "" {
point.Unit = ref.Unit()
}
if point.Name == "" {
point.Name = name
}
if point.Name == "" {
point.Name = PointToName(pid)
}
if point.GroupName == "" {
point.GroupName = groupName
}
dm.Add(NameDevicePoint(endpoint, pid), DataEntry {
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, point.Id),
// FullId: JoinDevicePoint(parent.Key, point.Id),
Parent: parent,
Point: point,
Date: date,
Value: ref.String(),
ValueFloat: ref.Value(),
})
}
}
func (dm *DataMap) AddFloat(endpoint string, parentId string, pid PointId, name string, date DateTime, value float64) {
for range Only.Once {
// fvs := Float64ToString(value)
point := GetPoint(parentId, pid)
if point == nil {
// No UV found. Create one.
dm.Add(pid, CreateDataEntryUnitValue(date, endpoint, parentId, pid, name, SetUnitValueFloat(value, "float")))
break
}
ref := SetUnitValueFloat(value, point.Unit)
if ref.Unit() != point.Unit {
fmt.Printf("OOOPS: Unit mismatch - %f %s != %f %s\n", value, point.Unit, ref.ValueFloat(), ref.Unit())
point.Unit = ref.Unit()
}
var parent ParentDevice
parent.Set(parentId)
point.Parents.Add(parent)
dm.Add(pid, DataEntry {
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, point.Id),
// FullId: JoinDevicePoint(parent.Key, point.Id),
Parent: parent,
Date: date,
Point: point,
Value: ref.String(),
ValueFloat: ref.Value(),
})
}
uv := SetUnitValueFloat(value, "float")
de := CreateDataEntryUnitValue(date, endpoint, parentId, pid, name, uv)
// de := CreateDataEntryUnitValue(date, endpoint, parentId, pid, name, UnitValue {
// Unit: "float",
// Value: fmt.Sprintf("%f", value),
// ValueFloat: 0,
// })
dm.Add(pid, de)
}
func (dm *DataMap) AddString(endpoint string, parentId string, pid PointId, name string, date DateTime, value string) {
dm.Add(pid, CreateDataEntryString(date, endpoint, parentId, pid, name, value))
}
func (dm *DataMap) AddInt(endpoint string, parentId string, pid PointId, name string, date DateTime, value int64) {
uv := SetUnitValueInteger(value, "int")
de := CreateDataEntryUnitValue(date, endpoint, parentId, pid, name, uv)
// de := CreateDataEntryUnitValue(date, endpoint, parentId, pid, name, UnitValue {
// Unit: "int",
// Value: fmt.Sprintf("%d", value),
// ValueFloat: float64(value),
// })
dm.Add(pid, de)
}
func (dm *DataMap) FromRefAddAlias(entry string, parentId string, pid PointId, name string) {
pe := dm.GetEntry(entry, 0)
if pe.IsNotValid() {
fmt.Printf("ERROR: FromRefAddAlias('%s', '%s', '%s', '%s')\n", entry, parentId, pid, name)
return
}
dm.Add(pid, pe.CreateAlias(pe.EndPoint, parentId, pid, name))
}
func (dm *DataMap) FromRefAddState(entry string, parentId string, pid PointId, name string) {
pe := dm.GetEntry(entry, 0)
if pe.IsNotValid() {
fmt.Printf("ERROR: FromRefAddState('%s', '%s', '%s', '%s')\n", entry, parentId, pid, name)
return
}
dm.Add(pid, pe.CreateState(pe.EndPoint, parentId, pid, name))
}
func (dm *DataMap) FromRefAddFloat(entry string, parentId string, pid PointId, name string, value float64) {
pe := dm.GetEntry(entry, 0)
if pe.IsNotValid() {
fmt.Printf("ERROR: FromRefAddFloat('%s', '%s', '%s', '%s')\n", entry, parentId, pid, name)
return
}
dm.Add(pid, pe.CreateFloat(pe.EndPoint, parentId, pid, name, value))
}
func (dm *DataMap) Print() {
for range Only.Once {
table := datatable.New("utf8-heavy")
table.AddHeaders(
"Index",
"EndPoint",
"Id",
"Name",
"Unit",
"Type",
"Value",
"Valid",
"GroupName",
"Parent Ids",
"Parent Types",
"Parent Codes",
)
for i, k := range dm.Order {
for _, v := range dm.DataPoints[k] {
table.AddRowItems(
i,
v.EndPoint,
v.Point.Id,
v.Point.Name,
v.Point.Unit,
v.Point.TimeSpan,
v.Value,
v.Point.Valid,
// fmt.Sprintf("%s\n%s\n", v.FullId, v.Value),
v.Point.GroupName,
v.Point.Parents.PsIds(),
v.Point.Parents.Types(),
v.Point.Parents.Codes(),
)
}
}
ret, _ := table.Render()
fmt.Println(ret)
}
}
func (de *DataEntry) CreateAlias(endpoint string, parentId string, pid PointId, name string) DataEntry {
if name == "" {
name = PointToName(pid)
}
ret := DataEntry {
Point: &Point {
Parents: de.Point.Parents,
Id: pid,
GroupName: "alias",
Name: name,
Unit: de.Point.Unit,
TimeSpan: de.Point.TimeSpan,
Valid: true,
States: nil,
},
Date: de.Date,
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, pid),
// FullId: JoinDevicePoint(parentId, pid),
Parent: de.Parent, // ParentDevice{},
Value: de.Value,
ValueFloat: de.ValueFloat,
ValueBool: de.ValueBool,
Index: de.Index,
}
ret.Parent.Set(parentId)
de.Point.Parents.Add(ret.Parent)
// de.FullId = JoinDevicePoint(endpoint, pid)
// de.FullId = NameDevicePoint(ret.Parent.Key, pid)
// de.Point.Id = pid
// de.Point.Name = name
// de.Point.GroupName = parentId
// de.Point.Valid = true
// de.EndPoint = endpoint
// de.Index = 0
return ret
}
func (de *DataEntry) CreateFloat(endpoint string, parentId string, pid PointId, name string, value float64) DataEntry {
if name == "" {
name = PointToName(pid)
}
de2 := de.CreateAlias(endpoint, parentId, pid, name)
uv := SetUnitValueFloat(value, de2.Point.Unit)
de2.Value = uv.String()
de2.ValueFloat = uv.Value()
return de2
}
func (de *DataEntry) CreateState(endpoint string, parentId string, pid PointId, name string) DataEntry {
if name == "" {
name = PointToName(pid)
}
de2 := de.CreateAlias(endpoint, parentId, pid, name)
if de2.ValueFloat == 0 {
de2.Value = "false"
de2.ValueBool = false
de2.ValueFloat = 0
} else {
de2.Value = "true"
de2.ValueBool = true
de2.ValueFloat = 1
}
de2.Point.Unit = "binary"
return de2
}
func JoinDevicePoint(device string, pid PointId) PointId {
var ret PointId
for range Only.Once {
if device == "" {
device = "virtual"
}
ret = PointId(fmt.Sprintf("%s.%s", device, pid))
}
return ret
}
func CreateDataEntryActive(date DateTime, endpoint string, parentId string, pid PointId, name string, value float64) DataEntry {
point := GetPoint(parentId, pid)
if point == nil {
if name == "" {
name = PointToName(pid)
}
point = CreatePoint(parentId, pid, name, "state")
}
var parent ParentDevice
parent.Set(parentId)
point.Parents.Add(parent)
return DataEntry {
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, point.Id),
// FullId: JoinDevicePoint(parent.Key, point.Id),
Parent: parent,
Point: point,
Date: date,
Value: fmt.Sprintf("%v", IsActive(value)),
ValueFloat: 0,
Index: 0,
}
}
func CreateDataEntryString(date DateTime, endpoint string, parentId string, pid PointId, name string, value string) DataEntry {
point := GetPoint(parentId, pid)
if point == nil {
if name == "" {
name = PointToName(pid)
}
point = CreatePoint(parentId, pid, name, "string")
}
var parent ParentDevice
parent.Set(parentId)
point.Parents.Add(parent)
return DataEntry {
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, pid),
// FullId: JoinDevicePoint(parent.Key, pid),
Parent: parent,
Point: point,
Date: date,
Value: value,
ValueFloat: 0,
Index: 0,
}
}
func CreateDataEntryUnitValue(date DateTime, endpoint string, parentId string, pid PointId, name string, value UnitValue) DataEntry {
value = value.UnitValueFix()
point := GetPoint(parentId, pid)
if point == nil {
if name == "" {
name = PointToName(pid)
}
point = CreatePoint(parentId, pid, name, value.Unit())
}
var parent ParentDevice
parent.Set(parentId)
point.Parents.Add(parent)
return DataEntry {
EndPoint: endpoint,
FullId: JoinDevicePoint(endpoint, pid),
// FullId: JoinDevicePoint(parent.Key, pid),
Parent: parent,
Point: point,
Date: date,
Value: value.String(),
ValueFloat: value.Value(),
Index: 0,
}
}
func CreatePoint(parentId string, pid PointId, name string, unit string) *Point {
if name == "" {
name = PointToName(pid)
}
ret := &Point {
Id: pid,
GroupName: parentId,
Name: name,
Unit: unit,
TimeSpan: "",
Valid: true,
}
return ret
}
func IsActive(value float64) bool {
if (value > 0.01) || (value < -0.01) {
return true
}
return false
}
func GetPercent(value float64, max float64) float64 {
if max == 0 {
return 0
}
return (value / max) * 100
}