Kickoff go application

This commit is contained in:
Felix Niederwanger 2023-05-30 21:48:06 +02:00
parent c513390287
commit fffb445b72
Signed by: phoenix
GPG key ID: 6E77A590E3F6D71C
9 changed files with 175 additions and 41 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/smartbridge

5
Makefile Normal file
View file

@ -0,0 +1,5 @@
default: all
all: smartbridge
smartbridge: cmd/smartbridge/*.go
go build -o $@ $^

13
cmd/smartbridge/config.go Normal file
View file

@ -0,0 +1,13 @@
package main
type Config struct {
Remote string // Remote IP address of the Smartbridge
Mqtt string // mqtt server
}
var cf Config
func (cf *Config) SetDefaults() {
cf.Remote = "192.168.242.199"
cf.Mqtt = "192.168.0.42"
}

49
cmd/smartbridge/main.go Normal file
View file

@ -0,0 +1,49 @@
package main
import (
"fmt"
"os"
"time"
)
var mqtt_c Mqtt
func establishMqtt() error {
var err error
n := 5
for i := 0; i < n; i++ {
mqtt_c, err = ConnectMqtt(cf.Mqtt, 1883)
if err == nil {
return nil
}
fmt.Fprintf(os.Stderr, "mqtt error: %s (attempt %d/%d)\n", err, i+1, n)
time.Sleep(time.Second * time.Duration(i))
}
return fmt.Errorf("connection failed")
}
func main() {
cf.SetDefaults()
if err := establishMqtt(); err != nil {
fmt.Fprintf(os.Stderr, "mqtt: %s\n", err)
os.Exit(1)
}
fmt.Println("smartbridge reader operational")
for true {
reading, err := ReadSmartbridge(cf.Remote)
if err != nil {
fmt.Fprintf(os.Stderr, "%s\n", err)
}
if reading.Status != "ok" {
fmt.Fprintf(os.Stderr, "status: %s\n", reading.Status)
} else {
data := fmt.Sprintf("{\"power\":%d,\"unit\":\"W\",\"timestamp\":%d}", reading.Electricity.Power.Current.Value, time.Now().Unix())
mqtt_c.Publish("home/power", data)
}
time.Sleep(5 * time.Second)
}
}

34
cmd/smartbridge/mqtt.go Normal file
View file

@ -0,0 +1,34 @@
package main
import (
"fmt"
mqtt "github.com/eclipse/paho.mqtt.golang"
)
type Mqtt struct {
client mqtt.Client
}
func ConnectMqtt(broker string, port int) (Mqtt, error) {
var ret Mqtt
opts := mqtt.NewClientOptions()
opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
opts.SetClientID("smartbridge")
//opts.SetUsername("emqx")
//opts.SetPassword("public")
//opts.SetDefaultPublishHandler(messagePubHandler)
//opts.OnConnect = connectHandler
//opts.OnConnectionLost = connectLostHandler
opts.AutoReconnect = true
ret.client = mqtt.NewClient(opts)
token := ret.client.Connect()
token.Wait()
return ret, token.Error()
}
func (m *Mqtt) Publish(topic string, message string) error {
tok := m.client.Publish(topic, 0, false, message)
tok.Wait()
return tok.Error()
}

View file

@ -0,0 +1,50 @@
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
)
type Reading struct {
Status string `json:"status"`
Electricity Electricity `json:"elec"`
}
type Electricity struct {
Power Power `json:"power"`
Import Power `json:"import"`
Export Power `json:"export"`
}
type Power struct {
Current Value `json:"now"`
Minimun Value `json:"min"`
Maximum Value `json:"max"`
}
type Value struct {
Value int `json:"value"`
Unit string `json:"unit"`
Timestamp int64 `json:"time"`
}
func ReadSmartbridge(remote string) (Reading, error) {
var reading Reading
uri := fmt.Sprintf("http://%s/meter/now", remote)
resp, err := http.Get(uri)
if err != nil {
return reading, err
}
if resp.StatusCode != 200 {
return reading, fmt.Errorf("http status code %d returned", resp.StatusCode)
}
defer resp.Body.Close()
buf, err := io.ReadAll(resp.Body)
if err != nil {
return reading, err
}
err = json.Unmarshal(buf, &reading)
return reading, err
}

11
go.mod Normal file
View file

@ -0,0 +1,11 @@
module feldspaten.org/smartbridge/v2
go 1.20
require github.com/eclipse/paho.mqtt.golang v1.4.2
require (
github.com/gorilla/websocket v1.4.2 // indirect
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
)

12
go.sum Normal file
View file

@ -0,0 +1,12 @@
github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U=
golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=

View file

@ -1,41 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import os
import time
import paho.mqtt.client as mqtt
import json
SOURCE = "http://192.168.242.199/meter/now"
MQTT_SERVER = "192.168.0.42"
MQTT_TOPIC = "home/power"
DELAY = 5
def obtain_data() :
req = requests.get(SOURCE)
req.raise_for_status()
return req.json()
if __name__ == "__main__" :
# MQTT client
client = mqtt.Client()
client.connect(MQTT_SERVER, 1883, 60)
while True :
data = obtain_data()
if data['status'] != 'ok' :
print("status: %s" % data['status'])
os.Exit(1)
# Get Power readings
power = data['elec']['power']['now']['value'] # Current power readings in Watt
# MQTT publish
tsp = int(time.time())
data = {"power": power, "timestamp": tsp}
msg = json.dumps(data)
print(msg)
result = client.publish(MQTT_TOPIC, msg)
time.sleep(DELAY)