summaryrefslogtreecommitdiff
path: root/homematic.go
diff options
context:
space:
mode:
authorxengineering <me@xengineering.eu>2025-12-20 13:47:56 +0100
committerxengineering <me@xengineering.eu>2025-12-20 13:47:56 +0100
commit6978bf0635372b0330629469fb86ddb640cdd863 (patch)
tree5c35b936a96c7383b85786fac39ea68cf3b96b98 /homematic.go
parent58d7c51baa053be8d6d4ec5f409fceef1c7c11b5 (diff)
downloadsia-server-6978bf0635372b0330629469fb86ddb640cdd863.tar
sia-server-6978bf0635372b0330629469fb86ddb640cdd863.tar.zst
sia-server-6978bf0635372b0330629469fb86ddb640cdd863.zip
Separate Homematic code
Similar to a previous refactoring of the MQTT-related code this removes all Homematic logic to a dedicated file. The only connection to the outside is the `tx chan MQTTMessage` channel and the `HomematicRun()` function. This makes the code more modular.
Diffstat (limited to 'homematic.go')
-rw-r--r--homematic.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/homematic.go b/homematic.go
new file mode 100644
index 0000000..ae12760
--- /dev/null
+++ b/homematic.go
@@ -0,0 +1,77 @@
+package main
+
+import (
+ "fmt"
+ "log"
+ "time"
+
+ "xengineering.eu/homematic-go/homematic"
+)
+
+const (
+ OPENCCU = `http://127.0.0.1:8080`
+ POLLING_PERIOD = 50 * time.Millisecond
+)
+
+func HomematicRun(tx chan MQTTMessage) {
+ req, inventory, err := Start()
+ if err != nil {
+ log.Fatalf("Failed startup process: %v", err)
+ }
+
+ cache := NewCache(tx)
+
+ for {
+ start := time.Now()
+
+ states, err := Poll(req, inventory)
+ if err != nil {
+ log.Fatalf("Failed to poll states: %v", err)
+ }
+
+ cache.Update(states)
+
+ WaitUntil(start.Add(POLLING_PERIOD))
+ }
+
+}
+
+func Start() (homematic.Requester, homematic.Devices, error) {
+ var req homematic.Requester
+ var inventory homematic.Devices
+ var err error
+
+ req = homematic.NewRequester(OPENCCU)
+ log.Printf("Created Homematic requester (%s).", OPENCCU)
+
+ inventory, err = req.ListDevices()
+ if err != nil {
+ return req, inventory, fmt.Errorf("Failed getting initial device list: %w", err)
+ }
+ log.Printf("Retrieved Homematic inventory with %d devices.", len(inventory))
+
+ return req, inventory, nil
+}
+
+func Poll(req homematic.Requester, inventory homematic.Devices) (States, error) {
+ states := make(States)
+
+ for _, device := range inventory {
+ if device.Type == `SHUTTER_CONTACT` {
+ state, err := req.GetValue(device.Address)
+ if err != nil {
+ return states, fmt.Errorf("Failed to get value: %w", err)
+ }
+ states[device.Address] = state
+ }
+ }
+
+ return states, nil
+}
+
+func WaitUntil(deadline time.Time) {
+ duration := time.Until(deadline)
+ if duration > 0 {
+ time.Sleep(duration)
+ }
+}