sensenet/topic/power/power.go

92 lines
2.0 KiB
Go

package power
import (
"context"
"encoding/json"
"fmt"
"log"
"git.wntrmute.dev/kyle/sensenet/topic"
"github.com/Masterminds/squirrel"
)
type Tuple struct {
Voltage float64 `json:"voltage"`
Current float64 `json:"current"`
Power float64 `json:"power"`
}
type Stat struct {
Battery Tuple `json:"battery"`
Wall Tuple `json:"wall"`
Charging bool `json:"charging"`
From string `json:"charging_from"`
}
var psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
func createTable(ctx context.Context, db topic.Database) error {
q := `CREATE TABLE IF NOT EXISTS power (
id uuid primary key default gen_random_uuid(),
source text not null,
timestamp int not null,
bvoltage real not null,
bcurrent real not null,
bpower real not null,
wvoltage real not null,
wcurrent real not null,
wpower real not null,
charging boolean not null,
charging_from text not null
);`
_, err := db.Exec(ctx, q)
return err
}
func store(ctx context.Context, db topic.Database, packet *topic.Packet) error {
stat := &Stat{}
err := json.Unmarshal(packet.Payload, stat)
if err != nil {
log.Printf("packet topic: %s [%x]", packet.Topic, packet.Topic)
log.Printf("packet payload: %s [%x]", packet.Payload, packet.Payload)
return fmt.Errorf("power: failed to unmarshal JSON: %w", err)
}
stmt := psql.Insert("power").Columns(
"source",
"timestamp",
"bvoltage",
"bcurrent",
"bpower",
"wvoltage",
"wcurrent",
"wpower",
"charging",
"charging_from",
).Values(
packet.Publisher,
packet.Received,
stat.Battery.Voltage,
stat.Battery.Current,
stat.Battery.Power,
stat.Wall.Voltage,
stat.Wall.Current,
stat.Wall.Power,
stat.Charging,
stat.From,
)
query, args, err := stmt.ToSql()
_, err = db.Exec(ctx, query, args...)
if err != nil {
return fmt.Errorf("Power.Store[%s]: %w", packet.Publisher, err)
}
return nil
}
func init() {
topic.Register("power", &topic.Topic{
CreateTable: createTable,
Store: store,
})
}