package main import ( "strconv" "bytes" "log" "net" "os" "time" "github.com/eclipse/paho.mqtt.golang" "github.com/shirou/gopsutil/host" ) // Get preferred outbound ip of this machine func GetOutboundIP() net.IP { conn, err := net.Dial("udp", "8.8.8.8:80") if err != nil { log.Fatal(err) } defer conn.Close() localAddr := conn.LocalAddr().(*net.UDPAddr) return localAddr.IP } func getMacAddr() (addr string) { interfaces, err := net.Interfaces() if err == nil { for _, i := range interfaces { if i.Flags&net.FlagUp != 0 && bytes.Compare(i.HardwareAddr, nil) != 0 { // Don't use random as we have a real address addr = i.HardwareAddr.String() break } } } return } //Publish a message and wait for confirmation func SyncPublish(client mqtt.Client, topic string, qos byte, retained bool, payload interface{}) { hostname, _ := os.Hostname() prefix := "homie/" + hostname + "/" token := client.Publish(prefix + topic, qos, retained, payload) if(!token.Wait()) { log.Fatal("Timeout on publish") log.Fatal(token.Error()) os.Exit(3) } } func main() { opts := mqtt.NewClientOptions().AddBroker("tcp://mqtt.jcktrue.dk:1883").SetClientID("gotrivial") hostname, _ := os.Hostname() opts.SetWill("homie/" + hostname + "/$state", "lost", 0, true); c := mqtt.NewClient(opts) if token := c.Connect(); token.Wait() && token.Error() != nil { panic(token.Error()) } SyncPublish(c, "$state", 0, true, "init") SyncPublish(c, "$homie", 0, true, "3.0.1") SyncPublish(c, "$name", 0, true, hostname) SyncPublish(c, "$localip", 0, true, GetOutboundIP().String()) SyncPublish(c, "$mac", 0, true, getMacAddr()) SyncPublish(c, "$fw/name", 0, true, "gomie") SyncPublish(c, "$fw/version", 0, true, "1.0") SyncPublish(c, "$implementation", 0, true, "gomie") SyncPublish(c, "$stats", 0, true, "uptime") uptimeSeconds, _ := host.Uptime() SyncPublish(c, "$stats/uptime", 0, true, strconv.FormatUint(uptimeSeconds,10)) SyncPublish(c, "$stats/interval", 0, true, "0") SyncPublish(c, "leax-backup/$name", 0, true, "LEAX Backup") SyncPublish(c, "leax-backup/$type", 0, true, "script") SyncPublish(c, "leax-backup/$properties", 0, true, "lastrun,output") SyncPublish(c, "trueserver-backup/$name", 0, true, "TRUESERVER Backup") SyncPublish(c, "trueserver-backup/$type", 0, true, "script") SyncPublish(c, "trueserver-backup/$properties", 0, true, "lastrun,output") SyncPublish(c, "$state", 0, true, "ready") //Done with initialization SyncPublish(c, "leax-backup/lastrun", 0, true, strconv.FormatInt(time.Now().Unix(),10)) SyncPublish(c, "leax-backup/output", 0, true, "Backup successful") SyncPublish(c, "trueserver-backup/lastrun", 0, true, strconv.FormatInt(time.Now().Unix(),10)) SyncPublish(c, "trueserver-backup/output", 0, true, "Backup successful") //All done SyncPublish(c, "$state", 0, true, "disconnected") c.Disconnect(1000) //Wait one second to disconnect }