diff --git a/pkg/client/deconzclient.go b/pkg/client/deconzclient.go index bc468f8..6f4cdc4 100644 --- a/pkg/client/deconzclient.go +++ b/pkg/client/deconzclient.go @@ -11,6 +11,11 @@ import ( "github.com/splattner/goucrt/pkg/integration" ) +var mapOnState = map[bool]entities.LightEntityState{ + true: entities.OnLightEntityState, + false: entities.OffLightEntityState, +} + // Denon AVR Client Implementation type DeconzClient struct { Client @@ -234,33 +239,27 @@ func (c *DeconzClient) handleNewSensorDeviceDiscovered(device *deconz.DeconzDevi func (c *DeconzClient) handleNewLightDeviceDiscovered(device *deconz.DeconzDevice) { light := entities.NewLightEntity(fmt.Sprintf("light%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "") - // All correct Attributes + // Add Features and initial values light.AddFeature(entities.OnOffLightEntityFeatures) light.AddFeature(entities.ToggleLightEntityFeatures) + light.UpdateAttribute(entities.StateLightEntityAttribute, mapOnState[device.IsOn()]) + light.AddFeature(entities.DimLightEntityFeatures) + light.UpdateAttribute(entities.BrightnessLightEntityAttribute, device.GetBrightness()) if device.Light.HasColor { switch device.Light.State.ColorMode { case "ct": light.AddFeature(entities.ColorTemperatureLightEntityFeatures) + light.UpdateAttribute(entities.ColorTemperatureLightEntityAttribute, device.GetColorTempInPercent()) case "hs": light.AddFeature(entities.ColorLightEntityFeatures) + light.UpdateAttribute(entities.HueLightEntityAttribute, device.GetHueConverted()) + light.UpdateAttribute(entities.SaturationLightEntityAttribute, device.GetSaturation()) } } // Set initial attribute - if light.HasAttribute(entities.StateLightEntityAttribute) { - if *device.Light.State.On { - light.Attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState - } else { - light.Attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState - } - } - - if light.HasAttribute(entities.BrightnessLightEntityAttribute) { - light.Attributes[string(entities.BrightnessLightEntityAttribute)] = device.Light.State.Bri - - } // Add commands light.AddCommand(entities.OnLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int { @@ -273,28 +272,31 @@ func (c *DeconzClient) handleNewLightDeviceDiscovered(device *deconz.DeconzDevic } else { if params["brightness"] != nil { - //bri, _ := strconv.ParseFloat(params["brightness"].(string), 32) - if err := device.SetBrightness(float32(params["brightness"].(float64))); err != nil { + + if err := device.SetBrightness(float32(params["brightness"].(uint))); err != nil { return 404 } } if params["hue"] != nil { - hue, _ := strconv.ParseFloat(params["hue"].(string), 32) + hue_converted, _ := strconv.ParseFloat(params["hue"].(string), 32) + hue := hue_converted / 360 * 65535 if err := device.SetHue(float32(hue)); err != nil { return 404 } } if params["saturation"] != nil { - saturation, _ := strconv.ParseFloat(params["saturation"].(string), 32) - if err := device.SetSaturation(float32(saturation)); err != nil { + if err := device.SetSaturation(float32(params["saturation"].(uint))); err != nil { return 404 } } - if params["color_temperature:44"] != nil { - ct, _ := strconv.ParseFloat(params["color_temperature:44"].(string), 32) + if params["color_temperature"] != nil { + + raw_ct := params["color_temperature"].(float64) + ct := raw_ct/100*(500-153) + 153 + if err := device.SetColorTemp(float32(ct)); err != nil { return 404 } @@ -316,7 +318,7 @@ func (c *DeconzClient) handleNewLightDeviceDiscovered(device *deconz.DeconzDevic if device.IsOn() { device.TurnOff() } else { - device.TurnOff() + device.TurnOn() } return 200 }) @@ -331,15 +333,33 @@ func (c *DeconzClient) handleNewLightDeviceDiscovered(device *deconz.DeconzDevic attributes := make(map[string]interface{}) if light.HasAttribute(entities.StateLightEntityAttribute) { - if *state.On { - attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState - } else { - attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState + attributes[string(entities.StateLightEntityAttribute)] = mapOnState[*state.On] + } + + if light.HasAttribute(entities.HueLightEntityAttribute) { + if state.Hue != nil { + attributes[string(entities.HueLightEntityAttribute)] = device.GetHueConverted() } } + if light.HasAttribute(entities.SaturationLightEntityAttribute) { + if state.Sat != nil { + attributes[string(entities.SaturationLightEntityAttribute)] = *state.Sat + } + + } + if light.HasAttribute(entities.BrightnessLightEntityAttribute) { - attributes[string(entities.BrightnessLightEntityAttribute)] = state.Bri + if state.Bri != nil { + attributes[string(entities.BrightnessLightEntityAttribute)] = *state.Bri + } + + } + + if light.HasAttribute(entities.ColorTemperatureLightEntityAttribute) { + if state.CT != nil { + attributes[string(entities.ColorTemperatureLightEntityAttribute)] = device.GetColorTempInPercent() + } } @@ -353,30 +373,22 @@ func (c *DeconzClient) handleNewLightDeviceDiscovered(device *deconz.DeconzDevic func (c *DeconzClient) handleNewGroupDeviceDiscovered(device *deconz.DeconzDevice) { group := entities.NewLightEntity(fmt.Sprintf("group%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "") + // Add Features and initial values group.AddFeature(entities.OnOffLightEntityFeatures) group.AddFeature(entities.ToggleLightEntityFeatures) - group.AddFeature(entities.DimLightEntityFeatures) - - if *device.Group.Action.CT > 0 { - switch device.Group.Action.ColorMode { - case "ct": - group.AddFeature(entities.ColorTemperatureLightEntityFeatures) - case "hs": - group.AddFeature(entities.ColorLightEntityFeatures) - } - } + group.UpdateAttribute(entities.StateLightEntityAttribute, mapOnState[device.IsOn()]) - // Set initial attribute - if group.HasAttribute(entities.StateLightEntityAttribute) { - if *device.Group.Action.On { - group.Attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState - } else { - group.Attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState - } - } - - if group.HasAttribute(entities.BrightnessLightEntityAttribute) { - group.Attributes[string(entities.BrightnessLightEntityAttribute)] = device.Group.Action.Bri + group.AddFeature(entities.DimLightEntityFeatures) + group.UpdateAttribute(entities.BrightnessLightEntityAttribute, device.GetBrightness()) + + switch device.Group.Action.ColorMode { + case "ct": + group.AddFeature(entities.ColorTemperatureLightEntityFeatures) + group.UpdateAttribute(entities.ColorTemperatureLightEntityAttribute, device.GetColorTempInPercent()) + case "hs": + group.AddFeature(entities.ColorLightEntityFeatures) + group.UpdateAttribute(entities.HueLightEntityAttribute, device.GetHueConverted()) + group.UpdateAttribute(entities.SaturationLightEntityAttribute, device.GetSaturation()) } // Commands @@ -397,21 +409,23 @@ func (c *DeconzClient) handleNewGroupDeviceDiscovered(device *deconz.DeconzDevic } if params["hue"] != nil { - hue, _ := strconv.ParseFloat(params["hue"].(string), 32) + hue_converted, _ := strconv.ParseFloat(params["hue"].(string), 32) + hue := hue_converted / 360 * 65535 if err := device.SetHue(float32(hue)); err != nil { return 404 } } if params["saturation"] != nil { - saturation, _ := strconv.ParseFloat(params["saturation"].(string), 32) - if err := device.SetSaturation(float32(saturation)); err != nil { + if err := device.SetSaturation(float32(params["saturation"].(uint))); err != nil { return 404 } } - if params["color_temperature:44"] != nil { - ct, _ := strconv.ParseFloat(params["color_temperature:44"].(string), 32) + if params["color_temperature"] != nil { + raw_ct := params["color_temperature"].(float64) + ct := raw_ct/100*(500-153) + 153 + if err := device.SetColorTemp(float32(ct)); err != nil { return 404 } @@ -432,7 +446,7 @@ func (c *DeconzClient) handleNewGroupDeviceDiscovered(device *deconz.DeconzDevic if device.IsOn() { device.TurnOff() } else { - device.TurnOff() + device.TurnOn() } return 200 }) @@ -446,16 +460,32 @@ func (c *DeconzClient) handleNewGroupDeviceDiscovered(device *deconz.DeconzDevic attributes := make(map[string]interface{}) if group.HasAttribute(entities.StateLightEntityAttribute) { - if *state.AnyOn { - attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState - } else { - attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState - } + attributes[string(entities.StateLightEntityAttribute)] = mapOnState[*state.AnyOn] + } if group.HasAttribute(entities.BrightnessLightEntityAttribute) { if state.Bri != nil { - group.Attributes[string(entities.BrightnessLightEntityAttribute)] = state.Bri + group.Attributes[string(entities.BrightnessLightEntityAttribute)] = *state.Bri + } + } + + if group.HasAttribute(entities.HueLightEntityAttribute) { + if state.Hue != nil { + group.Attributes[string(entities.HueLightEntityAttribute)] = device.GetHueConverted() + } + } + + if group.HasAttribute(entities.SaturationLightEntityAttribute) { + if state.Sat != nil { + // Todo mapping + group.Attributes[string(entities.SaturationLightEntityAttribute)] = *state.Sat + } + } + + if group.HasAttribute(entities.ColorTemperatureLightEntityAttribute) { + if state.CT != nil { + group.Attributes[string(entities.ColorTemperatureLightEntityAttribute)] = device.GetColorTempInPercent() } } diff --git a/pkg/deconz/deconz.go b/pkg/deconz/deconz.go index e9915ef..f18143f 100644 --- a/pkg/deconz/deconz.go +++ b/pkg/deconz/deconz.go @@ -1,9 +1,6 @@ package deconz import ( - deconzgroup "github.com/jurgen-kluft/go-conbee/groups" - deconzlight "github.com/jurgen-kluft/go-conbee/lights" - deconzsensor "github.com/jurgen-kluft/go-conbee/sensors" log "github.com/sirupsen/logrus" ) @@ -79,7 +76,7 @@ func (d *Deconz) removeDevice(allDevices interface{}) { var toRemove []*DeconzDevice switch allDevices := allDevices.(type) { - case []deconzsensor.Sensor: + case []DeconzSensor: // Loop trought the existing devices for _, dd := range d.allDeconzDevices { @@ -103,7 +100,7 @@ func (d *Deconz) removeDevice(allDevices interface{}) { } } - case []deconzlight.Light: + case []DeconzLight: // Loop trought the existing devices for _, dd := range d.allDeconzDevices { if dd.Type == LightDeconzDeviceType { @@ -125,7 +122,7 @@ func (d *Deconz) removeDevice(allDevices interface{}) { } } - case []deconzgroup.Group: + case []DeconzGroup: // Loop trought the existing devices for _, dd := range d.allDeconzDevices { if dd.Type == GroupDeconzDeviceType { diff --git a/pkg/deconz/device.go b/pkg/deconz/device.go index a132616..48a970d 100644 --- a/pkg/deconz/device.go +++ b/pkg/deconz/device.go @@ -90,8 +90,12 @@ func (d *DeconzDevice) TurnOn() error { switch d.Type { case LightDeconzDeviceType: + // Reset State + d.Light.State = DeconzState{} d.Light.State.SetOn(true) case GroupDeconzDeviceType: + // Reset State + d.Group.Action = DeconzState{} d.Group.Action.SetOn(true) } @@ -104,8 +108,12 @@ func (d *DeconzDevice) TurnOff() error { switch d.Type { case LightDeconzDeviceType: + // Reset State + d.Light.State = DeconzState{} d.Light.State.SetOn(false) case GroupDeconzDeviceType: + // Reset State + d.Group.Action = DeconzState{} d.Group.Action.SetOn(false) } @@ -123,6 +131,20 @@ func (d *DeconzDevice) IsOn() bool { return false } +func (d *DeconzDevice) GetBrightness() uint { + + var brightness uint + + switch d.Type { + case LightDeconzDeviceType: + brightness = uint(*d.Light.State.Bri) + case GroupDeconzDeviceType: + brightness = uint(*d.Group.Action.Bri) + } + + return brightness +} + func (d *DeconzDevice) SetBrightness(brightness float32) error { switch d.Type { @@ -171,6 +193,43 @@ func (d *DeconzDevice) SetColorTemp(ct float32) error { return d.setState() } +func (d *DeconzDevice) GetColorTemp() int { + + var ct int + switch d.Type { + case LightDeconzDeviceType: + ct = int(*d.Light.State.CT) + case GroupDeconzDeviceType: + ct = int(*d.Group.Action.CT) + } + + return ct + +} + +func (d *DeconzDevice) GetColorTempInPercent() int { + + ct := (float64(d.GetColorTemp()-153) / float64(500-153)) * 100 + + return int(ct) + +} + +func (d *DeconzDevice) GetHueConverted() int { + + var converted float32 + + switch d.Type { + case LightDeconzDeviceType: + converted = float32(*d.Light.State.Hue) / 65535 * 360 + case GroupDeconzDeviceType: + converted = float32(*d.Group.Action.Hue) / 65535 * 360 + } + + return int(converted) + +} + func (d *DeconzDevice) SetHue(hue float32) error { converted := uint16(hue) @@ -189,6 +248,20 @@ func (d *DeconzDevice) SetHue(hue float32) error { return d.setState() } +func (d *DeconzDevice) GetSaturation() uint { + + var saturation uint + + switch d.Type { + case LightDeconzDeviceType: + saturation = uint(*d.Light.State.Sat) + case GroupDeconzDeviceType: + saturation = uint(*d.Group.Action.Sat) + } + + return saturation +} + func (d *DeconzDevice) SetSaturation(saturation float32) error { converted := uint8(saturation) @@ -219,3 +292,90 @@ func (d *DeconzDevice) setState() error { return fmt.Errorf("Device Type not found") } + +// Update the local State with a new State (e.g. sent by Websocket Evnt) +func (d *DeconzDevice) updateState(newState *DeconzState) { + + switch d.Type { + case LightDeconzDeviceType: + if newState.Bri != nil { + d.Light.State.Bri = newState.Bri + } + if newState.Sat != nil { + d.Light.State.Sat = newState.Sat + } + + if newState.Hue != nil { + d.Light.State.Hue = newState.Hue + } + + if newState.CT != nil { + d.Light.State.CT = newState.CT + } + + if newState.On != nil { + d.Light.State.On = newState.On + } + + if newState.ColorLoopSpeed != nil { + d.Light.State.ColorLoopSpeed = newState.ColorLoopSpeed + } + + //Effect is no pointer + d.Light.State.Effect = newState.Effect + + if newState.Reachable != nil { + d.Light.State.Reachable = newState.Reachable + } + + if newState.XY != nil { + d.Light.State.XY = newState.XY + } + + if newState.TransitionTime != nil { + d.Light.State.TransitionTime = newState.TransitionTime + } + + case GroupDeconzDeviceType: + if newState.Bri != nil { + d.Group.Action.Bri = newState.Bri + } + if newState.Sat != nil { + d.Group.Action.Sat = newState.Sat + } + + if newState.Hue != nil { + d.Group.Action.Hue = newState.Hue + } + + if newState.CT != nil { + d.Group.Action.CT = newState.CT + } + + if newState.On != nil { + d.Group.Action.On = newState.On + } + + if newState.ColorLoopSpeed != nil { + d.Group.Action.ColorLoopSpeed = newState.ColorLoopSpeed + } + + // Effect is no pointer + d.Group.Action.Effect = newState.Effect + + if newState.Reachable != nil { + d.Group.Action.Reachable = newState.Reachable + } + + if newState.XY != nil { + d.Group.Action.XY = newState.XY + } + + if newState.TransitionTime != nil { + d.Light.State.TransitionTime = newState.TransitionTime + } + + case SensorDeconzDeviceType: + } + +} diff --git a/pkg/deconz/discovery.go b/pkg/deconz/discovery.go index b146edb..c0886a2 100644 --- a/pkg/deconz/discovery.go +++ b/pkg/deconz/discovery.go @@ -4,6 +4,8 @@ import ( log "github.com/sirupsen/logrus" ) +// Get All Lights, all Groupd, all Sensors +// Add them to the available devices func (d *Deconz) StartDiscovery(enableGroups bool) { log.WithField("DeCONZ Host", d.host).Info("Starting Deconz device discovery") @@ -54,6 +56,7 @@ func (d *Deconz) StartDiscovery(enableGroups bool) { log.Info("Deconz, Device Discovery finished") } +// Handle a new discovered group func (d *Deconz) groupsDiscovery(group DeconzGroup) { log.WithFields(log.Fields{ @@ -74,6 +77,7 @@ func (d *Deconz) groupsDiscovery(group DeconzGroup) { } } +// Handle a new discovered light func (d *Deconz) lightsDiscovery(light DeconzLight) { log.WithFields(log.Fields{ "Name": light.Name, @@ -94,6 +98,7 @@ func (d *Deconz) lightsDiscovery(light DeconzLight) { } +// Handle a new discovered sensor func (d *Deconz) sensorDiscovery(sensor DeconzSensor) { log.WithFields(log.Fields{ @@ -106,6 +111,8 @@ func (d *Deconz) sensorDiscovery(sensor DeconzSensor) { // See https://dresden-elektronik.github.io/deconz-rest-doc/endpoints/sensors/#supported-sensor-types-and-states switch sensor.Type { case "ZHAOpenClose", "ZHATemperature", "ZHAHumidity", "ZHAPressure": + // Currently we only look at those + // Todo: Maybee this can be done more generic by looking the State and figure out what we can use? deconzDevice := new(DeconzDevice) deconzDevice.Type = SensorDeconzDeviceType deconzDevice.Sensor = sensor diff --git a/pkg/deconz/group.go b/pkg/deconz/group.go index ec25938..b94b52d 100644 --- a/pkg/deconz/group.go +++ b/pkg/deconz/group.go @@ -171,7 +171,7 @@ func (d *DeconzDevice) setGroupState() error { _, err := d.SetGroupState(d.Group.ID, d.Group.Action) if err != nil { - log.Debugln("Deconz, SetGroupState Error", err) + log.WithError(err).Debug("Deconz, SetGroupState Error") return err } diff --git a/pkg/deconz/light.go b/pkg/deconz/light.go index 91083d0..1341616 100644 --- a/pkg/deconz/light.go +++ b/pkg/deconz/light.go @@ -20,16 +20,21 @@ var ( ) type DeconzLight struct { - Name string `json:"name"` - ID int `json:"id,omitempty"` - ETag string `json:"etag,omitempty"` - State DeconzState `json:"state,omitempty"` - HasColor bool `json:"hascolor,omitempty"` - Type string `json:"type,omitempty"` - Manufacturer string `json:"manufacturer,omitempty"` - ModelID string `json:"modelid,omitempty"` - UniqueID string `json:"uniqueid,omitempty"` - SWVersion string `json:"swversion,omitempty"` + Name string `json:"name"` + ID int `json:"id,omitempty"` + ETag string `json:"etag,omitempty"` + State DeconzState `json:"state,omitempty"` + HasColor bool `json:"hascolor,omitempty"` + Type string `json:"type,omitempty"` + ModelID string `json:"modelid,omitempty"` + UniqueID string `json:"uniqueid,omitempty"` + SWVersion string `json:"swversion,omitempty"` + LastAnnounced string `json:"lastannounced,omitempty"` + LastSeen string `json:"lastseen,omitempty"` + ManufacturerName string `json:"manufacturername,omitempty"` + ColorCapabilities int `json:"colorcapabilities,omitempty"` + Ctmax int `json:"ctmax,omitempty"` + Ctmin int `json:"ctmin,omitempty"` } func (d *DeconzDevice) GetLightState(lightID int) (DeconzLight, error) { diff --git a/pkg/deconz/sensor.go b/pkg/deconz/sensor.go index d76a992..fc33757 100644 --- a/pkg/deconz/sensor.go +++ b/pkg/deconz/sensor.go @@ -8,8 +8,6 @@ import ( "sort" "strconv" "strings" - - "github.com/jurgen-kluft/go-conbee/conbee" ) var ( @@ -41,10 +39,6 @@ type DeconzSensorConfig struct { SunsetOffset int16 `json:"sunsetoffset,omitempty"` } -func (s *DeconzSensor) setDefaults() { - s.Config.Reachable = true -} - func (d *DeconzDevice) GetSensor(sensorID int) (DeconzSensor, error) { var ll DeconzSensor url := fmt.Sprintf(getSensorURL, fmt.Sprintf("%s:%d", d.deconz.host, d.deconz.port), d.deconz.apikey, sensorID) @@ -70,7 +64,7 @@ func (d *DeconzDevice) GetSensor(sensorID int) (DeconzSensor, error) { return ll, err } -func (d *DeconzDevice) UpdateSensor(sensorID int, sensorName string) ([]conbee.ApiResponse, error) { +func (d *DeconzDevice) UpdateSensor(sensorID int, sensorName string) ([]ApiResponse, error) { url := fmt.Sprintf(getSensorURL, fmt.Sprintf("%s:%d", d.deconz.host, d.deconz.port), d.deconz.apikey, sensorID) data := fmt.Sprintf("{\"name\": \"%s\"}", sensorName) postbody := strings.NewReader(data) @@ -89,7 +83,7 @@ func (d *DeconzDevice) UpdateSensor(sensorID int, sensorName string) ([]conbee.A if err != nil { return nil, err } - var apiResponse []conbee.ApiResponse + var apiResponse []ApiResponse err = json.Unmarshal(contents, &apiResponse) if err != nil { return nil, err diff --git a/pkg/deconz/websocket.go b/pkg/deconz/websocket.go index 9385346..a90da3d 100644 --- a/pkg/deconz/websocket.go +++ b/pkg/deconz/websocket.go @@ -70,14 +70,6 @@ func (d *Deconz) StartandListenLoop() { log.WithField("RemoteAddr", ws.RemoteAddr().String()).Info("Could not send Ping message") return } - // case <-time.After(time.Duration(1) * time.Millisecond * 1000): - // // Send an echo packet every second - // err := conn.WriteMessage(websocket.TextMessage, []byte("Hello from vdcd-brige!")) - // if err != nil { - // log.WithError(err).Debug("Deconz, Error during writing to websocket") - // return - // } - } } } @@ -129,6 +121,7 @@ func (d *Deconz) websocketReceiveHandler(ws *websocket.Conn) { message.State.Reachable != nil || message.State.ColorMode != "" || message.State.ColorLoopSpeed != nil { + // only if some state acually changed for _, l := range d.allDeconzDevices { if l.Type == LightDeconzDeviceType { @@ -136,6 +129,7 @@ func (d *Deconz) websocketReceiveHandler(ws *websocket.Conn) { log.WithFields(log.Fields{ "ID": l.Light.ID, "Name": l.Light.Name}).Debug("Deconz Websocket changed event for light") + l.updateState(&message.State) l.stateChangeHandler(&message.State) break } @@ -155,6 +149,7 @@ func (d *Deconz) websocketReceiveHandler(ws *websocket.Conn) { log.WithFields(log.Fields{ "ID": l.Group.ID, "Name": l.Group.Name}).Debug("Deconz Websocket changed event for group") + l.updateState(&message.State) l.stateChangeHandler(&message.State) break } @@ -175,6 +170,7 @@ func (d *Deconz) websocketReceiveHandler(ws *websocket.Conn) { log.WithFields(log.Fields{ "ID": l.Sensor.ID, "Name": l.Sensor.Name}).Debug("Deconz, Websocket changed event for sensor") + l.updateState(&message.State) l.stateChangeHandler(&message.State) } } diff --git a/pkg/entities/light.go b/pkg/entities/light.go index fec3543..1da496b 100644 --- a/pkg/entities/light.go +++ b/pkg/entities/light.go @@ -100,8 +100,17 @@ func (e *LightEntity) HandleCommand(cmd_id string, params map[string]interface{} return 404 } +// Check if an Attribute is available func (e *LightEntity) HasAttribute(attribute LightEntityAttributes) bool { _, ok := e.Attributes[string(attribute)] return ok } + +// Update an Attribute if its available +func (e *LightEntity) UpdateAttribute(attribute LightEntityAttributes, value interface{}) { + + if e.HasAttribute(attribute) { + e.Attributes[string(attribute)] = value + } +} diff --git a/pkg/integration/requests.go b/pkg/integration/requests.go index e578f53..81b46cd 100644 --- a/pkg/integration/requests.go +++ b/pkg/integration/requests.go @@ -215,9 +215,19 @@ func (i *Integration) handleSetupDriverRequest(req *SetupDriverMessageReq) *Resp func (i *Integration) handleSubscribeEventRequest(req *SubscribeEventMessageReq) *SubscribeEventMessage { // Add entities to SubscribedEntities if not already in there - for _, e := range i.Entities { - entity_id := i.getEntityId(e) - if req.MsgData.EntityIds == nil || slices.Contains(req.MsgData.EntityIds, entity_id) { + if req.MsgData.EntityIds == nil { + // Subscribe to all available entities + for _, e := range i.Entities { + entity_id := i.getEntityId(e) + if !slices.Contains(i.SubscribedEntities, entity_id) { + log.WithField("entity_id", entity_id).Info("RT subscribed to entity") + i.SubscribedEntities = append(i.SubscribedEntities, entity_id) + + } + } + + } else { + for _, entity_id := range req.MsgData.EntityIds { if !slices.Contains(i.SubscribedEntities, entity_id) { log.WithField("entity_id", entity_id).Info("RT subscribed to entity") i.SubscribedEntities = append(i.SubscribedEntities, entity_id) @@ -240,7 +250,7 @@ func (i *Integration) handleSubscribeEventRequest(req *SubscribeEventMessageReq) func (i *Integration) handleUnsubscribeEventsRequest(req *UnubscribeEventMessageReq) *UnubscribeEventMessage { for ix, e := range i.SubscribedEntities { - if req.MsgData.EntityIds == nil || slices.Contains(i.SubscribedEntities, e) { + if req.MsgData.EntityIds == nil || slices.Contains(req.MsgData.EntityIds, e) { log.WithField("entity_id", e).Info("RT subscribed from entity") i.SubscribedEntities[ix] = i.SubscribedEntities[len(i.SubscribedEntities)-1] // Copy last element to index i.