mirror of
https://github.com/Xevion/go-ha.git
synced 2025-12-05 23:15:07 -06:00
Merge pull request #24 from metalmatze/service-errors
Return Service errors
This commit is contained in:
2
app.go
2
app.go
@@ -123,7 +123,7 @@ func NewApp(request NewAppRequest) (*App, error) {
|
||||
httpClient := http.NewHttpClient(baseURL, request.HAAuthToken)
|
||||
|
||||
wsWriter := &ws.WebsocketWriter{Conn: conn}
|
||||
service := newService(wsWriter, ctx, httpClient)
|
||||
service := newService(wsWriter)
|
||||
state, err := newState(httpClient, request.HomeZoneEntityId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,7 +8,6 @@ import (
|
||||
|
||||
type AlarmControlPanel struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
@@ -18,7 +15,7 @@ type AlarmControlPanel struct {
|
||||
// Send the alarm the command for arm away.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) ArmAway(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) ArmAway(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_arm_away"
|
||||
@@ -26,13 +23,13 @@ func (acp AlarmControlPanel) ArmAway(entityId string, serviceData ...map[string]
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the alarm the command for arm away.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) ArmWithCustomBypass(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) ArmWithCustomBypass(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_arm_custom_bypass"
|
||||
@@ -40,13 +37,13 @@ func (acp AlarmControlPanel) ArmWithCustomBypass(entityId string, serviceData ..
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the alarm the command for arm home.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) ArmHome(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) ArmHome(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_arm_home"
|
||||
@@ -54,13 +51,13 @@ func (acp AlarmControlPanel) ArmHome(entityId string, serviceData ...map[string]
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the alarm the command for arm night.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) ArmNight(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) ArmNight(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_arm_night"
|
||||
@@ -68,13 +65,13 @@ func (acp AlarmControlPanel) ArmNight(entityId string, serviceData ...map[string
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the alarm the command for arm vacation.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) ArmVacation(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) ArmVacation(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_arm_vacation"
|
||||
@@ -82,13 +79,13 @@ func (acp AlarmControlPanel) ArmVacation(entityId string, serviceData ...map[str
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the alarm the command for disarm.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) Disarm(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) Disarm(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_disarm"
|
||||
@@ -96,13 +93,13 @@ func (acp AlarmControlPanel) Disarm(entityId string, serviceData ...map[string]a
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the alarm the command for trigger.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (acp AlarmControlPanel) Trigger(entityId string, serviceData ...map[string]any) {
|
||||
func (acp AlarmControlPanel) Trigger(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "alarm_control_panel"
|
||||
req.Service = "alarm_trigger"
|
||||
@@ -110,5 +107,5 @@ func (acp AlarmControlPanel) Trigger(entityId string, serviceData ...map[string]
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
acp.conn.WriteMessage(req, acp.ctx)
|
||||
return acp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
"saml.dev/gome-assistant/types"
|
||||
)
|
||||
@@ -11,25 +9,24 @@ import (
|
||||
|
||||
type Climate struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (c Climate) SetFanMode(entityId string, fanMode string) {
|
||||
func (c Climate) SetFanMode(entityId string, fanMode string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "climate"
|
||||
req.Service = "set_fan_mode"
|
||||
req.ServiceData = map[string]any{"fan_mode": fanMode}
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (c Climate) SetTemperature(entityId string, serviceData types.SetTemperatureRequest) {
|
||||
func (c Climate) SetTemperature(entityId string, serviceData types.SetTemperatureRequest) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "climate"
|
||||
req.Service = "set_temperature"
|
||||
req.ServiceData = serviceData.ToJSON()
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,50 +8,49 @@ import (
|
||||
|
||||
type Cover struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Close all or specified cover. Takes an entityId.
|
||||
func (c Cover) Close(entityId string) {
|
||||
func (c Cover) Close(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "close_cover"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Close all or specified cover tilt. Takes an entityId.
|
||||
func (c Cover) CloseTilt(entityId string) {
|
||||
func (c Cover) CloseTilt(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "close_cover_tilt"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Open all or specified cover. Takes an entityId.
|
||||
func (c Cover) Open(entityId string) {
|
||||
func (c Cover) Open(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "open_cover"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Open all or specified cover tilt. Takes an entityId.
|
||||
func (c Cover) OpenTilt(entityId string) {
|
||||
func (c Cover) OpenTilt(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "open_cover_tilt"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Move to specific position all or specified cover. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (c Cover) SetPosition(entityId string, serviceData ...map[string]any) {
|
||||
func (c Cover) SetPosition(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "set_cover_position"
|
||||
@@ -61,12 +58,12 @@ func (c Cover) SetPosition(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Move to specific position all or specified cover tilt. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (c Cover) SetTiltPosition(entityId string, serviceData ...map[string]any) {
|
||||
func (c Cover) SetTiltPosition(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "set_cover_tilt_position"
|
||||
@@ -74,41 +71,41 @@ func (c Cover) SetTiltPosition(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Stop a cover entity. Takes an entityId.
|
||||
func (c Cover) Stop(entityId string) {
|
||||
func (c Cover) Stop(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "stop_cover"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Stop a cover entity tilt. Takes an entityId.
|
||||
func (c Cover) StopTilt(entityId string) {
|
||||
func (c Cover) StopTilt(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "stop_cover_tilt"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggle a cover open/closed. Takes an entityId.
|
||||
func (c Cover) Toggle(entityId string) {
|
||||
func (c Cover) Toggle(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "toggle"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggle a cover tilt open/closed. Takes an entityId.
|
||||
func (c Cover) ToggleTilt(entityId string) {
|
||||
func (c Cover) ToggleTilt(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "cover"
|
||||
req.Service = "toggle_cover_tilt"
|
||||
|
||||
c.conn.WriteMessage(req, c.ctx)
|
||||
return c.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"saml.dev/gome-assistant/internal"
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Fire an event
|
||||
@@ -24,7 +21,7 @@ type FireEventRequest struct {
|
||||
|
||||
// Fire an event. Takes an event type and an optional map that is sent
|
||||
// as `event_data`.
|
||||
func (e Event) Fire(eventType string, eventData ...map[string]any) {
|
||||
func (e Event) Fire(eventType string, eventData ...map[string]any) error {
|
||||
req := FireEventRequest{
|
||||
Id: internal.GetId(),
|
||||
Type: "fire_event",
|
||||
@@ -35,5 +32,5 @@ func (e Event) Fire(eventType string, eventData ...map[string]any) {
|
||||
req.EventData = eventData[0]
|
||||
}
|
||||
|
||||
e.conn.WriteMessage(req, e.ctx)
|
||||
return e.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
type HomeAssistant struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// TurnOn a Home Assistant entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (ha *HomeAssistant) TurnOn(entityId string, serviceData ...map[string]any) {
|
||||
func (ha *HomeAssistant) TurnOn(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "homeassistant"
|
||||
req.Service = "turn_on"
|
||||
@@ -21,12 +18,12 @@ func (ha *HomeAssistant) TurnOn(entityId string, serviceData ...map[string]any)
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
ha.conn.WriteMessage(req, ha.ctx)
|
||||
return ha.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggle a Home Assistant entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (ha *HomeAssistant) Toggle(entityId string, serviceData ...map[string]any) {
|
||||
func (ha *HomeAssistant) Toggle(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "homeassistant"
|
||||
req.Service = "toggle"
|
||||
@@ -34,13 +31,13 @@ func (ha *HomeAssistant) Toggle(entityId string, serviceData ...map[string]any)
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
ha.conn.WriteMessage(req, ha.ctx)
|
||||
return ha.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ha *HomeAssistant) TurnOff(entityId string) {
|
||||
func (ha *HomeAssistant) TurnOff(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "homeassistant"
|
||||
req.Service = "turn_off"
|
||||
|
||||
ha.conn.WriteMessage(req, ha.ctx)
|
||||
return ha.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,37 +8,36 @@ import (
|
||||
|
||||
type InputBoolean struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (ib InputBoolean) TurnOn(entityId string) {
|
||||
func (ib InputBoolean) TurnOn(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_boolean"
|
||||
req.Service = "turn_on"
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputBoolean) Toggle(entityId string) {
|
||||
func (ib InputBoolean) Toggle(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_boolean"
|
||||
req.Service = "toggle"
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputBoolean) TurnOff(entityId string) {
|
||||
func (ib InputBoolean) TurnOff(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_boolean"
|
||||
req.Service = "turn_off"
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputBoolean) Reload() {
|
||||
func (ib InputBoolean) Reload() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "input_boolean"
|
||||
req.Service = "reload"
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,22 +8,21 @@ import (
|
||||
|
||||
type InputButton struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (ib InputButton) Press(entityId string) {
|
||||
func (ib InputButton) Press(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_button"
|
||||
req.Service = "press"
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputButton) Reload() {
|
||||
func (ib InputButton) Reload() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "input_button"
|
||||
req.Service = "reload"
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -12,12 +11,11 @@ import (
|
||||
|
||||
type InputDatetime struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (ib InputDatetime) Set(entityId string, value time.Time) {
|
||||
func (ib InputDatetime) Set(entityId string, value time.Time) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_datetime"
|
||||
req.Service = "set_datetime"
|
||||
@@ -25,12 +23,12 @@ func (ib InputDatetime) Set(entityId string, value time.Time) {
|
||||
"timestamp": fmt.Sprint(value.Unix()),
|
||||
}
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputDatetime) Reload() {
|
||||
func (ib InputDatetime) Reload() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "input_datetime"
|
||||
req.Service = "reload"
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,39 +8,38 @@ import (
|
||||
|
||||
type InputNumber struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (ib InputNumber) Set(entityId string, value float32) {
|
||||
func (ib InputNumber) Set(entityId string, value float32) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_number"
|
||||
req.Service = "set_value"
|
||||
req.ServiceData = map[string]any{"value": value}
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputNumber) Increment(entityId string) {
|
||||
func (ib InputNumber) Increment(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_number"
|
||||
req.Service = "increment"
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputNumber) Decrement(entityId string) {
|
||||
func (ib InputNumber) Decrement(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_number"
|
||||
req.Service = "decrement"
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputNumber) Reload() {
|
||||
func (ib InputNumber) Reload() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "input_number"
|
||||
req.Service = "reload"
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,12 +8,11 @@ import (
|
||||
|
||||
type InputText struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (ib InputText) Set(entityId string, value string) {
|
||||
func (ib InputText) Set(entityId string, value string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "input_text"
|
||||
req.Service = "set_value"
|
||||
@@ -23,12 +20,12 @@ func (ib InputText) Set(entityId string, value string) {
|
||||
"value": value,
|
||||
}
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib InputText) Reload() {
|
||||
func (ib InputText) Reload() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "input_text"
|
||||
req.Service = "reload"
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,14 +8,13 @@ import (
|
||||
|
||||
type Light struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// TurnOn a light entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (l Light) TurnOn(entityId string, serviceData ...map[string]any) {
|
||||
func (l Light) TurnOn(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "light"
|
||||
req.Service = "turn_on"
|
||||
@@ -25,12 +22,12 @@ func (l Light) TurnOn(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
l.conn.WriteMessage(req, l.ctx)
|
||||
return l.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggle a light entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (l Light) Toggle(entityId string, serviceData ...map[string]any) {
|
||||
func (l Light) Toggle(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "light"
|
||||
req.Service = "toggle"
|
||||
@@ -38,12 +35,12 @@ func (l Light) Toggle(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
l.conn.WriteMessage(req, l.ctx)
|
||||
return l.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (l Light) TurnOff(entityId string) {
|
||||
func (l Light) TurnOff(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "light"
|
||||
req.Service = "turn_off"
|
||||
l.conn.WriteMessage(req, l.ctx)
|
||||
return l.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,14 +8,13 @@ import (
|
||||
|
||||
type Lock struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Lock a lock entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (l Lock) Lock(entityId string, serviceData ...map[string]any) {
|
||||
func (l Lock) Lock(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "lock"
|
||||
req.Service = "lock"
|
||||
@@ -25,12 +22,12 @@ func (l Lock) Lock(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
l.conn.WriteMessage(req, l.ctx)
|
||||
return l.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Unlock a lock entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (l Lock) Unlock(entityId string, serviceData ...map[string]any) {
|
||||
func (l Lock) Unlock(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "lock"
|
||||
req.Service = "unlock"
|
||||
@@ -38,5 +35,5 @@ func (l Lock) Unlock(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
l.conn.WriteMessage(req, l.ctx)
|
||||
return l.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,25 +8,24 @@ import (
|
||||
|
||||
type MediaPlayer struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Send the media player the command to clear players playlist.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) ClearPlaylist(entityId string) {
|
||||
func (mp MediaPlayer) ClearPlaylist(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "clear_playlist"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Group players together. Only works on platforms with support for player groups.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) Join(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) Join(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "join"
|
||||
@@ -36,63 +33,63 @@ func (mp MediaPlayer) Join(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command for next track.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Next(entityId string) {
|
||||
func (mp MediaPlayer) Next(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_next_track"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command for pause.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Pause(entityId string) {
|
||||
func (mp MediaPlayer) Pause(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_pause"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command for play.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Play(entityId string) {
|
||||
func (mp MediaPlayer) Play(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_play"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggle media player play/pause state.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) PlayPause(entityId string) {
|
||||
func (mp MediaPlayer) PlayPause(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_play_pause"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command for previous track.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Previous(entityId string) {
|
||||
func (mp MediaPlayer) Previous(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_previous_track"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command to seek in current playing media.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) Seek(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) Seek(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_seek"
|
||||
@@ -100,23 +97,23 @@ func (mp MediaPlayer) Seek(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the stop command.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Stop(entityId string) {
|
||||
func (mp MediaPlayer) Stop(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "media_stop"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command for playing media.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) PlayMedia(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) PlayMedia(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "play_media"
|
||||
@@ -124,12 +121,12 @@ func (mp MediaPlayer) PlayMedia(entityId string, serviceData ...map[string]any)
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Set repeat mode. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) RepeatSet(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) RepeatSet(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "repeat_set"
|
||||
@@ -137,13 +134,13 @@ func (mp MediaPlayer) RepeatSet(entityId string, serviceData ...map[string]any)
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command to change sound mode.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) SelectSoundMode(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) SelectSoundMode(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "select_sound_mode"
|
||||
@@ -151,13 +148,13 @@ func (mp MediaPlayer) SelectSoundMode(entityId string, serviceData ...map[string
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send the media player the command to change input source.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) SelectSource(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) SelectSource(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "select_source"
|
||||
@@ -165,13 +162,13 @@ func (mp MediaPlayer) SelectSource(entityId string, serviceData ...map[string]an
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Set shuffling state.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) Shuffle(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) Shuffle(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "shuffle_set"
|
||||
@@ -179,64 +176,64 @@ func (mp MediaPlayer) Shuffle(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggles a media player power state.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Toggle(entityId string) {
|
||||
func (mp MediaPlayer) Toggle(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "toggle"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Turn a media player power off.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) TurnOff(entityId string) {
|
||||
func (mp MediaPlayer) TurnOff(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "turn_off"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Turn a media player power on.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) TurnOn(entityId string) {
|
||||
func (mp MediaPlayer) TurnOn(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "turn_on"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Unjoin the player from a group. Only works on
|
||||
// platforms with support for player groups.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) Unjoin(entityId string) {
|
||||
func (mp MediaPlayer) Unjoin(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "unjoin"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Turn a media player volume down.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) VolumeDown(entityId string) {
|
||||
func (mp MediaPlayer) VolumeDown(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "volume_down"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Mute a media player's volume.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) VolumeMute(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) VolumeMute(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "volume_mute"
|
||||
@@ -244,13 +241,13 @@ func (mp MediaPlayer) VolumeMute(entityId string, serviceData ...map[string]any)
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Set a media player's volume level.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (mp MediaPlayer) VolumeSet(entityId string, serviceData ...map[string]any) {
|
||||
func (mp MediaPlayer) VolumeSet(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "volume_set"
|
||||
@@ -258,15 +255,15 @@ func (mp MediaPlayer) VolumeSet(entityId string, serviceData ...map[string]any)
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Turn a media player volume up.
|
||||
// Takes an entityId.
|
||||
func (mp MediaPlayer) VolumeUp(entityId string) {
|
||||
func (mp MediaPlayer) VolumeUp(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "media_player"
|
||||
req.Service = "volume_up"
|
||||
|
||||
mp.conn.WriteMessage(req, mp.ctx)
|
||||
return mp.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
"saml.dev/gome-assistant/types"
|
||||
)
|
||||
|
||||
type Notify struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// Send a notification. Takes a types.NotifyRequest.
|
||||
func (ha *Notify) Notify(reqData types.NotifyRequest) {
|
||||
// Notify sends a notification. Takes a types.NotifyRequest.
|
||||
func (ha *Notify) Notify(reqData types.NotifyRequest) error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "notify"
|
||||
req.Service = reqData.ServiceName
|
||||
@@ -26,5 +23,5 @@ func (ha *Notify) Notify(reqData types.NotifyRequest) {
|
||||
}
|
||||
|
||||
req.ServiceData = serviceData
|
||||
ha.conn.WriteMessage(req, ha.ctx)
|
||||
return ha.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,25 +1,24 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
/* Structs */
|
||||
|
||||
type Number struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (ib Number) SetValue(entityId string, value float32) {
|
||||
func (ib Number) SetValue(entityId string, value float32) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "number"
|
||||
req.Service = "set_value"
|
||||
req.ServiceData = map[string]any{"value": value}
|
||||
|
||||
ib.conn.WriteMessage(req, ib.ctx)
|
||||
return ib.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (ib Number) MustSetValue(entityId string, value float32) {
|
||||
if err := ib.SetValue(entityId, value); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,13 +8,12 @@ import (
|
||||
|
||||
type Scene struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Apply a scene. Takes map that is translated into service_data.
|
||||
func (s Scene) Apply(serviceData ...map[string]any) {
|
||||
func (s Scene) Apply(serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "scene"
|
||||
req.Service = "apply"
|
||||
@@ -24,12 +21,12 @@ func (s Scene) Apply(serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Create a scene entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (s Scene) Create(entityId string, serviceData ...map[string]any) {
|
||||
func (s Scene) Create(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "scene"
|
||||
req.Service = "create"
|
||||
@@ -37,21 +34,21 @@ func (s Scene) Create(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Reload the scenes.
|
||||
func (s Scene) Reload() {
|
||||
func (s Scene) Reload() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "scene"
|
||||
req.Service = "reload"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// TurnOn a scene entity. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (s Scene) TurnOn(entityId string, serviceData ...map[string]any) {
|
||||
func (s Scene) TurnOn(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "scene"
|
||||
req.Service = "turn_on"
|
||||
@@ -59,5 +56,5 @@ func (s Scene) TurnOn(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,43 +8,42 @@ import (
|
||||
|
||||
type Script struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Reload a script that was created in the HA UI.
|
||||
func (s Script) Reload(entityId string) {
|
||||
func (s Script) Reload(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "script"
|
||||
req.Service = "reload"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Toggle a script that was created in the HA UI.
|
||||
func (s Script) Toggle(entityId string) {
|
||||
func (s Script) Toggle(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "script"
|
||||
req.Service = "toggle"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Turn off a script that was created in the HA UI.
|
||||
func (s Script) TurnOff() {
|
||||
// TurnOff a script that was created in the HA UI.
|
||||
func (s Script) TurnOff() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "script"
|
||||
req.Service = "turn_off"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Turn on a script that was created in the HA UI.
|
||||
func (s Script) TurnOn(entityId string) {
|
||||
// TurnOn a script that was created in the HA UI.
|
||||
func (s Script) TurnOn(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "script"
|
||||
req.Service = "turn_on"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"saml.dev/gome-assistant/internal"
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
@@ -29,8 +27,8 @@ func BuildService[
|
||||
TTS |
|
||||
Vacuum |
|
||||
ZWaveJS,
|
||||
](conn *ws.WebsocketWriter, ctx context.Context) *T {
|
||||
return &T{conn: conn, ctx: ctx}
|
||||
](conn *ws.WebsocketWriter) *T {
|
||||
return &T{conn: conn}
|
||||
}
|
||||
|
||||
type BaseServiceRequest struct {
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,30 +8,30 @@ import (
|
||||
|
||||
type Switch struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
func (s Switch) TurnOn(entityId string) {
|
||||
func (s Switch) TurnOn(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "switch"
|
||||
req.Service = "turn_on"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (s Switch) Toggle(entityId string) {
|
||||
func (s Switch) Toggle(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "switch"
|
||||
req.Service = "toggle"
|
||||
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
func (s Switch) TurnOff(entityId string) {
|
||||
func (s Switch) TurnOff(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "switch"
|
||||
req.Service = "turn_off"
|
||||
s.conn.WriteMessage(req, s.ctx)
|
||||
|
||||
return s.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,24 +8,23 @@ import (
|
||||
|
||||
type TTS struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Remove all text-to-speech cache files and RAM cache.
|
||||
func (tts TTS) ClearCache() {
|
||||
func (tts TTS) ClearCache() error {
|
||||
req := NewBaseServiceRequest("")
|
||||
req.Domain = "tts"
|
||||
req.Service = "clear_cache"
|
||||
|
||||
tts.conn.WriteMessage(req, tts.ctx)
|
||||
return tts.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Say something using text-to-speech on a media player with cloud.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (tts TTS) CloudSay(entityId string, serviceData ...map[string]any) {
|
||||
func (tts TTS) CloudSay(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "tts"
|
||||
req.Service = "cloud_say"
|
||||
@@ -35,13 +32,13 @@ func (tts TTS) CloudSay(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
tts.conn.WriteMessage(req, tts.ctx)
|
||||
return tts.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Say something using text-to-speech on a media player with google_translate.
|
||||
// Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (tts TTS) GoogleTranslateSay(entityId string, serviceData ...map[string]any) {
|
||||
func (tts TTS) GoogleTranslateSay(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "tts"
|
||||
req.Service = "google_translate_say"
|
||||
@@ -49,5 +46,5 @@ func (tts TTS) GoogleTranslateSay(entityId string, serviceData ...map[string]any
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
tts.conn.WriteMessage(req, tts.ctx)
|
||||
return tts.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,54 +8,53 @@ import (
|
||||
|
||||
type Vacuum struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// Tell the vacuum cleaner to do a spot clean-up.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) CleanSpot(entityId string) {
|
||||
func (v Vacuum) CleanSpot(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "clean_spot"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Locate the vacuum cleaner robot.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) Locate(entityId string) {
|
||||
func (v Vacuum) Locate(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "locate"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Pause the cleaning task.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) Pause(entityId string) {
|
||||
func (v Vacuum) Pause(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "pause"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Tell the vacuum cleaner to return to its dock.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) ReturnToBase(entityId string) {
|
||||
func (v Vacuum) ReturnToBase(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "return_to_base"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Send a raw command to the vacuum cleaner. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (v Vacuum) SendCommand(entityId string, serviceData ...map[string]any) {
|
||||
func (v Vacuum) SendCommand(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "send_command"
|
||||
@@ -65,12 +62,12 @@ func (v Vacuum) SendCommand(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Set the fan speed of the vacuum cleaner. Takes an entityId and an optional
|
||||
// map that is translated into service_data.
|
||||
func (v Vacuum) SetFanSpeed(entityId string, serviceData ...map[string]any) {
|
||||
func (v Vacuum) SetFanSpeed(entityId string, serviceData ...map[string]any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "set_fan_speed"
|
||||
@@ -79,55 +76,55 @@ func (v Vacuum) SetFanSpeed(entityId string, serviceData ...map[string]any) {
|
||||
req.ServiceData = serviceData[0]
|
||||
}
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Start or resume the cleaning task.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) Start(entityId string) {
|
||||
func (v Vacuum) Start(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "start"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Start, pause, or resume the cleaning task.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) StartPause(entityId string) {
|
||||
func (v Vacuum) StartPause(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "start_pause"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Stop the current cleaning task.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) Stop(entityId string) {
|
||||
func (v Vacuum) Stop(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "stop"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Stop the current cleaning task and return to home.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) TurnOff(entityId string) {
|
||||
func (v Vacuum) TurnOff(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "turn_off"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
// Start a new cleaning task.
|
||||
// Takes an entityId.
|
||||
func (v Vacuum) TurnOn(entityId string) {
|
||||
func (v Vacuum) TurnOn(entityId string) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "vacuum"
|
||||
req.Service = "turn_on"
|
||||
|
||||
v.conn.WriteMessage(req, v.ctx)
|
||||
return v.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
|
||||
@@ -10,13 +8,12 @@ import (
|
||||
|
||||
type ZWaveJS struct {
|
||||
conn *ws.WebsocketWriter
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
/* Public API */
|
||||
|
||||
// ZWaveJS bulk_set_partial_config_parameters service.
|
||||
func (zw ZWaveJS) BulkSetPartialConfigParam(entityId string, parameter int, value any) {
|
||||
func (zw ZWaveJS) BulkSetPartialConfigParam(entityId string, parameter int, value any) error {
|
||||
req := NewBaseServiceRequest(entityId)
|
||||
req.Domain = "zwave_js"
|
||||
req.Service = "bulk_set_partial_config_parameters"
|
||||
@@ -25,5 +22,5 @@ func (zw ZWaveJS) BulkSetPartialConfigParam(entityId string, parameter int, valu
|
||||
"value": value,
|
||||
}
|
||||
|
||||
zw.conn.WriteMessage(req, zw.ctx)
|
||||
return zw.conn.WriteMessage(req)
|
||||
}
|
||||
|
||||
@@ -23,9 +23,9 @@ type ChanMsg struct {
|
||||
|
||||
func ListenWebsocket(conn *websocket.Conn, ctx context.Context, c chan ChanMsg) {
|
||||
for {
|
||||
bytes, err := ReadMessage(conn, ctx)
|
||||
bytes, err := ReadMessage(conn)
|
||||
if err != nil {
|
||||
slog.Error("Error reading from websocket:", err)
|
||||
slog.Error("Error reading from websocket", "err", err)
|
||||
close(c)
|
||||
break
|
||||
}
|
||||
|
||||
@@ -31,19 +31,14 @@ type WebsocketWriter struct {
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func (w *WebsocketWriter) WriteMessage(msg interface{}, ctx context.Context) error {
|
||||
func (w *WebsocketWriter) WriteMessage(msg any) error {
|
||||
w.mutex.Lock()
|
||||
defer w.mutex.Unlock()
|
||||
|
||||
err := w.Conn.WriteJSON(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return w.Conn.WriteJSON(msg)
|
||||
}
|
||||
|
||||
func ReadMessage(conn *websocket.Conn, ctx context.Context) ([]byte, error) {
|
||||
func ReadMessage(conn *websocket.Conn) ([]byte, error) {
|
||||
_, msg, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
return []byte{}, err
|
||||
@@ -73,7 +68,7 @@ func ConnectionFromUri(baseURL *url.URL, authToken string) (*websocket.Conn, con
|
||||
}
|
||||
|
||||
// Read auth_required message
|
||||
_, err = ReadMessage(conn, ctx)
|
||||
_, err = ReadMessage(conn)
|
||||
if err != nil {
|
||||
ctxCancel()
|
||||
slog.Error("Unknown error creating websocket client\n")
|
||||
@@ -113,7 +108,7 @@ type authResponse struct {
|
||||
}
|
||||
|
||||
func VerifyAuthResponse(conn *websocket.Conn, ctx context.Context) error {
|
||||
msg, err := ReadMessage(conn, ctx)
|
||||
msg, err := ReadMessage(conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -150,7 +145,7 @@ func SubscribeToEventType(eventType string, conn *WebsocketWriter, ctx context.C
|
||||
Type: "subscribe_events",
|
||||
EventType: eventType,
|
||||
}
|
||||
err := conn.WriteMessage(e, ctx)
|
||||
err := conn.WriteMessage(e)
|
||||
if err != nil {
|
||||
wrappedErr := fmt.Errorf("error writing to websocket: %w", err)
|
||||
slog.Error(wrappedErr.Error())
|
||||
|
||||
47
service.go
47
service.go
@@ -1,9 +1,6 @@
|
||||
package gomeassistant
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"saml.dev/gome-assistant/internal/http"
|
||||
"saml.dev/gome-assistant/internal/services"
|
||||
ws "saml.dev/gome-assistant/internal/websocket"
|
||||
)
|
||||
@@ -32,28 +29,28 @@ type Service struct {
|
||||
ZWaveJS *services.ZWaveJS
|
||||
}
|
||||
|
||||
func newService(conn *ws.WebsocketWriter, ctx context.Context, httpClient *http.HttpClient) *Service {
|
||||
func newService(conn *ws.WebsocketWriter) *Service {
|
||||
return &Service{
|
||||
AlarmControlPanel: services.BuildService[services.AlarmControlPanel](conn, ctx),
|
||||
Climate: services.BuildService[services.Climate](conn, ctx),
|
||||
Cover: services.BuildService[services.Cover](conn, ctx),
|
||||
Light: services.BuildService[services.Light](conn, ctx),
|
||||
HomeAssistant: services.BuildService[services.HomeAssistant](conn, ctx),
|
||||
Lock: services.BuildService[services.Lock](conn, ctx),
|
||||
MediaPlayer: services.BuildService[services.MediaPlayer](conn, ctx),
|
||||
Switch: services.BuildService[services.Switch](conn, ctx),
|
||||
InputBoolean: services.BuildService[services.InputBoolean](conn, ctx),
|
||||
InputButton: services.BuildService[services.InputButton](conn, ctx),
|
||||
InputText: services.BuildService[services.InputText](conn, ctx),
|
||||
InputDatetime: services.BuildService[services.InputDatetime](conn, ctx),
|
||||
InputNumber: services.BuildService[services.InputNumber](conn, ctx),
|
||||
Event: services.BuildService[services.Event](conn, ctx),
|
||||
Notify: services.BuildService[services.Notify](conn, ctx),
|
||||
Number: services.BuildService[services.Number](conn, ctx),
|
||||
Scene: services.BuildService[services.Scene](conn, ctx),
|
||||
Script: services.BuildService[services.Script](conn, ctx),
|
||||
TTS: services.BuildService[services.TTS](conn, ctx),
|
||||
Vacuum: services.BuildService[services.Vacuum](conn, ctx),
|
||||
ZWaveJS: services.BuildService[services.ZWaveJS](conn, ctx),
|
||||
AlarmControlPanel: services.BuildService[services.AlarmControlPanel](conn),
|
||||
Climate: services.BuildService[services.Climate](conn),
|
||||
Cover: services.BuildService[services.Cover](conn),
|
||||
Light: services.BuildService[services.Light](conn),
|
||||
HomeAssistant: services.BuildService[services.HomeAssistant](conn),
|
||||
Lock: services.BuildService[services.Lock](conn),
|
||||
MediaPlayer: services.BuildService[services.MediaPlayer](conn),
|
||||
Switch: services.BuildService[services.Switch](conn),
|
||||
InputBoolean: services.BuildService[services.InputBoolean](conn),
|
||||
InputButton: services.BuildService[services.InputButton](conn),
|
||||
InputText: services.BuildService[services.InputText](conn),
|
||||
InputDatetime: services.BuildService[services.InputDatetime](conn),
|
||||
InputNumber: services.BuildService[services.InputNumber](conn),
|
||||
Event: services.BuildService[services.Event](conn),
|
||||
Notify: services.BuildService[services.Notify](conn),
|
||||
Number: services.BuildService[services.Number](conn),
|
||||
Scene: services.BuildService[services.Scene](conn),
|
||||
Script: services.BuildService[services.Script](conn),
|
||||
TTS: services.BuildService[services.TTS](conn),
|
||||
Vacuum: services.BuildService[services.Vacuum](conn),
|
||||
ZWaveJS: services.BuildService[services.ZWaveJS](conn),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user