diff --git a/.idea/workspace.xml b/.idea/workspace.xml index 49ab9dcd5..7224ce385 100644 --- a/.idea/workspace.xml +++ b/.idea/workspace.xml @@ -5,13 +5,30 @@ - + + + + + + + + + + + + + + + + + + + - @@ -80,7 +97,7 @@ - + @@ -88,23 +105,6 @@ - - - - - - - - - - - - - - - - - @@ -153,12 +153,12 @@ file://$PROJECT_DIR$/iSolarCloud/AppService/queryDeviceList/data.go - 201 + 207 file://$PROJECT_DIR$/iSolarCloud/api/struct_endpoint.go - 105 + 118 @@ -206,14 +206,9 @@ 260 - - file://$PROJECT_DIR$/iSolarCloud/api/struct_points.go - 289 - file://$PROJECT_DIR$/iSolarCloud/highlevel.go - 518 + 521 @@ -238,7 +233,7 @@ file://$PROJECT_DIR$/iSolarCloud/highlevel.go - 658 + 662 @@ -271,13 +266,90 @@ 273 + + file://$PROJECT_DIR$/iSolarCloud/AppService/queryDeviceList/data.go + 566 + + + file://$PROJECT_DIR$/cmd/cmd_mqtt.go + 369 + + + file://$PROJECT_DIR$/iSolarCloud/api/struct_data.go + 189 + + + file://$PROJECT_DIR$/iSolarCloud/api/apiReflect/reflect.go + 636 + + + file://$PROJECT_DIR$/iSolarCloud/api/apiReflect/reflect.go + 667 + + + file://$PROJECT_DIR$/iSolarCloud/AppService/getPsList/data.go + 322 + + + file://$PROJECT_DIR$/iSolarCloud/AppService/getPsList/data.go + 255 + + + file://$PROJECT_DIR$/cmd/cmd_mqtt.go + 461 + + + file://$PROJECT_DIR$/iSolarCloud/AppService/queryDeviceList/data.go + 332 + + + file://$PROJECT_DIR$/iSolarCloud/AppService/queryDeviceList/data.go + 326 + + + file://$PROJECT_DIR$/iSolarCloud/highlevel.go + 350 + + + file://$PROJECT_DIR$/iSolarCloud/highlevel.go + 341 + + + file://$PROJECT_DIR$/cmd/cmd_api.go + 179 + + + file://$PROJECT_DIR$/iSolarCloud/struct.go + 121 + + + file://$PROJECT_DIR$/iSolarCloud/api/struct_endpoint.go + 107 + - + + - + + diff --git a/cmd/cmd_api.go b/cmd/cmd_api.go index 790e38db5..cf556d6d4 100644 --- a/cmd/cmd_api.go +++ b/cmd/cmd_api.go @@ -183,7 +183,16 @@ func cmdApiGetFunc(_ *cobra.Command, args []string) { break } - Cmd.Error = Cmd.SunGrow.GetByJson(args[0], args[1]).GetError() + ep := Cmd.SunGrow.GetByJson(args[0], args[1]) + if Cmd.SunGrow.Error != nil { + Cmd.Error = Cmd.SunGrow.Error + break + } + if Cmd.Error != nil { + break + } + + Cmd.Error = ep.GetError() if Cmd.Error != nil { break } @@ -200,7 +209,16 @@ func cmdApiRawFunc(_ *cobra.Command, args []string) { break } - Cmd.Error = Cmd.SunGrow.GetByJson(args[0], args[1]).GetError() + ep := Cmd.SunGrow.GetByJson(args[0], args[1]) + if Cmd.SunGrow.Error != nil { + Cmd.Error = Cmd.SunGrow.Error + break + } + if Cmd.Error != nil { + break + } + + Cmd.Error = ep.GetError() if Cmd.Error != nil { break } @@ -217,7 +235,16 @@ func cmdApiSaveFunc(_ *cobra.Command, args []string) { break } - Cmd.Error = Cmd.SunGrow.GetByJson(args[0], args[1]).GetError() + ep := Cmd.SunGrow.GetByJson(args[0], args[1]) + if Cmd.SunGrow.Error != nil { + Cmd.Error = Cmd.SunGrow.Error + break + } + if Cmd.Error != nil { + break + } + + Cmd.Error = ep.GetError() if Cmd.Error != nil { break } diff --git a/cmd/cmd_data.go b/cmd/cmd_data.go index cff0ae664..f53898723 100644 --- a/cmd/cmd_data.go +++ b/cmd/cmd_data.go @@ -61,10 +61,11 @@ func AttachCmdData(cmd *cobra.Command) *cobra.Command { AttachCmdDataTemplate(cmdDataGet) AttachCmdDataTemplatePoints(cmdDataGet) AttachCmdDataPoints(cmdDataGet) - AttachCmdDataPointNames(cmdDataGet) + AttachCmdDataTemplates(cmdDataGet) AttachCmdDataMqtt(cmdDataGet) AttachCmdDataRealTime(cmdDataGet) AttachCmdDataPsDetails(cmdDataGet) + AttachCmdDataPointNames(cmdDataGet) // ******************************************************************************** var cmdDataRaw = &cobra.Command{ @@ -85,7 +86,7 @@ func AttachCmdData(cmd *cobra.Command) *cobra.Command { AttachCmdDataStats(cmdDataRaw) AttachCmdDataTemplate(cmdDataRaw) AttachCmdDataPoints(cmdDataRaw) - AttachCmdDataPointNames(cmdDataRaw) + AttachCmdDataTemplates(cmdDataRaw) AttachCmdDataMqtt(cmdDataRaw) AttachCmdDataRealTime(cmdDataRaw) AttachCmdDataPsDetails(cmdDataRaw) @@ -109,10 +110,11 @@ func AttachCmdData(cmd *cobra.Command) *cobra.Command { AttachCmdDataStats(cmdDataSave) AttachCmdDataTemplate(cmdDataSave) AttachCmdDataPoints(cmdDataSave) - AttachCmdDataPointNames(cmdDataSave) + AttachCmdDataTemplates(cmdDataSave) AttachCmdDataMqtt(cmdDataSave) AttachCmdDataRealTime(cmdDataSave) AttachCmdDataPsDetails(cmdDataSave) + AttachCmdDataPointNames(cmdDataSave) // ******************************************************************************** var cmdDataGraph = &cobra.Command{ diff --git a/cmd/cmd_data_sub.go b/cmd/cmd_data_sub.go index 280aa94e9..45708e426 100644 --- a/cmd/cmd_data_sub.go +++ b/cmd/cmd_data_sub.go @@ -95,7 +95,7 @@ func AttachCmdDataPoints(cmd *cobra.Command) *cobra.Command { return cmd } -func AttachCmdDataPointNames(cmd *cobra.Command) *cobra.Command { +func AttachCmdDataTemplates(cmd *cobra.Command) *cobra.Command { // ******************************************************************************** var c = &cobra.Command{ Use: "templates", @@ -185,3 +185,25 @@ func AttachCmdDataPsDetails(cmd *cobra.Command) *cobra.Command { return cmd } + +func AttachCmdDataPointNames(cmd *cobra.Command) *cobra.Command { + // ******************************************************************************** + var c = &cobra.Command{ + Use: "point-names", + Aliases: []string{"names"}, + Short: fmt.Sprintf("Get iSolarCloud point names."), + Long: fmt.Sprintf("Get iSolarCloud point names."), + DisableFlagParsing: false, + DisableFlagsInUseLine: false, + PreRunE: Cmd.SunGrowArgs, + RunE: func(cmd *cobra.Command, args []string) error { + _ = SwitchOutput(cmd) + return Cmd.SunGrow.GetPointNames(args...) + }, + Args: cobra.MinimumNArgs(0), + } + cmd.AddCommand(c) + c.Example = PrintExamples(c, "") + + return cmd +} diff --git a/cmd/cmd_mqtt.go b/cmd/cmd_mqtt.go index 25386c2b4..da0d10bc4 100644 --- a/cmd/cmd_mqtt.go +++ b/cmd/cmd_mqtt.go @@ -292,22 +292,33 @@ func Update1(newDay bool) error { if newDay { LogPrintDate("New day: Configuring %d entries in HASSIO.\n", len(data.Entries)) - for _, r := range data.Entries { + for _, o := range data.Order { + r := data.Entries[o] + fmt.Printf("C") re := mmHa.EntityConfig { - Type: r.ValueType.Type, - Name: r.ValueType.Id, // PointName, + Name: r.Point.Id, // PointName, SubName: "", - ParentId: r.ValueType.PsKey, + ParentId: r.EndPoint, ParentName: "", - UniqueId: r.PointId, - FullName: r.ValueType.Description, - Units: r.Unit, - ValueName: r.PointId, + UniqueId: r.Point.Id, + FullId: r.Point.FullId, + Units: r.Point.Unit, + ValueName: r.Point.Name, DeviceClass: "", + StateClass: r.Point.Type, Value: r.Value, + + // Icon: "", + // ValueTemplate: "", + // LastReset: "", + // LastResetValueTemplate: "", } + // if re.LastResetValueTemplate != "" { + // fmt.Printf("HEY\n") + // } + Cmd.Error = Cmd.Mqtt.BinarySensorPublishConfig(re) if Cmd.Error != nil { break @@ -322,19 +333,24 @@ func Update1(newDay bool) error { } LogPrintDate("Updating %d entries to HASSIO.\n", len(data.Entries)) - for _, r := range data.Entries { + for _, o := range data.Order { + r := data.Entries[o] + fmt.Printf("U") re := mmHa.EntityConfig { - Type: r.ValueType.Type, - Name: r.ValueType.Id, // PointName, + Name: r.Point.Id, // PointName, SubName: "", - ParentId: r.ValueType.PsKey, + ParentId: r.EndPoint, ParentName: "", - UniqueId: r.PointId, - FullName: r.ValueType.Description, - Units: r.Unit, - ValueName: r.PointId, + UniqueId: r.Point.Id, + // UniqueId: r.Id, + FullId: r.Point.FullId, + // FullName: r.Point.Name, + Units: r.Point.Unit, + ValueName: r.Point.Name, + // ValueName: r.Id, DeviceClass: "", + StateClass: r.Point.Type, Value: r.Value, } @@ -369,20 +385,25 @@ func Update2(newDay bool) error { if newDay { LogPrintDate("New day: Configuring %d entries in HASSIO.\n", len(data.Entries)) - for _, r := range data.Entries { + for _, o := range data.Order { + r := data.Entries[o] + fmt.Printf("C") re := mmHa.EntityConfig { - Type: r.ValueType.Type, - Name: r.ValueType.Id, // PointName, + Name: r.Point.Id, // PointName, SubName: "", - ParentId: r.ValueType.PsKey, + ParentId: r.EndPoint, ParentName: "", - UniqueId: r.PointId, - FullName: r.ValueType.Description, - Units: r.Unit, - ValueName: r.PointId, + UniqueId: r.Point.Id, + // UniqueId: r.Id, + FullId: r.Point.FullId, + // FullName: r.Point.Name, + Units: r.Point.Unit, + ValueName: r.Point.Name, + // ValueName: r.Id, DeviceClass: "", + StateClass: r.Point.Type, Value: r.Value, } @@ -400,20 +421,25 @@ func Update2(newDay bool) error { } LogPrintDate("Updating %d entries to HASSIO.\n", len(data.Entries)) - for _, r := range data.Entries { + for _, o := range data.Order { + r := data.Entries[o] + fmt.Printf("U") re := mmHa.EntityConfig { - Type: r.ValueType.Type, - Name: r.ValueType.Id, // PointName, + Name: r.Point.Id, // PointName, SubName: "", - ParentId: r.ValueType.PsKey, + ParentId: r.EndPoint, ParentName: "", - UniqueId: r.PointId, - FullName: r.ValueType.Description, - Units: r.Unit, - ValueName: r.PointId, + UniqueId: r.Point.Id, + // UniqueId: r.Id, + FullId: r.Point.FullId, + // FullName: r.Point.Name, + Units: r.Point.Unit, + ValueName: r.Point.Name, + // ValueName: r.Id, DeviceClass: "", + StateClass: r.Point.Type, Value: r.Value, } diff --git a/examples.txt b/examples.txt index 495dbcfeb..af450adaf 100644 --- a/examples.txt +++ b/examples.txt @@ -99,3 +99,15 @@ sensor.sungrow_total_load_active_power == sensor.sungrow_total_active_power ./bin/GoSungrow data save template 8042 20220212 ./bin/GoSungrow get raw template 20220202 ./bin/GoSungrow get template 8042 20220212 + + +################################################################################ + +"energy_flow" +1 / 3 - PV2Load && PV2Battery + + + "1" - PV to Load + "3" - Battery to Load + "5" - PV to Battery + diff --git a/go.mod b/go.mod index 7e2a6c900..d02a95cbe 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.17 require ( github.com/acarl005/textcol v0.0.0 + github.com/davecgh/go-spew v1.1.1 github.com/eclipse/paho.mqtt.golang v1.3.5 github.com/go-co-op/gocron v1.13.0 github.com/go-git/go-billy/v5 v5.3.1 diff --git a/iSolarCloud/AppService/getPowerDeviceModelTree/data.go b/iSolarCloud/AppService/getPowerDeviceModelTree/data.go index 35758e739..81dc9a2eb 100644 --- a/iSolarCloud/AppService/getPowerDeviceModelTree/data.go +++ b/iSolarCloud/AppService/getPowerDeviceModelTree/data.go @@ -10,7 +10,7 @@ const Url = "/v1/devService/getPowerDeviceModelTree" const Disabled = true type RequestData struct { - // DeviceType string `json:"device_type" required:"true"` + Id string `json:"id" required:"true"` } func (rd RequestData) IsValid() error { diff --git a/iSolarCloud/AppService/getPowerDevicePointInfo/data.go b/iSolarCloud/AppService/getPowerDevicePointInfo/data.go index 38d906194..5dc27c833 100644 --- a/iSolarCloud/AppService/getPowerDevicePointInfo/data.go +++ b/iSolarCloud/AppService/getPowerDevicePointInfo/data.go @@ -2,15 +2,14 @@ package getPowerDevicePointInfo import ( "GoSungrow/iSolarCloud/api/apiReflect" - "errors" "fmt" ) const Url = "/v1/reportService/getPowerDevicePointInfo" -const Disabled = true +const Disabled = false type RequestData struct { - // DeviceType string `json:"device_type" required:"true"` + Id string `json:"id" required:"true"` } func (rd RequestData) IsValid() error { @@ -24,17 +23,23 @@ func (rd RequestData) Help() string { type ResultData struct { - Dummy string `json:"dummy"` + DeviceType int64 `json:"device_type" PointId:"device_type" PointType:""` + ID int64 `json:"id" PointId:"id" PointType:""` + Period int64 `json:"period" PointId:"period" PointType:""` + PointID int64 `json:"point_id" PointId:"point_id" PointType:""` + PointName string `json:"point_name" PointId:"point_name" PointType:""` + ShowPointName string `json:"show_point_name" PointId:"show_point_name" PointType:""` + TranslationID int64 `json:"translation_id" PointId:"translation_id" PointType:""` } func (e *ResultData) IsValid() error { var err error - switch { - case e.Dummy == "": - break - default: - err = errors.New(fmt.Sprintf("unknown error '%s'", e.Dummy)) - } + // switch { + // case e.Dummy == "": + // break + // default: + // err = errors.New(fmt.Sprintf("unknown error '%s'", e.Dummy)) + // } return err } diff --git a/iSolarCloud/AppService/getPowerDevicePointInfo/struct.go b/iSolarCloud/AppService/getPowerDevicePointInfo/struct.go index 07617fdc1..c24709374 100644 --- a/iSolarCloud/AppService/getPowerDevicePointInfo/struct.go +++ b/iSolarCloud/AppService/getPowerDevicePointInfo/struct.go @@ -24,6 +24,7 @@ type EndPoint struct { api.EndPointStruct Request Request Response Response + RawResponse []byte } // Request - Holds the api.RequestCommon and user RequestData structures. See data.go for request fields. @@ -127,7 +128,8 @@ func (e EndPoint) Call() api.EndPoint { // GetJsonData - Get the JSON representation of ResultData, either as condensed or "pretty". func (e EndPoint) GetJsonData(raw bool) output.Json { if raw { - return output.Json(e.ApiRoot.Body) + // return output.GetAsPrettyJson(string(e.RawResponse)) + return output.Json(e.RawResponse) } else { return output.GetAsPrettyJson(e.Response.ResultData) } @@ -247,6 +249,7 @@ func (e EndPoint) IsRequestValid() error { // (Used by the web call method.) func (e EndPoint) SetResponse(ref []byte) api.EndPoint { for range Only.Once { + e.RawResponse = ref e.Error = json.Unmarshal(ref, &e.Response) if e.Error != nil { break diff --git a/iSolarCloud/AppService/getPowerDevicePointNames/data.go b/iSolarCloud/AppService/getPowerDevicePointNames/data.go index 6cb8dd73a..32563c7b2 100644 --- a/iSolarCloud/AppService/getPowerDevicePointNames/data.go +++ b/iSolarCloud/AppService/getPowerDevicePointNames/data.go @@ -19,6 +19,11 @@ const ( DeviceType11 = "11" DeviceType14 = "14" DeviceType17 = "17" + DeviceType23 = "23" + DeviceType26 = "26" + DeviceType37 = "37" + DeviceType41 = "41" + DeviceType47 = "47" ) var DeviceTypes = []string{ @@ -30,6 +35,11 @@ var DeviceTypes = []string{ DeviceType11, DeviceType14, DeviceType17, + DeviceType23, + DeviceType26, + DeviceType37, + DeviceType41, + DeviceType47, } type RequestData struct { diff --git a/iSolarCloud/AppService/getPsDetailWithPsType/data.go b/iSolarCloud/AppService/getPsDetailWithPsType/data.go index af701bf63..beef685fd 100644 --- a/iSolarCloud/AppService/getPsDetailWithPsType/data.go +++ b/iSolarCloud/AppService/getPsDetailWithPsType/data.go @@ -196,7 +196,7 @@ func (e *EndPoint) GetDataTable() output.Table { _ = table.AddRow( now, api.NameDevicePoint(e.Response.ResultData.PsPsKey, n), - p.Description, + p.Name, keys[n].Value, p.Unit, keys[n].Unit, @@ -207,7 +207,7 @@ func (e *EndPoint) GetDataTable() output.Table { _ = table.AddRow( now, api.NameDevicePoint(e.Response.ResultData.PsPsKey, n), - api.UpperCase(n), + api.PointToName(n), keys[n].Value, keys[n].Unit, keys[n].Unit, @@ -226,7 +226,7 @@ func (e *EndPoint) GetDataTable() output.Table { _ = table.AddRow( now, api.NameDevicePoint(sid.PsKey, n), - p.Description, + p.Name, keys[n].Value, p.Unit, keys[n].Unit, @@ -237,7 +237,7 @@ func (e *EndPoint) GetDataTable() output.Table { _ = table.AddRow( now, api.NameDevicePoint(sid.PsKey, n), - api.UpperCase(n), + api.PointToName(n), keys[n].Value, keys[n].Unit, keys[n].Unit, @@ -261,8 +261,8 @@ func (e *EndPoint) GetDataTable() output.Table { return table } -func (e *EndPoint) GetData() api.Data { - var ret api.Data +func (e *EndPoint) GetData() api.DataMap { + var ret api.DataMap // for range Only.Once { // index := 0 diff --git a/iSolarCloud/AppService/getPsList/data.go b/iSolarCloud/AppService/getPsList/data.go index 336631930..53132754f 100644 --- a/iSolarCloud/AppService/getPsList/data.go +++ b/iSolarCloud/AppService/getPsList/data.go @@ -6,7 +6,6 @@ import ( "GoSungrow/iSolarCloud/api/apiReflect" "GoSungrow/iSolarCloud/api/output" "fmt" - "strconv" "time" ) @@ -27,35 +26,35 @@ func (rd RequestData) Help() string { type ResultData struct { PageList []struct { - AlarmCount int64 `json:"alarm_count"` - AlarmDevCount int64 `json:"alarm_dev_count"` - AreaID interface{} `json:"area_id"` - AreaType interface{} `json:"area_type"` - ArrearsStatus int64 `json:"arrears_status"` - BuildDate string `json:"build_date"` - BuildStatus int64 `json:"build_status"` - Co2Reduce api.UnitValue `json:"co2_reduce"` - Co2ReduceTotal api.UnitValue `json:"co2_reduce_total"` - CurrPower api.UnitValue `json:"curr_power"` - DailyIrradiation api.UnitValue `json:"daily_irradiation"` - DailyIrradiationVirgin interface{} `json:"daily_irradiation_virgin"` - DesignCapacity string `json:"design_capacity"` - DesignCapacityUnit string `json:"design_capacity_unit"` - DesignCapacityVirgin float64 `json:"design_capacity_virgin"` - EquivalentHour api.UnitValue `json:"equivalent_hour"` - EsDisenergy api.UnitValue `json:"es_disenergy"` - EsEnergy api.UnitValue `json:"es_energy"` - EsPower api.UnitValue `json:"es_power"` - EsTotalDisenergy api.UnitValue `json:"es_total_disenergy"` - EsTotalEnergy api.UnitValue `json:"es_total_energy"` - ExpectInstallDate string `json:"expect_install_date"` - FaultAlarmOfflineDevCount int64 `json:"fault_alarm_offline_dev_count"` - FaultCount int64 `json:"fault_count"` - FaultDevCount int64 `json:"fault_dev_count"` - GcjLatitude string `json:"gcj_latitude"` - GcjLongitude string `json:"gcj_longitude"` - GprsLatitude interface{} `json:"gprs_latitude"` - GprsLongitude interface{} `json:"gprs_longitude"` + AlarmCount int64 `json:"alarm_count" PointId:"alarm_count" PointType:"PointTypeBoot"` + AlarmDevCount int64 `json:"alarm_dev_count" PointId:"alarm_dev_count" PointType:"PointTypeBoot"` + AreaID interface{} `json:"area_id" PointId:"area_id" PointType:""` + AreaType interface{} `json:"area_type" PointId:"area_type" PointType:""` + ArrearsStatus int64 `json:"arrears_status" PointId:"arrears_status" PointType:""` + BuildDate string `json:"build_date" PointId:"build_date" PointType:""` + BuildStatus int64 `json:"build_status" PointId:"build_status" PointType:""` + Co2Reduce api.UnitValue `json:"co2_reduce" PointId:"co2_reduce" PointType:""` + Co2ReduceTotal api.UnitValue `json:"co2_reduce_total" PointId:"co2_reduce_total" PointType:"PointTypeTotal"` + CurrPower api.UnitValue `json:"curr_power" PointId:"curr_power" PointType:""` + DailyIrradiation api.UnitValue `json:"daily_irradiation" PointId:"daily_irradiation" PointType:"PointTypeDaily"` + DailyIrradiationVirgin interface{} `json:"daily_irradiation_virgin" PointId:"daily_irradiation_virgin" PointType:"PointTypeDaily"` + DesignCapacity string `json:"design_capacity" PointId:"design_capacity" PointType:""` + DesignCapacityUnit string `json:"design_capacity_unit" PointId:"design_capacity_unit" PointType:""` + DesignCapacityVirgin float64 `json:"design_capacity_virgin" PointId:"design_capacity_virgin" PointType:""` + EquivalentHour api.UnitValue `json:"equivalent_hour" PointId:"equivalent_hour" PointType:"PointTypeDaily"` + EsDisenergy api.UnitValue `json:"es_discharge_energy" PointId:"es_discharge_energy" PointAlias:"p83089" PointType:""` + EsEnergy api.UnitValue `json:"es_energy" PointId:"es_energy" PointAlias:"p83120" PointType:""` + EsPower api.UnitValue `json:"es_power" PointId:"es_power" PointAlias:"p83081" PointType:""` + EsTotalDisenergy api.UnitValue `json:"es_total_discharge_energy" PointId:"es_total_discharge_energy" PointAlias:"p83095" PointType:"PointTypeTotal"` + EsTotalEnergy api.UnitValue `json:"es_total_energy" PointId:"es_total_energy" PointAlias:"p83127" PointType:"PointTypeTotal"` + ExpectInstallDate string `json:"expect_install_date" PointId:"expect_install_date" PointType:""` + FaultAlarmOfflineDevCount int64 `json:"fault_alarm_offline_dev_count" PointId:"fault_alarm_offline_dev_count" PointType:""` + FaultCount int64 `json:"fault_count" PointId:"fault_count" PointType:""` + FaultDevCount int64 `json:"fault_dev_count" PointId:"fault_dev_count" PointType:""` + GcjLatitude string `json:"gcj_latitude" PointId:"gcj_latitude" PointType:""` + GcjLongitude string `json:"gcj_longitude" PointId:"gcj_longitude" PointType:""` + GprsLatitude interface{} `json:"gprs_latitude" PointId:"gprs_latitude" PointType:""` + GprsLongitude interface{} `json:"gprs_longitude" PointId:"gprs_longitude" PointType:""` Images []struct { FileID int64 `json:"file_id"` ID int64 `json:"id"` @@ -66,90 +65,90 @@ type ResultData struct { PsID int64 `json:"ps_id"` PsUnitUUID interface{} `json:"ps_unit_uuid"` } `json:"images"` - InstallDate string `json:"install_date"` - InstalledPowerMap api.UnitValue `json:"installed_power_map"` - InstalledPowerVirgin float64 `json:"installed_power_virgin"` - InstallerAlarmCount int64 `json:"installer_alarm_count"` - InstallerFaultCount int64 `json:"installer_fault_count"` - InstallerPsFaultStatus int64 `json:"installer_ps_fault_status"` - IsBankPs int64 `json:"is_bank_ps"` - IsTuv int64 `json:"is_tuv"` - JoinYearInitElec float64 `json:"join_year_init_elec"` - Latitude float64 `json:"latitude"` - Location string `json:"location"` - Longitude float64 `json:"longitude"` - MapLatitude string `json:"map_latitude"` - MapLongitude string `json:"map_longitude"` - MlpeFlag int64 `json:"mlpe_flag"` - Nmi interface{} `json:"nmi"` - OfflineDevCount int64 `json:"offline_dev_count"` - OperateYear interface{} `json:"operate_year"` - OperationBusName interface{} `json:"operation_bus_name"` - OwnerAlarmCount int64 `json:"owner_alarm_count"` - OwnerFaultCount int64 `json:"owner_fault_count"` - OwnerPsFaultStatus int64 `json:"owner_ps_fault_status"` - P83022y string `json:"p83022y"` - P83046 interface{} `json:"p83046"` - P83048 interface{} `json:"p83048"` - P83049 interface{} `json:"p83049"` - P83050 interface{} `json:"p83050"` - P83051 interface{} `json:"p83051"` - P83054 interface{} `json:"p83054"` - P83055 interface{} `json:"p83055"` - P83067 interface{} `json:"p83067"` - P83070 interface{} `json:"p83070"` - P83076 float64 `json:"p83076"` - P83077 float64 `json:"p83077"` - P83081 float64 `json:"p83081"` - P83089 float64 `json:"p83089"` - P83095 float64 `json:"p83095"` - P83118 float64 `json:"p83118"` - P83120 float64 `json:"p83120"` - P83127 float64 `json:"p83127"` - ParamCo2 float64 `json:"param_co2"` - ParamCoal float64 `json:"param_coal"` - ParamIncome float64 `json:"param_income"` - ParamMeter float64 `json:"param_meter"` - ParamNox float64 `json:"param_nox"` - ParamPowder float64 `json:"param_powder"` - ParamSo2 float64 `json:"param_so2"` - ParamTree float64 `json:"param_tree"` - ParamWater float64 `json:"param_water"` - PrScale string `json:"pr_scale"` - Producer interface{} `json:"producer"` - PsCountryID int64 `json:"ps_country_id"` - PsFaultStatus int64 `json:"ps_fault_status"` - PsHealthStatus string `json:"ps_health_status"` - PsHolder string `json:"ps_holder"` - PsID int64 `json:"ps_id"` - PsIsNotInit string `json:"ps_is_not_init"` - PsName string `json:"ps_name"` - PsShortName string `json:"ps_short_name"` - PsStatus int64 `json:"ps_status"` - PsTimezone string `json:"ps_timezone"` - PsType int64 `json:"ps_type"` - PvEnergy api.UnitValue `json:"pv_energy"` - PvPower api.UnitValue `json:"pv_power"` - Radiation api.UnitValue `json:"radiation"` - RadiationVirgin interface{} `json:"radiation_virgin"` - RecoreCreateTime string `json:"recore_create_time"` - SafeStartDate string `json:"safe_start_date"` - ShareType string `json:"share_type"` - ShippingAddress string `json:"shipping_address"` - ShippingZipCode string `json:"shipping_zip_code"` - TodayEnergy api.UnitValue `json:"today_energy"` - TodayIncome api.UnitValue `json:"today_income"` - TotalCapcity api.UnitValue `json:"total_capcity"` - TotalEnergy api.UnitValue `json:"total_energy"` - TotalIncome api.UnitValue `json:"total_income"` - TotalInitCo2Accelerate float64 `json:"total_init_co2_accelerate"` - TotalInitElec float64 `json:"total_init_elec"` - TotalInitProfit float64 `json:"total_init_profit"` - UseEnergy api.UnitValue `json:"use_energy"` - ValidFlag int64 `json:"valid_flag"` - WgsLatitude float64 `json:"wgs_latitude"` - WgsLongitude float64 `json:"wgs_longitude"` - ZipCode string `json:"zip_code"` + InstallDate string `json:"install_date" PointId:"install_date" PointType:""` + InstalledPowerMap api.UnitValue `json:"installed_power_map" PointId:"installed_power_map" PointType:""` + InstalledPowerVirgin float64 `json:"installed_power_virgin" PointId:"installed_power_virgin" PointType:""` + InstallerAlarmCount int64 `json:"installer_alarm_count" PointId:"installer_alarm_count" PointType:""` + InstallerFaultCount int64 `json:"installer_fault_count" PointId:"installer_fault_count" PointType:""` + InstallerPsFaultStatus int64 `json:"installer_ps_fault_status" PointId:"installer_ps_fault_status" PointType:""` + IsBankPs int64 `json:"is_bank_ps" PointId:"is_bank_ps" PointType:""` + IsTuv int64 `json:"is_tuv" PointId:"is_tuv" PointType:""` + JoinYearInitElec float64 `json:"join_year_init_elec" PointId:"join_year_init_elec" PointType:""` + Latitude float64 `json:"latitude" PointId:"latitude" PointType:""` + Location string `json:"location" PointId:"location" PointType:""` + Longitude float64 `json:"longitude" PointId:"longitude" PointType:""` + MapLatitude string `json:"map_latitude" PointId:"map_latitude" PointType:""` + MapLongitude string `json:"map_longitude" PointId:"map_longitude" PointType:""` + MlpeFlag int64 `json:"mlpe_flag" PointId:"mlpe_flag" PointType:""` + Nmi interface{} `json:"nmi" PointId:"nmi" PointType:""` + OfflineDevCount int64 `json:"offline_dev_count" PointId:"offline_dev_count" PointType:""` + OperateYear interface{} `json:"operate_year" PointId:"operate_year" PointType:""` + OperationBusName interface{} `json:"operation_bus_name" PointId:"operation_bus_name" PointType:""` + OwnerAlarmCount int64 `json:"owner_alarm_count" PointId:"owner_alarm_count" PointType:""` + OwnerFaultCount int64 `json:"owner_fault_count" PointId:"owner_fault_count" PointType:""` + OwnerPsFaultStatus int64 `json:"owner_ps_fault_status" PointId:"owner_ps_fault_status" PointType:""` + P83022y string `json:"p83022y" PointId:"P83022" PointType:""` + P83046 interface{} `json:"p83046" PointId:"p83046" PointType:""` + P83048 interface{} `json:"p83048" PointId:"p83048" PointType:""` + P83049 interface{} `json:"p83049" PointId:"p83049" PointType:""` + P83050 interface{} `json:"p83050" PointId:"p83050" PointType:""` + P83051 interface{} `json:"p83051" PointId:"p83051" PointType:""` + P83054 interface{} `json:"p83054" PointId:"p83054" PointType:""` + P83055 interface{} `json:"p83055" PointId:"p83055" PointType:""` + P83067 interface{} `json:"p83067" PointId:"p83067" PointType:""` + P83070 interface{} `json:"p83070" PointId:"p83070" PointType:""` + P83076 float64 `json:"p83076" PointId:"p83076" PointType:""` // Dupe of PvPower + P83077 float64 `json:"p83077" PointId:"p83077" PointType:""` + P83081 float64 `json:"p83081" PointId:"p83081" PointType:""` // Dupe of EsPower + P83089 float64 `json:"p83089" PointId:"p83089" PointType:""` // Dupe of EsDisenergy + P83095 float64 `json:"p83095" PointId:"p83095" PointType:""` // Dupe of EsTotalDisenergy + P83118 float64 `json:"p83118" PointId:"p83118" PointType:""` // Dupe of UseEnergy + P83120 float64 `json:"p83120" PointId:"p83120" PointType:""` // Dupe of EsEnergy + P83127 float64 `json:"p83127" PointId:"p83127" PointType:""` // Dupe of EsTotalEnergy + ParamCo2 float64 `json:"param_co2" PointId:"param_co2" PointType:""` + ParamCoal float64 `json:"param_coal" PointId:"param_coal" PointType:""` + ParamIncome float64 `json:"param_income" PointId:"param_income" PointType:""` + ParamMeter float64 `json:"param_meter" PointId:"param_meter" PointType:""` + ParamNox float64 `json:"param_nox" PointId:"param_nox" PointType:""` + ParamPowder float64 `json:"param_powder" PointId:"param_powder" PointType:""` + ParamSo2 float64 `json:"param_so2" PointId:"param_so2" PointType:""` + ParamTree float64 `json:"param_tree" PointId:"param_tree" PointType:""` + ParamWater float64 `json:"param_water" PointId:"param_water" PointType:""` + PrScale string `json:"pr_scale" PointId:"pr_scale" PointType:""` + Producer interface{} `json:"producer" PointId:"producer" PointType:""` + PsCountryID int64 `json:"ps_country_id" PointId:"ps_country_id" PointType:""` + PsFaultStatus int64 `json:"ps_fault_status" PointId:"ps_fault_status" PointType:""` + PsHealthStatus string `json:"ps_health_status" PointId:"ps_health_status" PointType:""` + PsHolder string `json:"ps_holder" PointId:"ps_holder" PointType:""` + PsID int64 `json:"ps_id" PointId:"ps_id" PointType:""` + PsIsNotInit string `json:"ps_is_not_init" PointId:"ps_is_not_init" PointType:""` + PsName string `json:"ps_name" PointId:"ps_name" PointType:""` + PsShortName string `json:"ps_short_name" PointId:"ps_short_name" PointType:""` + PsStatus int64 `json:"ps_status" PointId:"ps_status" PointType:""` + PsTimezone string `json:"ps_timezone" PointId:"ps_timezone" PointType:""` + PsType int64 `json:"ps_type" PointId:"ps_type" PointType:""` + PvEnergy api.UnitValue `json:"pv_energy" PointId:"pv_energy" PointAlias:"p83077" PointType:""` + PvPower api.UnitValue `json:"pv_power" PointId:"pv_power" PointAlias:"p83076" PointType:""` + Radiation api.UnitValue `json:"radiation" PointId:"radiation" PointType:""` + RadiationVirgin interface{} `json:"radiation_virgin" PointId:"radiation_virgin" PointType:""` + RecoreCreateTime string `json:"recore_create_time" PointId:"recore_create_time" PointType:""` + SafeStartDate string `json:"safe_start_date" PointId:"safe_start_date" PointType:""` + ShareType string `json:"share_type" PointId:"share_type" PointType:""` + ShippingAddress string `json:"shipping_address" PointId:"shipping_address" PointType:""` + ShippingZipCode string `json:"shipping_zip_code" PointId:"shipping_zip_code" PointType:""` + TodayEnergy api.UnitValue `json:"today_energy" PointId:"today_energy" PointType:"PointTypeDaily"` + TodayIncome api.UnitValue `json:"today_income" PointId:"today_income" PointType:"PointTypeDaily"` + TotalCapcity api.UnitValue `json:"total_capacity" PointId:"total_capacity" PointType:"PointTypeTotal"` + TotalEnergy api.UnitValue `json:"total_energy" PointId:"total_energy" PointType:"PointTypeTotal"` + TotalIncome api.UnitValue `json:"total_income" PointId:"total_income" PointType:"PointTypeTotal"` + TotalInitCo2Accelerate float64 `json:"total_init_co2_accelerate" PointId:"total_init_co2_accelerate" PointType:"PointTypeTotal"` + TotalInitElec float64 `json:"total_init_elec" PointId:"total_init_elec" PointType:"PointTypeTotal"` + TotalInitProfit float64 `json:"total_init_profit" PointId:"total_init_profit" PointType:"PointTypeTotal"` + UseEnergy api.UnitValue `json:"use_energy" PointId:"use_energy" PointAlias:"p83118" PointType:""` + ValidFlag int64 `json:"valid_flag" PointId:"valid_flag" PointType:""` + WgsLatitude float64 `json:"wgs_latitude" PointId:"wgs_latitude" PointType:""` + WgsLongitude float64 `json:"wgs_longitude" PointId:"wgs_longitude" PointType:""` + ZipCode string `json:"zip_code" PointId:"zip_code" PointType:""` } `json:"pageList"` RowCount int64 `json:"rowCount"` } @@ -239,12 +238,12 @@ func (e *EndPoint) GetPsId() int64 { return e.Response.ResultData.GetPsId() } -func (e *EndPoint) GetData() api.Data { +func (e *EndPoint) GetData() api.DataMap { return e.Response.ResultData.GetData() } -func (e *ResultData) GetData() api.Data { - var ret api.Data +func (e *ResultData) GetData() api.DataMap { + entries := api.NewDataMap() for range Only.Once { i := len(e.PageList) @@ -252,50 +251,51 @@ func (e *ResultData) GetData() api.Data { break } - now := api.NewDateTime(time.Now().Round(5 * time.Minute).Format(api.DtLayoutZeroSeconds)) + // now := api.NewDateTime(time.Now().Round(5 * time.Minute).Format(api.DtLayoutZeroSeconds)) for _, p := range e.PageList { - psId := strconv.FormatInt(p.PsID, 10) + // psId := strconv.FormatInt(p.PsID, 10) + entries.StructToPoints("", p) - ret.Entries = append(ret.Entries, add(now, psId, "p83077", "Pv Energy", p.PvEnergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83089", "Es Discharge Energy", p.EsDisenergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83095", "Es Total Discharge Energy", p.EsTotalDisenergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83118", "Use Energy", p.UseEnergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83120", "Es Energy", p.EsEnergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83127", "Es Total Energy", p.EsTotalEnergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83076", "Pv Power", p.PvPower, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "p83081", "Es Power", p.EsPower, len(ret.Entries))) - - ret.Entries = append(ret.Entries, add(now, psId, "co2_reduce", "Co2 Reduce", p.Co2Reduce, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "co2_reduce_total", "Co2 Reduce Total", p.Co2ReduceTotal, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "curr_power", "Curr Power", p.CurrPower, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "daily_irradiation", "Daily Irradiation", p.DailyIrradiation, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "equivalent_hour", "Equivalent Hour", p.EquivalentHour, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "installed_power_map", "Installed Power Map", p.InstalledPowerMap, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "radiation", "Radiation", p.Radiation, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "today_energy", "Today Energy", p.TodayEnergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "today_income", "Today Income", p.TodayIncome, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "total_capacity", "Total Capacity", p.TotalCapcity, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "total_energy", "Total Energy", p.TotalEnergy, len(ret.Entries))) - ret.Entries = append(ret.Entries, add(now, psId, "total_income", "Total Income", p.TotalIncome, len(ret.Entries))) - - ret.Entries = append(ret.Entries, addValue(now, psId, "build_date", "Build Date", p.BuildDate, len(ret.Entries))) - ret.Entries = append(ret.Entries, addIntValue(now, psId, "build_status", "Build Status", p.BuildStatus, len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(now, psId, "latitude", "Latitude", p.Latitude, len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(now, psId, "longitude", "Longitude", p.Longitude, len(ret.Entries))) - ret.Entries = append(ret.Entries, addValue(now, psId, "location", "Location", p.Location, len(ret.Entries))) - - ret.Entries = append(ret.Entries, addIntValue(now, psId, "installer_ps_fault_status", "Installer PS Fault Status", p.InstallerPsFaultStatus, len(ret.Entries))) - ret.Entries = append(ret.Entries, addIntValue(now, psId, "owner_ps_fault_status", "Owner PS Fault Status", p.OwnerPsFaultStatus, len(ret.Entries))) - ret.Entries = append(ret.Entries, addIntValue(now, psId, "ps_fault_status", "PS Fault Status", p.PsFaultStatus, len(ret.Entries))) - ret.Entries = append(ret.Entries, addValue(now, psId, "ps_health_status", "PS Health Status", p.PsHealthStatus, len(ret.Entries))) - - ret.Entries = append(ret.Entries, addValue(now, psId, "ps_holder", "PS Holder", p.PsHolder, len(ret.Entries))) - ret.Entries = append(ret.Entries, addIntValue(now, psId, "ps_id", "PS Id", p.PsID, len(ret.Entries))) - ret.Entries = append(ret.Entries, addValue(now, psId, "ps_name", "PS Name", p.PsName, len(ret.Entries))) - ret.Entries = append(ret.Entries, addValue(now, psId, "ps_short_name", "PS Short Name", p.PsShortName, len(ret.Entries))) - ret.Entries = append(ret.Entries, addIntValue(now, psId, "ps_status", "PS Status", p.PsStatus, len(ret.Entries))) - ret.Entries = append(ret.Entries, addIntValue(now, psId, "ps_type", "PS Type", p.PsType, len(ret.Entries))) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83077"}, now, p.PvEnergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83089"}, now, p.EsDisenergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83095"}, now, p.EsTotalDisenergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83118"}, now, p.UseEnergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83120"}, now, p.EsEnergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83127"}, now, p.EsTotalEnergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83076"}, now, p.PvPower.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"p83081"}, now, p.EsPower.Value) + // + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"co2_reduce", Unit:p.Co2Reduce.Unit}, now, p.Co2Reduce.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"co2_reduce_total", Unit:p.Co2ReduceTotal.Unit}, now, p.Co2ReduceTotal.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"curr_power", Unit:p.CurrPower.Unit}, now, p.CurrPower.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"daily_irradiation", Unit:p.DailyIrradiation.Unit}, now, p.DailyIrradiation.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"equivalent_hour", Unit:p.EquivalentHour.Unit}, now, p.EquivalentHour.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"installed_power_map", Unit:p.InstalledPowerMap.Unit}, now, p.InstalledPowerMap.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"radiation", Unit:p.Radiation.Unit}, now, p.Radiation.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"today_energy", Unit:p.TodayEnergy.Unit}, now, p.TodayEnergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"today_income", Unit:p.TodayIncome.Unit}, now, p.TodayIncome.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"total_capacity", Unit:p.TotalCapcity.Unit}, now, p.TotalCapcity.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"total_energy", Unit:p.TotalEnergy.Unit}, now, p.TotalEnergy.Value) + // entries.AddEntry(api.Point{PsKey: "virtual", Id:"total_income", Unit:p.TotalIncome.Unit}, now, p.TotalIncome.Value) + // + // entries.AddString(now, psId, "build_date", "", p.BuildDate) + // entries.AddInt(now, psId, "build_status", "", p.BuildStatus) + // entries.AddFloat(now, psId, "latitude", "", p.Latitude) + // entries.AddFloat(now, psId, "longitude", "", p.Longitude) + // entries.AddString(now, psId, "location", "", p.Location) + // + // entries.AddInt(now, psId, "installer_ps_fault_status", "", p.InstallerPsFaultStatus) + // entries.AddInt(now, psId, "owner_ps_fault_status", "", p.OwnerPsFaultStatus) + // entries.AddInt(now, psId, "ps_fault_status", "", p.PsFaultStatus) + // entries.AddString(now, psId, "ps_health_status", "", p.PsHealthStatus) + // + // entries.AddString(now, psId, "ps_holder", "", p.PsHolder) + // entries.AddInt(now, psId, "ps_id", "", p.PsID) + // entries.AddString(now, psId, "ps_name", "", p.PsName) + // entries.AddString(now, psId, "ps_short_name", "", p.PsShortName) + // entries.AddInt(now, psId, "ps_status", "", p.PsStatus) + // entries.AddInt(now, psId, "ps_type", "", p.PsType) // ret = append(ret, []string{now, "Pv Energy", p.PvEnergy.Value, p.PvEnergy.Unit}) // p83077 // ret = append(ret, []string{now, "Es Discharge Energy", p.EsDisenergy.Value, p.EsDisenergy.Unit}) // p83089 @@ -320,86 +320,111 @@ func (e *ResultData) GetData() api.Data { // ret = append(ret, []string{now, "Total Income", p.TotalIncome.Value, p.TotalIncome.Unit}) } } - return ret -} - -func addState(now api.DateTime, point string, name string, state bool, index int) api.DataEntry { - return add(now, "virtual", point, name, api.UnitValue{ Value: fmt.Sprintf("%v", state) }, index) - - // return api.DataEntry { - // Date: now, - // PointId: api.NameDevicePoint("virtual", point), - // PointGroupName: "Virtual", - // PointName: name, - // Value: fmt.Sprintf("%v", state), - // Unit: "binary", - // ValueType: &api.Point{ - // PsKey: "virtual", - // Id: point, - // Description: name, - // Unit: "binary", - // Type: "PointTypeInstant", - // }, - // Index: index, - // } -} - -func addValue(now api.DateTime, psId string, point string, name string, value string, index int) api.DataEntry { - return add(now, psId, point, name, api.UnitValue{ Value: value }, index) - - // vt := api.GetPoint(psId, point) - // if !vt.Valid { - // vt = &api.Point{ - // PsKey: psId, - // Id: point, - // Description: name, - // Unit: "", - // Type: "PointTypeInstant", - // } - // } - // return api.DataEntry { - // Date: now, - // PointId: api.NameDevicePoint(psId, point), - // PointGroupName: "Summary", - // PointName: name, - // Value: value, - // Unit: "", - // ValueType: vt, - // Index: index, - // } -} - -func addIntValue(now api.DateTime, psId string, point string, name string, value int64, index int) api.DataEntry { - return add(now, psId, point, name, api.UnitValue{ Value: strconv.FormatInt(value, 10) }, index) -} - -func addFloatValue(now api.DateTime, psId string, point string, name string, value float64, index int) api.DataEntry { - return add(now, psId, point, name, api.UnitValue{ Value: api.Float64ToString(value) }, index) -} - -func add(now api.DateTime, psId string, point string, name string, value api.UnitValue, index int) api.DataEntry { - vt := api.GetPoint(psId, point) - if !vt.Valid { - vt = &api.Point{ - PsKey: psId, - Id: point, - Description: name, - Unit: value.Unit, - Type: "PointTypeInstant", - } - } - return api.DataEntry { - Date: now, - PointId: api.NameDevicePoint(psId, point), - PointGroupName: "Virtual", - PointName: name, - Value: value.Value, - Unit: value.Unit, - ValueType: vt, - Index: index, - } + return entries } +// func add(now api.DateTime, psId string, pid string, name string, p api.UnitValue) api.DataEntry { +// +// vt := api.GetPoint(psId, pid) +// if !vt.Valid { +// vt = &api.Point { +// PsKey: psId, +// Id: pid, +// Description: name, +// Unit: p.Unit, +// Type: "PointTypeInstant", +// } +// } +// fv, _ := strconv.ParseFloat(p.Value, 64) +// return api.DataEntry { +// Date: now, +// PointId: api.NameDevicePoint(psId, pid), +// PointGroupName: "Virtual", +// PointName: name, +// Value: p.Value, +// ValueFloat: fv, +// Unit: p.Unit, +// ValueType: vt, +// Index: 0, +// } +// } +// +// func addState(now api.DateTime, point string, name string, state bool) api.DataEntry { +// return add(now, "virtual", point, name, api.UnitValue{ Value: fmt.Sprintf("%v", state) }) +// +// // return api.DataEntry { +// // Date: now, +// // PointId: api.NameDevicePoint("virtual", point), +// // PointGroupName: "Virtual", +// // PointName: name, +// // Value: fmt.Sprintf("%v", state), +// // Unit: "binary", +// // ValueType: &api.Point{ +// // PsKey: "virtual", +// // Id: point, +// // Description: name, +// // Unit: "binary", +// // Type: "PointTypeInstant", +// // }, +// // Index: index, +// // } +// } +// +// func addValue(now api.DateTime, psId string, point string, name string, value string) api.DataEntry { +// return add(now, psId, point, name, api.UnitValue{ Value: value }) +// // vt := api.GetPoint(psId, point) +// // if !vt.Valid { +// // vt = &api.Point{ +// // PsKey: psId, +// // Id: point, +// // Description: name, +// // Unit: "", +// // Type: "PointTypeInstant", +// // } +// // } +// // return api.DataEntry { +// // Date: now, +// // PointId: api.NameDevicePoint(psId, point), +// // PointGroupName: "Summary", +// // PointName: name, +// // Value: value, +// // Unit: "", +// // ValueType: vt, +// // Index: index, +// // } +// } +// +// func addIntValue(now api.DateTime, psId string, point string, name string, value int64) api.DataEntry { +// return add(now, psId, point, name, api.UnitValue{ Value: strconv.FormatInt(value, 10) }) +// } +// +// func addFloatValue(now api.DateTime, psId string, point string, name string, value float64) api.DataEntry { +// return add(now, psId, point, name, api.UnitValue{ Value: api.Float64ToString(value) }) +// } +// +// func add2(now api.DateTime, psId string, point string, name string, value api.UnitValue) api.DataEntry { +// vt := api.GetPoint(psId, point) +// if !vt.Valid { +// vt = &api.Point{ +// PsKey: psId, +// Id: point, +// Description: name, +// Unit: value.Unit, +// Type: "PointTypeInstant", +// } +// } +// return api.DataEntry { +// Date: now, +// PointId: api.NameDevicePoint(psId, point), +// PointGroupName: "Virtual", +// PointName: name, +// Value: value.Value, +// Unit: value.Unit, +// ValueType: vt, +// Index: 0, +// } +// } +// // func (e *ResultData) GetData() [][]string { // var ret [][]string // for range Only.Once { diff --git a/iSolarCloud/AppService/queryDeviceList/data.go b/iSolarCloud/AppService/queryDeviceList/data.go index 386cf4435..2d184fad3 100644 --- a/iSolarCloud/AppService/queryDeviceList/data.go +++ b/iSolarCloud/AppService/queryDeviceList/data.go @@ -7,7 +7,6 @@ import ( "GoSungrow/iSolarCloud/api/output" "fmt" "strconv" - "strings" ) const Url = "/v1/devService/queryDeviceList" @@ -28,10 +27,10 @@ func (rd RequestData) Help() string { type ResultData struct { DevCountByStatusMap struct { - FaultCount int64 `json:"fault_count"` - OfflineCount int64 `json:"offline_count"` - RunCount int64 `json:"run_count"` - WarningCount int64 `json:"warning_count"` + FaultCount int64 `json:"fault_count" PointId:"fault_count" PointType:""` + OfflineCount int64 `json:"offline_count" PointId:"offline_count" PointType:""` + RunCount int64 `json:"run_count" PointId:"run_count" PointType:""` + WarningCount int64 `json:"warning_count" PointId:"warning_count" PointType:""` } `json:"dev_count_by_status_map"` DevCountByTypeMap struct { One4 int64 `json:"14"` @@ -88,57 +87,58 @@ type ResultData struct { Nine9 string `json:"99"` } `json:"dev_type_definition"` PageList []struct { - AlarmCount int64 `json:"alarm_count"` - ChnnlID int64 `json:"chnnl_id"` - CommandStatus int64 `json:"command_status"` - ComponentAmount int64 `json:"component_amount"` - DataFlag int64 `json:"data_flag"` - DataFlagDetail int64 `json:"data_flag_detail"` - DeviceArea string `json:"device_area"` - DeviceAreaName string `json:"device_area_name"` - DeviceCode int64 `json:"device_code"` - DeviceID int64 `json:"device_id"` - DeviceModelCode string `json:"device_model_code"` - DeviceModelID string `json:"device_model_id"` - DeviceName string `json:"device_name"` - DeviceStatus int64 `json:"device_status"` - DeviceType int64 `json:"device_type"` - FaultCount int64 `json:"fault_count"` - FaultStatus string `json:"fault_status"` - FunctionEnum string `json:"function_enum"` - InstallerAlarmCount int64 `json:"installer_alarm_count"` - InstallerDevFaultStatus int64 `json:"installer_dev_fault_status"` - InstallerFaultCount int64 `json:"installer_fault_count"` - InverterModelType int64 `json:"inverter_model_type"` - IsDeveloper string `json:"is_developer"` - IsG2point5Module int64 `json:"is_g2point5_module"` - IsInit int64 `json:"is_init"` - IsSecond int64 `json:"is_second"` - IsSupportParamset int64 `json:"is_support_paramset"` - NodeTimestamps interface{} `json:"node_timestamps"` - OwnerAlarmCount int64 `json:"owner_alarm_count"` - OwnerDevFaultStatus int64 `json:"owner_dev_fault_status"` - OwnerFaultCount int64 `json:"owner_fault_count"` + AlarmCount int64 `json:"alarm_count" PointId:"alarm_count" PointType:""` + ChnnlID int64 `json:"chnnl_id" PointId:"channel_id" PointType:""` + CommandStatus int64 `json:"command_status" PointId:"command_status" PointType:""` + ComponentAmount int64 `json:"component_amount" PointId:"component_amount" PointType:""` + DataFlag int64 `json:"data_flag" PointId:"data_flag" PointType:""` + DataFlagDetail int64 `json:"data_flag_detail" PointId:"data_flag_detail" PointType:""` + DeviceArea string `json:"device_area" PointId:"device_area" PointType:""` + DeviceAreaName string `json:"device_area_name" PointId:"device_area_name" PointType:""` + DeviceCode int64 `json:"device_code" PointId:"device_code" PointType:""` + DeviceID int64 `json:"device_id" PointId:"device_id" PointType:""` + DeviceModelCode string `json:"device_model_code" PointId:"device_model_code" PointType:""` + DeviceModelID string `json:"device_model_id" PointId:"device_model_id" PointType:""` + DeviceName string `json:"device_name" PointId:"device_name" PointType:""` + DeviceStatus int64 `json:"device_status" PointId:"device_status" PointType:""` + DeviceType int64 `json:"device_type" PointId:"device_type" PointType:""` + FaultCount int64 `json:"fault_count" PointId:"fault_count" PointType:""` + FaultStatus string `json:"fault_status" PointId:"fault_status" PointType:""` + FunctionEnum string `json:"function_enum" PointId:"function_enum" PointType:""` + InstallerAlarmCount int64 `json:"installer_alarm_count" PointId:"installer_alarm_count" PointType:""` + InstallerDevFaultStatus int64 `json:"installer_dev_fault_status" PointId:"installer_dev_fault_status" PointType:""` + InstallerFaultCount int64 `json:"installer_fault_count" PointId:"installer_fault_count" PointType:""` + InverterModelType int64 `json:"inverter_model_type" PointId:"inverter_model_type" PointType:""` + IsDeveloper string `json:"is_developer" PointId:"is_developer" PointType:""` + IsG2point5Module int64 `json:"is_g2point5_module" PointId:"is_g2point5_module" PointType:""` + IsInit int64 `json:"is_init" PointId:"is_init" PointType:""` + IsSecond int64 `json:"is_second" PointId:"is_second" PointType:""` + IsSupportParamset int64 `json:"is_support_paramset" PointId:"is_support_paramset" PointType:""` + NodeTimestamps interface{} `json:"node_timestamps" PointId:"node_timestamps" PointType:""` + OwnerAlarmCount int64 `json:"owner_alarm_count" PointId:"owner_alarm_count" PointType:""` + OwnerDevFaultStatus int64 `json:"owner_dev_fault_status" PointId:"owner_dev_fault_status" PointType:""` + OwnerFaultCount int64 `json:"owner_fault_count" PointId:"owner_fault_count" PointType:""` PointData PointData `json:"point_data"` - Points interface{} `json:"points"` + Points interface{} `json:"points" PointId:"points" PointType:""` PsTimezoneInfo struct { IsDst string `json:"is_dst"` TimeZone string `json:"time_zone"` } `json:"psTimezoneInfo"` - PsID int64 `json:"ps_id"` - PsKey string `json:"ps_key"` - RelState int64 `json:"rel_state"` - Sn string `json:"sn"` - StringAmount int64 `json:"string_amount"` - TypeName string `json:"type_name"` - UnitName interface{} `json:"unit_name"` - UUID string `json:"uuid"` - UUIDIndexCode string `json:"uuid_index_code"` + PsID int64 `json:"ps_id" PointId:"ps_id" PointType:""` + PsKey string `json:"ps_key" PointId:"ps_key" PointType:""` + RelState int64 `json:"rel_state" PointId:"rel_state" PointType:""` + Sn string `json:"sn" PointId:"sn" PointType:""` + StringAmount int64 `json:"string_amount" PointId:"string_amount" PointType:""` + TypeName string `json:"type_name" PointId:"type_name" PointType:""` + UnitName interface{} `json:"unit_name" PointId:"unit_name" PointType:""` + UUID string `json:"uuid" PointId:"uuid" PointType:""` + UUIDIndexCode string `json:"uuid_index_code" PointId:"uuid_index_code" PointType:""` } `json:"pageList"` RowCount int64 `json:"rowCount"` } -type PointData []struct { +type PointData []PointStruct +type PointStruct struct { CodeID int64 `json:"code_id"` CodeIDOrderID string `json:"code_id_order_id"` CodeName string `json:"code_name"` @@ -162,6 +162,12 @@ type PointData []struct { ValueDescription string `json:"value_description"` } +// type VirtualPointStruct struct { +// api.DataEntry +// ValueFloat float64 +// } + + func (e *ResultData) IsValid() error { var err error // switch { @@ -221,8 +227,8 @@ func (e *EndPoint) GetDataTable() output.Table { _ = table.SetHeader( "Date", - "Point Id", - "Point Group Name", + "PointStruct Id", + "PointStruct Group Name", "Description", "Value", "Unit", @@ -273,182 +279,191 @@ func (e *EndPoint) GetDataTable() output.Table { return table } -func (e *EndPoint) GetData() api.Data { - var ret api.Data +type DataEntry api.DataEntry +type EntryMap api.DataMap + +func (e *EndPoint) GetData() api.DataMap { + entries := api.NewDataMap() for range Only.Once { - // Used for virtual entries. - // 0 - sungrow_battery_charging_power - var PVPowerToBattery float64 + // // Used for virtual entries. + // // 0 - sungrow_battery_charging_power + // var PVPowerToBattery VirtualPointStruct + // + // // sensor.sungrow_battery_discharging_power + // var BatteryPowerToLoad VirtualPointStruct + // + // // 0 - sensor.sungrow_total_export_active_power + // var PVPowerToGrid VirtualPointStruct + // + // // sensor.sungrow_purchased_power + // var GridPowerToLoad VirtualPointStruct + // + // // 0 - sensor.sungrow_daily_battery_charging_energy_from_pv + // var YieldBatteryCharge VirtualPointStruct + // // var DailyBatteryChargingEnergy VirtualPointStruct + // + // // sensor.sungrow_daily_battery_discharging_energy + // var DailyBatteryDischargingEnergy VirtualPointStruct + // + // // 0 - sensor.sungrow_daily_feed_in_energy_pv + // var YieldFeedIn VirtualPointStruct + // + // // sensor.sungrow_daily_purchased_energy + // var DailyPurchasedEnergy VirtualPointStruct + // + // var PVPower VirtualPointStruct + // + // var LoadPower VirtualPointStruct + // + // var YieldSelfConsumption VirtualPointStruct + // // var DailyFeedInEnergy VirtualPointStruct + // var TotalPvYield VirtualPointStruct + // + // var DailyTotalLoad VirtualPointStruct + // + // var TotalEnergyConsumption VirtualPointStruct - // sensor.sungrow_battery_discharging_power - var BatteryPowerToLoad float64 + entries.StructToPoints("", e.Response.ResultData.DevCountByStatusMap) + for _, d := range e.Response.ResultData.PageList { + entries.StructToPoints("", d) + } - // 0 - sensor.sungrow_total_export_active_power - var PVPowerToGrid float64 - - // sensor.sungrow_purchased_power - var GridPowerToLoad float64 - - // 0 - sensor.sungrow_daily_battery_charging_energy_from_pv - var YieldBatteryCharge float64 - // var DailyBatteryChargingEnergy float64 - - // sensor.sungrow_daily_battery_discharging_energy - var DailyBatteryDischargingEnergy float64 - - // 0 - sensor.sungrow_daily_feed_in_energy_pv - var YieldFeedIn float64 - - // sensor.sungrow_daily_purchased_energy - var DailyPurchasedEnergy float64 - - var PVPower float64 - - var LoadPower float64 - - var YieldSelfConsumption float64 - // var DailyFeedInEnergy float64 - var TotalPvYield float64 - - var DailyTotalLoad float64 - - var TotalEnergyConsumption float64 - - // index := 0 for _, d := range e.Response.ResultData.PageList { for _, p := range d.PointData { - if p.Unit == "W" { - fv, err := api.DivideByThousand(p.Value) - // fv, err := strconv.ParseFloat(p.Value, 64) - // fv = fv / 1000 - if err == nil { - // p.Value = fmt.Sprintf("%.3f", fv) - p.Value = fv - p.Unit = "kW" - } - } + pid := api.SetPoint(strconv.FormatInt(p.PointID, 10)) + uv := api.CreateUnitValue(p.Value, p.Unit) + entries.AddUnitValue("", d.PsKey, pid, p.PointName, api.NewDateTime(p.TimeStamp), uv) - if p.Unit == "Wh" { - fv, err := api.DivideByThousand(p.Value) - // fv, err := strconv.ParseFloat(p.Value, 64) - // fv = fv / 1000 - if err == nil { - // p.Value = fmt.Sprintf("%.3f", fv) - p.Value = fv - p.Unit = "kWh" - } - } - - vt := api.GetPointInt(d.PsKey, p.PointID) - if !vt.Valid { - vt = &api.Point{ - PsKey: d.PsKey, - Id: "p" + strings.TrimPrefix(strconv.FormatInt(p.PointID, 10), "p"), - Description: p.PointName, - Unit: p.Unit, - Type: "", - } - } - ret.Entries = append(ret.Entries, api.DataEntry { - Date: api.NewDateTime(p.TimeStamp), - PointId: api.NameDevicePointInt(d.PsKey, p.PointID), - PointGroupName: p.PointGroupName, - PointName: p.PointName, - Value: p.Value, - Unit: p.Unit, - ValueType: vt, - Index: len(ret.Entries), - }) + // vt := api.GetPointInt(d.PsKey, p.PointID) + // if !vt.Valid { + // vt = &api.Point { + // PsKey: d.PsKey, + // Id: api.PointToName(strconv.FormatInt(p.PointID, 10)), + // Name: p.PointName, + // Unit: uv.Unit, + // Type: "PointTypeInstant", + // } + // } + // + // entries.Add(pid, api.DataEntry { + // Date: api.NewDateTime(p.TimeStamp), + // Id: api.NameDevicePointInt(d.PsKey, p.PointID), + // GroupName: p.PointGroupName, + // Name: p.PointName, + // Value: uv.Value, + // ValueFloat: uv.ValueFloat, + // Unit: uv.Unit, + // Point: vt, + // Index: 0, + // }) // Handle virtual results. - switch p.PointID { - case 13126: - // BatteryChargingPower - PVPowerToBattery, _ = strconv.ParseFloat(p.Value, 64) - case 13150: - // BatteryDischargingPower - BatteryPowerToLoad, _ = strconv.ParseFloat(p.Value, 64) - case 13121: - // TotalExportActivePower - PVPowerToGrid, _ = strconv.ParseFloat(p.Value, 64) - case 13149: - // PurchasedPower - GridPowerToLoad, _ = strconv.ParseFloat(p.Value, 64) - case 13003: - // TotalDcPower - PVPower, _ = strconv.ParseFloat(p.Value, 64) - case 13119: - // TotalLoadActivePower - LoadPower, _ = strconv.ParseFloat(p.Value, 64) - - case 13028: - // DailyBatteryChargingEnergy - // DailyBatteryChargingEnergy, _ = strconv.ParseFloat(p.Value, 64) - case 13174: - // DailyBatteryChargingEnergyFromPv - YieldBatteryCharge, _ = strconv.ParseFloat(p.Value, 64) - case 13029: - // DailyBatteryDischargingEnergy - DailyBatteryDischargingEnergy, _ = strconv.ParseFloat(p.Value, 64) - case 13173: - // DailyFeedInEnergyPv - YieldFeedIn, _ = strconv.ParseFloat(p.Value, 64) - case 13147: - // DailyPurchasedEnergy - DailyPurchasedEnergy, _ = strconv.ParseFloat(p.Value, 64) - - case 13116: - // DailyLoadEnergyConsumptionFromPv - YieldSelfConsumption, _ = strconv.ParseFloat(p.Value, 64) - case 13122: - // DailyFeedInEnergy, _ = strconv.ParseFloat(p.Value, 64) - case 13134: - // TotalPvYield - TotalPvYield, _ = strconv.ParseFloat(p.Value, 64) - - case 13199: - // Daily Load Energy Consumption - DailyTotalLoad, _ = strconv.ParseFloat(p.Value, 64) - - case 13130: - // Total Load Energy Consumption - TotalEnergyConsumption, _ = strconv.ParseFloat(p.Value, 64) - } - - // switch strings.ReplaceAll(p.PointName, " ", "") { - // case "BatteryChargingPower": - // BatteryChargingPower, _ = strconv.ParseFloat(p.Value, 64) - // case "BatteryDischargingPower": - // BatteryDischargingPower, _ = strconv.ParseFloat(p.Value, 64) - // case "TotalExportActivePower": - // TotalExportActivePower, _ = strconv.ParseFloat(p.Value, 64) - // case "PurchasedPower": - // PurchasedPower, _ = strconv.ParseFloat(p.Value, 64) - // case "TotalDCPower": - // TotalDcPower, _ = strconv.ParseFloat(p.Value, 64) - // case "TotalLoadActivePower": - // TotalLoadActivePower, _ = strconv.ParseFloat(p.Value, 64) + // switch pid { + // case "13126": + // // BatteryChargingPower + // entries["PVPowerToBattery"] = entries[pid] + // case "13150": + // // BatteryDischargingPower + // entries["BatteryPowerToLoad"] = entries[pid] + // case "13121": + // // TotalExportActivePower + // entries["PVPowerToGrid"] = entries[pid] + // case "13149": + // // PurchasedPower + // entries["GridPowerToLoad"] = entries[pid] + // case "13003": + // // TotalDcPower + // entries["PVPower"] = addVirtualAlias(entries[pid], "pv_power", "PV Power") + // case "13119": + // // TotalLoadActivePower + // entries["LoadPower"] = addVirtualAlias(entries[pid], "load_power", "Load Power") // - // case "DailyBatteryChargingEnergyFromPv": - // DailyBatteryChargingEnergyFromPv, _ = strconv.ParseFloat(p.Value, 64) - // case "DailyBatteryDischargingEnergy": - // DailyBatteryDischargingEnergy, _ = strconv.ParseFloat(p.Value, 64) - // case "DailyFeedInEnergyPv": - // DailyFeedInEnergyPv, _ = strconv.ParseFloat(p.Value, 64) - // case "DailyPurchasedEnergy": - // DailyPurchasedEnergy, _ = strconv.ParseFloat(p.Value, 64) + // // addVirtualAlias(entries[pid], "FOO", "FOO") + // + // case "13112": + // // Daily PV Yield + // entries["DailyPvEnergy"] = addVirtualAlias(entries["DailyPvEnergy"], "daily_pv_energy", "Daily PV Energy") + // case "13174": + // // DailyBatteryChargingEnergyFromPv + // entries["YieldBatteryCharge"] = addVirtualAlias(entries[pid], "pv_battery_charge", "PV Battery Charge") + // case "13029": + // // DailyBatteryDischargingEnergy + // entries["DailyBatteryDischargingEnergy"] = entries[pid] + // case "13122": + // // entries["DailyFeedInEnergy"] = addVirtualAlias(entries[pid], "pv_feed_in", "PV Feed In") + // // @TODO - This may differ from DailyFeedInEnergyPv + // case "13173": + // // DailyFeedInEnergyPv + // entries["YieldFeedIn"] = addVirtualAlias(entries[pid], "pv_feed_in", "PV Feed In") + // case "13147": + // // DailyPurchasedEnergy + // entries["DailyPurchasedEnergy"] = addVirtualAlias(entries[pid], "daily_purchased_energy", "Daily Purchased Energy") + // + // case "13116": + // // DailyLoadEnergyConsumptionFromPv + // entries["YieldSelfConsumption"] = addVirtualAlias(entries[pid], "pv_self_consumption", "PV Self Consumption") + // case "13134": + // // TotalPvYield + // entries["TotalPvYield"] = addVirtualAlias(entries[pid], "pv_total_yield", "PV Total Yield") + // + // case "13199": + // // Daily Load Energy Consumption + // entries["DailyTotalLoad"] = addVirtualAlias(entries[pid], "daily_total_energy", "Daily Total Energy") + // + // case "13130": + // // Total Load Energy Consumption + // entries["TotalEnergyConsumption"] = addVirtualAlias(entries[pid], "total_energy_consumption", "Total Energy Consumption" // } } } - if len(ret.Entries) == 0 { + if len(entries.Entries) == 0 { break } - // Add virtual entries. - ts := ret.Entries[0].Date - var value float64 + // TotalDcPower + entries.FromRefAddAlias("p13003", api.VirtualPsId, "pv_power", "") + // BatteryChargingPower + entries.FromRefAddAlias("p13126", api.VirtualPsId, "pv_power_to_battery", "") + // BatteryDischargingPower + entries.FromRefAddAlias("p13150", api.VirtualPsId, "battery_power_to_load", "") + // TotalExportActivePower + entries.FromRefAddAlias("p13121", api.VirtualPsId, "pv_power_to_grid", "") + + // TotalLoadActivePower + entries.FromRefAddAlias("p13119", api.VirtualPsId, "load_power", "") + + // PurchasedPower + entries.FromRefAddAlias("p13149", api.VirtualPsId, "grid_power_to_load", "") + + // Daily PV Yield + entries.FromRefAddAlias("p13112", api.VirtualPsId, "daily_pv_energy", "") + // DailyPvEnergy := entries.getFloatValue("DailyTotalLoad") - entries.getFloatValue("DailyPurchasedEnergy") + // DailyBatteryChargingEnergyFromPv + entries.FromRefAddAlias("p13174", api.VirtualPsId, "pv_battery_charge", "") + // DailyBatteryDischargingEnergy + entries.FromRefAddAlias("p13029", api.VirtualPsId, "battery_discharge", "") + + // @TODO - This may differ from DailyFeedInEnergyPv + // entries["DailyFeedInEnergy"] = entries.AddVirtualAliasFromRef("13122", "pv_feed_in", "PV Feed In") + + // DailyFeedInEnergyPv + entries.FromRefAddAlias("p13173", api.VirtualPsId, "pv_feed_in", "") + // DailyPurchasedEnergy + entries.FromRefAddAlias("p13147", api.VirtualPsId, "daily_purchased_energy", "") + // DailyLoadEnergyConsumptionFromPv + entries.FromRefAddAlias("p13116", api.VirtualPsId, "pv_self_consumption", "") + // TotalPvYield + entries.FromRefAddAlias("p13134", api.VirtualPsId, "pv_total_yield", "") + // Daily Load Energy Consumption + entries.FromRefAddAlias("p13199", api.VirtualPsId, "daily_total_energy", "") + // Total Load Energy Consumption + entries.FromRefAddAlias("p13130", api.VirtualPsId, "total_energy_consumption", "") + // entries.AddPointFromRef(api.Point{ Id:"p13130" }, api.Point{ PsKey:api.VirtualPsId, Id:"total_energy_consumption" }) + + // entries.CopyEntry("p13130").CreateAlias() + // entries.GetEntry(api.Point{PsKey:psId, Id:"total_income", Unit:p.TotalIncome.Unit, Type:api.PointTypeTotal}, now, p.TotalIncome.Value) /* PVPower - TotalDcPower @@ -457,313 +472,237 @@ func (e *EndPoint) GetData() api.Data { PVPowerToGrid - TotalExportActivePower LoadPower - TotalLoadActivePower - BatteryToLoad - BatteryDischargingPower - BatteryToGrid - ? + BatteryPowerToLoad - BatteryDischargingPower + BatteryPowerToGrid - ? - GridPower - TotalDcPower - GridToLoad - PurchasedPower - GridToBattery - ? + GridPower - lowerUpper(PVPowerToGrid, GridPowerToLoad) + GridPowerToLoad - PurchasedPower + GridPowerToBattery - ? - DailyLoadEnergyConsumptionFromPv - Self-consumption - DailyBatteryChargingEnergyFromPv - Battery charge - DailyFeedInEnergyPv - Feed-In + YieldSelfConsumption - DailyLoadEnergyConsumptionFromPv + YieldBatteryCharge - DailyBatteryChargingEnergyFromPv + YieldFeedIn - DailyFeedInEnergyPv */ - YieldTotal := YieldSelfConsumption + YieldBatteryCharge + YieldFeedIn - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_daily_yield", "PV Daily Yield", YieldTotal, "kWh", len(ret.Entries))) + // Add virtual entries. + // ts := ret.Entries[0].Date + // var value float64 - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_self_consumption", "PV Self Consumption", YieldSelfConsumption, "kWh", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_battery_charge", "PV Battery Charge", YieldBatteryCharge, "kWh", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_feed_in", "PV Feed In", YieldFeedIn, "kWh", len(ret.Entries))) + entries.FromRefAddFloat("pv_self_consumption", + api.VirtualPsId,"pv_daily_yield", "", + entries.GetFloatValue("pv_self_consumption") + entries.GetFloatValue("pv_battery_charge") + entries.GetFloatValue("pv_feed_in")) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_self_consumption_percent", "PV Self Consumption Percent", getPercent(YieldSelfConsumption, YieldTotal), "%", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_battery_charge_percent", "PV Battery Charge Percent", getPercent(YieldBatteryCharge, YieldTotal), "%", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_feed_in_percent", "PV Feed In Percent", getPercent(YieldFeedIn, YieldTotal), "%", len(ret.Entries))) + entries.FromRefAddFloat("daily_pv_energy", + api.VirtualPsId,"pv_self_consumption_percent", "", + entries.GetPercent("pv_self_consumption", "daily_pv_energy")) + entries.FromRefAddFloat("daily_pv_energy", + api.VirtualPsId,"pv_battery_charge_percent", "", + entries.GetPercent("pv_battery_charge", "daily_pv_energy")) + entries.FromRefAddFloat("daily_pv_energy", + api.VirtualPsId,"pv_feed_in_percent", "", + entries.GetPercent("pv_feed_in", "daily_pv_energy")) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_total_yield", "PV Total Yield", TotalPvYield, "MWh", len(ret.Entries))) + // @TODO - Add this calculation. + DailyPvEnergy := entries.GetFloatValue("daily_total_energy") - entries.GetFloatValue("daily_purchased_energy") + fmt.Sprintf("%f", DailyPvEnergy) + entries.FromRefAddFloat("daily_total_energy", + api.VirtualPsId,"daily_pv_energy_percent", "", + api.GetPercent(DailyPvEnergy, entries.GetValue("daily_total_energy"))) + entries.FromRefAddFloat("daily_total_energy", + api.VirtualPsId,"daily_purchased_energy_percent", "", + entries.GetPercent("daily_purchased_energy", "daily_total_energy")) - DailyPvEnergy := DailyTotalLoad - DailyPurchasedEnergy - ret.Entries = append(ret.Entries, addFloatValue(ts, "daily_total_energy", "Daily Total Energy", DailyTotalLoad, "kWh", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "daily_pv_energy", "Daily PV Energy", DailyPvEnergy, "kWh", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "daily_purchased_energy", "Daily Purchased Energy", DailyPurchasedEnergy, "kWh", len(ret.Entries))) + entries.FromRefAddFloat("pv_power", + api.VirtualPsId,"pv_power_to_load", "", + entries.GetFloatValue("pv_power") - entries.GetFloatValue("pv_power_to_battery") - entries.GetFloatValue("pv_power_to_grid")) - ret.Entries = append(ret.Entries, addFloatValue(ts, "daily_pv_energy_percent", "Daily PV Energy Percent", getPercent(DailyPvEnergy, DailyTotalLoad), "%", len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "daily_purchased_energy_percent", "Daily Purchased Energy Percent", getPercent(DailyPurchasedEnergy, DailyTotalLoad), "%", len(ret.Entries))) + // Battery + entries.FromRefAddFloat("pv_power_to_battery", + api.VirtualPsId,"battery_power", "", + entries.LowerUpper("pv_power_to_battery", "battery_power_to_load")) + entries.FromRefAddFloat("pv_power_to_battery", + api.VirtualPsId,"battery_power_to_grid", "", + 0.0) - ret.Entries = append(ret.Entries, addFloatValue(ts, "total_energy_consumption", "Total Energy Consumption", TotalEnergyConsumption, "MWh", len(ret.Entries))) + // Grid + entries.FromRefAddFloat("grid_power_to_load", + api.VirtualPsId,"grid_power", "", + entries.LowerUpper("pv_power_to_grid", "grid_power_to_load")) + entries.FromRefAddFloat("grid_power_to_load", + api.VirtualPsId,"grid_power_to_battery", "", + 0.0) - // PVPower := PVPower - // PVPowerToBattery := PVPowerToBattery - // PVPowerToGrid := PVPowerToGrid - PVPowerToLoad := PVPower - PVPowerToBattery - PVPowerToGrid - ret.Entries = append(ret.Entries, addState(ts, "pv_power_active", "PV Power Active", isActive(PVPower), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_power", "PV Power", PVPower, "kW", len(ret.Entries))) + entries.FromRefAddState("pv_power", api.VirtualPsId,"pv_power_active", "") + entries.FromRefAddState("battery_power", api.VirtualPsId,"battery_power_active", "") + entries.FromRefAddState("grid_power", api.VirtualPsId,"grid_power_active", "") + entries.FromRefAddState("load_power", api.VirtualPsId,"load_power_active", "") - ret.Entries = append(ret.Entries, addState(ts, "pv_power_to_battery_active", "PV Power To Battery Active", isActive(PVPowerToBattery), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_power_to_battery", "PV Power To Battery", PVPowerToBattery, "kW", len(ret.Entries))) + entries.FromRefAddState("pv_power_to_battery", api.VirtualPsId,"pv_power_to_battery_active", "") + entries.FromRefAddState("pv_power_to_load", api.VirtualPsId,"pv_power_to_load_active", "") + entries.FromRefAddState("pv_power_to_grid", api.VirtualPsId,"pv_power_to_grid_active", "") - ret.Entries = append(ret.Entries, addState(ts, "pv_power_to_load_active", "PV Power To Load Active", isActive(PVPowerToLoad), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_power_to_load", "PV Power To Load", PVPowerToLoad, "kW", len(ret.Entries))) + entries.FromRefAddState("battery_power_to_load", api.VirtualPsId,"battery_power_to_load_active", "") + entries.FromRefAddState("battery_power_to_grid", api.VirtualPsId,"battery_power_to_grid_active", "") - ret.Entries = append(ret.Entries, addState(ts, "pv_power_to_grid_active", "PV Power To Grid Active", isActive(PVPowerToGrid), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_power_to_grid", "PV Power To Grid", PVPowerToGrid, "kW", len(ret.Entries))) + entries.FromRefAddState("grid_power_to_load", api.VirtualPsId,"grid_power_to_load_active", "") + entries.FromRefAddState("grid_power_to_battery", api.VirtualPsId,"grid_power_to_battery_active", "") - // BatteryToLoad := BatteryToLoad - BatteryPower := lowerUpper(PVPowerToBattery, BatteryPowerToLoad) - BatteryToGrid := 0.0 - ret.Entries = append(ret.Entries, addState(ts, "battery_power_active", "Battery Power Active", isActive(BatteryPower), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "battery_power", "Battery Power", BatteryPower, "kW", len(ret.Entries))) + entries.FromRefAddFloat("pv_battery_charge", + api.VirtualPsId, "battery_energy", "", + entries.LowerUpper("pv_battery_charge", "battery_discharge")) - ret.Entries = append(ret.Entries, addState(ts, "battery_power_to_load_active", "Battery Power To Load Active", isActive(BatteryPowerToLoad), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "battery_power_to_load", "Battery Power To Load", BatteryPowerToLoad, "kW", len(ret.Entries))) - - ret.Entries = append(ret.Entries, addState(ts, "battery_power_to_grid_active", "Battery Power To Grid Active", isActive(BatteryToGrid), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "battery_power_to_grid", "Battery Power To Grid", BatteryToGrid, "kW", len(ret.Entries))) + entries.FromRefAddFloat("pv_feed_in", + api.VirtualPsId,"grid_energy", "", + entries.LowerUpper("pv_feed_in", "daily_purchased_energy")) - // GridToLoad := GridToLoad - GridPower := lowerUpper(PVPowerToGrid, GridPowerToLoad) - GridToBattery := 0.0 - ret.Entries = append(ret.Entries, addState(ts, "grid_power_active", "Grid Power Active", isActive(GridPower), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "grid_power", "Grid Power", GridPower, "kW", len(ret.Entries))) - - ret.Entries = append(ret.Entries, addState(ts, "grid_power_to_load_active", "Grid Power To Load Active", isActive(GridPowerToLoad), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "grid_power_to_load", "Grid Power To Load", GridPowerToLoad, "kW", len(ret.Entries))) - - ret.Entries = append(ret.Entries, addState(ts, "grid_power_to_battery_active", "Grid Power To Battery Active", isActive(GridToBattery), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "grid_power_to_battery", "Grid Power To Battery", GridToBattery, "kW", len(ret.Entries))) - - - // LoadPower := LoadPower - ret.Entries = append(ret.Entries, addState(ts, "load_power_active", "Load Power Active", isActive(LoadPower), len(ret.Entries))) - ret.Entries = append(ret.Entries, addFloatValue(ts, "load_power", "Load Power", LoadPower, "kW", len(ret.Entries))) - - - // { - // if isActive(BatteryChargingPower) { - // value = 0 - BatteryChargingPower - // - // ret.Entries = append(ret.Entries, addState(ts, "battery_power_active", "Battery Power Active", true, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "pv_flow_to_battery", "PV Flow To Battery", true, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "battery_flow_to_load", "Battery Flow To Load", false, len(ret.Entries))) - // - // } else if isActive(BatteryDischargingPower) { - // value = BatteryDischargingPower - // - // ret.Entries = append(ret.Entries, addState(ts, "battery_power_active", "Battery Power Active", true, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "pv_flow_to_battery", "PV Flow To Battery", false, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "battery_flow_to_load", "Battery Flow To Load", true, len(ret.Entries))) - // - // } else { - // value = 0 - // - // ret.Entries = append(ret.Entries, addState(ts, "battery_power_active", "Battery Power Active", false, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "pv_flow_to_battery", "PV Flow To Battery", false, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "battery_flow_to_load", "Battery Flow To Load", false, len(ret.Entries))) - // } - // - // ret.Entries = append(ret.Entries, addFloatValue(ts, "battery_power", "Battery Power", value, len(ret.Entries))) + // for _, pid := range entries.Order { + // // entries[pid].Index = i + // ret.Entries = append(ret.Entries, entries.Entries[pid]) // } - // - // { - // if isActive(TotalExportActivePower) { - // value = 0 - TotalExportActivePower - // - // ret.Entries = append(ret.Entries, addState(ts, "grid_power_active", "Grid Power Active", true, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "pv_flow_to_grid", "PV Flow To Grid", true, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "grid_flow_to_load", "Grid Flow To Load", false, len(ret.Entries))) - // - // } else if isActive(PurchasedPower) { - // value = PurchasedPower - // - // ret.Entries = append(ret.Entries, addState(ts, "grid_power_active", "Grid Power Active", true, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "pv_flow_to_grid", "PV Flow To Grid", false, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "grid_flow_to_load", "Grid Flow To Load", true, len(ret.Entries))) - // - // } else { - // value = 0 - // - // ret.Entries = append(ret.Entries, addState(ts, "grid_power_active", "Grid Power Active", false, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "pv_flow_to_grid", "PV Flow To Grid", false, len(ret.Entries))) - // ret.Entries = append(ret.Entries, addState(ts, "grid_flow_to_load", "Grid Flow To Load", false, len(ret.Entries))) - // } - // - // ret.Entries = append(ret.Entries, addFloatValue(ts, "grid_power", "Grid Power", value, len(ret.Entries))) - // } - // - // { - // ret.Entries = append(ret.Entries, addState(ts, "pv_power_active", "PV Power Active", isActive(TotalDcPower), len(ret.Entries))) - // ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_power", "PV Power", TotalDcPower, len(ret.Entries))) - // - // value = TotalDcPower - BatteryChargingPower - TotalExportActivePower - // ret.Entries = append(ret.Entries, addFloatValue(ts, "pv_power_to_load", "PV Power To Load", value, len(ret.Entries))) - // } - // - // { - // ret.Entries = append(ret.Entries, addState(ts, "load_power_active", "Load Power Active", isActive(TotalLoadActivePower), len(ret.Entries))) - // - // ret.Entries = append(ret.Entries, api.DataEntry{ - // Date: ts, - // PointId: "virtual.pv_power_to_grid", - // PointGroupName: "Virtual", - // PointName: "PV Power To Grid", - // Value: api.Float64ToString(TotalExportActivePower), - // Unit: "kW", - // ValueType: &api.Point{ - // PsKey: "virtual", - // Id: "pv_power_to_grid", - // Description: "PV Power To Grid", - // Unit: "kW", - // Type: "PointTypeInstant", - // }, - // Index: len(ret.Entries), - // }) - // } - - { - if YieldBatteryCharge > 0 { - value = 0 - YieldBatteryCharge - } else { - value = DailyBatteryDischargingEnergy - } - ret.Entries = append(ret.Entries, api.DataEntry{ - Date: ts, - PointId: "virtual.battery_energy", - PointGroupName: "Virtual", - PointName: "Battery Energy", - Value: api.Float64ToString(value), - Unit: "kWh", - ValueType: &api.Point{ - PsKey: "virtual", - Id: "battery_energy", - Description: "Battery Energy", - Unit: "kWh", - Type: "PointTypeInstant", - }, - Index: len(ret.Entries), - }) - } - - { - if YieldFeedIn > 0 { - value = 0 - YieldFeedIn - } else { - value = DailyPurchasedEnergy - } - ret.Entries = append(ret.Entries, api.DataEntry{ - Date: ts, - PointId: "virtual.grid_energy", - PointGroupName: "Virtual", - PointName: "Grid Energy", - Value: api.Float64ToString(value), - Unit: "kWh", - ValueType: &api.Point{ - PsKey: "virtual", - Id: "grid_energy", - Description: "Grid Energy", - Unit: "kWh", - Type: "PointTypeInstant", - }, - Index: len(ret.Entries), - }) - } - } - return ret + return entries } -func lowerUpper(lower float64, upper float64) float64 { - if lower > 0 { - return 0 - lower - } - return upper -} - -func getPercent(value float64, max float64) float64 { - return (value / max) * 100 -} +// func (ref *EntryMap) getFloatValue(entry string) float64 { +// return (*ref)[entry].ValueFloat +// } +// +// func lowerUpper(lower api.DataEntry, upper api.DataEntry) float64 { +// if lower.ValueFloat > 0 { +// return 0 - lower.ValueFloat +// } +// return upper.ValueFloat +// } +// +// func getPercent(value api.DataEntry, max api.DataEntry) float64 { +// if max.ValueFloat == 0 { +// return 0 +// } +// return (value.ValueFloat / max.ValueFloat) * 100 +// } -func addState(now api.DateTime, point string, name string, state bool, index int) api.DataEntry { - return add(now, "virtual", point, name, api.UnitValue{ Value: fmt.Sprintf("%v", state), Unit: "binary"}, index) - - // return api.DataEntry { - // Date: now, - // PointId: api.NameDevicePoint("virtual", point), - // PointGroupName: "Virtual", - // PointName: name, - // Value: fmt.Sprintf("%v", state), - // Unit: "binary", - // ValueType: &api.Point{ - // PsKey: "virtual", - // Id: point, - // Description: name, - // Unit: "binary", - // Type: "PointTypeInstant", - // }, - // Index: index, - // } -} - -func addValue(now api.DateTime, point string, name string, value string, unit string, index int) api.DataEntry { - return add(now, "virtual", point, name, api.UnitValue{ Value: value, Unit: unit}, index) - - // vt := api.GetPoint(psId, point) - // if !vt.Valid { - // vt = &api.Point{ - // PsKey: psId, - // Id: point, - // Description: name, - // Unit: "", - // Type: "PointTypeInstant", - // } - // } - // return api.DataEntry { - // Date: now, - // PointId: api.NameDevicePoint(psId, point), - // PointGroupName: "Summary", - // PointName: name, - // Value: value, - // Unit: "", - // ValueType: vt, - // Index: index, - // } -} - -func addIntValue(now api.DateTime, point string, name string, value int64, unit string, index int) api.DataEntry { - return add(now, "virtual", point, name, api.UnitValue{ Value: strconv.FormatInt(value, 10), Unit: unit }, index) -} - -func addFloatValue(now api.DateTime, point string, name string, value float64, unit string, index int) api.DataEntry { - return add(now, "virtual", point, name, api.UnitValue{ Value: api.Float64ToString(value), Unit: unit }, index) -} - -func add(now api.DateTime, psId string, point string, name string, value api.UnitValue, index int) api.DataEntry { - vt := api.GetPoint(psId, point) - if !vt.Valid { - vt = &api.Point{ - PsKey: psId, - Id: point, - Description: name, - Unit: value.Unit, - Type: "PointTypeInstant", - } - } - return api.DataEntry { - Date: now, - PointId: api.NameDevicePoint(psId, point), - PointGroupName: "Virtual", - PointName: name, - Value: value.Value, - Unit: value.Unit, - ValueType: vt, - Index: index, - } -} - +// func addState(now api.DateTime, point string, name string, state bool, index int) api.DataEntry { +// return add(now, "virtual", point, name, api.UnitValue{ Value: fmt.Sprintf("%v", state), Unit: "binary"}, index) +// } +// +// func addValue(now api.DateTime, point string, name string, value string, unit string, index int) api.DataEntry { +// return add(now, "virtual", point, name, api.UnitValue{ Value: value, Unit: unit}, index) +// +// // vt := api.GetPoint(psId, point) +// // if !vt.Valid { +// // vt = &api.PointStruct{ +// // PsKey: psId, +// // Id: point, +// // Description: name, +// // Unit: "", +// // Type: "PointTypeInstant", +// // } +// // } +// // return api.DataEntry { +// // Date: now, +// // PointId: api.NameDevicePoint(psId, point), +// // PointGroupName: "Summary", +// // PointName: name, +// // Value: value, +// // Unit: "", +// // ValueType: vt, +// // Index: index, +// // } +// } +// +// func addIntValue(now api.DateTime, point string, name string, value int64, unit string, index int) api.DataEntry { +// return add(now, "virtual", point, name, api.UnitValue{ Value: strconv.FormatInt(value, 10), Unit: unit }, index) +// } +// +// func addFloatValue(now api.DateTime, point string, name string, value float64, unit string, index int) api.DataEntry { +// return add(now, "virtual", point, name, api.UnitValue{ Value: api.Float64ToString(value), Unit: unit }, index) +// } +// +// func addFloatValue(ref api.DataEntry, psId string, point string, name string, index int) api.DataEntry { +// ref.PointId = psId +// ref.PointName = point +// return add(now, "virtual", point, name, api.UnitValue{ Value: api.Float64ToString(value), Unit: unit }, index) +// } +// +// func addVirtualState(ref api.DataEntry, point string, name string) api.DataEntry { +// +// return api.DataEntry { +// Date: ref.Date, +// PointId: api.NameDevicePoint("virtual", point), +// PointGroupName: "Virtual", +// PointName: name, +// Value: fmt.Sprintf("%v", isActive(ref.ValueFloat)), +// ValueFloat: 0, +// Unit: "binary", +// ValueType: &api.Point { +// PsKey: "virtual", +// Id: point, +// Description: name, +// Unit: "binary", +// }, +// Index: 0, +// } +// } +// +// func addVirtualValue(ref api.DataEntry, point string, name string, value float64) api.DataEntry { +// return api.DataEntry { +// Date: ref.Date, +// PointId: api.NameDevicePoint("virtual", point), +// PointGroupName: "Virtual", +// PointName: name, +// Value: api.Float64ToString(value), +// ValueFloat: value, +// Unit: ref.Unit, +// ValueType: &api.Point { +// PsKey: "virtual", +// Id: point, +// Description: name, +// Unit: ref.Unit, +// }, +// Index: 0, +// } +// } +// +// func addVirtualAlias(ref api.DataEntry, point string, name string) api.DataEntry { +// ref.PointId = api.NameDevicePoint("virtual", point) +// ref.PointGroupName = "Virtual" +// ref.PointName = name +// ref.ValueType.PsKey = "virtual" +// ref.ValueType.Description = name +// ref.ValueType.Id = point +// ref.Index = 0 +// +// return ref +// } +// +// func add(now api.DateTime, psId string, point string, name string, value api.UnitValue) api.DataEntry { +// vt := api.GetPoint(psId, point) +// if !vt.Valid { +// vt = &api.Point{ +// PsKey: psId, +// Id: point, +// Description: name, +// Unit: value.Unit, +// Type: "PointTypeInstant", +// } +// } +// return api.DataEntry { +// Date: now, +// PointId: api.NameDevicePoint(psId, point), +// PointGroupName: "Virtual", +// PointName: name, +// Value: value.Value, +// Unit: value.Unit, +// ValueType: vt, +// Index: 0, +// } +// } +// // func addState(now api.DateTime, point string, name string, state bool, index int) api.DataEntry { // return api.DataEntry { // Date: now, @@ -772,7 +711,7 @@ func add(now api.DateTime, psId string, point string, name string, value api.Uni // PointName: name, // Value: fmt.Sprintf("%v", state), // Unit: "binary", -// ValueType: &api.Point{ +// ValueType: &api.PointStruct{ // PsKey: "virtual", // Id: point, // Description: name, @@ -782,10 +721,10 @@ func add(now api.DateTime, psId string, point string, name string, value api.Uni // Index: index, // } // } - -func isActive(value float64) bool { - if (value > 0.01) || (value < -0.01) { - return true - } - return false -} +// +// func isActive(value float64) bool { +// if (value > 0.01) || (value < -0.01) { +// return true +// } +// return false +// } diff --git a/iSolarCloud/AppService/queryDeviceRealTimeDataByPsKeys/data.go b/iSolarCloud/AppService/queryDeviceRealTimeDataByPsKeys/data.go index bbaadfcaf..512b0d17d 100644 --- a/iSolarCloud/AppService/queryDeviceRealTimeDataByPsKeys/data.go +++ b/iSolarCloud/AppService/queryDeviceRealTimeDataByPsKeys/data.go @@ -108,8 +108,8 @@ func (e *EndPoint) GetDataTable() output.Table { return table } -func (e *EndPoint) GetData() api.Data { - var ret api.Data +func (e *EndPoint) GetData() api.DataMap { + var ret api.DataMap // for range Only.Once { // index := 0 diff --git a/iSolarCloud/api/apiReflect/reflect.go b/iSolarCloud/api/apiReflect/reflect.go index 7916a893a..437479651 100644 --- a/iSolarCloud/api/apiReflect/reflect.go +++ b/iSolarCloud/api/apiReflect/reflect.go @@ -6,7 +6,9 @@ import ( "encoding/json" "errors" "fmt" + "github.com/davecgh/go-spew/spew" "hash/fnv" + "runtime" "strconv" // "github.com/google/uuid" @@ -211,25 +213,25 @@ func PrintHeader(i interface{}) string { s := reflect.ValueOf(i) // .Elem() typeOf := s.Type() switch s.Kind().String() { - case "string": - ret = fmt.Sprintf("%v", s) - default: - for id := 0; id < s.NumField(); id++ { - // value := fmt.Sprintf("%v", s.Field(id).Interface()) - // if value == "" { - // continue - // } - ret += fmt.Sprintf("%s (%s),", - typeOf.Field(id).Name, - typeOf.Field(id).Tag.Get("json"), - ) - // fmt.Printf("%d: %s %s = %v\n", - // i, - // typeOfT.Field(i).Name, - // s.Field(i).Type(), - // s.Field(i).Interface(), - // ) - } + case "string": + ret = fmt.Sprintf("%v", s) + default: + for id := 0; id < s.NumField(); id++ { + // value := fmt.Sprintf("%v", s.Field(id).Interface()) + // if value == "" { + // continue + // } + ret += fmt.Sprintf("%s (%s),", + typeOf.Field(id).Name, + typeOf.Field(id).Tag.Get("json"), + ) + // fmt.Printf("%d: %s %s = %v\n", + // i, + // typeOfT.Field(i).Name, + // s.Field(i).Type(), + // s.Field(i).Interface(), + // ) + } } return ret @@ -599,6 +601,73 @@ func GetFingerprint(ref interface{}) string { return ret } + +type DataStructureMap map[string]DataStructure +type DataStructure struct { + Json string + PointId string + PointType string + PointUnit string + PointDevice string + PointName string +} + +func GetCallerPackage(skip int) string { + var ret string + if pc, _, _, ok := runtime.Caller(skip); ok { + funcName := runtime.FuncForPC(pc).Name() + slash := strings.LastIndexByte(funcName, '/') + if slash < 0 { + slash = 0 + } + dot := strings.IndexByte(funcName, '.') + ret = funcName[slash+1:dot] + } + return ret +} + +func GetTagPointType(ref interface{}) DataStructureMap { + ret := make(DataStructureMap) + + for range Only.Once { + // required := GetOptionsRequired(ref) + + vo := reflect.ValueOf(ref) + to := reflect.TypeOf(ref) + spew.Dump(&vo) + spew.Dump(&to) + + // Iterate over all available fields and read the tag value + for i := 0; i < vo.NumField(); i++ { + fieldTo := to.Field(i) + spew.Dump(&fieldTo) + + // j := fieldTo.Tag.Get("json") + // pid := fieldTo.Tag.Get("json") + + name := fieldTo.Name + foo := DataStructure{ + Json: fieldTo.Tag.Get("json"), + PointDevice: fieldTo.Tag.Get("PointDevice"), + PointId: fieldTo.Tag.Get("PointId"), + PointName: fieldTo.Tag.Get("PointName"), + PointUnit: fieldTo.Tag.Get("PointUnit"), + PointType: fieldTo.Tag.Get("PointType"), + } + ret[name] = foo + + // fieldVo := vo.Field(i) + // value := fmt.Sprintf("%v", fieldVo.Interface()) + // if value == "" { + // err = errors.New(fmt.Sprintf("option '%s' is empty", fieldTo.Name)) + // break + // } + } + } + + return ret +} + func hash(s string) uint32 { h := fnv.New32a() _, _ = h.Write([]byte(s)) diff --git a/iSolarCloud/api/funcs.go b/iSolarCloud/api/funcs.go new file mode 100644 index 000000000..df4b3082b --- /dev/null +++ b/iSolarCloud/api/funcs.go @@ -0,0 +1,27 @@ +package api + +import ( + "strings" +) + + +func CleanString(s string) string { + // var ret string + var result strings.Builder + for i := 0; i < len(s); i++ { + b := s[i] + if ('a' <= b && b <= 'z') || + ('A' <= b && b <= 'Z') || + ('0' <= b && b <= '9') || + (b == '-') || + (b == '_') || + (b == '.') || + b == ' ' { + result.WriteByte(b) + } + } + + // dupes := regexp.MustCompile(`\s+`) + // ret = dupes.ReplaceAllString(result.String(), ) + return result.String() +} diff --git a/iSolarCloud/api/nullEndPoint/struct.go b/iSolarCloud/api/nullEndPoint/struct.go index d38a657bb..32b6b0e09 100644 --- a/iSolarCloud/api/nullEndPoint/struct.go +++ b/iSolarCloud/api/nullEndPoint/struct.go @@ -24,6 +24,7 @@ type EndPoint struct { api.EndPointStruct Request Request Response Response + RawResponse []byte } // Request - Holds the api.RequestCommon and user RequestData structures. See data.go for request fields. @@ -127,7 +128,8 @@ func (e EndPoint) Call() api.EndPoint { // GetJsonData - Get the JSON representation of ResultData, either as condensed or "pretty". func (e EndPoint) GetJsonData(raw bool) output.Json { if raw { - return output.Json(e.ApiRoot.Body) + // return output.GetAsPrettyJson(string(e.RawResponse)) + return output.Json(e.RawResponse) } else { return output.GetAsPrettyJson(e.Response.ResultData) } @@ -247,6 +249,7 @@ func (e EndPoint) IsRequestValid() error { // (Used by the web call method.) func (e EndPoint) SetResponse(ref []byte) api.EndPoint { for range Only.Once { + e.RawResponse = ref e.Error = json.Unmarshal(ref, &e.Response) if e.Error != nil { break diff --git a/iSolarCloud/api/struct_data.go b/iSolarCloud/api/struct_data.go new file mode 100644 index 000000000..b9f9185bc --- /dev/null +++ b/iSolarCloud/api/struct_data.go @@ -0,0 +1,798 @@ +package api + +import ( + "GoSungrow/Only" + "GoSungrow/iSolarCloud/api/apiReflect" + "fmt" + "github.com/davecgh/go-spew/spew" + "reflect" + "strconv" + "time" +) + + +const ( + PointTypeInstant = "instant" + PointTypeBoot = "boot" + PointTypeDaily = "daily" + PointTypeMonthly = "monthly" + PointTypeYearly = "yearly" + PointTypeTotal = "total" +) + + +type DataMap struct { + Entries map[string]DataEntry + Order []string +} + +type DataEntry struct { + EndPoint string `json:"endpoint"` + Point *Point `json:"point"` + Date DateTime `json:"date"` + // Id string `json:"id"` + // GroupName string `json:"group_name"` + // Name string `json:"name"` + // Unit string `json:"unit"` + Value string `json:"value"` + ValueFloat float64 `json:"value_float"` + Index int `json:"index"` +} + +func NewDataMap() DataMap { + return DataMap{ Entries: make(map[string]DataEntry)} +} + +// func (dm *DataMap) Add(point string, entry DataEntry) { +// dm.Entries[point] = entry +// dm.Order = append(dm.Order, point) +// } + + +func (dm *DataMap) StructToPoints(endpoint string, ref interface{}) { + for range Only.Once { + if endpoint == "" { + endpoint = apiReflect.GetCallerPackage(2) + } + + now := NewDateTime(time.Now().Round(5 * time.Minute).Format(DtLayoutZeroSeconds)) + + vo := reflect.ValueOf(ref) + to := reflect.TypeOf(ref) + + // Iterate over all available fields and read the tag value + for i := 0; i < vo.NumField(); i++ { + fieldTo := to.Field(i) + valueTo := vo.Field(i).Interface() + spew.Dump(&fieldTo) + + j := fieldTo.Tag.Get("json") + pid := fieldTo.Tag.Get("json") + if (j != "") && (pid == "") { + pid = j + } else if (pid != "") && (j == "") { + j = pid + } + + name := fieldTo.Tag.Get("PointName") + if name == "" { + name = PointToName(pid) + } + + device := fieldTo.Tag.Get("PointDevice") + if device == "" { + device = "virtual" + } + + var ignore bool + if fieldTo.Tag.Get("PointIgnore") != "" { + ignore = true + } + + fullName := JoinDevicePoint(device, pid) + + unit := fieldTo.Tag.Get("PointUnit") + var uv UnitValue + if unit == "" { + bar := fieldTo.Type.Name() + fmt.Printf("bar:%v\n", bar) + fmt.Println("") + switch bar { + case "int": + uv.Unit = "integer" + uv.ValueInt = valueTo.(int64) + uv.Value = strconv.FormatInt(uv.ValueInt, 10) + case "int32": + uv.Unit = "integer" + uv.ValueInt = valueTo.(int64) + uv.Value = strconv.FormatInt(uv.ValueInt, 10) + case "int64": + uv.Unit = "integer" + uv.ValueInt = valueTo.(int64) + uv.Value = strconv.FormatInt(uv.ValueInt, 10) + + case "float32": + uv.Unit = "float" + uv.ValueFloat = float64(valueTo.(float32)) + uv.Value = Float64ToString(uv.ValueFloat) + case "float64": + uv.Unit = "float" + uv.ValueFloat = valueTo.(float64) + uv.Value = Float64ToString(uv.ValueFloat) + + case "string": + uv.Unit = "string" + uv.Value = valueTo.(string) + + case "UnitValue": + fallthrough + case "api.UnitValue": + uv = valueTo.(UnitValue) + uv = uv.UnitValueFix() + + default: + ignore = true + } + } + + if ignore { + continue + } + + // foo := apiReflect.DataStructure { + // Json: j, + // PointDevice: device, + // PointId: pid, + // PointName: name, + // PointUnit: uv.Unit, + // PointType: fieldTo.Tag.Get("PointType"), + // } + // ret[fieldTo.Name] = foo + + p := Point { + EndPoint: endpoint, + FullId: fullName, + PsKey: device, + Id: pid, + GroupName: "", + Name: name, + Unit: uv.Unit, + Type: fieldTo.Tag.Get("PointType"), + Valid: true, + } + dm.AddEntry(p, now, uv.Value) + + alias := fieldTo.Tag.Get("PointAlias") + if alias != "" { + p.FullId = NameDevicePoint(device, alias) + p.Id = alias + dm.AddEntry(p, now, uv.Value) + } + + // spew.Dump(&foo) + // fieldVo := vo.Field(i) + // value := fmt.Sprintf("%v", fieldVo.Interface()) + // if value == "" { + // err = errors.New(fmt.Sprintf("option '%s' is empty", fieldTo.Name)) + // break + // } + } + } +} + +func (dm *DataMap) GetEntry(entry string) DataEntry { + ret := dm.Entries[entry] + return ret +} + +func (dm *DataMap) CopyEntry(entry string) *DataEntry { + ret := dm.Entries[entry] + return &ret + // return &DataEntry { + // Date: DateTime{}, + // Point: nil, + // Value: "", + // ValueFloat: 0, + // Index: 0, + // } +} + +func (dm *DataMap) GetFloatValue(entry string) float64 { + return dm.Entries[entry].ValueFloat +} + +func (dm *DataMap) LowerUpper(lower string, upper string) float64 { + l := dm.GetEntry(lower) + u := dm.GetEntry(upper) + + if l.ValueFloat > 0 { + return 0 - l.ValueFloat + } + return u.ValueFloat +} + +func (dm *DataMap) GetPercent(value string, max string) float64 { + v := dm.GetEntry(value) + m := dm.GetEntry(max) + return GetPercent(v.ValueFloat, m.ValueFloat) +} + +func (dm *DataMap) GetValue(refname string) float64 { + v := dm.GetEntry(refname) + return v.ValueFloat +} + + +// func (dm *DataMap) FromRefAddState(refname string, psId string, point string, name string) { +// v := dm.GetEntry(refname) +// dm.Entries[point] = v.CreateState(psId, point, name) +// dm.Order = append(dm.Order, point) +// } + +// func (dm *DataMap) AddVirtualValue(refname string, point string, name string, value float64) { +// v := dm.GetEntry(refname) +// dm.Entries[point] = v.CreateFloat(VirtualPsId, point, name, value) +// dm.Order = append(dm.Order, point) +// } +// +// func (ref *DataMap) AddUnitValue(refname string, point string, name string, value UnitValue) { +// v := ref.GetEntry(refname) +// ref.Entries[point] = v.FromRefAddFloat("virtual", point, name, value.Value) +// ref.Order = append(ref.Order, point) +// } + + +func (dm *DataMap) Add(point string, de DataEntry) { + for range Only.Once { + // point := de.ValueType.Id + de.Index = len(dm.Entries) + dm.Entries[point] = de + dm.Order = append(dm.Order, point) + + if _, ok := Points[point]; ok { + break + } + Points[point] = *de.Point + } +} + +func (dm *DataMap) AddEntry(point Point, date DateTime, value string) { + for range Only.Once { + unit := point.Unit // Save unit. + + // Match to a previously defined point. + p := GetPoint(point.PsKey, point.Id) + if p == nil { + point = *p + } + + if point.PsKey == "" { + point.PsKey = "virtual" + } + if point.Name == "" { + point.Name = PointToName(point.Id) + } + if point.FullId == "" { + point.FullId = JoinDevicePoint(point.PsKey, point.Id) + } + ref := CreateUnitValue(value, unit) + point.Unit = ref.Unit + point.Valid = true + + // foo := Point { + // PsKey: psId, + // Id: "total_income", + // Unit: p.TotalIncome.Unit, + // Type: PointTypeTotal, + // } + // + // p := GetPoint(point.PsKey, point.Id) + // if p == nil { + // fmt.Printf("Found point already: %s.%s\n", p.PsKey, p.Id) + // fmt.Println("&point") + // spew.Dump(&point) + // fmt.Println("&p") + // spew.Dump(&p) + // // dm.Add(point.Id, CreateDataEntryUnitValue(date, point.PsKey, point.Id, point.Name, ref)) + // // if p.Name == "" { + // // p.Name = PointToName(point.Id) + // // } + // // p = CreatePoint(psId, point, name, value.Unit) + // // break + // } + + dm.Add(JoinDevicePoint(point.EndPoint, point.Id), DataEntry { + EndPoint: point.EndPoint, + Point: &point, + Date: date, + Value: ref.Value, + ValueFloat: ref.ValueFloat, + }) + } +} + +// func (dm *DataMap) AddPointAlias(refPoint Point, point Point) { +// for range Only.Once { +// p := GetPoint(refPoint.PsKey, refPoint.Id) +// if p != nil { +// fmt.Printf("Found point already: %s.%s\n", p.PsKey, p.Id) +// fmt.Println("&point") +// spew.Dump(&point) +// fmt.Println("&p") +// spew.Dump(&p) +// break +// } +// +// if p.PsKey == "" { +// p.PsKey = "virtual" +// } +// if p.Name == "" { +// p.Name = PointToName(point.Id) +// } +// if p.FullId == "" { +// p.FullId = JoinDevicePoint(point.PsKey, point.Id) +// } +// ref := CreateUnitValue(value, p.Unit) +// p.Unit = ref.Unit +// p.Valid = true +// +// dm.Add(point.Id, DataEntry { +// Date: date, +// Point: p, +// Value: ref.Value, +// ValueFloat: ref.ValueFloat, +// }) +// } +// } + +func (dm *DataMap) FromRefAddAlias2(refname string, psId string, point string, name string) { + de := dm.GetEntry(refname) + dm.Add(point, de.CreateAlias(psId, point, name)) +} + +func (dm *DataMap) AddEntryFromRef(refPoint Point, point Point, date DateTime, value string) { + for range Only.Once { + p := GetPoint(refPoint.PsKey, refPoint.Id) + if p != nil { + fmt.Printf("Found point already: %s.%s\n", p.PsKey, p.Id) + fmt.Println("&point") + spew.Dump(&point) + fmt.Println("&p") + spew.Dump(&p) + break + } + + if point.PsKey == "" { + point.PsKey = "virtual" + } + if point.Name == "" { + point.Name = PointToName(point.Id) + } + if point.FullId == "" { + point.FullId = JoinDevicePoint(point.PsKey, point.Id) + } + ref := CreateUnitValue(value, point.Unit) + point.Unit = ref.Unit + point.Valid = true + + dm.Add(point.Id, DataEntry { + Date: date, + Point: p, + Value: ref.Value, + ValueFloat: ref.ValueFloat, + }) + } +} + + +func JoinDevicePoint(device string, point string) string { + var ret string + for range Only.Once { + if device == "" { + device = "virtual" + } + ret = device + "." + point + } + return ret +} + +func (dm *DataMap) AddUnitValue(endpoint string, psId string, point string, name string, date DateTime, ref UnitValue) { + for range Only.Once { + if endpoint == "" { + endpoint = apiReflect.GetCallerPackage(2) + } + + ref = ref.UnitValueFix() + + p := GetPoint(psId, point) + if p == nil { + // No UV found. Create one. + dm.Add(point, CreateDataEntryUnitValue(date, psId, point, name, ref)) + break + } + + if p.Unit == "" { + p.Unit = ref.Unit + } + if p.Name == "" { + p.Name = name + } + if p.Name == "" { + p.Name = PointToName(point) + } + dm.Add(point, DataEntry { + Date: date, + Point: p, + Value: ref.Value, + ValueFloat: ref.ValueFloat, + }) + } +} + +func (dm *DataMap) AddFloat(psId string, point string, name string, date DateTime, value float64) { + for range Only.Once { + fvs := Float64ToString(value) + p := GetPoint(psId, point) + if p == nil { + // No UV found. Create one. + dm.Add(point, CreateDataEntryUnitValue(date, psId, point, name, CreateUnitValue(fvs, "float"))) + break + } + ref := CreateUnitValue(fvs, p.Unit) + if ref.Unit != p.Unit { + fmt.Printf("OOOPS: Unit mismatch - %f %s != %f %s\n", value, p.Unit, ref.ValueFloat, ref.Unit) + p.Unit = ref.Unit + } + dm.Add(point, DataEntry { + Date: date, + Point: p, + Value: ref.Value, + ValueFloat: ref.ValueFloat, + }) + } + + de := CreateDataEntryUnitValue(date, psId, point, name, UnitValue { + Unit: "float", + Value: fmt.Sprintf("%f", value), + ValueFloat: 0, + }) + dm.Add(point, de) +} + +func (dm *DataMap) AddString(psId string, point string, name string, date DateTime, value string) { + dm.Add(point, CreateDataEntryString(date, psId, point, name, value)) +} + +func (dm *DataMap) AddInt(psId string, point string, name string, date DateTime, value int64) { + de := CreateDataEntryUnitValue(date, psId, point, name, UnitValue { + Unit: "int", + Value: fmt.Sprintf("%d", value), + ValueFloat: float64(value), + }) + dm.Add(point, de) +} + + +// func (dm *DataMap) AddVirtualAliasFromRef(refname string, point string, name string) { +// de := dm.GetEntry(refname) +// dm.Add(point, de.CreateAlias("virtual", point, name)) +// } + +func (dm *DataMap) FromRefAddAlias(refname string, psId string, point string, name string) { + de := dm.GetEntry(refname) + dm.Add(point, de.CreateAlias(psId, point, name)) +} + +func (dm *DataMap) FromRefAddState(refname string, psId string, point string, name string) { + v := dm.GetEntry(refname) + dm.Add(point, v.CreateState(psId, point, name)) +} + +func (dm *DataMap) FromRefAddFloat(refname string, psId string, point string, name string, value float64) { + de := dm.GetEntry(refname) + dm.Add(point, de.CreateFloat(psId, point, name, value)) +} + +func (dm *DataMap) CopyPoint(refname string, psId string, point string, name string, value float64) { + de := dm.GetEntry(refname) + dm.Add(point, de.CreateFloat(psId, point, name, value)) +} + + +func (de *DataEntry) CreateAlias(psId string, point string, name string) DataEntry { + if name == "" { + name = PointToName(point) + } + + de.Point.FullId = NameDevicePoint(psId, point) + de.Point.PsKey = psId + de.Point.Id = point + de.Point.Name = name + de.Point.GroupName = psId + de.Point.Valid = true + de.Index = 0 + + return *de +} + +func (de *DataEntry) CreateFloat(psId string, point string, name string, value float64) DataEntry { + if name == "" { + name = PointToName(point) + } + + de2 := de.CreateAlias(psId, point, name) + uv := CreateUnitValue(Float64ToString(value), de2.Point.Unit) + de2.Value = uv.Value + de2.ValueFloat = uv.ValueFloat + + return de2 + // if name == "" { + // name = PointToName(point) + // } + // + // return DataEntry { + // Date: de.Date, + // Value: Float64ToString(v), + // ValueFloat: v, + // Point: &Point { + // FullId: NameDevicePoint(psId, point), + // GroupName: psId, + // PsKey: psId, + // Id: point, + // Name: name, + // Unit: u, + // Type: "", + // Valid: true, + // }, + // Index: 0, + // } +} + +func (de *DataEntry) CreateState(psId string, point string, name string) DataEntry { + if name == "" { + name = PointToName(point) + } + + de2 := de.CreateAlias(psId, point, name) + de2.Value = fmt.Sprintf("%v", IsActive(de.ValueFloat)) + de2.ValueFloat = 0 + de2.Point.Unit = "binary" + + return de2 + + // return DataEntry { + // Date: de.Date, + // Value: fmt.Sprintf("%v", IsActive(de.ValueFloat)), + // ValueFloat: 0, + // Point: &Point { + // FullId: NameDevicePoint(psId, point), + // PsKey: psId, + // Id: point, + // GroupName: psId, + // Name: name, + // Unit: "binary", + // Type: "", + // Valid: true, + // }, + // Index: 0, + // } +} + +func (de *DataEntry) UpdateMeta(date *DateTime, psId string, point string, name string) { + + if date != nil { + de.Date = *date + } + if name == "" { + name = PointToName(point) + } + + de.Point.FullId = NameDevicePoint(psId, point) + de.Point.PsKey = psId + de.Point.Id = point + de.Point.Name = name + de.Point.GroupName = psId + de.Index = 0 +} + + +func CreateDataEntryActive(date DateTime, psId string, point string, name string, value float64) DataEntry { + p := GetPoint(psId, point) + if p == nil { + if name == "" { + name = PointToName(point) + } + p = CreatePoint(psId, point, name, "state") + } + + return DataEntry { + Date: date, + Value: fmt.Sprintf("%v", IsActive(value)), + ValueFloat: 0, + Point: p, + Index: 0, + } +} + +func CreateDataEntryString(date DateTime, psId string, point string, name string, value string) DataEntry { + p := GetPoint(psId, point) + if p == nil { + if name == "" { + name = PointToName(point) + } + p = CreatePoint(psId, point, name, "string") + } + + return DataEntry { + Date: date, + Value: value, + ValueFloat: 0, + Point: p, + Index: 0, + } +} + +func CreateDataEntryUnitValue(date DateTime, psId string, point string, name string, value UnitValue) DataEntry { + value = value.UnitValueFix() + + p := GetPoint(psId, point) + if p == nil { + if name == "" { + name = PointToName(point) + } + p = CreatePoint(psId, point, name, value.Unit) + } + + return DataEntry { + Date: date, + Value: value.Value, + ValueFloat: value.ValueFloat, + Point: p, + Index: 0, + } +} + +func CreatePoint(psId string, point string, name string, unit string) *Point { + if name == "" { + name = PointToName(point) + } + + return &Point { + FullId: NameDevicePoint(psId, point), + PsKey: psId, + Id: point, + GroupName: psId, + Name: name, + Unit: unit, + Type: "", + Valid: true, + } +} + + +func CreateUnitValue(value string, unit string) UnitValue { + ret := UnitValue { + Unit: unit, + Value: value, + } + return ret.UnitValueFix() +} + + +func (ref *UnitValue) UnitValueFix() UnitValue { + if ref.Unit == "W" { + fvs, err := DivideByThousand(ref.Value) + // fv, err := strconv.ParseFloat(p.Value, 64) + // fv = fv / 1000 + if err == nil { + // p.Value = fmt.Sprintf("%.3f", fv) + ref.Value = fvs + ref.Unit = "kW" + } + } + + if ref.Unit == "Wh" { + fvs, err := DivideByThousand(ref.Value) + // fv, err := strconv.ParseFloat(p.Value, 64) + // fv = fv / 1000 + if err == nil { + // p.Value = fmt.Sprintf("%.3f", fv) + ref.Value = fvs + ref.Unit = "kWh" + } + } + + ref.ValueFloat, _ = strconv.ParseFloat(ref.Value, 64) + + return *ref +} + +func (ref *UnitValue) UnitValueToPoint(psId string, point string, name string) *Point { + uv := ref.UnitValueFix() + + // u := ref.Unit + // + // if ref.Unit == "W" { + // fvs, err := DivideByThousand(ref.Value) + // // fv, err := strconv.ParseFloat(p.Value, 64) + // // fv = fv / 1000 + // if err == nil { + // // p.Value = fmt.Sprintf("%.3f", fv) + // ref.Value = fvs + // ref.Unit = "kW" + // } + // } + // + // if ref.Unit == "Wh" { + // fvs, err := DivideByThousand(ref.Value) + // // fv, err := strconv.ParseFloat(p.Value, 64) + // // fv = fv / 1000 + // if err == nil { + // // p.Value = fmt.Sprintf("%.3f", fv) + // ref.Value = fvs + // ref.Unit = "kWh" + // } + // } + + if name == "" { + name = PointToName(point) + } + + vt := GetPoint(psId, point) + if !vt.Valid { + vt = &Point { + PsKey: psId, + Id: point, + Name: name, + Unit: uv.Unit, + Type: "PointTypeInstant", + Valid: true, + } + } + + return vt +} + +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 +} + +// // entries.AddVirtualValue("DailyTotalLoad", "DailyPvEnergyPercent", "daily_pv_energy_percent", "Daily PV Energy Percent", value) +// func NameToRefName(name string) string { +// var ret string // "Daily PV Energy Percent" +// ret = strings.ReplaceAll(name, " ", "_") +// ret = strings.ToLower(ret) +// return ret +// } +// +// func (upper *DataEntry) LowerUpper(lower DataEntry) float64 { +// if lower.ValueFloat > 0 { +// return 0 - lower.ValueFloat +// } +// return upper.ValueFloat +// } +// +// Type string +// Name string +// SubName string +// +// ParentId string +// ParentName string +// +// UniqueId string +// FullName string +// Units string +// ValueName string +// DeviceClass string +// +// Value string \ No newline at end of file diff --git a/iSolarCloud/api/struct_endpoint.go b/iSolarCloud/api/struct_endpoint.go index 3c09d21cd..4b0fda02a 100644 --- a/iSolarCloud/api/struct_endpoint.go +++ b/iSolarCloud/api/struct_endpoint.go @@ -11,7 +11,8 @@ import ( type EndPointName string type EndPointStruct struct { - ApiRoot Web `json:"-"` + ApiRoot Web `json:"-"` + RawResponse []byte Area AreaName `json:"area"` Name EndPointName `json:"name"` @@ -102,6 +103,18 @@ func (ep EndPointStruct) String() string { return ret } +func (ep EndPointStruct) ResponseAsJson(raw bool, r interface{}) output.Json { + var ret output.Json + for range Only.Once { + if raw { + ret = output.GetAsPrettyJson(r) + break + } + ret = output.GetAsPrettyJson(r) + } + return ret +} + func MarshalJSON(endpoint EndPoint) ([]byte, error) { e := endpoint.SetError("") j, err := json.Marshal(&struct { diff --git a/iSolarCloud/api/struct_points.go b/iSolarCloud/api/struct_points.go index 43dfa088f..0e36295b6 100644 --- a/iSolarCloud/api/struct_points.go +++ b/iSolarCloud/api/struct_points.go @@ -8,23 +8,21 @@ import ( "time" ) - const ( - PointTypeInstant = "instant" - PointTypeDaily = "daily" - PointTypeMonthly = "monthly" - PointTypeYearly = "yearly" - PointTypeTotal = "total" + VirtualPsId = "virtual" ) type Point struct { - PsKey string - Id string - Description string - Unit string - Type string - Valid bool + EndPoint string `json:"endpoint"` + FullId string `json:"full_id"` + PsKey string `json:"ps_key"` + Id string `json:"id"` + GroupName string `json:"group_name"` + Name string `json:"name"` + Unit string `json:"unit"` + Type string `json:"type"` + Valid bool `json:"valid"` } type PointsMap map[string]Point @@ -40,6 +38,7 @@ func ResolvePoint(point string) *Point { return Points.Resolve(point) } + // p1 // p1001 // p1002 @@ -100,148 +99,188 @@ func ResolvePoint(point string) *Point { // Points Discovered points from the API var Points = PointsMap { - "p13001": { PsKey: "1129147_14_1_1", Id: "p13001", Description: "MPPT1 Voltage", Unit: "V", Type: PointTypeInstant }, + // Added manually + // "p83022y": { PsKey: "virtual", Id: "p83022", Name: "", Unit: "kWh", Type: PointTypeInstant }, + // "p83076": { PsKey: "virtual", Id: "p83076", Name: "Pv Power", Unit: "kWh", Type: PointTypeInstant }, + // "p83077": { PsKey: "virtual", Id: "p83077", Name: "Pv Energy", Unit: "kWh", Type: PointTypeInstant }, + // "p83081": { PsKey: "virtual", Id: "p83081", Name: "Es Power", Unit: "kWh", Type: PointTypeInstant }, + // "p83089": { PsKey: "virtual", Id: "p83089", Name: "Es Discharge Energy", Unit: "kWh", Type: PointTypeInstant }, + // "p83095": { PsKey: "virtual", Id: "p83095", Name: "Es Total Discharge Energy", Unit: "kWh", Type: PointTypeTotal }, + // "p83118": { PsKey: "virtual", Id: "p83118", Name: "Use Energy", Unit: "kWh", Type: PointTypeInstant }, + // "p83120": { PsKey: "virtual", Id: "p83120", Name: "Es Energy", Unit: "kWh", Type: PointTypeInstant }, + // "p83127": { PsKey: "virtual", Id: "p83127", Name: "Es Total Energy", Unit: "kWh", Type: PointTypeTotal }, - "p13012": { PsKey: "1129147_14_1_1", Id: "p13012", Description: "Total Reactive Power", Unit: "kvar", Type: PointTypeDaily }, + // "co2_reduce": { PsKey: "virtual", Id: "co2_reduce", Name: "co2_reduce", Unit: "FOO", Type: PointTypeInstant }, + // "co2_reduce_total": { PsKey: "virtual", Id: "co2_reduce_total", Name: "co2_reduce_total", Unit: "FOO", Type: PointTypeTotal }, + // "curr_power": { PsKey: "virtual", Id: "curr_power", Name: "curr_power", Unit: "FOO", Type: PointTypeInstant }, + // "daily_irradiation": { PsKey: "virtual", Id: "daily_irradiation", Name: "daily_irradiation", Unit: "FOO", Type: PointTypeDaily }, + // "equivalent_hour": { PsKey: "virtual", Id: "equivalent_hour", Name: "equivalent_hour", Unit: "FOO", Type: PointTypeDaily }, + // "installed_power_map": { PsKey: "virtual", Id: "installed_power_map", Name: "installed_power_map", Unit: "FOO", Type: PointTypeInstant }, + // "radiation": { PsKey: "virtual", Id: "radiation", Name: "radiation", Unit: "FOO", Type: PointTypeInstant }, + // "today_energy": { PsKey: "virtual", Id: "today_energy", Name: "today_energy", Unit: "FOO", Type: PointTypeDaily }, + // "today_income": { PsKey: "virtual", Id: "today_income", Name: "today_income", Unit: "FOO", Type: PointTypeDaily }, + // "total_capacity": { PsKey: "virtual", Id: "total_capacity", Name: "total_capacity", Unit: "FOO", Type: PointTypeTotal }, + // "total_energy": { PsKey: "virtual", Id: "total_energy", Name: "total_energy", Unit: "FOO", Type: PointTypeTotal }, + // "total_income": { PsKey: "virtual", Id: "total_income", Name: "total_income", Unit: "FOO", Type: PointTypeTotal }, + // Added manually - "p13105": { PsKey: "1129147_14_1_1", Id: "p13105", Description: "MPPT2 Voltage", Unit: "V", Type: PointTypeInstant }, - "p13122": { PsKey: "1129147_14_1_1", Id: "p13122", Description: "Daily Feed-in Energy", Unit: "kWh", Type: PointTypeDaily }, + "p13001": { PsKey: "1129147_14_1_1", Id: "p13001", Name: "MPPT1 Voltage", Unit: "V", Type: PointTypeInstant }, - "p13125": { PsKey: "1129147_14_1_1", Id: "p13125", Description: "Total Feed-in Energy", Unit: "kWh", Type: PointTypeTotal }, + "p13012": { PsKey: "1129147_14_1_1", Id: "p13012", Name: "Total Reactive Power", Unit: "kvar", Type: PointTypeDaily }, - "p13138": { PsKey: "1129147_14_1_1", Id: "p13138", Description: "Battery Voltage", Unit: "V", Type: PointTypeInstant }, + "p13105": { PsKey: "1129147_14_1_1", Id: "p13105", Name: "MPPT2 Voltage", Unit: "V", Type: PointTypeInstant }, - "p13144": { PsKey: "1129147_14_1_1", Id: "p13144", Description: "Daily Self-consumption Rate", Unit: "%", Type: PointTypeDaily }, + "p13122": { PsKey: "1129147_14_1_1", Id: "p13122", Name: "Daily Feed-in Energy", Unit: "kWh", Type: PointTypeDaily }, - "p13157": { PsKey: "1129147_14_1_1", Id: "p13157", Description: "Phase A Voltage", Unit: "V", Type: PointTypeInstant }, + "p13125": { PsKey: "1129147_14_1_1", Id: "p13125", Name: "Total Feed-in Energy", Unit: "kWh", Type: PointTypeTotal }, - "p13158": { PsKey: "1129147_14_1_1", Id: "p13158", Description: "Phase B Voltage", Unit: "V", Type: PointTypeInstant }, + "p13138": { PsKey: "1129147_14_1_1", Id: "p13138", Name: "Battery Voltage", Unit: "V", Type: PointTypeInstant }, - "p13159": { PsKey: "1129147_14_1_1", Id: "p13159", Description: "Phase C Voltage", Unit: "V", Type: PointTypeInstant }, + "p13144": { PsKey: "1129147_14_1_1", Id: "p13144", Name: "Daily Self-consumption Rate", Unit: "%", Type: PointTypeDaily }, - "p13161": { PsKey: "1129147_14_1_1", Id: "p13161", Description: "Bus Voltage", Unit: "V", Type: PointTypeInstant }, - "p13173": { PsKey: "1129147_14_1_1", Id: "p13173", Description: "Daily Feed-in Energy (PV)", Unit: "kWh", Type: PointTypeDaily }, - "p13175": { PsKey: "1129147_14_1_1", Id: "p13175", Description: "Total Feed-in Energy (PV)", Unit: "kWh", Type: PointTypeTotal }, - "p13002": { PsKey: "1129147_14_1_1", Id: "p13002", Description: "MPPT1 Current", Unit: "A", Type: PointTypeInstant }, - "p13003": { PsKey: "1129147_14_1_1", Id: "p13003", Description: "Total DC Power", Unit: "kW" }, - "p13007": { PsKey: "1129147_14_1_1", Id: "p13007", Description: "Grid Frequency", Unit: "Hz", Type: PointTypeInstant }, - "p13008": { PsKey: "1129147_14_1_1", Id: "p13008", Description: "Phase A Current", Unit: "A", Type: PointTypeInstant }, - "p13009": { PsKey: "1129147_14_1_1", Id: "p13009", Description: "Phase B Current", Unit: "A", Type: PointTypeInstant }, - "p13010": { PsKey: "1129147_14_1_1", Id: "p13010", Description: "Phase C Current", Unit: "A", Type: PointTypeInstant }, - "p13011": { PsKey: "1129147_14_1_1", Id: "p13011", Description: "Total Active Power", Unit: "kW" }, - "p13013": { PsKey: "1129147_14_1_1", Id: "p13013", Description: "Total Power Factor", Unit: "" }, - "p13018": { PsKey: "1129147_14_1_1", Id: "p13018", Description: "Total Apparent Power", Unit: "VA" }, - "p13019": { PsKey: "1129147_14_1_1", Id: "p13019", Description: "Internal Air Temperature", Unit: "℃", Type: PointTypeInstant }, - "p13028": { PsKey: "1129147_14_1_1", Id: "p13028", Description: "Daily Battery Charging Energy", Unit: "kWh", Type: PointTypeDaily }, - "p13029": { PsKey: "1129147_14_1_1", Id: "p13029", Description: "Daily Battery Discharging Energy", Unit: "kWh", Type: PointTypeDaily }, - "p13034": { PsKey: "1129147_14_1_1", Id: "p13034", Description: "Total Battery Charging Energy", Unit: "kWh" , Type: PointTypeTotal }, - "p13035": { PsKey: "1129147_14_1_1", Id: "p13035", Description: "Total Battery Discharging Energy", Unit: "kWh" , Type: PointTypeTotal }, - "p13106": { PsKey: "1129147_14_1_1", Id: "p13106", Description: "MPPT2 Current", Unit: "A", Type: PointTypeInstant }, - "p13112": { PsKey: "1129147_14_1_1", Id: "p13112", Description: "Daily PV Yield", Unit: "kWh", Type: PointTypeDaily }, - "p13116": { PsKey: "1129147_14_1_1", Id: "p13116", Description: "Daily Load Energy Consumption from PV", Unit: "kWh", Type: PointTypeDaily }, - "p13119": { PsKey: "1129147_14_1_1", Id: "p13119", Description: "Total Load Active Power", Unit: "kW" }, - "p13121": { PsKey: "1129147_14_1_1", Id: "p13121", Description: "Total Export Active Power", Unit: "kW" }, - "p13126": { PsKey: "1129147_14_1_1", Id: "p13126", Description: "Battery Charging Power", Unit: "kW" }, - "p13130": { PsKey: "1129147_14_1_1", Id: "p13130", Description: "Total Load Energy Consumption", Unit: "kWh" , Type: PointTypeTotal }, - "p13134": { PsKey: "1129147_14_1_1", Id: "p13134", Description: "Total PV Yield", Unit: "kWh" , Type: PointTypeTotal }, - "p13137": { PsKey: "1129147_14_1_1", Id: "p13137", Description: "Total Load Energy Consumption from PV", Unit: "kWh" , Type: PointTypeTotal }, - "p13139": { PsKey: "1129147_14_1_1", Id: "p13139", Description: "Battery Current", Unit: "A", Type: PointTypeInstant }, - "p13140": { PsKey: "1129147_14_1_1", Id: "p13140", Description: "Battery Capacity(kWh)", Unit: "kWh" }, - "p13141": { PsKey: "1129147_14_1_1", Id: "p13141", Description: "Battery Level (SOC)", Unit: "%", Type: PointTypeInstant }, - "p13142": { PsKey: "1129147_14_1_1", Id: "p13142", Description: "Battery Health (SOH)", Unit: "%", Type: PointTypeInstant }, - "p13143": { PsKey: "1129147_14_1_1", Id: "p13143", Description: "Battery Temperature", Unit: "℃", Type: PointTypeInstant }, - "p13147": { PsKey: "1129147_14_1_1", Id: "p13147", Description: "Daily Purchased Energy", Unit: "kWh", Type: PointTypeDaily }, - "p13148": { PsKey: "1129147_14_1_1", Id: "p13148", Description: "Total Purchased Energy", Unit: "kWh", Type: PointTypeTotal }, - "p13149": { PsKey: "1129147_14_1_1", Id: "p13149", Description: "Purchased Power", Unit: "kW" }, - "p13150": { PsKey: "1129147_14_1_1", Id: "p13150", Description: "Battery Discharging Power", Unit: "kW" }, - "p13160": { PsKey: "1129147_14_1_1", Id: "p13160", Description: "Array Insulation Resistance", Unit: "kΩ", Type: PointTypeInstant }, - "p13162": { PsKey: "1129147_14_1_1", Id: "p13162", Description: "Max. Charging Current (BMS)", Unit: "A", Type: PointTypeInstant }, - "p13163": { PsKey: "1129147_14_1_1", Id: "p13163", Description: "Max. Discharging Current (BMS)", Unit: "A", Type: PointTypeInstant }, - "p13174": { PsKey: "1129147_14_1_1", Id: "p13174", Description: "Daily Battery Charging Energy from PV", Unit: "kWh", Type: PointTypeDaily }, - "p13176": { PsKey: "1129147_14_1_1", Id: "p13176", Description: "Total Battery Charging Energy from PV", Unit: "kWh", Type: PointTypeTotal }, - "p13199": { PsKey: "1129147_14_1_1", Id: "p13199", Description: "Daily Load Energy Consumption", Unit: "kWh", Type: PointTypeDaily }, - "p18062": { PsKey: "1129147_14_1_1", Id: "p18062", Description: "Phase A Backup Current", Unit: "A", Type: PointTypeInstant }, - "p18063": { PsKey: "1129147_14_1_1", Id: "p18063", Description: "Phase B Backup Current", Unit: "A", Type: PointTypeInstant }, - "p18064": { PsKey: "1129147_14_1_1", Id: "p18064", Description: "Phase C Backup Current", Unit: "A", Type: PointTypeInstant }, - "p18065": { PsKey: "1129147_14_1_1", Id: "p18065", Description: "Phase A Backup Power", Unit: "kW" }, - "p18066": { PsKey: "1129147_14_1_1", Id: "p18066", Description: "Phase B Backup Power", Unit: "kW" }, - "p18067": { PsKey: "1129147_14_1_1", Id: "p18067", Description: "Phase C Backup Power", Unit: "kW" }, - "p18068": { PsKey: "1129147_14_1_1", Id: "p18068", Description: "Total Backup Power", Unit: "kW" }, - "p83001": { PsKey: "1129147_11_0_0", Id: "p83001", Description: "Inverter AC Power Normalization", Unit: "kW/kWp" }, - "p83002": { PsKey: "1129147_11_0_0", Id: "p83002", Description: "Inverter AC Power", Unit: "kW" }, - "p83004": { PsKey: "1129147_11_0_0", Id: "p83004", Description: "Inverter Total Yield", Unit: "kWh" }, - "p83005": { PsKey: "1129147_11_0_0", Id: "p83005", Description: "Daily Equivalent Hours of Meter", Unit: "h", Type: PointTypeDaily }, - "p83006": { PsKey: "1129147_11_0_0", Id: "p83006", Description: "Meter Daily Yield", Unit: "kWh" }, - "p83007": { PsKey: "1129147_11_0_0", Id: "p83007", Description: "Meter PR", Unit: "%", Type: PointTypeInstant }, - "p83008": { PsKey: "1129147_11_0_0", Id: "p83008", Description: "Daily Equivalent Hours of Inverter", Unit: "h", Type: PointTypeDaily }, - "p83009": { PsKey: "1129147_11_0_0", Id: "p83009", Description: "Daily Yield by Inverter", Unit: "kWh", Type: PointTypeDaily }, - "p83010": { PsKey: "1129147_11_0_0", Id: "p83010", Description: "Inverter PR", Unit: "%", Type: PointTypeInstant }, - "p83013": { PsKey: "1129147_11_0_0", Id: "p83013", Description: "Daily Irradiation", Unit: "Wh/m2" }, - "p83016": { PsKey: "1129147_11_0_0", Id: "p83016", Description: "Plant Ambient Temperature", Unit: "℃", Type: PointTypeInstant }, - "p83017": { PsKey: "1129147_11_0_0", Id: "p83017", Description: "Plant Module Temperature", Unit: "℃", Type: PointTypeInstant }, - "p83018": { PsKey: "1129147_11_0_0", Id: "p83018", Description: "Daily Yield (Theoretical)", Unit: "kWh", Type: PointTypeDaily }, - "p83019": { PsKey: "1129147_11_0_0", Id: "p83019", Description: "Power/Installed Power of Plant", Unit: "%", Type: PointTypeInstant }, - "p83020": { PsKey: "1129147_11_0_0", Id: "p83020", Description: "Meter Total Yield", Unit: "kWh" }, - "p83021": { PsKey: "1129147_11_0_0", Id: "p83021", Description: "Accumulative Power Consumption by Meter", Unit: "kWh" }, - "p83022": { PsKey: "1129147_11_0_0", Id: "p83022", Description: "Daily Yield of Plant", Unit: "kWh", Type: PointTypeDaily }, - "p83023": { PsKey: "1129147_11_0_0", Id: "p83023", Description: "Plant PR", Unit: "%", Type: PointTypeInstant }, - "p83024": { PsKey: "1129147_11_0_0", Id: "p83024", Description: "Plant Total Yield", Unit: "kWh" }, - "p83025": { PsKey: "1129147_11_0_0", Id: "p83025", Description: "Plant Equivalent Hours", Unit: "h" }, - "p83032": { PsKey: "1129147_11_0_0", Id: "p83032", Description: "Meter AC Power", Unit: "kW" }, - "p83033": { PsKey: "1129147_11_0_0", Id: "p83033", Description: "Plant Power", Unit: "kW" }, - "p83097": { PsKey: "1129147_11_0_0", Id: "p83097", Description: "Daily Load Energy Consumption from PV", Unit: "kWh", Type: PointTypeDaily }, - "p83100": { PsKey: "1129147_11_0_0", Id: "p83100", Description: "Total Load Energy Consumption from PV", Unit: "kWh" }, - "p83102": { PsKey: "1129147_11_0_0", Id: "p83102", Description: "Daily Purchased Energy", Unit: "kWh", Type: PointTypeDaily }, - "p83105": { PsKey: "1129147_11_0_0", Id: "p83105", Description: "Total Purchased Energy", Unit: "kWh" }, - "p83106": { PsKey: "1129147_11_0_0", Id: "p83106", Description: "Load Power", Unit: "kW" }, - "p83124": { PsKey: "1129147_11_0_0", Id: "p83124", Description: "Total Load Energy Consumption", Unit: "MWh" }, - "p83128": { PsKey: "1129147_11_0_0", Id: "p83128", Description: "Total Active Power of Optical Storage", Unit: "kW" }, - "p83129": { PsKey: "1129147_11_0_0", Id: "p83129", Description: "Battery SOC", Unit: "%", Type: PointTypeInstant }, - "p83233": { PsKey: "1129147_11_0_0", Id: "p83233", Description: "Total field maximum rechargeable power", Unit: "MW" }, - "p83234": { PsKey: "1129147_11_0_0", Id: "p83234", Description: "Total field maximum dischargeable power", Unit: "MW" }, - "p83235": { PsKey: "1129147_11_0_0", Id: "p83235", Description: "Total field chargeable energy", Unit: "MWh" }, - "p83236": { PsKey: "1129147_11_0_0", Id: "p83236", Description: "Total field dischargeable energy", Unit: "MWh" }, - "p83237": { PsKey: "1129147_11_0_0", Id: "p83237", Description: "Total field energy storage maximum reactive power", Unit: "MW" }, - "p83238": { PsKey: "1129147_11_0_0", Id: "p83238", Description: "Total field energy storage active power", Unit: "MW" }, - "p83239": { PsKey: "1129147_11_0_0", Id: "p83239", Description: "Total field reactive power", Unit: "Mvar" }, - "p83241": { PsKey: "1129147_11_0_0", Id: "p83241", Description: "Total field charge capacity", Unit: "MWh" }, - "p83242": { PsKey: "1129147_11_0_0", Id: "p83242", Description: "Total field discharge capacity", Unit: "MWh" }, - "p83243": { PsKey: "1129147_11_0_0", Id: "p83243", Description: "Total field daily charge capacity", Unit: "MWh" }, - "p83244": { PsKey: "1129147_11_0_0", Id: "p83244", Description: "Total field daily discharge capacity", Unit: "MWh" }, - "p83252": { PsKey: "1129147_11_0_0", Id: "p83252", Description: "Battery Level (SOC)", Unit: "%", Type: PointTypeInstant }, - "p83419": { PsKey: "1129147_11_0_0", Id: "p83419", Description: "Daily Highest Inverter Power/Inverter Installed Capacity", Unit: "%" }, - "p83420": { PsKey: "1129147_11_0_0", Id: "p83420", Description: "Current Power/Inverter Installed Capacity", Unit: "%", Type: PointTypeInstant }, - "p83549": { PsKey: "1129147_11_0_0", Id: "p83549", Description: "Grid active power", Unit: "kW" }, + "p13157": { PsKey: "1129147_14_1_1", Id: "p13157", Name: "Phase A Voltage", Unit: "V", Type: PointTypeInstant }, - "p23014": { PsKey: "1129147_22_247_1", Id: "p23014", Description: "WLAN Signal Strength", Unit: "" }, + "p13158": { PsKey: "1129147_14_1_1", Id: "p13158", Name: "Phase B Voltage", Unit: "V", Type: PointTypeInstant }, + + "p13159": { PsKey: "1129147_14_1_1", Id: "p13159", Name: "Phase C Voltage", Unit: "V", Type: PointTypeInstant }, + + "p13161": { PsKey: "1129147_14_1_1", Id: "p13161", Name: "Bus Voltage", Unit: "V", Type: PointTypeInstant }, + "p13173": { PsKey: "1129147_14_1_1", Id: "p13173", Name: "Daily Feed-in Energy (PV)", Unit: "kWh", Type: PointTypeDaily }, + "p13175": { PsKey: "1129147_14_1_1", Id: "p13175", Name: "Total Feed-in Energy (PV)", Unit: "kWh", Type: PointTypeTotal }, + "p13002": { PsKey: "1129147_14_1_1", Id: "p13002", Name: "MPPT1 Current", Unit: "A", Type: PointTypeInstant }, + "p13003": { PsKey: "1129147_14_1_1", Id: "p13003", Name: "Total DC Power", Unit: "kW" }, + "p13007": { PsKey: "1129147_14_1_1", Id: "p13007", Name: "Grid Frequency", Unit: "Hz", Type: PointTypeInstant }, + "p13008": { PsKey: "1129147_14_1_1", Id: "p13008", Name: "Phase A Current", Unit: "A", Type: PointTypeInstant }, + "p13009": { PsKey: "1129147_14_1_1", Id: "p13009", Name: "Phase B Current", Unit: "A", Type: PointTypeInstant }, + "p13010": { PsKey: "1129147_14_1_1", Id: "p13010", Name: "Phase C Current", Unit: "A", Type: PointTypeInstant }, + "p13011": { PsKey: "1129147_14_1_1", Id: "p13011", Name: "Total Active Power", Unit: "kW" }, + "p13013": { PsKey: "1129147_14_1_1", Id: "p13013", Name: "Total Power Factor", Unit: "" }, + "p13018": { PsKey: "1129147_14_1_1", Id: "p13018", Name: "Total Apparent Power", Unit: "VA" }, + "p13019": { PsKey: "1129147_14_1_1", Id: "p13019", Name: "Internal Air Temperature", Unit: "℃", Type: PointTypeInstant }, + "p13028": { PsKey: "1129147_14_1_1", Id: "p13028", Name: "Daily Battery Charging Energy", Unit: "kWh", Type: PointTypeDaily }, + "p13029": { PsKey: "1129147_14_1_1", Id: "p13029", Name: "Daily Battery Discharging Energy", Unit: "kWh", Type: PointTypeDaily }, + "p13034": { PsKey: "1129147_14_1_1", Id: "p13034", Name: "Total Battery Charging Energy", Unit: "kWh" , Type: PointTypeTotal }, + "p13035": { PsKey: "1129147_14_1_1", Id: "p13035", Name: "Total Battery Discharging Energy", Unit: "kWh" , Type: PointTypeTotal }, + "p13106": { PsKey: "1129147_14_1_1", Id: "p13106", Name: "MPPT2 Current", Unit: "A", Type: PointTypeInstant }, + "p13112": { PsKey: "1129147_14_1_1", Id: "p13112", Name: "Daily PV Yield", Unit: "kWh", Type: PointTypeDaily }, + "p13116": { PsKey: "1129147_14_1_1", Id: "p13116", Name: "Daily Load Energy Consumption from PV", Unit: "kWh", Type: PointTypeDaily }, + "p13119": { PsKey: "1129147_14_1_1", Id: "p13119", Name: "Total Load Active Power", Unit: "kW" }, + "p13121": { PsKey: "1129147_14_1_1", Id: "p13121", Name: "Total Export Active Power", Unit: "kW" }, + "p13126": { PsKey: "1129147_14_1_1", Id: "p13126", Name: "Battery Charging Power", Unit: "kW" }, + "p13130": { PsKey: "1129147_14_1_1", Id: "p13130", Name: "Total Load Energy Consumption", Unit: "kWh" , Type: PointTypeTotal }, + "p13134": { PsKey: "1129147_14_1_1", Id: "p13134", Name: "Total PV Yield", Unit: "kWh" , Type: PointTypeTotal }, + "p13137": { PsKey: "1129147_14_1_1", Id: "p13137", Name: "Total Load Energy Consumption from PV", Unit: "kWh" , Type: PointTypeTotal }, + "p13139": { PsKey: "1129147_14_1_1", Id: "p13139", Name: "Battery Current", Unit: "A", Type: PointTypeInstant }, + "p13140": { PsKey: "1129147_14_1_1", Id: "p13140", Name: "Battery Capacity(kWh)", Unit: "kWh" }, + "p13141": { PsKey: "1129147_14_1_1", Id: "p13141", Name: "Battery Level (SOC)", Unit: "%", Type: PointTypeInstant }, + "p13142": { PsKey: "1129147_14_1_1", Id: "p13142", Name: "Battery Health (SOH)", Unit: "%", Type: PointTypeInstant }, + "p13143": { PsKey: "1129147_14_1_1", Id: "p13143", Name: "Battery Temperature", Unit: "℃", Type: PointTypeInstant }, + "p13147": { PsKey: "1129147_14_1_1", Id: "p13147", Name: "Daily Purchased Energy", Unit: "kWh", Type: PointTypeDaily }, + "p13148": { PsKey: "1129147_14_1_1", Id: "p13148", Name: "Total Purchased Energy", Unit: "kWh", Type: PointTypeTotal }, + "p13149": { PsKey: "1129147_14_1_1", Id: "p13149", Name: "Purchased Power", Unit: "kW" }, + "p13150": { PsKey: "1129147_14_1_1", Id: "p13150", Name: "Battery Discharging Power", Unit: "kW" }, + "p13160": { PsKey: "1129147_14_1_1", Id: "p13160", Name: "Array Insulation Resistance", Unit: "kΩ", Type: PointTypeInstant }, + "p13162": { PsKey: "1129147_14_1_1", Id: "p13162", Name: "Max. Charging Current (BMS)", Unit: "A", Type: PointTypeInstant }, + "p13163": { PsKey: "1129147_14_1_1", Id: "p13163", Name: "Max. Discharging Current (BMS)", Unit: "A", Type: PointTypeInstant }, + "p13174": { PsKey: "1129147_14_1_1", Id: "p13174", Name: "Daily Battery Charging Energy from PV", Unit: "kWh", Type: PointTypeDaily }, + "p13176": { PsKey: "1129147_14_1_1", Id: "p13176", Name: "Total Battery Charging Energy from PV", Unit: "kWh", Type: PointTypeTotal }, + "p13199": { PsKey: "1129147_14_1_1", Id: "p13199", Name: "Daily Load Energy Consumption", Unit: "kWh", Type: PointTypeDaily }, + "p18062": { PsKey: "1129147_14_1_1", Id: "p18062", Name: "Phase A Backup Current", Unit: "A", Type: PointTypeInstant }, + "p18063": { PsKey: "1129147_14_1_1", Id: "p18063", Name: "Phase B Backup Current", Unit: "A", Type: PointTypeInstant }, + "p18064": { PsKey: "1129147_14_1_1", Id: "p18064", Name: "Phase C Backup Current", Unit: "A", Type: PointTypeInstant }, + "p18065": { PsKey: "1129147_14_1_1", Id: "p18065", Name: "Phase A Backup Power", Unit: "kW" }, + "p18066": { PsKey: "1129147_14_1_1", Id: "p18066", Name: "Phase B Backup Power", Unit: "kW" }, + "p18067": { PsKey: "1129147_14_1_1", Id: "p18067", Name: "Phase C Backup Power", Unit: "kW" }, + "p18068": { PsKey: "1129147_14_1_1", Id: "p18068", Name: "Total Backup Power", Unit: "kW" }, + "p83001": { PsKey: "1129147_11_0_0", Id: "p83001", Name: "Inverter AC Power Normalization", Unit: "kW/kWp" }, + "p83002": { PsKey: "1129147_11_0_0", Id: "p83002", Name: "Inverter AC Power", Unit: "kW" }, + "p83004": { PsKey: "1129147_11_0_0", Id: "p83004", Name: "Inverter Total Yield", Unit: "kWh" }, + "p83005": { PsKey: "1129147_11_0_0", Id: "p83005", Name: "Daily Equivalent Hours of Meter", Unit: "h", Type: PointTypeDaily }, + "p83006": { PsKey: "1129147_11_0_0", Id: "p83006", Name: "Meter Daily Yield", Unit: "kWh" }, + "p83007": { PsKey: "1129147_11_0_0", Id: "p83007", Name: "Meter PR", Unit: "%", Type: PointTypeInstant }, + "p83008": { PsKey: "1129147_11_0_0", Id: "p83008", Name: "Daily Equivalent Hours of Inverter", Unit: "h", Type: PointTypeDaily }, + "p83009": { PsKey: "1129147_11_0_0", Id: "p83009", Name: "Daily Yield by Inverter", Unit: "kWh", Type: PointTypeDaily }, + "p83010": { PsKey: "1129147_11_0_0", Id: "p83010", Name: "Inverter PR", Unit: "%", Type: PointTypeInstant }, + "p83013": { PsKey: "1129147_11_0_0", Id: "p83013", Name: "Daily Irradiation", Unit: "Wh/m2" }, + "p83016": { PsKey: "1129147_11_0_0", Id: "p83016", Name: "Plant Ambient Temperature", Unit: "℃", Type: PointTypeInstant }, + "p83017": { PsKey: "1129147_11_0_0", Id: "p83017", Name: "Plant Module Temperature", Unit: "℃", Type: PointTypeInstant }, + "p83018": { PsKey: "1129147_11_0_0", Id: "p83018", Name: "Daily Yield (Theoretical)", Unit: "kWh", Type: PointTypeDaily }, + "p83019": { PsKey: "1129147_11_0_0", Id: "p83019", Name: "Power/Installed Power of Plant", Unit: "%", Type: PointTypeInstant }, + "p83020": { PsKey: "1129147_11_0_0", Id: "p83020", Name: "Meter Total Yield", Unit: "kWh" }, + "p83021": { PsKey: "1129147_11_0_0", Id: "p83021", Name: "Accumulative Power Consumption by Meter", Unit: "kWh" }, + "p83022": { PsKey: "1129147_11_0_0", Id: "p83022", Name: "Daily Yield of Plant", Unit: "kWh", Type: PointTypeDaily }, + "p83023": { PsKey: "1129147_11_0_0", Id: "p83023", Name: "Plant PR", Unit: "%", Type: PointTypeInstant }, + "p83024": { PsKey: "1129147_11_0_0", Id: "p83024", Name: "Plant Total Yield", Unit: "kWh" }, + "p83025": { PsKey: "1129147_11_0_0", Id: "p83025", Name: "Plant Equivalent Hours", Unit: "h" }, + "p83032": { PsKey: "1129147_11_0_0", Id: "p83032", Name: "Meter AC Power", Unit: "kW" }, + "p83033": { PsKey: "1129147_11_0_0", Id: "p83033", Name: "Plant Power", Unit: "kW" }, + "p83097": { PsKey: "1129147_11_0_0", Id: "p83097", Name: "Daily Load Energy Consumption from PV", Unit: "kWh", Type: PointTypeDaily }, + "p83100": { PsKey: "1129147_11_0_0", Id: "p83100", Name: "Total Load Energy Consumption from PV", Unit: "kWh" }, + "p83102": { PsKey: "1129147_11_0_0", Id: "p83102", Name: "Daily Purchased Energy", Unit: "kWh", Type: PointTypeDaily }, + "p83105": { PsKey: "1129147_11_0_0", Id: "p83105", Name: "Total Purchased Energy", Unit: "kWh" }, + "p83106": { PsKey: "1129147_11_0_0", Id: "p83106", Name: "Load Power", Unit: "kW" }, + "p83124": { PsKey: "1129147_11_0_0", Id: "p83124", Name: "Total Load Energy Consumption", Unit: "MWh" }, + "p83128": { PsKey: "1129147_11_0_0", Id: "p83128", Name: "Total Active Power of Optical Storage", Unit: "kW" }, + "p83129": { PsKey: "1129147_11_0_0", Id: "p83129", Name: "Battery SOC", Unit: "%", Type: PointTypeInstant }, + "p83233": { PsKey: "1129147_11_0_0", Id: "p83233", Name: "Total field maximum rechargeable power", Unit: "MW" }, + "p83234": { PsKey: "1129147_11_0_0", Id: "p83234", Name: "Total field maximum dischargeable power", Unit: "MW" }, + "p83235": { PsKey: "1129147_11_0_0", Id: "p83235", Name: "Total field chargeable energy", Unit: "MWh" }, + "p83236": { PsKey: "1129147_11_0_0", Id: "p83236", Name: "Total field dischargeable energy", Unit: "MWh" }, + "p83237": { PsKey: "1129147_11_0_0", Id: "p83237", Name: "Total field energy storage maximum reactive power", Unit: "MW" }, + "p83238": { PsKey: "1129147_11_0_0", Id: "p83238", Name: "Total field energy storage active power", Unit: "MW" }, + "p83239": { PsKey: "1129147_11_0_0", Id: "p83239", Name: "Total field reactive power", Unit: "Mvar" }, + "p83241": { PsKey: "1129147_11_0_0", Id: "p83241", Name: "Total field charge capacity", Unit: "MWh" }, + "p83242": { PsKey: "1129147_11_0_0", Id: "p83242", Name: "Total field discharge capacity", Unit: "MWh" }, + "p83243": { PsKey: "1129147_11_0_0", Id: "p83243", Name: "Total field daily charge capacity", Unit: "MWh" }, + "p83244": { PsKey: "1129147_11_0_0", Id: "p83244", Name: "Total field daily discharge capacity", Unit: "MWh" }, + "p83252": { PsKey: "1129147_11_0_0", Id: "p83252", Name: "Battery Level (SOC)", Unit: "%", Type: PointTypeInstant }, + "p83419": { PsKey: "1129147_11_0_0", Id: "p83419", Name: "Daily Highest Inverter Power/Inverter Installed Capacity", Unit: "%" }, + "p83420": { PsKey: "1129147_11_0_0", Id: "p83420", Name: "Current Power/Inverter Installed Capacity", Unit: "%", Type: PointTypeInstant }, + "p83549": { PsKey: "1129147_11_0_0", Id: "p83549", Name: "Grid active power", Unit: "kW" }, + + "p23014": { PsKey: "1129147_22_247_1", Id: "p23014", Name: "WLAN Signal Strength", Unit: "" }, } +func (pm PointsMap) Get(device string, point string) *Point { + dp := device + "." + SetPoint(point) + if p, ok := pm[dp]; ok { + p.Valid = true + p.FullId = NameDevicePoint(device, point) + return &p + } -func GetPoint(device string, point string) *Point { - return Points.Get(device, point) + dp = SetPoint(point) + if p, ok := pm[dp]; ok { + p.Valid = true + p.FullId = NameDevicePoint(device, point) + return &p + } + + return &Point { + FullId: NameDevicePoint(device, point), + PsKey: device, + Id: dp, + Name: "", + Unit: "", + Type: "", + Valid: false, + } } -func GetPointInt(device string, point int64) *Point { - return Points.Get(device, strconv.FormatInt(point, 10)) +func (pm PointsMap) GetDevicePoint(devicePoint string) *Point { + ret := &Point{} + for range Only.Once { + s := strings.Split(devicePoint, ".") + if len(s) < 2 { + break + } + ret = pm.Get(s[0], s[1]) + } + return ret } -func GetDevicePoint(devicePoint string) *Point { - return Points.GetDevicePoint(devicePoint) -} - -// func GetPointName(device string, point int64) string { -// return fmt.Sprintf("%s.%d", device, point) -// } - -func NameDevicePointInt(device string, point int64) string { - return fmt.Sprintf("%s.%d", device, point) -} - -func NameDevicePoint(device string, point string) string { - return fmt.Sprintf("%s.%s", device, point) -} func (p *Point) WhenReset() string { var ret string @@ -290,41 +329,6 @@ func (p Point) String() string { return p.Type } -func (pm PointsMap) Get(device string, point string) *Point { - dp := device + ".p" + strings.TrimPrefix(point, "p") - if p, ok := pm[dp]; ok { - p.Valid = true - return &p - } - - dp = "p" + strings.TrimPrefix(point, "p") - if p, ok := pm[dp]; ok { - p.Valid = true - return &p - } - - return &Point { - PsKey: device, - Id: dp, - Description: "", - Unit: "", - Type: "", - Valid: false, - } -} - -func (pm PointsMap) GetDevicePoint(devicePoint string) *Point { - ret := &Point{} - for range Only.Once { - s := strings.Split(devicePoint, ".") - if len(s) < 2 { - break - } - ret = pm.Get(s[0], s[1]) - } - return ret -} - func (p Point) IsInstant() bool { if p.Type == PointTypeInstant { return true @@ -361,39 +365,45 @@ func (p Point) IsTotal() bool { } -func UpperCase(s string) string { +func GetPoint(device string, point string) *Point { + return Points.Get(device, point) +} + +func GetPointInt(device string, point int64) *Point { + return Points.Get(device, strconv.FormatInt(point, 10)) +} + +func GetDevicePoint(devicePoint string) *Point { + return Points.GetDevicePoint(devicePoint) +} + +// func GetPointName(device string, point int64) string { +// return fmt.Sprintf("%s.%d", device, point) +// } + +func NameDevicePointInt(device string, point int64) string { + return fmt.Sprintf("%s.%d", device, point) +} + +func NameDevicePoint(device string, point string) string { + return fmt.Sprintf("%s.%s", device, point) +} + +func SetPoint(point string) string { + for range Only.Once { + p := strings.TrimPrefix(point, "p") + _, err := strconv.ParseInt(p, 10, 64) + if err == nil { + point = "p" + p + break + } + } + return point +} + +func PointToName(s string) string { + s = CleanString(s) s = strings.ReplaceAll(s, "_", " ") s = strings.Title(s) return s } - - -type Data struct { - Entries []DataEntry -} - -type DataEntry struct { - Date DateTime `json:"date"` - PointId string `json:"point_id"` - PointGroupName string `json:"point_group_name"` - PointName string `json:"point_name"` - Value string `json:"value"` - Unit string `json:"unit"` - ValueType *Point `json:"value_type"` - Index int `json:"index"` -} - -// Type string -// Name string -// SubName string -// -// ParentId string -// ParentName string -// -// UniqueId string -// FullName string -// Units string -// ValueName string -// DeviceClass string -// -// Value string \ No newline at end of file diff --git a/iSolarCloud/api/struct_template_points.go b/iSolarCloud/api/struct_template_points.go index fccc020f0..7b43dd9dc 100644 --- a/iSolarCloud/api/struct_template_points.go +++ b/iSolarCloud/api/struct_template_points.go @@ -56,7 +56,8 @@ func CreatePoints(points []string) TemplatePoints { for _, p := range points { pa := strings.Split(p, ".") if len(pa) == 2 { - pa[1] = "p" + strings.TrimPrefix(pa[1], "p") + pa[1] = SetPoint(pa[1]) + // pa[1] = "p" + strings.TrimPrefix(pa[1], "p") ret = append(ret, TemplatePoint{ Description: "", PsKey: pa[0], @@ -68,8 +69,3 @@ func CreatePoints(points []string) TemplatePoints { } return ret } - -func SetPointName(pskey string, point string) string { - point = strings.TrimPrefix(point, "p") - return pskey + ".p" + point -} diff --git a/iSolarCloud/api/types.go b/iSolarCloud/api/types.go index a2639ea4a..922008e93 100644 --- a/iSolarCloud/api/types.go +++ b/iSolarCloud/api/types.go @@ -13,7 +13,8 @@ import ( type UnitValue struct { Unit string `json:"unit"` Value string `json:"value"` - Point *Point `json:"point"` + ValueFloat float64 `json:"value_float,omitempty"` + ValueInt int64 `json:"value_int,omitempty"` } type UnitValues []UnitValue type UnitValueMap map[string]UnitValue diff --git a/iSolarCloud/highlevel.go b/iSolarCloud/highlevel.go index aa186d006..12bf99a72 100644 --- a/iSolarCloud/highlevel.go +++ b/iSolarCloud/highlevel.go @@ -124,7 +124,7 @@ func (sg *SunGrow) GetTemplatePoints(template string) error { table := output.NewTable() sg.Error = table.SetHeader( - "Point Id", + "PointStruct Id", "Description", "Unit", ) @@ -337,9 +337,12 @@ func (sg *SunGrow) QueryPs(psId int64) getPsList.EndPoint { return ret } -func (sg *SunGrow) GetPointNames() error { +func (sg *SunGrow) GetPointNames(devices ...string) error { for range Only.Once { - for _, dt := range getPowerDevicePointNames.DeviceTypes { + if len(devices) == 0 { + devices = getPowerDevicePointNames.DeviceTypes + } + for _, dt := range devices { ep := sg.GetByStruct( "AppService.getPowerDevicePointNames", getPowerDevicePointNames.RequestData{DeviceType: dt}, @@ -548,6 +551,7 @@ func (sg *SunGrow) GetPointData(date string, pointNames api.TemplatePoints) erro return sg.Error } + func (sg *SunGrow) GetPsId() (int64, error) { var ret int64 diff --git a/iSolarCloud/struct.go b/iSolarCloud/struct.go index 7914a005f..06544f555 100644 --- a/iSolarCloud/struct.go +++ b/iSolarCloud/struct.go @@ -126,18 +126,18 @@ func (sg *SunGrow) GetByJson(endpoint string, request string) api.EndPoint { } switch { - case sg.OutputType.IsNone(): + case sg.OutputType.IsNone(): - case sg.OutputType.IsFile(): - sg.Error = ret.WriteDataFile() + case sg.OutputType.IsFile(): + sg.Error = ret.WriteDataFile() - case sg.OutputType.IsRaw(): - fmt.Println(ret.GetJsonData(true)) + case sg.OutputType.IsRaw(): + fmt.Println(ret.GetJsonData(true)) - case sg.OutputType.IsJson(): - fmt.Println(ret.GetJsonData(false)) + case sg.OutputType.IsJson(): + fmt.Println(ret.GetJsonData(false)) - default: + default: } } return ret diff --git a/mmHa/binary_sensor.go b/mmHa/binary_sensor.go index 769c902fd..220583a4f 100644 --- a/mmHa/binary_sensor.go +++ b/mmHa/binary_sensor.go @@ -31,9 +31,9 @@ func (m *Mqtt) BinarySensorPublishConfig(config EntityConfig) error { payload := BinarySensor { Device: device, - Name: JoinStrings(m.Device.Name, config.ParentName, config.FullName), + Name: JoinStrings(m.Device.Name, config.ParentName, config.FullId), StateTopic: JoinStringsForTopic(m.binarySensorPrefix, st, "state"), - StateClass: "measurement", + StateClass: config.StateClass, UniqueId: st, UnitOfMeasurement: config.Units, DeviceClass: config.DeviceClass, diff --git a/mmHa/sensors.go b/mmHa/sensors.go index 8a731d44b..082ac75ed 100644 --- a/mmHa/sensors.go +++ b/mmHa/sensors.go @@ -15,13 +15,16 @@ func (m *Mqtt) SensorPublishConfig(config EntityConfig) error { break } - // LastReset := m.GetLastReset(config.UniqueId) - // LastResetValueTemplate := "" - // if LastReset != "" { - // LastResetValueTemplate = "{{ value_json.last_reset | as_datetime() }}" + // if config.LastReset == "" { + // config.LastReset = m.GetLastReset(config.UniqueId) + // } + // if config.LastReset != "" { + // if config.LastResetValueTemplate == "" { + // config.LastResetValueTemplate = "{{ value_json.last_reset | as_datetime() }}" + // } // // LastResetValueTemplate = "{{ value_json.last_reset | int | timestamp_local | as_datetime }}" // } - // + // switch config.Units { // case "MW": // fallthrough @@ -76,10 +79,10 @@ func (m *Mqtt) SensorPublishConfig(config EntityConfig) error { payload := Sensor { Device: device, - Name: JoinStrings(m.Device.Name, config.ParentName, config.FullName), + Name: JoinStrings(m.Device.Name, config.ParentName, config.FullId), StateTopic: JoinStringsForTopic(m.sensorPrefix, st, "state"), // StateTopic: m.GetSensorStateTopic(name, config.SubName),m.EntityPrefix, m.Device.FullName, config.SubName - StateClass: "measurement", + StateClass: config.StateClass, UniqueId: st, UnitOfMeasurement: config.Units, DeviceClass: config.DeviceClass, @@ -129,7 +132,7 @@ func (m *Mqtt) SensorPublishValue(config EntityConfig) error { st := JoinStringsForId(m.Device.Name, config.ParentId, config.Name) payload := MqttState { - LastReset: m.GetLastReset(config.UniqueId), + LastReset: m.GetLastReset(config.FullId), Value: config.Value, } st = JoinStringsForTopic(m.sensorPrefix, st, "state") @@ -192,10 +195,10 @@ func (m *Mqtt) PublishSensorValues(configs []EntityConfig) error { if topic == "" { topic = JoinStringsForId(m.Device.Name, oid.ParentName, oid.Name) } - if _, ok := cs[oid.Type]; !ok { - cs[oid.Type] = make(Fields) + if _, ok := cs[oid.StateClass]; !ok { + cs[oid.StateClass] = make(Fields) } - cs[oid.Type][oid.ValueName] = oid.Value + cs[oid.StateClass][oid.ValueName] = oid.Value } for n, c := range cs { diff --git a/mmHa/struct.go b/mmHa/struct.go index 43a00480d..4713ddcdc 100644 --- a/mmHa/struct.go +++ b/mmHa/struct.go @@ -434,6 +434,9 @@ func (m *Mqtt) GetLastReset(pointType string) string { if !pt.Valid { break } + if pt.Type == "" { + break + } ret = pt.WhenReset() } @@ -442,18 +445,19 @@ func (m *Mqtt) GetLastReset(pointType string) string { type EntityConfig struct { - Type string + // Type string Name string SubName string ParentId string ParentName string - UniqueId string - FullName string - Units string + UniqueId string + FullId string + Units string ValueName string DeviceClass string + StateClass string Icon string Value string @@ -478,9 +482,13 @@ func (config *EntityConfig) IsSensor() bool { if config.IsLight() { break } - if config.Units == "" { - break - } + // if config.Value != "" { + // ok = true + // break + // } + // if config.Units == "" { + // break + // } ok = true } @@ -613,14 +621,30 @@ func (config *EntityConfig) FixConfig() { break } - pt := api.GetDevicePoint(config.UniqueId) + pt := api.GetDevicePoint(config.FullId) if !pt.Valid { break } - config.LastReset = pt.WhenReset() + if config.StateClass == "instant" { + config.StateClass = "measurement" + break + } + + if config.StateClass == "" { + config.StateClass = "measurement" + break + } + + config.LastReset = pt.WhenReset() config.LastResetValueTemplate = SetDefault(config.LastResetValueTemplate, "{{ value_json.last_reset | as_datetime() }}") // config.LastResetValueTemplate = SetDefault(config.LastResetValueTemplate, "{{ value_json.last_reset | int | timestamp_local | as_datetime }}") + + if config.LastReset == "" { + config.StateClass = "measurement" + break + } + config.StateClass = "total" } } diff --git a/mmHa/switch.go b/mmHa/switch.go index 4a5cdd2a3..e0a65ccb1 100644 --- a/mmHa/switch.go +++ b/mmHa/switch.go @@ -25,7 +25,7 @@ func (m *Mqtt) SwitchPublishConfig(config EntityConfig) error { payload := Switch { Device: device, - Name: JoinStrings(m.Device.Name, config.ParentName, config.FullName), + Name: JoinStrings(m.Device.Name, config.ParentName, config.FullId), StateTopic: JoinStringsForTopic(m.binarySensorPrefix, st, "state"), CommandTopic: JoinStringsForTopic(m.binarySensorPrefix, st, "cmd"), UniqueId: st, @@ -34,6 +34,8 @@ func (m *Mqtt) SwitchPublishConfig(config EntityConfig) error { PayloadOn: "true", PayloadOff: "false", + StateOn: "true", + StateOff: "false", ValueTemplate: config.ValueTemplate, Icon: config.Icon, @@ -52,8 +54,6 @@ func (m *Mqtt) SwitchPublishConfig(config EntityConfig) error { // Optimistic: false, // PayloadAvailable: "", // PayloadNotAvailable: "", - // StateOff: "", - // StateOn: "", } ct := JoinStringsForTopic(m.binarySensorPrefix, st, "config")