]> git.giacomolli.uk - onehouse/blob - driver/alamo/gateway_record.go
Exchange bounded Alamo gateway requests
[onehouse] / driver / alamo / gateway_record.go
1 package alamo
2
3 import (
4 "encoding/hex"
5 "fmt"
6 "math"
7 "strings"
8 )
9
10 type gatewayRecord struct {
11 MAC *string `json:"mac"`
12 Power *int `json:"power"`
13 Target *float64 `json:"stemp"`
14 Room *float64 `json:"temp"`
15 Floor *float64 `json:"sensor"`
16 Active *int `json:"ativo"`
17 Locked *int `json:"bloqueio"`
18 }
19
20 func (r gatewayRecord) state() (State, error) {
21 if r.MAC == nil || r.Power == nil || r.Target == nil || r.Room == nil || r.Floor == nil || r.Active == nil || r.Locked == nil {
22 return State{}, fmt.Errorf("gateway record is incomplete")
23 }
24
25 mac, err := normalizeMAC(*r.MAC)
26 if err != nil {
27 return State{}, fmt.Errorf("validate record MAC: %w", err)
28 }
29
30 if !binary(*r.Power) || !binary(*r.Active) || !binary(*r.Locked) {
31 return State{}, fmt.Errorf("gateway flags must be zero or one")
32 }
33
34 if !finite(*r.Target) || !finite(*r.Room) || !finite(*r.Floor) {
35 return State{}, fmt.Errorf("gateway temperatures must be finite")
36 }
37
38 return State{
39 MAC: mac,
40 Power: *r.Power == 1,
41 TargetTemperature: *r.Target,
42 CurrentTemperature: *r.Room,
43 FloorTemperature: *r.Floor,
44 Active: *r.Active == 1,
45 Locked: *r.Locked == 1,
46 }, nil
47 }
48
49 func normalizeMAC(value string) (string, error) {
50 if len(value) != 12 {
51 return "", fmt.Errorf("MAC must contain twelve hexadecimal digits")
52 }
53
54 _, err := hex.DecodeString(value)
55 if err != nil {
56 return "", fmt.Errorf("MAC must contain twelve hexadecimal digits")
57 }
58
59 return strings.ToLower(value), nil
60 }
61
62 func binary(value int) bool {
63 return value == 0 || value == 1
64 }
65
66 func finite(value float64) bool {
67 return !math.IsNaN(value) && !math.IsInf(value, 0)
68 }