From 6978bf0635372b0330629469fb86ddb640cdd863 Mon Sep 17 00:00:00 2001 From: xengineering Date: Sat, 20 Dec 2025 13:47:56 +0100 Subject: 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. --- homematic.go | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 homematic.go (limited to 'homematic.go') 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) + } +} -- cgit v1.2.3-70-g09d2