]> git.giacomolli.uk - onehouse/blobdiff - protocol/address.go
Publish typed values with bounded repeat timing
[onehouse] / protocol / address.go
index 31d1b45741db4da93a90e855a957ec9af675dcb6..7786dfdfdb3d6c7f3f6bb38ddc255ff70b70d18f 100644 (file)
@@ -11,20 +11,28 @@ const (
 
        // Descriptor identifies retained device metadata.
        Descriptor Kind = "descriptor"
+
        // Availability identifies retained device reachability.
        Availability Kind = "availability"
+
        // Reported identifies a retained point value.
        Reported Kind = "reported"
+
        // Telemetry identifies a non-retained measurement.
        Telemetry Kind = "telemetry"
+
        // Event identifies a non-retained occurrence.
        Event Kind = "events"
+
        // Command identifies a non-retained point request.
        Command Kind = "commands"
+
        // CommandBatch identifies an ordered group of point requests.
        CommandBatch Kind = "batch"
+
        // Result identifies a command outcome.
        Result Kind = "results"
+
        // HubStatus identifies retained Zigbee hub diagnostics.
        HubStatus Kind = "status"
 )
@@ -40,8 +48,8 @@ type Address struct {
        Target string
 }
 
-// Topic validates the address and returns its exact publication topic.
-func (a Address) Topic() (string, error) {
+// topic validates the address and returns its exact publication topic.
+func (a Address) topic() (string, error) {
        if !ValidID(a.ID) {
                return "", fmt.Errorf("address ID must be a canonical ULID")
        }
@@ -80,8 +88,8 @@ func (a Address) Topic() (string, error) {
        return Root + "/devices/" + a.ID + "/" + string(a.Kind) + "/" + a.Target, nil
 }
 
-// ParseTopic rejects malformed topics, wildcards, and unsupported operations.
-func ParseTopic(topic string) (Address, error) {
+// parseTopic rejects malformed topics, wildcards, and unsupported operations.
+func parseTopic(topic string) (Address, error) {
        parts := strings.Split(topic, "/")
        if len(parts) < 5 || parts[0]+"/"+parts[1] != Root {
                return Address{}, fmt.Errorf("topic must use the versioned root")
@@ -91,9 +99,15 @@ func ParseTopic(topic string) (Address, error) {
 
        switch {
        case len(parts) == 6 && parts[2] == "zigbee" && parts[3] == "hubs" && parts[5] == "status":
-               address = Address{Kind: HubStatus, ID: parts[4]}
+               address = Address{
+                       Kind: HubStatus,
+                       ID:   parts[4],
+               }
        case (len(parts) == 5 || len(parts) == 6) && parts[2] == "devices":
-               address = Address{Kind: Kind(parts[4]), ID: parts[3]}
+               address = Address{
+                       Kind: Kind(parts[4]),
+                       ID:   parts[3],
+               }
                if len(parts) == 6 {
                        address.Target = parts[5]
                        if address.Kind == Command && address.Target == "$batch" {
@@ -105,7 +119,7 @@ func ParseTopic(topic string) (Address, error) {
                return Address{}, fmt.Errorf("topic layout is invalid")
        }
 
-       canonical, err := address.Topic()
+       canonical, err := address.topic()
        if err != nil {
                return Address{}, fmt.Errorf("validate topic address: %w", err)
        }
@@ -127,12 +141,30 @@ type Subscription struct {
 // house-state input. Telemetry uses QoS 0. Other subscriptions use QoS 1.
 func CoreSubscriptions() []Subscription {
        return []Subscription{
-               {Filter: Root + "/devices/+/descriptor", QoS: 1},
-               {Filter: Root + "/devices/+/availability", QoS: 1},
-               {Filter: Root + "/devices/+/reported/+", QoS: 1},
-               {Filter: Root + "/devices/+/telemetry/+", QoS: 0},
-               {Filter: Root + "/devices/+/events/+", QoS: 1},
-               {Filter: Root + "/devices/+/results/+", QoS: 1},
+               {
+                       Filter: Root + "/devices/+/descriptor",
+                       QoS:    1,
+               },
+               {
+                       Filter: Root + "/devices/+/availability",
+                       QoS:    1,
+               },
+               {
+                       Filter: Root + "/devices/+/reported/+",
+                       QoS:    1,
+               },
+               {
+                       Filter: Root + "/devices/+/telemetry/+",
+                       QoS:    0,
+               },
+               {
+                       Filter: Root + "/devices/+/events/+",
+                       QoS:    1,
+               },
+               {
+                       Filter: Root + "/devices/+/results/+",
+                       QoS:    1,
+               },
        }
 }
 
@@ -142,10 +174,16 @@ func CommandSubscription(deviceID string) (Subscription, error) {
                return Subscription{}, fmt.Errorf("device ID must be a canonical ULID")
        }
 
-       return Subscription{Filter: Root + "/devices/" + deviceID + "/commands/+", QoS: 1}, nil
+       return Subscription{
+               Filter: Root + "/devices/" + deviceID + "/commands/+",
+               QoS:    1,
+       }, nil
 }
 
 // HubStatusSubscription returns the filter for all Zigbee hub diagnostics.
 func HubStatusSubscription() Subscription {
-       return Subscription{Filter: Root + "/zigbee/hubs/+/status", QoS: 1}
+       return Subscription{
+               Filter: Root + "/zigbee/hubs/+/status",
+               QoS:    1,
+       }
 }