@@ -2,6 +2,7 @@ package homeassistant
2
2
3
3
import (
4
4
"encoding/json"
5
+ "strings"
5
6
"time"
6
7
7
8
"github.com/mutablelogic/go-client/pkg/client"
@@ -17,6 +18,16 @@ type State struct {
17
18
Attributes map [string ]any `json:"attributes"`
18
19
}
19
20
21
+ type Sensor struct {
22
+ Type string `json:"type"`
23
+ Entity string `json:"entity_id"`
24
+ Name string `json:"friendly_name"`
25
+ Value string `json:"state,omitempty"`
26
+ Unit string `json:"unit_of_measurement,omitempty"`
27
+ Class string `json:"device_class,omitempty"`
28
+ LastChanged time.Time `json:"last_changed"`
29
+ }
30
+
20
31
///////////////////////////////////////////////////////////////////////////////
21
32
// API CALLS
22
33
@@ -33,10 +44,138 @@ func (c *Client) States() ([]State, error) {
33
44
return response , nil
34
45
}
35
46
47
+ // Sensors returns all sensor entities and their state
48
+ func (c * Client ) Sensors () ([]Sensor , error ) {
49
+ // Return the response
50
+ var response []State
51
+ payload := client .NewRequest (client .ContentTypeJson )
52
+ if err := c .Do (payload , & response , client .OptPath ("states" )); err != nil {
53
+ return nil , err
54
+ }
55
+
56
+ // Filter out sensors
57
+ var sensors []Sensor
58
+ for _ , state := range response {
59
+ if ! strings .HasPrefix (state .Entity , "sensor." ) && ! strings .HasPrefix (state .Entity , "binary_sensor." ) {
60
+ continue
61
+ }
62
+ sensors = append (sensors , Sensor {
63
+ Type : "sensor" ,
64
+ Entity : state .Entity ,
65
+ Name : state .Name (),
66
+ Value : state .State ,
67
+ Unit : state .UnitOfMeasurement (),
68
+ Class : state .DeviceClass (),
69
+ LastChanged : state .LastChanged ,
70
+ })
71
+ }
72
+
73
+ // Return success
74
+ return sensors , nil
75
+ }
76
+
77
+ // Actuators returns all button, switch and lock entities and their state
78
+ func (c * Client ) Actuators () ([]Sensor , error ) {
79
+ // Return the response
80
+ var response []State
81
+ payload := client .NewRequest (client .ContentTypeJson )
82
+ if err := c .Do (payload , & response , client .OptPath ("states" )); err != nil {
83
+ return nil , err
84
+ }
85
+
86
+ // Filter out buttons, locks, and switches
87
+ var sensors []Sensor
88
+ for _ , state := range response {
89
+ if ! strings .HasPrefix (state .Entity , "button." ) && ! strings .HasPrefix (state .Entity , "lock." ) && ! strings .HasPrefix (state .Entity , "switch." ) {
90
+ continue
91
+ }
92
+ sensors = append (sensors , Sensor {
93
+ Type : "actuator" ,
94
+ Entity : state .Entity ,
95
+ Name : state .Name (),
96
+ Value : state .State ,
97
+ Class : state .DeviceClass (),
98
+ LastChanged : state .LastChanged ,
99
+ })
100
+ }
101
+
102
+ // Return success
103
+ return sensors , nil
104
+ }
105
+
106
+ // Lights returns all light entities and their state
107
+ func (c * Client ) Lights () ([]Sensor , error ) {
108
+ // Return the response
109
+ var response []State
110
+ payload := client .NewRequest (client .ContentTypeJson )
111
+ if err := c .Do (payload , & response , client .OptPath ("states" )); err != nil {
112
+ return nil , err
113
+ }
114
+
115
+ // Filter out sensors
116
+ var lights []Sensor
117
+ for _ , state := range response {
118
+ if ! strings .HasPrefix (state .Entity , "light." ) {
119
+ continue
120
+ }
121
+ lights = append (lights , Sensor {
122
+ Type : "light" ,
123
+ Entity : state .Entity ,
124
+ Name : state .Name (),
125
+ Value : state .State ,
126
+ LastChanged : state .LastChanged ,
127
+ })
128
+ }
129
+
130
+ // Return success
131
+ return lights , nil
132
+ }
133
+
36
134
///////////////////////////////////////////////////////////////////////////////
37
135
// STRINGIFY
38
136
39
137
func (s State ) String () string {
40
138
data , _ := json .MarshalIndent (s , "" , " " )
41
139
return string (data )
42
140
}
141
+
142
+ func (s Sensor ) String () string {
143
+ data , _ := json .MarshalIndent (s , "" , " " )
144
+ return string (data )
145
+ }
146
+
147
+ ///////////////////////////////////////////////////////////////////////////////
148
+ // METHODS
149
+
150
+ func (s State ) Name () string {
151
+ name , ok := s .Attributes ["friendly_name" ]
152
+ if ! ok {
153
+ return s .Entity
154
+ } else if name_ , ok := name .(string ); ! ok {
155
+ return s .Entity
156
+ } else {
157
+ return name_
158
+ }
159
+ }
160
+
161
+ func (s State ) DeviceClass () string {
162
+ class , ok := s .Attributes ["device_class" ]
163
+ if ! ok {
164
+ return ""
165
+ } else if class_ , ok := class .(string ); ! ok {
166
+ return ""
167
+ } else {
168
+ return class_
169
+ }
170
+ }
171
+
172
+ func (s State ) UnitOfMeasurement () string {
173
+ unit , ok := s .Attributes ["unit_of_measurement" ]
174
+ if ! ok {
175
+ return ""
176
+ } else if unit_ , ok := unit .(string ); ! ok {
177
+ return ""
178
+ } else {
179
+ return unit_
180
+ }
181
+ }
0 commit comments