Skip to content

Commit

Permalink
Allow conditionally triggering different scenes
Browse files Browse the repository at this point in the history
  • Loading branch information
dansimau committed Dec 24, 2024
1 parent 4822c97 commit 9b1bc4c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
26 changes: 25 additions & 1 deletion automations/sensor_lights.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import (
"github.com/dansimau/hal"
)

type ConditionScene struct {
Condition func() bool
Scene map[string]any
}

// SensorsTriggerLights is an automation that combines one or more sensors
// (motion or presence sensors) and a set of lights. Lights are turned on when
// any of the sensors are triggered and turned off after a given duration.
Expand All @@ -15,6 +20,7 @@ type SensorsTriggerLights struct {
log *slog.Logger

condition func() bool // optional: func that must return true for the automation to run
conditionScene []ConditionScene
sensors []hal.EntityInterface
turnsOnLights []hal.LightInterface
turnsOffLights []hal.LightInterface
Expand All @@ -36,6 +42,16 @@ func (a *SensorsTriggerLights) WithCondition(condition func() bool) *SensorsTrig
return a
}

// WithConditionScene allows you to specify a scene to trigger based on a condition.
func (a *SensorsTriggerLights) WithConditionScene(condition func() bool, scene map[string]any) *SensorsTriggerLights {
a.conditionScene = append(a.conditionScene, ConditionScene{
Condition: condition,
Scene: scene,
})

return a
}

// WithLights sets the lights that will be turned on and off. Overrides
// TurnsOnLights and TurnsOffLights.
func (a *SensorsTriggerLights) WithLights(lights ...hal.LightInterface) *SensorsTriggerLights {
Expand Down Expand Up @@ -116,8 +132,16 @@ func (a *SensorsTriggerLights) stopTurnOffTimer() {
}

func (a *SensorsTriggerLights) turnOnLights() {
var attributes map[string]any

for _, conditionScene := range a.conditionScene {
if conditionScene.Condition() {
attributes = conditionScene.Scene
}
}

for _, light := range a.turnsOnLights {
if err := light.TurnOn(); err != nil {
if err := light.TurnOn(attributes); err != nil {
slog.Error("Error turning on light", "error", err)
}
}
Expand Down
22 changes: 15 additions & 7 deletions entity_light.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (

type LightInterface interface {
IsOn() bool
TurnOn() error
TurnOn(attributes ...map[string]any) error
TurnOff() error
}

Expand All @@ -25,7 +25,7 @@ func (l *Light) IsOn() bool {
return l.Entity.GetState().State == "on"
}

func (l *Light) TurnOn() error {
func (l *Light) TurnOn(attributes ...map[string]any) error {
if l.connection == nil {
slog.Error("Light not registered", "entity", l.GetID())

Expand All @@ -34,13 +34,21 @@ func (l *Light) TurnOn() error {

slog.Debug("Turning on light", "entity", l.GetID())

data := map[string]any{
"entity_id": []string{l.GetID()},
}

for _, attribute := range attributes {
for k, v := range attribute {
data[k] = v
}
}

_, err := l.connection.HomeAssistant().CallService(hassws.CallServiceRequest{
Type: hassws.MessageTypeCallService,
Domain: "light",
Service: "turn_on",
Data: map[string]any{
"entity_id": []string{l.GetID()},
},
Data: data,
})
if err != nil {
slog.Error("Error turning on light", "entity", l.GetID(), "error", err)
Expand Down Expand Up @@ -85,11 +93,11 @@ func (lg LightGroup) IsOn() bool {
return true
}

func (lg LightGroup) TurnOn() error {
func (lg LightGroup) TurnOn(attributes ...map[string]any) error {
var errs []error

for _, l := range lg {
if err := l.TurnOn(); err != nil {
if err := l.TurnOn(attributes...); err != nil {
errs = append(errs, err)
}
}
Expand Down

0 comments on commit 9b1bc4c

Please sign in to comment.