Skip to content

Commit

Permalink
Deconz sensor handling
Browse files Browse the repository at this point in the history
  • Loading branch information
splattner committed Sep 24, 2023
1 parent 63d892f commit 20498e9
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 134 deletions.
289 changes: 167 additions & 122 deletions pkg/client/deconzclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type DeconzClient struct {
func NewDeconzClient(i *integration.Integration) *DeconzClient {
client := DeconzClient{}

i.Config["ignoreEntitySubscription"] = true

client.IntegrationDriver = i
// Start without a connection
client.DeviceState = integration.DisconnectedDeviceState
Expand Down Expand Up @@ -185,168 +187,211 @@ func (c *DeconzClient) configureDeconz() {

}

func (c *DeconzClient) handleNewDeviceDiscovered(device *deconz.DeconzDevice) {
log.WithFields(log.Fields{
"id": device.GetID(),
"type": device.Type,
"name": device.GetName(),
}).Debug("New Deconz Device discovered")
func (c *DeconzClient) handleNewSensorDeviceDiscovered(device *deconz.DeconzDevice) {

switch device.Type {
case deconz.SensorDeconzDeviceType:
//sensor := entities.NewSensorEntity(fmt.Sprintf("light%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "")
var sensor *entities.SensorEntity
if device.Sensor.State.Temperature > 0 {
sensor = entities.NewSensorEntity(fmt.Sprintf("sensor%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "", entities.TemperaturSensorDeviceClass)
}

//c.IntegrationDriver.AddEntity(sensor)
if device.Sensor.State.Humidity > 0 {
sensor = entities.NewSensorEntity(fmt.Sprintf("sensor%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "", entities.HumiditySensorDeviceClass)
}

case deconz.LightDeconzDeviceType:
light := entities.NewLightEntity(fmt.Sprintf("light%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "")
if sensor != nil {

// All correct Attributes
light.AddFeature(entities.OnOffLightEntityFeatures)
light.AddFeature(entities.ToggleLightEntityFeatures)
light.AddFeature(entities.DimLightEntityFeatures)

if device.Light.HasColor {
switch device.Light.State.ColorMode {
case "ct":
light.AddFeature(entities.ColorTemperatureLightEntityFeatures)
case "hs":
light.AddFeature(entities.ColorLightEntityFeatures)
}
}
device.SetHandleChangeStateFunc(func(state *deconz.DeconzState) {
log.WithFields(log.Fields{
"ID": device.GetID(),
"State": state,
}).Debug("Sensor changed")

attributes := make(map[string]interface{})

switch sensor.DeviceClass {
case entities.TemperaturSensorDeviceClass:
attributes["value"] = state.Temperature

case entities.HumiditySensorDeviceClass:
attributes["value"] = state.Humidity

// 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
sensor.SetAttributes(attributes)

})

c.IntegrationDriver.AddEntity(sensor)
}
}

func (c *DeconzClient) handleNewLightDeviceDiscovered(device *deconz.DeconzDevice) {
light := entities.NewLightEntity(fmt.Sprintf("light%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "")

// All correct Attributes
light.AddFeature(entities.OnOffLightEntityFeatures)
light.AddFeature(entities.ToggleLightEntityFeatures)
light.AddFeature(entities.DimLightEntityFeatures)

if device.Light.HasColor {
switch device.Light.State.ColorMode {
case "ct":
light.AddFeature(entities.ColorTemperatureLightEntityFeatures)
case "hs":
light.AddFeature(entities.ColorLightEntityFeatures)
}
}

// Add commands
light.AddCommand(entities.OnLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
// 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 err := device.TurnOn(); err != nil {
return 404
}
return 200
})
if light.HasAttribute(entities.BrightnessLightEntityAttribute) {
light.Attributes[string(entities.BrightnessLightEntityAttribute)] = device.Light.State.Bri

light.AddCommand(entities.OffLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
}

if err := device.TurnOff(); err != nil {
return 404
}
return 200
})
// Add commands
light.AddCommand(entities.OnLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {

light.AddCommand(entities.ToggleLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
if device.IsOn() {
device.TurnOff()
} else {
device.TurnOff()
}
return 200
})
if err := device.TurnOn(); err != nil {
return 404
}
return 200
})

// Set the Handle State Change function
device.SetHandleChangeStateFunc(func(state *deconz.DeconzState) {
log.WithFields(log.Fields{
"ID": device.GetID(),
"Type": device.Type,
}).Debug("Handle State Change")
light.AddCommand(entities.OffLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {

attributes := make(map[string]interface{})
if err := device.TurnOff(); err != nil {
return 404
}
return 200
})

light.AddCommand(entities.ToggleLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
if device.IsOn() {
device.TurnOff()
} else {
device.TurnOff()
}
return 200
})

if light.HasAttribute(entities.StateLightEntityAttribute) {
if *state.On {
attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState
} else {
attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState
}
}
// Set the Handle State Change function
device.SetHandleChangeStateFunc(func(state *deconz.DeconzState) {
log.WithFields(log.Fields{
"ID": device.GetID(),
"Type": device.Type,
}).Debug("Handle State Change")

if light.HasAttribute(entities.BrightnessLightEntityAttribute) {
attributes[string(entities.BrightnessLightEntityAttribute)] = state.Bri
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
}
}

light.SetAttributes(attributes)
if light.HasAttribute(entities.BrightnessLightEntityAttribute) {
attributes[string(entities.BrightnessLightEntityAttribute)] = state.Bri

})
}

c.IntegrationDriver.AddEntity(light)
light.SetAttributes(attributes)

case deconz.GroupDeconzDeviceType:
})

group := entities.NewLightEntity(fmt.Sprintf("group%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "")
// Group only allows for on/off -> basic switch, no dimming
group.AddFeature(entities.OnOffLightEntityFeatures)
group.AddFeature(entities.ToggleLightEntityFeatures)
c.IntegrationDriver.AddEntity(light)
}

// Set initial attribute
// if group.HasAttribute(entities.StateLightEntityAttribute) {
// if *&device.Group.State.AnyOn {
// light.Attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState
// } else {
// light.Attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState
// }
// }
func (c *DeconzClient) handleNewGroupDeviceDiscovered(device *deconz.DeconzDevice) {
group := entities.NewLightEntity(fmt.Sprintf("group%d", device.GetID()), entities.LanguageText{En: device.GetName()}, "")
// Group only allows for on/off -> basic switch, no dimming
group.AddFeature(entities.OnOffLightEntityFeatures)
group.AddFeature(entities.ToggleLightEntityFeatures)

// 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
}
}

// Commands
// Commands

group.AddCommand(entities.OnLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
group.AddCommand(entities.OnLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {

if err := device.TurnOn(); err != nil {
return 404
}
return 200
})
if err := device.TurnOn(); err != nil {
return 404
}
return 200
})

group.AddCommand(entities.OffLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
group.AddCommand(entities.OffLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {

if err := device.TurnOff(); err != nil {
return 404
}
return 200
})
if err := device.TurnOff(); err != nil {
return 404
}
return 200
})

group.AddCommand(entities.ToggleLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
if device.IsOn() {
device.TurnOff()
} else {
device.TurnOff()
}
return 200
})

group.AddCommand(entities.ToggleLightEntityCommand, func(entity entities.LightEntity, params map[string]interface{}) int {
if device.IsOn() {
device.TurnOff()
device.SetHandleChangeStateFunc(func(state *deconz.DeconzState) {
log.WithFields(log.Fields{
"ID": device.GetID(),
"Type": device.Type,
}).Debug("Handle State Change")

attributes := make(map[string]interface{})

if group.HasAttribute(entities.StateLightEntityAttribute) {
if *&state.AnyOn {
attributes[string(entities.StateLightEntityAttribute)] = entities.OnLightEntityState
} else {
device.TurnOff()
attributes[string(entities.StateLightEntityAttribute)] = entities.OffLightEntityState
}
return 200
})
}

device.SetHandleChangeStateFunc(func(state *deconz.DeconzState) {
log.WithFields(log.Fields{
"ID": device.GetID(),
"Type": device.Type,
}).Debug("Handle State Change")
group.SetAttributes(attributes)

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
}
}
c.IntegrationDriver.AddEntity(group)
}

func (c *DeconzClient) handleNewDeviceDiscovered(device *deconz.DeconzDevice) {
log.WithFields(log.Fields{
"id": device.GetID(),
"type": device.Type,
"name": device.GetName(),
}).Debug("New Deconz Device discovered")

group.SetAttributes(attributes)
switch device.Type {
case deconz.SensorDeconzDeviceType:
c.handleNewSensorDeviceDiscovered(device)

})
case deconz.LightDeconzDeviceType:
c.handleNewLightDeviceDiscovered(device)

c.IntegrationDriver.AddEntity(group)
case deconz.GroupDeconzDeviceType:
c.handleNewGroupDeviceDiscovered(device)
}

}
Expand Down
5 changes: 4 additions & 1 deletion pkg/deconz/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@ type DeconzState struct {
AnyOn bool `json:"any_on,omitempty"`

// Sensor
ButtonEvent int `json:"buttonevent,omitempty"`
ButtonEvent int `json:"buttonevent,omitempty"`
Humidity *uint16 `json:"humidity,omitempty"`
Temperature *int16 `json:"temperature,omitempty"`
Pressure *int16 `json:"pressure,omitempty"`
}
2 changes: 1 addition & 1 deletion pkg/integration/advertisement.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func (i *Integration) startAdvertising() {
"ws_path=/ws",
}

server, err := zeroconf.Register(i.Metadata.DriverId, "_uc-integration._tcp", "local.", i.config["listenport"].(int), txt, nil)
server, err := zeroconf.Register(i.Metadata.DriverId, "_uc-integration._tcp", "local.", i.Config["listenport"].(int), txt, nil)
if err != nil {
panic(err)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/integration/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ func (i *Integration) SendEntityChangeEvent(e interface{}) {
log.WithField("subscribedEtities", i.SubscribedEntities).Debug("Currently subscribed entities")

// Only send the event when remote is subscribed to
if slices.Contains(i.SubscribedEntities, entity_id) {
if (i.Config["ignoreEntitySubscription"] != nil && i.Config["ignoreEntitySubscription"].(bool)) || slices.Contains(i.SubscribedEntities, entity_id) {

var res interface{}
now := time.Now()
Expand Down
Loading

0 comments on commit 20498e9

Please sign in to comment.