v3.0.1 - MQTT option control

This commit is contained in:
MickMake 2022-12-20 20:28:51 +11:00
parent e76f44356c
commit 9a3d0795c8
28 changed files with 650 additions and 331 deletions

77
.idea/workspace.xml generated
View File

@ -5,8 +5,34 @@
</component>
<component name="ChangeListManager">
<list default="true" id="76adadc9-ae71-42a6-82a1-66dbc8ecb14c" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/mmHa/options.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/main.go" beforeDir="false" afterPath="$PROJECT_DIR$/main.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/cmd/cmd_mqtt.go" beforeDir="false" afterPath="$PROJECT_DIR$/cmd/cmd_mqtt.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/alarm_control_panel.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/alarm_control_panel.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/binary_sensor.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/binary_sensor.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/button.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/button.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/camera.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/camera.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/climate.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/climate.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/config.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/config.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/cover.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/cover.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/device_tracker.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/device_tracker.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/device_trigger.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/device_trigger.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/fan.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/fan.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/funcs.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/funcs.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/humidifier.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/humidifier.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/lights.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/lights.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/lock.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/lock.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/number.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/number.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/scene.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/scene.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/select.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/select.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/sensors.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/sensors.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/siren.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/siren.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/struct.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/struct.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/switch.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/switch.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/tag.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/tag.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/text.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/text.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/update.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/update.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/mmHa/vacuum.go" beforeDir="false" afterPath="$PROJECT_DIR$/mmHa/vacuum.go" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
@ -202,11 +228,6 @@
<line>669</line>
<option name="timeStamp" value="4201" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/binary_sensor.go</url>
<line>87</line>
<option name="timeStamp" value="4693" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/iSolarCloud/api/GoStruct/structmap.go</url>
<line>122</line>
@ -224,12 +245,12 @@
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/iSolarCloud/api/GoStruct/struct_reflect.go</url>
<line>951</line>
<line>953</line>
<option name="timeStamp" value="5785" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/iSolarCloud/api/GoStruct/struct_reflect.go</url>
<line>962</line>
<line>964</line>
<option name="timeStamp" value="5786" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
@ -612,11 +633,6 @@
<line>71</line>
<option name="timeStamp" value="8311" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/config.go</url>
<line>50</line>
<option name="timeStamp" value="8337" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/iSolarCloud/api/GoStruct/valueTypes/uv.go</url>
<line>976</line>
@ -627,6 +643,41 @@
<line>97</line>
<option name="timeStamp" value="8398" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>302</line>
<option name="timeStamp" value="8428" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>329</line>
<option name="timeStamp" value="8429" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>384</line>
<option name="timeStamp" value="8430" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>255</line>
<option name="timeStamp" value="8445" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>281</line>
<option name="timeStamp" value="8546" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>287</line>
<option name="timeStamp" value="8547" />
</line-breakpoint>
<line-breakpoint enabled="true" type="DlvLineBreakpoint">
<url>file://$PROJECT_DIR$/mmHa/struct.go</url>
<line>254</line>
<option name="timeStamp" value="8548" />
</line-breakpoint>
</breakpoints>
<default-breakpoints>
<breakpoint type="DlvErrorBreakpoint" />

View File

