From 02b6c413f16ba2cb0ee064af007dabc1a11a54fc Mon Sep 17 00:00:00 2001 From: Matthias Loibl Date: Fri, 17 Jan 2025 17:50:06 +0100 Subject: [PATCH] Return Service errors Additionally, removed the context that gets passed into the Services but isn't used in one of them. The websockets APIs also don't have any use for context. --- app.go | 2 +- internal/services/alarm_control_panel.go | 31 ++++---- internal/services/climate.go | 11 ++- internal/services/cover.go | 43 ++++++----- internal/services/event.go | 7 +- internal/services/homeassistant.go | 15 ++-- internal/services/input_boolean.go | 19 +++-- internal/services/input_button.go | 11 ++- internal/services/input_datetime.go | 10 ++- internal/services/input_number.go | 19 +++-- internal/services/input_text.go | 11 ++- internal/services/light.go | 15 ++-- internal/services/lock.go | 11 ++- internal/services/media_player.go | 91 ++++++++++++------------ internal/services/notify.go | 9 +-- internal/services/number.go | 17 +++-- internal/services/scene.go | 19 +++-- internal/services/script.go | 23 +++--- internal/services/services.go | 6 +- internal/services/switch.go | 16 ++--- internal/services/tts.go | 15 ++-- internal/services/vacuum.go | 47 ++++++------ internal/services/zwavejs.go | 7 +- internal/websocket/reader.go | 4 +- internal/websocket/websocket.go | 18 ++--- service.go | 47 ++++++------ 26 files changed, 228 insertions(+), 296 deletions(-) diff --git a/app.go b/app.go index 4cd6e79..fa36255 100644 --- a/app.go +++ b/app.go @@ -125,7 +125,7 @@ func NewApp(request NewAppRequest) (*App, error) { } 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 diff --git a/internal/services/alarm_control_panel.go b/internal/services/alarm_control_panel.go index 5b0756e..33698d7 100644 --- a/internal/services/alarm_control_panel.go +++ b/internal/services/alarm_control_panel.go @@ -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) } diff --git a/internal/services/climate.go b/internal/services/climate.go index 797215f..6e00a55 100644 --- a/internal/services/climate.go +++ b/internal/services/climate.go @@ -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) } diff --git a/internal/services/cover.go b/internal/services/cover.go index 8fb6e75..b1f72e1 100644 --- a/internal/services/cover.go +++ b/internal/services/cover.go @@ -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) } diff --git a/internal/services/event.go b/internal/services/event.go index 9205db1..6d9ddad 100644 --- a/internal/services/event.go +++ b/internal/services/event.go @@ -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) } diff --git a/internal/services/homeassistant.go b/internal/services/homeassistant.go index 8400509..3e119ac 100644 --- a/internal/services/homeassistant.go +++ b/internal/services/homeassistant.go @@ -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) } diff --git a/internal/services/input_boolean.go b/internal/services/input_boolean.go index ac589f7..4eef1af 100644 --- a/internal/services/input_boolean.go +++ b/internal/services/input_boolean.go @@ -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) } diff --git a/internal/services/input_button.go b/internal/services/input_button.go index e0ec541..c574dbb 100644 --- a/internal/services/input_button.go +++ b/internal/services/input_button.go @@ -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) } diff --git a/internal/services/input_datetime.go b/internal/services/input_datetime.go index 92c12d5..1e8a7fe 100644 --- a/internal/services/input_datetime.go +++ b/internal/services/input_datetime.go @@ -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) } diff --git a/internal/services/input_number.go b/internal/services/input_number.go index 59409f6..a81b494 100644 --- a/internal/services/input_number.go +++ b/internal/services/input_number.go @@ -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) } diff --git a/internal/services/input_text.go b/internal/services/input_text.go index b7a0d1a..4e45b06 100644 --- a/internal/services/input_text.go +++ b/internal/services/input_text.go @@ -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) } diff --git a/internal/services/light.go b/internal/services/light.go index c1a2179..cea5bc1 100644 --- a/internal/services/light.go +++ b/internal/services/light.go @@ -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) } diff --git a/internal/services/lock.go b/internal/services/lock.go index e122b25..862aad2 100644 --- a/internal/services/lock.go +++ b/internal/services/lock.go @@ -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) } diff --git a/internal/services/media_player.go b/internal/services/media_player.go index 727d7a9..a8a9d1d 100644 --- a/internal/services/media_player.go +++ b/internal/services/media_player.go @@ -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) } diff --git a/internal/services/notify.go b/internal/services/notify.go index e76dd42..6d87c58 100644 --- a/internal/services/notify.go +++ b/internal/services/notify.go @@ -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) } diff --git a/internal/services/number.go b/internal/services/number.go index 243603e..addac70 100644 --- a/internal/services/number.go +++ b/internal/services/number.go @@ -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) + } } diff --git a/internal/services/scene.go b/internal/services/scene.go index e17ada9..3d180a6 100644 --- a/internal/services/scene.go +++ b/internal/services/scene.go @@ -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) } diff --git a/internal/services/script.go b/internal/services/script.go index b80dbbb..4537a85 100644 --- a/internal/services/script.go +++ b/internal/services/script.go @@ -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) } diff --git a/internal/services/services.go b/internal/services/services.go index 6dbb024..dab7c57 100644 --- a/internal/services/services.go +++ b/internal/services/services.go @@ -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 { diff --git a/internal/services/switch.go b/internal/services/switch.go index 0e7be52..b2bd431 100644 --- a/internal/services/switch.go +++ b/internal/services/switch.go @@ -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) } diff --git a/internal/services/tts.go b/internal/services/tts.go index 74b4963..9d1c439 100644 --- a/internal/services/tts.go +++ b/internal/services/tts.go @@ -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) } diff --git a/internal/services/vacuum.go b/internal/services/vacuum.go index fbc71b0..ad97a87 100644 --- a/internal/services/vacuum.go +++ b/internal/services/vacuum.go @@ -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) } diff --git a/internal/services/zwavejs.go b/internal/services/zwavejs.go index f19fc6f..b18751b 100644 --- a/internal/services/zwavejs.go +++ b/internal/services/zwavejs.go @@ -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) } diff --git a/internal/websocket/reader.go b/internal/websocket/reader.go index 6ac4640..93cbe86 100644 --- a/internal/websocket/reader.go +++ b/internal/websocket/reader.go @@ -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 } diff --git a/internal/websocket/websocket.go b/internal/websocket/websocket.go index 2eec28b..edce1ba 100644 --- a/internal/websocket/websocket.go +++ b/internal/websocket/websocket.go @@ -14,6 +14,7 @@ import ( "time" "github.com/gorilla/websocket" + i "saml.dev/gome-assistant/internal" ) @@ -29,19 +30,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 @@ -72,7 +68,7 @@ func ConnectionFromUri(uri, authToken string) (*websocket.Conn, context.Context, } // Read auth_required message - _, err = ReadMessage(conn, ctx) + _, err = ReadMessage(conn) if err != nil { ctxCancel() slog.Error("Unknown error creating websocket client\n") @@ -112,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 } @@ -149,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()) diff --git a/service.go b/service.go index c861ec7..7d243a3 100644 --- a/service.go +++ b/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), } }