summaryrefslogtreecommitdiff
path: root/shelly.go
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2026-03-23 21:34:58 +0100
committerxengineering <me@xengineering.eu>2026-03-25 21:09:11 +0100
commitbfd840bfd843f95183568f7ef6a9880a810ce049 (patch)
tree3f35a2db20d9f069fddff86637617030a01c33bf /shelly.go
parent1bd2833f81379f25b29ab5d929f14e51700fa471 (diff)
downloadsia-server-bfd840bfd843f95183568f7ef6a9880a810ce049.tar
sia-server-bfd840bfd843f95183568f7ef6a9880a810ce049.tar.zst
sia-server-bfd840bfd843f95183568f7ef6a9880a810ce049.zip
Add Shelly cover message parsing
This results in the information of which command is to issue and which IP address the command has to be sent to. This is what is needed to deliver the message with Websockets. This delivery is the last step to implement basic Shelly cover support.
Diffstat (limited to 'shelly.go')
-rw-r--r--shelly.go48
1 files changed, 47 insertions, 1 deletions
diff --git a/shelly.go b/shelly.go
index 0d33182..7396bbb 100644
--- a/shelly.go
+++ b/shelly.go
@@ -1,11 +1,57 @@
package main
import (
+ "fmt"
"log"
+ "net"
+ "strings"
)
func ShellyRun(config ShellyConfigs, rx chan MQTTMessage) {
for message := range rx {
- log.Printf("Got MQTT message: %v", message)
+ ip, command, err := parseMessage(config, message)
+ if err != nil {
+ log.Println(err)
+ continue
+ }
+
+ log.Printf("Send '%s' to '%s'.", command, ip)
+ }
+}
+
+func parseMessage(config ShellyConfigs, m MQTTMessage) (ip *net.IP, command string, err error) {
+ elements := strings.Split(m.Topic, "/")
+
+ if len(elements) != 3 {
+ return nil, "", fmt.Errorf(
+ "Expected three topic levels but got %d in '%s'.",
+ len(elements), m.Topic,
+ )
+ }
+
+ if elements[0] != "cover" || elements[2] != "movement" {
+ return nil, "", fmt.Errorf("Expected cover/<id>/movement but got: %s", m.Topic)
}
+
+ switch string(m.Payload) {
+ case "extend":
+ command = "Cover.Close"
+ case "retract":
+ command = "Cover.Open"
+ case "stop":
+ command = "Cover.Stop"
+ default:
+ return nil, "", fmt.Errorf("Invalid payload '%s'.", m.Payload)
+ }
+
+ id := elements[1]
+
+ for _, c := range config {
+ if c.ID == id {
+ ip := net.ParseIP(c.IP)
+ return &ip, command, nil
+ }
+ }
+
+ return nil, "", fmt.Errorf("Got message for unknown cover '%s'", id)
}