Skip to content

Commit 2dd9355

Browse files
committed
Updated
1 parent c727b3e commit 2dd9355

File tree

2 files changed

+178
-0
lines changed

2 files changed

+178
-0
lines changed

pkg/homeassistant/states.go

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package homeassistant
22

33
import (
44
"encoding/json"
5+
"strings"
56
"time"
67

78
"github.com/mutablelogic/go-client/pkg/client"
@@ -17,6 +18,16 @@ type State struct {
1718
Attributes map[string]any `json:"attributes"`
1819
}
1920

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+
2031
///////////////////////////////////////////////////////////////////////////////
2132
// API CALLS
2233

@@ -33,10 +44,138 @@ func (c *Client) States() ([]State, error) {
3344
return response, nil
3445
}
3546

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+
36134
///////////////////////////////////////////////////////////////////////////////
37135
// STRINGIFY
38136

39137
func (s State) String() string {
40138
data, _ := json.MarshalIndent(s, "", " ")
41139
return string(data)
42140
}
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+
}

pkg/homeassistant/states_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,42 @@ func Test_states_001(t *testing.T) {
2222

2323
t.Log(states)
2424
}
25+
26+
func Test_states_002(t *testing.T) {
27+
assert := assert.New(t)
28+
client, err := homeassistant.New(GetEndPoint(t), GetApiKey(t), opts.OptTrace(os.Stderr, true))
29+
assert.NoError(err)
30+
assert.NotNil(client)
31+
32+
sensors, err := client.Sensors()
33+
assert.NoError(err)
34+
assert.NotNil(sensors)
35+
36+
t.Log(sensors)
37+
}
38+
39+
func Test_states_003(t *testing.T) {
40+
assert := assert.New(t)
41+
client, err := homeassistant.New(GetEndPoint(t), GetApiKey(t), opts.OptTrace(os.Stderr, true))
42+
assert.NoError(err)
43+
assert.NotNil(client)
44+
45+
lights, err := client.Lights()
46+
assert.NoError(err)
47+
assert.NotNil(lights)
48+
49+
t.Log(lights)
50+
}
51+
52+
func Test_states_004(t *testing.T) {
53+
assert := assert.New(t)
54+
client, err := homeassistant.New(GetEndPoint(t), GetApiKey(t), opts.OptTrace(os.Stderr, true))
55+
assert.NoError(err)
56+
assert.NotNil(client)
57+
58+
actuators, err := client.Actuators()
59+
assert.NoError(err)
60+
assert.NotNil(actuators)
61+
62+
t.Log(actuators)
63+
}

0 commit comments

Comments
 (0)