package main import ( "fmt" "log" "time" mqtt "github.com/eclipse/paho.mqtt.golang" "xengineering.eu/homematic-go/homematic" ) const ( OPENCCU = `http://127.0.0.1:8080` BROKER = `tcp://127.0.0.1:1883` CLIENT_ID = `sia-server` TOPIC_PREFIX = `sia` QOS = byte(0) RETAINED = false MQTT_CONNECT_TIMEOUT = time.Second * 5 MQTT_DISCONNECT_TIMEOUT_US = 500 ) func main() { log.Println("+++ Started Sia server +++") defer log.Println("--- Stopped Sia server ---") req := homematic.NewRequester(OPENCCU) log.Printf("Created Homematic requester (%s).", OPENCCU) inventory, err := req.ListDevices() if err != nil { log.Fatalf("Failed to retrieve device list: %v", err) } log.Printf("Retrieved Homematic inventory with %d devices.", len(inventory)) client, err := ConnectMQTT(BROKER, CLIENT_ID) if err != nil { log.Fatalf("Could not connect to MQTT broker: %v", err) } defer func () { client.Disconnect(MQTT_DISCONNECT_TIMEOUT_US) log.Println("Disconnected from MQTT broker.") }() log.Printf("Connected to MQTT broker (%s).", BROKER) for _, device := range inventory { if device.Type == `SHUTTER_CONTACT` { state, err := req.GetValue(device.Address) if err != nil { log.Fatalf("Failed to get value: %v", err) } topic := fmt.Sprintf("%s/contact/%s/state", TOPIC_PREFIX, device.Address) payload := []byte(fmt.Sprintf("%t", state)) client.Publish(topic, QOS, RETAINED, payload) } } } func ConnectMQTT(broker string, id string) (mqtt.Client, error) { opts := mqtt.NewClientOptions() opts.AddBroker(broker) opts.SetClientID(id) opts.SetCleanSession(true) client := mqtt.NewClient(opts) token := client.Connect() success := token.WaitTimeout(MQTT_CONNECT_TIMEOUT) if !success { return client, fmt.Errorf("Timed out after %v.", MQTT_CONNECT_TIMEOUT) } err := token.Error() if err != nil { return client, err } return client, nil }