Publish packets.

This commit is contained in:
2022-02-27 02:10:21 -08:00
parent a3966fc28b
commit 579c17bb6a
11 changed files with 624 additions and 36 deletions

View File

@@ -3,6 +3,8 @@ package pht
import (
"context"
"encoding/json"
"fmt"
"log"
"git.wntrmute.dev/kyle/sensenet/topic"
"github.com/Masterminds/squirrel"
@@ -11,13 +13,13 @@ import (
var psql = squirrel.StatementBuilder.PlaceholderFormat(squirrel.Dollar)
func createTable(ctx context.Context, db topic.Database) error {
stmt := `CREATE TABLE pht IF NOT EXISTS (
stmt := `CREATE TABLE IF NOT EXISTS pht (
id uuid primary key default gen_random_uuid(),
source text,
timestamp int,
temp real,
press real,
humid real
source text not null,
timestamp int not null,
temp real not null,
press real not null,
humid real not null
);`
_, err := db.Exec(ctx, stmt)
return err
@@ -34,7 +36,9 @@ func store(ctx context.Context, db topic.Database, packet *topic.Packet) error {
r := &reading{}
err := json.Unmarshal(packet.Payload, r)
if err != nil {
return err
log.Printf("packet topic: %s [%x]", packet.Topic, packet.Topic)
log.Printf("packet payload: %s [%x]", packet.Payload, packet.Payload)
return fmt.Errorf("pht: failed to unmarshal JSON: %w", err)
}
stmt := psql.Insert("pht").Columns(
"source",
@@ -42,7 +46,7 @@ func store(ctx context.Context, db topic.Database, packet *topic.Packet) error {
"temp",
"press",
"humid",
).Values(packet.Publisher, r.Timestamp, r.Pressure, r.Humidity)
).Values(packet.Publisher, r.Timestamp, r.Temperature, r.Pressure, r.Humidity)
query, args, err := stmt.ToSql()
if err != nil {
return err
@@ -52,11 +56,9 @@ func store(ctx context.Context, db topic.Database, packet *topic.Packet) error {
return err
}
var PHT = &topic.Topic{
CreateTable: createTable,
Store: store,
}
func init() {
topic.Register("pht", PHT)
topic.Register("pht", &topic.Topic{
CreateTable: createTable,
Store: store,
})
}

91
topic/power/power.go Normal file
View File

@@ -0,0 +1,91 @@
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,
})
}

View File

@@ -6,6 +6,7 @@ import (
"log"
"sync"
"git.wntrmute.dev/kyle/sensenet/config"
"github.com/jackc/pgconn"
)
@@ -35,6 +36,7 @@ func Register(topic string, handler *Topic) {
}
registry.topics[topic] = handler
log.Println("registered handler for topic", topic)
}
type Packet struct {
@@ -49,8 +51,9 @@ func Setup(ctx context.Context, db Database) error {
registry.lock.Lock()
defer registry.lock.Unlock()
for key, topic := range registry.topics {
log.Println("running CreateTable for", key)
log.Println("creating tables")
for _, topic := range registry.topics {
err := topic.CreateTable(ctx, db)
if err != nil {
return err
@@ -68,3 +71,18 @@ func Publish(ctx context.Context, db Database, packet *Packet) error {
return topic.Store(ctx, db, packet)
}
func ValidateTopics(publishers map[string]*config.Publisher) bool {
valid := true
for _, pub := range publishers {
for _, topic := range pub.Topics {
if _, ok := registry.topics[topic]; !ok {
log.Printf("missing handler for topic %s", topic)
valid = valid && ok
}
}
}
return valid
}