@ -10,6 +10,7 @@ import (
"github.com/MickMake/GoUnify/Only"
"github.com/MickMake/GoUnify/cmdHelp"
"github.com/MickMake/GoUnify/cmdLog"
mqtt "github.com/eclipse/paho.mqtt.golang"
"github.com/go-co-op/gocron"
"github.com/spf13/cobra"
"github.com/spf13/viper"
@ -26,8 +27,8 @@ const (
DefaultVendor = "MickMake"
flagMqttUsername = "mqtt-user"
flagMqttPassword = "mqtt-password"
flagMqttHost = "mqtt-host"
flagMqttPort = "mqtt-port"
flagMqttHost = "mqtt-host"
flagMqttPort = "mqtt-port"
)
@ -45,6 +46,10 @@ type CmdMqtt struct {
Client *mmHa.Mqtt
endpoints MqttEndPoints
points getDevicePointAttrs.PointsMap
optionLogLevel int
optionSleepDelay time.Duration
optionFetchSchedule time.Duration
}
func NewCmdMqtt() *CmdMqtt {
@ -57,6 +62,10 @@ func NewCmdMqtt() *CmdMqtt {
cmd: nil,
SelfCmd: nil,
},
optionLogLevel: LogLevelInfo,
optionSleepDelay: time.Second * 40, // Takes up to 40 seconds for data to come in.
optionFetchSchedule: time.Minute * 5,
}
}
@ -153,7 +162,7 @@ func (c *CmdMqtt) AttachFlags(cmd *cobra.Command, viper *viper.Viper) {
func (c *CmdMqtt) MqttArgs(_ *cobra.Command, _ []string) error {
for range Only.Once {
cmdLog.LogPrintDate("Connecting to MQTT HASSIO Service...\n")
c.LogInfo("Connecting to MQTT HASSIO Service...\n")
c.Client = mmHa.New(mmHa.Mqtt {
ClientId: DefaultServiceName,
EntityPrefix: DefaultServiceName,
@ -167,37 +176,26 @@ func (c *CmdMqtt) MqttArgs(_ *cobra.Command, _ []string) error {
break
}
cmdLog.LogPrintDate("Connecting to SunGrow...\n")
c.LogInfo("Connecting to SunGrow...\n")
c.Client.SungrowDevices, c.Error = cmds.Api.SunGrow.GetDeviceList()
// ca.Mqtt.Client.SungrowDevices, ca.Error = ca.Api.SunGrow.GetPsKeys()
// ca.Mqtt.Client.SungrowDevices, ca.Error = ca.Api.SunGrow.GetPsIds()
// ca.Mqtt.Client.SungrowDevices, ca.Error = ca.Api.SunGrow.GetPsTreeMenu()
if c.Error != nil {
break
}
cmdLog.LogPrintDate("Found SunGrow %d devices\n", len(c.Client.SungrowDevices))
c.LogInfo("Found SunGrow %d devices\n", len(c.Client.SungrowDevices))
c.Client.DeviceName = DefaultServiceName
c.Error = c.Client.SetDeviceConfig(
c.Client.DeviceName,
c.Client.DeviceName,
"virtual",
"virtual",
"",
"",
_, c.Error = c.Client.SetDeviceConfig(
c.Client.DeviceName, c.Client.DeviceName,
"virtual", "virtual", "", DefaultServiceName,
DefaultServiceArea,
)
if c.Error != nil {
break
}
c.Error = c.Client.SetDeviceConfig(
c.Client.DeviceName,
c.Client.DeviceName,
"system",
"system",
"",
"",
_, c.Error = c.Client.SetDeviceConfig(
c.Client.DeviceName, c.Client.DeviceName,
"system", "system", "", DefaultServiceName,
DefaultServiceArea,
)
if c.Error != nil {
@ -211,26 +209,18 @@ func (c *CmdMqtt) MqttArgs(_ *cobra.Command, _ []string) error {
parent = c.Client.DeviceName
}
c.Error = c.Client.SetDeviceConfig(
DefaultServiceName,
parent,
psId.PsKey.Value(),
psId.DeviceName.Value(),
psId.DeviceModel.Value(),
psId.FactoryName.Value(),
_, c.Error = c.Client.SetDeviceConfig(
DefaultServiceName, DefaultServiceName,
psId.PsId.String(), psId.FactoryName.Value(), psId.FactoryName.Value(), psId.FactoryName.Value(),
DefaultServiceArea,
)
if c.Error != nil {
break
}
c.Error = c.Client.SetDeviceConfig(
DefaultServiceName,
DefaultServiceName,
psId.PsId.String(),
psId.FactoryName.Value(),
psId.FactoryName.Value(),
psId.FactoryName.Value(),
_, c.Error = c.Client.SetDeviceConfig(
DefaultServiceName, parent,
psId.PsKey.Value(), psId.DeviceName.Value(), psId.DeviceModel.Value(), psId.FactoryName.Value(),
DefaultServiceArea,
)
if c.Error != nil {
@ -245,7 +235,12 @@ func (c *CmdMqtt) MqttArgs(_ *cobra.Command, _ []string) error {
break
}
cmdLog.LogPrintDate("Caching Sungrow metadata...\n")
c.Error = c.Options()
if c.Error != nil {
break
}
c.LogInfo("Caching Sungrow metadata...\n")
c.Error = c.GetEndPoints()
if c.Error != nil {
break
@ -255,7 +250,7 @@ func (c *CmdMqtt) MqttArgs(_ *cobra.Command, _ []string) error {
if c.Error != nil {
break
}
cmdLog.LogPrintDate("Cached %d Sungrow data points...\n", len(c.points))
c.LogInfo("Cached %d Sungrow data points...\n", len(c.points))
}
return c.Error
@ -267,46 +262,26 @@ func (c *CmdMqtt) CmdMqtt(cmd *cobra.Command, _ []string) error {
func (c *CmdMqtt) CmdMqttRun(_ *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: DefaultVendor,
// Model: "SunGrow inverter",
// Name: "SunGrow inverter online",
// SwVersion: "GoSungrow https://github.com/MickMake/GoSungrow",
// ViaDevice: DefaultServiceName,
// },
// 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
// }
c.Error = c.Cron()
if c.Error != nil {
break
}
cmdLog.LogPrintDate("Starting ticker...\n")
updateCounter := 0
timer := time.NewTicker(60 * time.Second)
c.LogInfo("Starting ticker...\n")
c.LogInfo("Fetch Schedule: %s\n", c.GetFetchSchedule())
c.LogInfo("Sleep Delay: %s\n", c.GetSleepDelay())
resolution := time.Second * 10
updateCounter := int(c.optionFetchSchedule / resolution)
timer := time.NewTicker(resolution)
for t := range timer.C {
if updateCounter < 5 {
updateCounter++
cmdLog.LogPrintDate("Sleeping: %d\n", updateCounter)
if updateCounter >= 0 {
updateCounter--
c.LogDebug("Sleeping: %d\n", updateCounter)
continue
}
updateCounter = 0
cmdLog.LogPrintDate("Update: %s\n", t.String())
updateCounter = int(c.optionFetchSchedule / resolution)
c.LogDebug("Update: %s\n", t.String())
c.Error = c.Cron()
if c.Error != nil {
break
@ -342,7 +317,7 @@ func (c *CmdMqtt) CmdMqttSync(_ *cobra.Command, args []string) error {
}
job.IsRunning()
cmdLog.LogPrintDate("Created job schedule using '%s'\n", cronString)
c.LogInfo("Created job schedule using '%s'\n", cronString)
cron.StartBlocking()
if c.Error != nil {
break
@ -353,6 +328,8 @@ func (c *CmdMqtt) CmdMqttSync(_ *cobra.Command, args []string) error {
}
// -------------------------------------------------------------------------------- //
func (c *CmdMqtt) Cron() error {
for range Only.Once {
if c == nil {
@ -368,7 +345,8 @@ func (c *CmdMqtt) Cron() error {
if c.Client.IsFirstRun() {
c.Client.UnsetFirstRun()
} else {
time.Sleep(time.Second * 40) // Takes up to 40 seconds for data to come in.
c.LogDebug("Sleeping for %s...\n", c.GetSleepDelay())
time.Sleep(c.optionSleepDelay)
}
newDay := false
@ -400,7 +378,7 @@ func (c *CmdMqtt) Cron() error {
}
if c.Error != nil {
cmdLog.LogPrintDate("Error: %s\n", c.Error)
c.LogError("%s\n", c.Error)
}
return c.Error
}
@ -408,7 +386,7 @@ func (c *CmdMqtt) Cron() error {
func (c *CmdMqtt) Update(endpoint string, data api.DataMap, newDay bool) error {
for range Only.Once {
// Also getPowerStatistics, getHouseholdStoragePsReport, getPsList, getUpTimePoint,
cmdLog.LogPrintDate("Syncing %d entries with HASSIO from %s.\n", len(data.Map), endpoint)
c.LogInfo("Syncing %d entries with HASSIO from %s.\n", len(data.Map), endpoint)
for o := range data.Map {
entries := data.Map[o]
@ -416,7 +394,8 @@ func (c *CmdMqtt) Update(endpoint string, data api.DataMap, newDay bool) error {
if !r.Point.Valid {
// cmdLog.LogPrintDate("\n[%s] - invalid value - %s ...\n", r.Current.FieldPath.String(), r.Value.String())
fmt.Printf("?")
c.LogDebug("Invalid: [%s] = '%s'\n", r.EndPoint, r.Value.String())
c.LogPlainInfo("?")
continue
}
@ -461,22 +440,17 @@ func (c *CmdMqtt) Update(endpoint string, data api.DataMap, newDay bool) error {
FullId: id, // string(r.FullId), // WAS r.Point.FullId
// FullName: r.Point.Name,
Units: r.Point.Unit,
ValueName: r.Point.Description,
// ValueName: r.Id,
// ValueName: r.Point.Description,
// ValueName: r.Point.Id,
DeviceClass: "",
StateClass: r.Point.UpdateFreq,
Value: r.Value,
Value: &r.Value,
Point: r.Point,
LastReset: r.Point.WhenReset(),
// LastResetValueTemplate: "",
}
// if strings.Contains(r.EndPoint, "13149") || strings.Contains(r.Current.DataStructure.Endpoint.String(), "13149") ||
// strings.Contains(r.EndPoint, "13119") || strings.Contains(r.Current.DataStructure.Endpoint.String(), "13119") {
// fmt.Sprintf("")
// }
switch {
case r.Point.IsTotal():
re.StateClass = "total"
@ -485,7 +459,8 @@ func (c *CmdMqtt) Update(endpoint string, data api.DataMap, newDay bool) error {
}
if newDay {
fmt.Printf("C")
c.LogDebug("Config: [%s]\n", r.EndPoint)
c.LogPlainInfo("C")
c.Error = c.Client.BinarySensorPublishConfig(re)
if c.Error != nil {
break
@ -497,11 +472,8 @@ func (c *CmdMqtt) Update(endpoint string, data api.DataMap, newDay bool) error {
}
}
// if strings.Contains(r.EndPoint, "p13115") || strings.Contains(r.Current.DataStructure.Endpoint.String(), "p13115") {
// fmt.Sprintf("")
// }
fmt.Printf("U")
c.LogDebug("Update: [%s] = '%s' %s\n", r.EndPoint, r.Value.String(), r.Value.Unit())
c.LogPlainInfo("U")
c.Error = c.Client.BinarySensorPublishValue(re)
if c.Error != nil {
break
@ -512,11 +484,7 @@ func (c *CmdMqtt) Update(endpoint string, data api.DataMap, newDay bool) error {
break
}
}
fmt.Println()
}
if c.Error != nil {
cmdLog.LogPrintDate("Error: %s\n", c.Error)
c.LogPlainInfo("\n")
}
return c.Error
}
@ -540,13 +508,9 @@ func (c *CmdMqtt) GetEndPoints() error {
// All := []string{ "queryDeviceList", "getPsList", "getPsDetailWithPsType", "getPsDetail", "getKpiInfo"} //, queryMutiPointDataList, getDevicePointMinuteDataList }
// All := []string{ "WebIscmAppService.getDeviceModel" }
for name := range c.endpoints {
c.Error = c.Client.SetDeviceConfig(
DefaultServiceName,
DefaultServiceName,
name,
DefaultServiceName + "." + name,
DefaultServiceName,
DefaultVendor,
_, c.Error = c.Client.SetDeviceConfig(
DefaultServiceName, DefaultServiceName,
name, DefaultServiceName + "." + name, DefaultServiceName, DefaultVendor,
DefaultServiceArea,
)
if c.Error != nil {
@ -631,6 +595,237 @@ func (c *CmdMqtt) UpdatePoint(entry *api.DataEntry) error {
}
// -------------------------------------------------------------------------------- //
const (
LogLevelDebug = 0
LogLevelInfo = iota
LogLevelWarning = iota
LogLevelError = iota
LogLevelDebugStr = "debug"
LogLevelInfoStr = "info"
LogLevelWarningStr = "warning"
LogLevelErrorStr = "error"
)
func (c *CmdMqtt) SetLogLevel(level string) {
switch strings.ToLower(level) {
case LogLevelDebugStr:
c.optionLogLevel = LogLevelDebug
case LogLevelInfoStr:
c.optionLogLevel = LogLevelInfo
case LogLevelWarningStr:
c.optionLogLevel = LogLevelWarning
case LogLevelErrorStr:
c.optionLogLevel = LogLevelError
default:
cmdLog.LogPrintDate("Unknown log level, setting to default.")
c.optionLogLevel = LogLevelInfo
}
}
func (c *CmdMqtt) GetLogLevel() string {
var ret string
switch c.optionLogLevel {
case LogLevelDebug:
ret = LogLevelDebugStr
case LogLevelInfo:
ret = LogLevelInfoStr
case LogLevelWarning:
ret = LogLevelWarningStr
case LogLevelError:
ret = LogLevelErrorStr
default:
ret = LogLevelInfoStr
}
return ret
}
func (c *CmdMqtt) LogDebug(format string, args ...interface{}) {
if LogLevelDebug >= c.optionLogLevel {
cmdLog.LogPrintDate("DEBUG: " + format, args...)
}
}
func (c *CmdMqtt) LogInfo(format string, args ...interface{}) {
if LogLevelInfo >= c.optionLogLevel {
cmdLog.LogPrintDate("INFO: " + format, args...)
}
}
func (c *CmdMqtt) LogWarning(format string, args ...interface{}) {
if LogLevelWarning >= c.optionLogLevel {
cmdLog.LogPrintDate("WARNING: " + format, args...)
}
}
func (c *CmdMqtt) LogError(format string, args ...interface{}) {
if LogLevelError >= c.optionLogLevel {
cmdLog.LogPrintDate("ERROR: " + format, args...)
}
}
func (c *CmdMqtt) LogPlainDebug(format string, args ...interface{}) {
if LogLevelDebug >= c.optionLogLevel {
fmt.Print(cmdLog.LogSprintf(format, args...))
}
}
func (c *CmdMqtt) LogPlainInfo(format string, args ...interface{}) {
if LogLevelInfo >= c.optionLogLevel {
fmt.Print(cmdLog.LogSprintf(format, args...))
}
}
func (c *CmdMqtt) LogPlainWarning(format string, args ...interface{}) {
if LogLevelWarning >= c.optionLogLevel {
fmt.Print(cmdLog.LogSprintf(format, args...))
}
}
func (c *CmdMqtt) LogPlainError(format string, args ...interface{}) {
if LogLevelError >= c.optionLogLevel {
fmt.Print(cmdLog.LogSprintf(format, args...))
}
}
const (
OptionLogLevel = "loglevel"
OptionFetchSchedule = "fetchschedule"
OptionSleepDelay = "sleepdelay"
OptionServiceState = "servicestate"
)
func (c *CmdMqtt) Options() error {
for range Only.Once {
c.Error = c.Client.SetOption(OptionLogLevel, "Log Level",
c.optionFuncLogLevel,
LogLevelErrorStr, LogLevelWarningStr, LogLevelInfoStr, LogLevelDebugStr)
if c.Error != nil {
break
}
c.Error = c.Client.SetOptionValue(OptionLogLevel, c.GetLogLevel())
if c.Error != nil {
break
}
c.Error = c.Client.SetOption(OptionFetchSchedule, "Fetch Schedule",
c.optionFuncFetchSchedule,
"2m", "3m", "4m", "5m", "6m", "7m", "8m", "9m", "10m")
if c.Error != nil {
break
}
c.Error = c.Client.SetOptionValue(OptionFetchSchedule, c.GetFetchSchedule())
if c.Error != nil {
break
}
c.Error = c.Client.SetOption(OptionSleepDelay, "Sleep Delay After Schedule",
c.optionFuncSleepDelay,
"0s", "10s", "20s", "30s", "40s", "50s", "60s")
if c.Error != nil {
break
}
c.Error = c.Client.SetOptionValue(OptionSleepDelay, c.GetSleepDelay())
if c.Error != nil {
break
}
c.Error = c.Client.SetOption(OptionServiceState, "Service State",
c.optionFuncServiceState,
"Run", "Restart", "Stop")
if c.Error != nil {
break
}
c.Error = c.Client.SetOptionValue(OptionServiceState, "Run")
if c.Error != nil {
break
}
}
return c.Error
}
func (c *CmdMqtt) optionFuncLogLevel(_ mqtt.Client, msg mqtt.Message) {
for range Only.Once {
request := strings.ToLower(string(msg.Payload()))
c.LogInfo("Option[%s] set to '%s'\n", OptionLogLevel, request)
c.SetLogLevel(request)
c.Error = c.Client.SetOptionValue(OptionLogLevel, request)
if c.Error != nil {
c.LogError("%s\n", c.Error)
break
}
}
}
func (c *CmdMqtt) optionFuncFetchSchedule(_ mqtt.Client, msg mqtt.Message) {
for range Only.Once {
request := strings.ToLower(string(msg.Payload()))
c.LogInfo("Option[%s] set to '%s'\n", OptionFetchSchedule, request)
c.optionFetchSchedule, c.Error = time.ParseDuration(request)
if c.Error != nil {
c.LogError("%s\n", c.Error)
break
}
c.Error = c.Client.SetOptionValue(OptionFetchSchedule, c.GetFetchSchedule())
if c.Error != nil {
c.LogError("%s\n", c.Error)
break
}
}
}
func (c *CmdMqtt) GetFetchSchedule() string {
return fmt.Sprintf("%.0fm", c.optionFetchSchedule.Minutes())
}
func (c *CmdMqtt) optionFuncSleepDelay(_ mqtt.Client, msg mqtt.Message) {
for range Only.Once {
request := strings.ToLower(string(msg.Payload()))
c.LogInfo("Option[%s] set to '%s'\n", OptionSleepDelay, request)
c.optionSleepDelay, c.Error = time.ParseDuration(request)
if c.Error != nil {
c.LogError("%s\n", c.Error)
break
}
c.Error = c.Client.SetOptionValue(OptionSleepDelay, request)
if c.Error != nil {
c.LogError("%s\n", c.Error)
break
}
}
}
func (c *CmdMqtt) GetSleepDelay() string {
return fmt.Sprintf("%.0fs", c.optionSleepDelay.Seconds())
}
func (c *CmdMqtt) optionFuncServiceState(_ mqtt.Client, msg mqtt.Message) {
for range Only.Once {
request := strings.ToLower(string(msg.Payload()))
c.LogInfo("Option[%s] set to '%s'\n", OptionServiceState, request)
switch request {
case "Run":
case "Restart":
case "Stop":
}
c.Error = c.Client.SetOptionValue(OptionServiceState, request)
if c.Error != nil {
c.LogError("%s\n", c.Error)
break
}
}
}
// -------------------------------------------------------------------------------- //
type MqttEndPoints map[string]MqttEndPoint
type MqttEndPoint struct {
Include []string `json:"include"`

View File

@ -88,8 +88,8 @@ func (m *Mqtt) AlarmControlPanelPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -114,8 +114,8 @@ func (m *Mqtt) BinarySensorPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -66,8 +66,8 @@ func (m *Mqtt) ButtonPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) CameraPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) ClimatePublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -65,5 +65,4 @@ func (m *Mqtt) NewDevice(config EntityConfig) (bool, Device) {
}
return ok, ret
}

View File

@ -73,8 +73,8 @@ func (m *Mqtt) CoverPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) DeviceTrackerPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) DeviceTriggerPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) FanPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -41,10 +41,6 @@ func JoinStringsForId(args ...string) string {
return strings.Join(newargs, "-")
}
// func (c *Config) JoinStringsForId() string {
// return JoinStringsForId(m.Device.FullName, c.ParentName, c.FullName)
// }
func JoinStringsForTopic(args ...string) string {
var newargs []string
var re = regexp.MustCompile(`( |:)+`)

View File

@ -72,8 +72,8 @@ func (m *Mqtt) HumidifierPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -77,8 +77,8 @@ func (m *Mqtt) LightPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) LockPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) NumberPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

128
mmHa/options.go Normal file
View File

@ -0,0 +1,128 @@
package mmHa
import (
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
"errors"
"github.com/MickMake/GoUnify/Only"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
type Options struct {
Map map[string]Option
}
type Option struct {
Config *EntityConfig
Handler mqtt.MessageHandler
Values []string
}
func (m *Mqtt) SetOption(id string, name string, fn mqtt.MessageHandler, options ...string) error {
for range Only.Once {
m.err = m.UserOptions.SetOption(id, name, fn, options...)
if m.err != nil {
break
}
ec := m.UserOptions.EntityConfig(id)
m.err = m.SelectPublishConfig(*ec, fn)
if m.err != nil {
break
}
}
return m.err
}
func (m *Mqtt) SetOptionValue(id string, value string) error {
for range Only.Once {
m.err = m.UserOptions.SetOptionValue(id, value)
if m.err != nil {
break
}
ec := m.UserOptions.EntityConfig(id)
m.err = m.SelectPublishValue(*ec)
if m.err != nil {
break
}
}
return m.err
}
func (m *Mqtt) GetOption(id string) string {
return m.UserOptions.GetOption(id)
}
const OptionEnabled = "Enabled"
const OptionDisabled = "Disabled"
func (m *Options) SetOption(id string, name string, handler mqtt.MessageHandler, values ...string) error {
var err error
for range Only.Once {
if len(values) == 0 {
values = []string{OptionEnabled, OptionDisabled}
}
m.Map[id] = Option {
Config: &EntityConfig {
Name: "Option " + name,
FullId: JoinStringsForId("option", id),
Icon: "mdi:format-list-group",
// ValueTemplate: `{"value": "{{ value }}"}`,
Units: LabelSelect,
ParentName: "options",
Options: values,
},
Handler: handler,
Values: values,
}
}
return err
}
func (m *Options) SetOptionValue(id string, value string) error {
var err error
for range Only.Once {
if _, ok := m.Map[id]; !ok {
err = errors.New("not exist")
break
}
if m.Map[id].Config.Value == nil {
uv := valueTypes.SetUnitValueString("", "", value)
m.Map[id].Config.Value = &uv
break
}
m.Map[id].Config.Value.SetString(value)
}
return err
}
func (m *Options) GetOption(id string) string {
var ret string
for range Only.Once {
if value, ok := m.Map[id]; ok {
ret = value.Config.Value.String()
break
}
}
return ret
}
func (m *Options) EntityConfig(id string) *EntityConfig {
var ret *EntityConfig
for range Only.Once {
if r, ok := m.Map[id]; ok {
ret = r.Config
break
}
}
return ret
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) ScenePublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -2,14 +2,16 @@ package mmHa
import (
"encoding/json"
"fmt"
"github.com/MickMake/GoUnify/Only"
mqtt "github.com/eclipse/paho.mqtt.golang"
"strings"
)
const LabelSelect = "select"
func (m *Mqtt) SelectPublishConfig(config EntityConfig) error {
func (m *Mqtt) SelectPublishConfig(config EntityConfig, fn mqtt.MessageHandler) error {
for range Only.Once {
config.FixConfig()
@ -23,55 +25,25 @@ func (m *Mqtt) SelectPublishConfig(config EntityConfig) error {
}
id := JoinStringsForId(m.DeviceName, config.FullId)
// {
// "device": {
// "connections": [
// [
// "GoSungrow",
// "GoSungrow-Control"
// ]
// ],
// "identifiers": [
// "GoSungrow-Control"
// ],
// "manufacturer": "MickMake",
// "model": "GoSungrow",
// "name": "GoSungrow Control",
// "suggested_area": "Roof",
// "sw_version": "GoSungrow https://github.com/MickMake/GoSungrow",
// "via_device": "GoSungrow"
// },
// "object_id": "GoSungrow-select-endpoints",
// "unique_id": "GoSungrow-select-endpoints",
// "name": "GoSungrow Select EndPoints",
// "command_topic": "homeassistant/select/GoSungrow/endpoint-select/set",
// "state_topic": "homeassistant/select/GoSungrow/endpoint-select/state",
// "command_template": "{\"select\": \"{{ value }}\" }",
// "value_template": "{{ value_json.select }}",
// "enabled_by_default": true,
// "retain": true,
// "encoding": "utf-8",
// "icon": "mdi:format-list-group",
// "options": [
// "queryDeviceList",
// "getPsList",
// "getPsDetail"
// ]
// }
cmdTopic := JoinStringsForTopic(m.Prefix, LabelSelect, m.ClientId, id, "cmd")
payload := Select {
Device: newDevice,
Name: String(JoinStrings(m.DeviceName, config.Name)),
StateTopic: String(JoinStringsForTopic(m.Prefix, LabelSelect, m.ClientId, id, "state")),
CommandTopic: String(JoinStringsForTopic(m.Prefix, LabelSelect, m.ClientId, id, "cmd")),
ObjectId: String(id),
UniqueId: String(id),
Qos: 0,
Retain: true,
ValueTemplate: Template(config.ValueTemplate),
Icon: Icon(config.Icon),
Device: newDevice,
Name: String(JoinStrings(m.DeviceName, config.Name)),
StateTopic: String(JoinStringsForTopic(m.Prefix, LabelSelect, m.ClientId, id, "state")),
// CommandTemplate: Template(fmt.Sprintf(`"%s":"{{ value }}"`, config.FullId)),
// CommandTemplate: Template(fmt.Sprintf(`{{ value_json.value }}`)),
CommandTemplate: Template(fmt.Sprintf(`{{ value }}`)),
CommandTopic: String(cmdTopic),
ObjectId: String(id),
UniqueId: String(id),
Qos: 0,
Retain: true,
EnabledByDefault: true,
Encoding: "utf-8",
Options: config.Options,
ValueTemplate: Template(config.ValueTemplate),
Icon: Icon(config.Icon),
}
tag := JoinStringsForTopic(m.Prefix, LabelSelect, m.ClientId, id, "config")
@ -79,6 +51,11 @@ func (m *Mqtt) SelectPublishConfig(config EntityConfig) error {
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}
m.err = m.Subscribe(cmdTopic, fn)
if m.err != nil {
break
}
}
return m.err
@ -104,15 +81,15 @@ func (m *Mqtt) SelectPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}
break
}
payload := MqttState{
payload := MqttState {
LastReset: config.LastReset, // m.GetLastReset(config.FullId),
Value: value,
}
@ -319,40 +296,3 @@ func (config *EntityConfig) IsSelect() bool {
return ok
}
// {
// "device": {
// "connections": [
// [
// "GoSungrow",
// "GoSungrow-Control"
// ]
// ],
// "identifiers": [
// "GoSungrow-Control"
// ],
// "manufacturer": "MickMake",
// "model": "GoSungrow",
// "name": "GoSungrow Control",
// "suggested_area": "Roof",
// "sw_version": "GoSungrow https://github.com/MickMake/GoSungrow",
// "via_device": "GoSungrow"
// },
// "object_id": "GoSungrow-select-endpoints",
// "unique_id": "GoSungrow-select-endpoints",
// "name": "GoSungrow Select EndPoints",
// "command_topic": "homeassistant/select/GoSungrow/endpoint-select/set",
// "state_topic": "homeassistant/select/GoSungrow/endpoint-select/state",
// "command_template": "{\"select\": \"{{ value }}\" }",
// "value_template": "{{ value_json.select }}",
// "enabled_by_default": true,
// "retain": true,
// "encoding": "utf-8",
// "icon": "mdi:format-list-group",
// "options": [
// "queryDeviceList",
// "getPsList",
// "getPsDetail"
// ]
// }

View File

@ -70,13 +70,15 @@ func (m *Mqtt) SensorPublishValue(config EntityConfig) error {
tag := JoinStringsForTopic(m.Prefix, LabelSensor, m.ClientId, id, "state")
value := config.Value.String()
// fmt.Printf("[%s] = %s", tag, value)
if value == "--" {
value = ""
}
// fmt.Printf("(%s)\n", value)
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) SirenPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -8,8 +8,10 @@ import (
"errors"
"fmt"
"github.com/MickMake/GoUnify/Only"
"github.com/MickMake/GoUnify/cmdLog"
mqtt "github.com/eclipse/paho.mqtt.golang"
"net/url"
"strings"
"time"
)
@ -27,27 +29,19 @@ type Mqtt struct {
client mqtt.Client
pubClient mqtt.Client
clientOptions *mqtt.ClientOptions
DeviceName string
LastRefresh time.Time `json:"-"`
SungrowDevices getDeviceList.Devices `json:"-"`
// SungrowDevices valueTypes.PsKeys `json:"-"`
// SungrowDevices valueTypes.PsIds `json:"-"`
// SungrowDevices getPsTreeMenu.ResultData `json:"-"`
SungrowPsIds map[valueTypes.PsId]bool
DeviceName string
MqttDevices map[string]Device
Prefix string
// selectPrefix string
// servicePrefix string
// sensorPrefix string
// lightPrefix string
// switchPrefix string
// binarySensorPrefix string
MqttDevices map[string]Device
Prefix string
UserOptions Options
token mqtt.Token
firstRun bool
err error
debug bool
}
@ -72,11 +66,17 @@ func New(req Mqtt) *Mqtt {
ret.MqttDevices = make(map[string]Device)
ret.SungrowPsIds = make(map[valueTypes.PsId]bool)
ret.Timeout = time.Second * 5
ret.UserOptions.Map = make(map[string]Option, 0)
}
return &ret
}
func (m *Mqtt) IsDebug() bool {
return m.debug
}
func (m *Mqtt) IsFirstRun() bool {
return m.firstRun
}
@ -212,27 +212,25 @@ func (m *Mqtt) Connect() error {
break
}
// Device: newDevice,
// Name: String(JoinStrings(m.DeviceName, config.Name)),
// StateTopic: String(JoinStringsForTopic(m.switchPrefix, id, "state")),
// CommandTopic: String(JoinStringsForTopic(m.switchPrefix, id, "cmd")),
// ObjectId: String(id),
// UniqueId: String(id),
// Qos: 0,
// Retain: true,
//
// ValueTemplate: Template(config.ValueTemplate),
// Icon: Icon(config.Icon),
m.err = m.SelectPublishConfig(EntityConfig {
Name: "Debug Level",
FullId: "GoSungrow.Control.DebugLevel",
Icon: "",
ValueTemplate: `{\"select\": \"{{ value }}\"}`,
})
_, m.err = m.SetDeviceConfig(
m.DeviceName, m.DeviceName,
"options", "Options", "", m.DeviceName,
m.DeviceName,
)
if m.err != nil {
break
}
m.err = m.Subscribe(JoinStringsForTopic(m.Prefix, LabelSelect, m.ClientId, "state"), m.Fart)
m.err = m.SetOption("mqtt_debug", "Mqtt Debug", m.funcMqttDebug)
if m.err != nil {
break
}
v := "Disabled"
if m.debug {
v = "Enabled"
}
m.err = m.SetOptionValue("mqtt_debug", v)
if m.err != nil {
break
}
@ -241,10 +239,15 @@ func (m *Mqtt) Connect() error {
return m.err
}
func (m *Mqtt) Fart(client mqtt.Client, msg mqtt.Message) {
func (m *Mqtt) funcMqttDebug(_ mqtt.Client, msg mqtt.Message) {
for range Only.Once {
fmt.Printf("DONE\n")
time.Sleep(1 * time.Second)
request := strings.ToLower(string(msg.Payload()))
cmdLog.LogPrintDate("Option[%s] set to '%s'\n", msg.Topic(), request)
if request == strings.ToLower(OptionEnabled) {
m.debug = true
break
}
m.debug = false
}
}
@ -276,7 +279,7 @@ func (m *Mqtt) createClientOptions() error {
// type SubscribeFunc func(client mqtt.Client, msg mqtt.Message)
func (m *Mqtt) subscribeDefault(client mqtt.Client, msg mqtt.Message) {
fmt.Printf("* [%s] %s\n", msg.Topic(), string(msg.Payload()))
fmt.Printf("*%t> [%s] %s\n", client.IsConnected(), msg.Topic(), string(msg.Payload()))
}
func (m *Mqtt) Subscribe(topic string, fn mqtt.MessageHandler) error {
@ -287,7 +290,7 @@ func (m *Mqtt) Subscribe(topic string, fn mqtt.MessageHandler) error {
t := m.client.Subscribe(topic, 0, fn)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
// m.err = errors.New("mqtt subscribe timeout")
}
}
return m.err
@ -303,32 +306,32 @@ func (m *Mqtt) Publish(topic string, qos byte, retained bool, payload interface{
return m.err
}
func (m *Mqtt) PublishState(Type string, subtopic string, payload interface{}) error {
for range Only.Once {
// topic = JoinStringsForId(m.EntityPrefix, m.Device.Name, topic)
// topic = JoinStringsForTopic(m.sensorPrefix, topic, "state")
// st := JoinStringsForTopic(m.sensorPrefix, JoinStringsForId(m.EntityPrefix, m.Device.FullName, strings.ReplaceAll(subName, "/", ".")), "state")
topic := ""
switch Type {
case LabelSensor:
topic = JoinStringsForTopic(m.Prefix, LabelSensor, m.ClientId, subtopic, "state")
case LabelBinarySensor:
topic = JoinStringsForTopic(m.Prefix, LabelBinarySensor, m.ClientId, subtopic, "state")
case LabelLight:
topic = JoinStringsForTopic(m.Prefix, LabelLight, m.ClientId, subtopic, "state")
case LabelSwitch:
topic = JoinStringsForTopic(m.Prefix, LabelSwitch, m.ClientId, subtopic, "state")
default:
topic = JoinStringsForTopic(m.Prefix, LabelSensor, m.ClientId, subtopic, "state")
}
t := m.client.Publish(topic, 0, true, payload)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}
}
return m.err
}
// func (m *Mqtt) PublishState(Type string, subtopic string, payload interface{}) error {
// for range Only.Once {
// // topic = JoinStringsForId(m.EntityPrefix, m.Device.Name, topic)
// // topic = JoinStringsForTopic(m.sensorPrefix, topic, "state")
// // st := JoinStringsForTopic(m.sensorPrefix, JoinStringsForId(m.EntityPrefix, m.Device.FullName, strings.ReplaceAll(subName, "/", ".")), "state")
// topic := ""
// switch Type {
// case LabelSensor:
// topic = JoinStringsForTopic(m.Prefix, LabelSensor, m.ClientId, subtopic, "state")
// case LabelBinarySensor:
// topic = JoinStringsForTopic(m.Prefix, LabelBinarySensor, m.ClientId, subtopic, "state")
// case LabelLight:
// topic = JoinStringsForTopic(m.Prefix, LabelLight, m.ClientId, subtopic, "state")
// case LabelSwitch:
// topic = JoinStringsForTopic(m.Prefix, LabelSwitch, m.ClientId, subtopic, "state")
// default:
// topic = JoinStringsForTopic(m.Prefix, LabelSensor, m.ClientId, subtopic, "state")
// }
//
// t := m.client.Publish(topic, 0, true, payload)
// if !t.WaitTimeout(m.Timeout) {
// m.err = t.Error()
// }
// }
// return m.err
// }
func (m *Mqtt) PublishValue(Type string, subtopic string, value string) error {
for range Only.Once {
@ -386,7 +389,9 @@ func (m *Mqtt) PublishValue(Type string, subtopic string, value string) error {
return m.err
}
func (m *Mqtt) SetDeviceConfig(swname string, parentId string, id string, name string, model string, vendor string, area string) error {
func (m *Mqtt) SetDeviceConfig(swname string, parentId string, id string, name string, model string, vendor string, area string) (Device, error) {
var ret Device
for range Only.Once {
// id = JoinStringsForId(m.EntityPrefix, id)
@ -400,7 +405,7 @@ func (m *Mqtt) SetDeviceConfig(swname string, parentId string, id string, name s
}
}
m.MqttDevices[id] = Device {
ret = Device {
Connections: c,
Identifiers: []string{JoinStringsForId(m.EntityPrefix, id)},
Manufacturer: vendor,
@ -410,27 +415,29 @@ func (m *Mqtt) SetDeviceConfig(swname string, parentId string, id string, name s
ViaDevice: swname,
SuggestedArea: area,
}
}
return m.err
}
func (m *Mqtt) GetLastReset(pointType string) string {
var ret string
for range Only.Once {
pt := api.GetDevicePoint(pointType)
if !pt.Valid {
break
}
if pt.UpdateFreq == "" {
break
}
ret = pt.WhenReset()
m.MqttDevices[id] = ret
}
return ret
return ret, m.err
}
// func (m *Mqtt) GetLastReset(pointType string) string {
// var ret string
//
// for range Only.Once {
// pt := api.GetDevicePoint(pointType)
// if !pt.Valid {
// break
// }
// if pt.UpdateFreq == "" {
// break
// }
// ret = pt.WhenReset()
// }
//
// return ret
// }
type MqttState struct {
LastReset string `json:"last_reset,omitempty"`
@ -468,7 +475,7 @@ type EntityConfig struct {
StateClass string
Icon string
Value valueTypes.UnitValue
Value *valueTypes.UnitValue
Point *api.Point
ValueTemplate string
@ -479,6 +486,7 @@ type EntityConfig struct {
IgnoreUpdate bool
haType string
Options []string
}
func (config *EntityConfig) FixConfig() {

View File

@ -81,8 +81,8 @@ func (m *Mqtt) SwitchPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) TagPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -73,8 +73,8 @@ func (m *Mqtt) TextPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -73,8 +73,8 @@ func (m *Mqtt) UpdatePublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}

View File

@ -72,8 +72,8 @@ func (m *Mqtt) VacuumPublishValue(config EntityConfig) error {
}
// @TODO - Real hack here. Need to properly check for JSON.
if strings.Contains(config.Value.String(), `{`) || strings.Contains(config.Value.String(), `":`) {
t := m.client.Publish(tag, 0, true, config.Value.String())
if strings.Contains(value, `{`) || strings.Contains(value, `":`) {
t := m.client.Publish(tag, 0, true, value)
if !t.WaitTimeout(m.Timeout) {
m.err = t.Error()
}