mirror of
https://github.com/MickMake/GoSungrow.git
synced 2025-03-25 09:01:43 +01:00
465 lines
11 KiB
Go
465 lines
11 KiB
Go
package cmd
|
|
|
|
import (
|
|
"GoSungrow/Only"
|
|
"GoSungrow/mmHa"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/go-co-op/gocron"
|
|
"github.com/spf13/cobra"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
|
|
func AttachCmdMqtt(cmd *cobra.Command) *cobra.Command {
|
|
// ******************************************************************************** //
|
|
var cmdMqtt = &cobra.Command{
|
|
Use: "mqtt",
|
|
Aliases: []string{""},
|
|
Short: fmt.Sprintf("Connect to a HASSIO broker."),
|
|
Long: fmt.Sprintf("Connect to a HASSIO broker."),
|
|
DisableFlagParsing: false,
|
|
DisableFlagsInUseLine: false,
|
|
PreRunE: Cmd.MqttArgs,
|
|
RunE: cmdMqttFunc,
|
|
Args: cobra.MinimumNArgs(1),
|
|
}
|
|
cmd.AddCommand(cmdMqtt)
|
|
cmdMqtt.Example = PrintExamples(cmdMqtt, "run", "sync")
|
|
|
|
|
|
// ******************************************************************************** //
|
|
var cmdMqttRun = &cobra.Command{
|
|
Use: "run",
|
|
Aliases: []string{""},
|
|
Short: fmt.Sprintf("One-off sync to a HASSIO broker."),
|
|
Long: fmt.Sprintf("One-off sync to a HASSIO broker."),
|
|
DisableFlagParsing: false,
|
|
DisableFlagsInUseLine: false,
|
|
PreRunE: Cmd.MqttArgs,
|
|
RunE: cmdMqttRunFunc,
|
|
Args: cobra.RangeArgs(0, 1),
|
|
}
|
|
cmdMqtt.AddCommand(cmdMqttRun)
|
|
cmdMqttRun.Example = PrintExamples(cmdMqttRun, "")
|
|
|
|
// ******************************************************************************** //
|
|
var cmdMqttSync = &cobra.Command{
|
|
Use: "sync",
|
|
Aliases: []string{""},
|
|
Short: fmt.Sprintf("Sync to a HASSIO MQTT broker."),
|
|
Long: fmt.Sprintf("Sync to a HASSIO MQTT broker."),
|
|
DisableFlagParsing: false,
|
|
DisableFlagsInUseLine: false,
|
|
PreRunE: Cmd.MqttArgs,
|
|
RunE: cmdMqttSyncFunc,
|
|
Args: cobra.RangeArgs(0, 1),
|
|
}
|
|
cmdMqtt.AddCommand(cmdMqttSync)
|
|
cmdMqttSync.Example = PrintExamples(cmdMqttSync, "", "all")
|
|
|
|
return cmdMqtt
|
|
}
|
|
|
|
|
|
func (ca *CommandArgs) MqttArgs(cmd *cobra.Command, args []string) error {
|
|
for range Only.Once {
|
|
ca.Error = ca.ProcessArgs(cmd, args)
|
|
if ca.Error != nil {
|
|
break
|
|
}
|
|
|
|
LogPrintDate("Connecting to SunGrow...\n")
|
|
Cmd.Error = Cmd.SunGrowArgs(cmd, args)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
var id int64
|
|
id, Cmd.Error = Cmd.SunGrow.GetPsId()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
var model string
|
|
model, Cmd.Error = Cmd.SunGrow.GetPsModel()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
var serial string
|
|
serial, Cmd.Error = Cmd.SunGrow.GetPsSerial()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
LogPrintDate("Found SunGrow device %s id:%d serial:%s\n", model, id, serial)
|
|
|
|
LogPrintDate("Connecting to MQTT HASSIO Service...\n")
|
|
Cmd.Mqtt = mmHa.New(mmHa.Mqtt {
|
|
ClientId: "GoSunGrow",
|
|
Username: Cmd.MqttUsername,
|
|
Password: Cmd.MqttPassword,
|
|
Host: Cmd.MqttHost,
|
|
Port: Cmd.MqttPort,
|
|
})
|
|
Cmd.Error = Cmd.Mqtt.GetError()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.SetDeviceConfig("GoSunGrow", strconv.FormatInt(id, 10), "GoSungrow", model, "Sungrow", "Roof")
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.Connect()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
// if Cmd.Mqtt.PsId == 0 {
|
|
// Cmd.Mqtt.PsId, Cmd.Error = Cmd.SunGrow.GetPsId()
|
|
// if Cmd.Error != nil {
|
|
// break
|
|
// }
|
|
// LogPrintDate("Found SunGrow device %d\n", Cmd.Mqtt.PsId)
|
|
// }
|
|
}
|
|
|
|
return Cmd.Error
|
|
}
|
|
|
|
|
|
func cmdMqttFunc(cmd *cobra.Command, _ []string) error {
|
|
return cmd.Help()
|
|
}
|
|
|
|
func cmdMqttRunFunc(_ *cobra.Command, _ []string) error {
|
|
for range Only.Once {
|
|
// switch1 := mmMqtt.BinarySensor {
|
|
// Device: mmMqtt.Device {
|
|
// Connections: [][]string{{"sungrow_address", "0"}},
|
|
// Identifiers: []string{"sungrow_bin_sensor_0"},
|
|
// Manufacturer: "MickMake",
|
|
// Model: "SunGrow inverter",
|
|
// Name: "SunGrow inverter online",
|
|
// SwVersion: "GoSunGrow https://github.com/MickMake/GoSungrow",
|
|
// ViaDevice: "GoSunGrow",
|
|
// },
|
|
// Name: "SunGrow inverter online",
|
|
// StateTopic: "homeassistant/binary_sensor/GoSunGrow_0/state",
|
|
// UniqueId: "sungrow_bin_sensor_0",
|
|
// }
|
|
// err = foo.Publish("homeassistant/binary_sensor/GoSunGrow_0/config", 0, true, switch1.Json())
|
|
// if err != nil {
|
|
// break
|
|
// }
|
|
// err = foo.Publish("homeassistant/binary_sensor/GoSunGrow_0/state", 0, true, "OFF")
|
|
// if err != nil {
|
|
// break
|
|
// }
|
|
|
|
Cmd.Error = MqttCron()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
LogPrintDate("Starting ticker...\n")
|
|
updateCounter := 0
|
|
timer := time.NewTicker(60 * time.Second)
|
|
for t := range timer.C {
|
|
if updateCounter < 5 {
|
|
updateCounter++
|
|
LogPrintDate("Sleeping: %d\n", updateCounter)
|
|
continue
|
|
}
|
|
|
|
updateCounter = 0
|
|
LogPrintDate("Update: %s\n", t.String())
|
|
Cmd.Error = MqttCron()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
// ep = Cmd.SunGrow.QueryDevice(psId)
|
|
// if ep.IsError() {
|
|
// Cmd.Error = ep.GetError()
|
|
// break
|
|
// }
|
|
//
|
|
// data = ep.GetData()
|
|
// for _, r := range data.Entries {
|
|
// // fmt.Printf("%s ", r.PointId)
|
|
// Cmd.Error = foo.SensorPublishState(r.PointId, r.Value)
|
|
// if err != nil {
|
|
// break
|
|
// }
|
|
// }
|
|
// // fmt.Println()
|
|
}
|
|
}
|
|
|
|
return Cmd.Error
|
|
}
|
|
|
|
func cmdMqttSyncFunc(_ *cobra.Command, args []string) error {
|
|
|
|
for range Only.Once {
|
|
// */1 * * * * /dir/command args args
|
|
cronString := "*/5 * * * *"
|
|
if len(args) > 0 {
|
|
cronString = strings.Join(args[0:5], " ")
|
|
cronString = strings.ReplaceAll(cronString, ".", "*")
|
|
}
|
|
|
|
Cron.Scheduler = gocron.NewScheduler(time.UTC)
|
|
Cron.Scheduler = Cron.Scheduler.Cron(cronString)
|
|
Cron.Scheduler = Cron.Scheduler.SingletonMode()
|
|
|
|
Cmd.Error = MqttCron()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cron.Job, Cmd.Error = Cron.Scheduler.Do(MqttCron)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
LogPrintDate("Created job schedule using '%s'\n", cronString)
|
|
Cron.Scheduler.StartBlocking()
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
}
|
|
|
|
return Cmd.Error
|
|
}
|
|
|
|
func MqttCron() error {
|
|
for range Only.Once {
|
|
if Cmd.Mqtt == nil {
|
|
Cmd.Error = errors.New("mqtt not available")
|
|
break
|
|
}
|
|
|
|
if Cmd.SunGrow == nil {
|
|
Cmd.Error = errors.New("sungrow not available")
|
|
break
|
|
}
|
|
|
|
if Cmd.Mqtt.IsFirstRun() {
|
|
Cmd.Mqtt.UnsetFirstRun()
|
|
} else {
|
|
time.Sleep(time.Second * 40) // Takes up to 40 seconds for data to come in.
|
|
}
|
|
|
|
newDay := false
|
|
if Cmd.Mqtt.IsNewDay() {
|
|
newDay = true
|
|
}
|
|
|
|
Cmd.Error = Update1(newDay)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Update2(newDay)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Mqtt.LastRefresh = time.Now()
|
|
}
|
|
|
|
if Cmd.Error != nil {
|
|
LogPrintDate("Error: %s\n", Cmd.Error)
|
|
}
|
|
return Cmd.Error
|
|
}
|
|
|
|
func Update1(newDay bool) error {
|
|
for range Only.Once {
|
|
// Also getPowerStatistics, getHouseholdStoragePsReport, getPsList, getUpTimePoint,
|
|
ep := Cmd.SunGrow.QueryDevice(Cmd.Mqtt.PsId)
|
|
if ep.IsError() {
|
|
Cmd.Error = ep.GetError()
|
|
break
|
|
}
|
|
data := ep.GetData()
|
|
|
|
if newDay {
|
|
LogPrintDate("New day: Configuring %d entries in HASSIO.\n", len(data.Entries))
|
|
for _, r := range data.Entries {
|
|
fmt.Printf("C")
|
|
re := mmHa.EntityConfig {
|
|
Type: r.ValueType.Type,
|
|
Name: r.ValueType.Id, // PointName,
|
|
SubName: "",
|
|
ParentId: r.ValueType.PsKey,
|
|
ParentName: "",
|
|
UniqueId: r.PointId,
|
|
FullName: r.ValueType.Description,
|
|
Units: r.Unit,
|
|
ValueName: r.PointId,
|
|
DeviceClass: "",
|
|
Value: r.Value,
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.BinarySensorPublishConfig(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.SensorPublishConfig(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
LogPrintDate("Updating %d entries to HASSIO.\n", len(data.Entries))
|
|
for _, r := range data.Entries {
|
|
fmt.Printf("U")
|
|
re := mmHa.EntityConfig {
|
|
Type: r.ValueType.Type,
|
|
Name: r.ValueType.Id, // PointName,
|
|
SubName: "",
|
|
ParentId: r.ValueType.PsKey,
|
|
ParentName: "",
|
|
UniqueId: r.PointId,
|
|
FullName: r.ValueType.Description,
|
|
Units: r.Unit,
|
|
ValueName: r.PointId,
|
|
DeviceClass: "",
|
|
Value: r.Value,
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.BinarySensorPublishValue(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.SensorPublishValue(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
if Cmd.Error != nil {
|
|
LogPrintDate("Error: %s\n", Cmd.Error)
|
|
}
|
|
return Cmd.Error
|
|
}
|
|
|
|
func Update2(newDay bool) error {
|
|
for range Only.Once {
|
|
// Also getPowerStatistics, getHouseholdStoragePsReport, getPsList, getUpTimePoint,
|
|
ep := Cmd.SunGrow.QueryPs(Cmd.Mqtt.PsId)
|
|
if ep.IsError() {
|
|
Cmd.Error = ep.GetError()
|
|
break
|
|
}
|
|
data := ep.GetData()
|
|
|
|
if newDay {
|
|
LogPrintDate("New day: Configuring %d entries in HASSIO.\n", len(data.Entries))
|
|
for _, r := range data.Entries {
|
|
fmt.Printf("C")
|
|
|
|
re := mmHa.EntityConfig {
|
|
Type: r.ValueType.Type,
|
|
Name: r.ValueType.Id, // PointName,
|
|
SubName: "",
|
|
ParentId: r.ValueType.PsKey,
|
|
ParentName: "",
|
|
UniqueId: r.PointId,
|
|
FullName: r.ValueType.Description,
|
|
Units: r.Unit,
|
|
ValueName: r.PointId,
|
|
DeviceClass: "",
|
|
Value: r.Value,
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.BinarySensorPublishConfig(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.SensorPublishConfig(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
LogPrintDate("Updating %d entries to HASSIO.\n", len(data.Entries))
|
|
for _, r := range data.Entries {
|
|
fmt.Printf("U")
|
|
|
|
re := mmHa.EntityConfig {
|
|
Type: r.ValueType.Type,
|
|
Name: r.ValueType.Id, // PointName,
|
|
SubName: "",
|
|
ParentId: r.ValueType.PsKey,
|
|
ParentName: "",
|
|
UniqueId: r.PointId,
|
|
FullName: r.ValueType.Description,
|
|
Units: r.Unit,
|
|
ValueName: r.PointId,
|
|
DeviceClass: "",
|
|
Value: r.Value,
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.BinarySensorPublishValue(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
|
|
Cmd.Error = Cmd.Mqtt.SensorPublishValue(re)
|
|
if Cmd.Error != nil {
|
|
break
|
|
}
|
|
}
|
|
fmt.Println()
|
|
}
|
|
|
|
if Cmd.Error != nil {
|
|
LogPrintDate("Error: %s\n", Cmd.Error)
|
|
}
|
|
return Cmd.Error
|
|
}
|
|
|
|
|
|
// func toggle(v string) string {
|
|
// switch v {
|
|
// case "OFF":
|
|
// v = "ON"
|
|
// case "ON":
|
|
// v = "OFF"
|
|
// }
|
|
// return v
|
|
// }
|
|
//
|
|
// func randoPercent() string {
|
|
// t := time.Now()
|
|
// min := 0
|
|
// max := t.Second()
|
|
// i := (rand.Intn(max - min) + min) * t.Minute() // / float64(max)
|
|
// return fmt.Sprintf("%.2f", (float64(i) / 3600) * 100)
|
|
// }
|
|
//
|
|
// func randoKWh() string {
|
|
// t := time.Now()
|
|
// min := 0
|
|
// max := t.Minute()
|
|
// i := (rand.Intn(max - min) + min) * t.Second() // / float64(max)
|
|
// return fmt.Sprintf("%.2f", (float64(i) / 3600) * 11000)
|
|
// }
|