Skip to content

Commit

Permalink
events and devices update
Browse files Browse the repository at this point in the history
  • Loading branch information
gaetancollaud committed Dec 11, 2023
1 parent 0b91905 commit 3bfce83
Show file tree
Hide file tree
Showing 6 changed files with 332 additions and 74 deletions.
2 changes: 1 addition & 1 deletion docs/api/appartment.http
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ Authorization: Bearer {{api-key}}
###

// @no-cookie-jar
GET {{host}}/api/v1/apartment/status?include=zones
GET {{host}}/api/v1/apartment/status
Authorization: Bearer {{api-key}}
127 changes: 68 additions & 59 deletions pkg/controller/modules/devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,19 @@ func (c *DeviceModule) Start() error {
//}
devices, err := c.dsRegistry.GetDevices()

if err != nil {

// TODO refresh values in registry directly
for _, device := range devices {
err := c.dsRegistry.DeviceChangeSubscribe(device.DeviceId, func(deviceId string, outputId string, oldValue float64, newValue float64) {
err := c.updateDevice(deviceId)
if err != nil {
log.Error().Err(err).Str("deviceid", deviceId).Msg("Error updating device ")
}
})
if err != nil {
return err
}
}

if err != nil {
// Refresh devices values.
if c.refreshAtStart {
go func() {
Expand All @@ -91,14 +100,6 @@ func (c *DeviceModule) Start() error {
}
}

// TODO handle that in registry
// Subscribe to DigitalStrom events.
if err := c.dsClient.EventSubscribe(digitalstrom.EventTypeCallScene, func(client digitalstrom.Client, event digitalstrom.Event) error {
return c.onDsEvent(event)
}); err != nil {
return err
}

// Subscribe to MQTT events.
for _, device := range devices {
outputs, err := c.dsRegistry.GetOutputsOfDevice(device.DeviceId)
Expand Down Expand Up @@ -135,10 +136,12 @@ func (c *DeviceModule) Start() error {
}

func (c *DeviceModule) Stop() error {
// TODO do this in registry
if err := c.dsClient.EventUnsubscribe(digitalstrom.EventTypeCallScene); err != nil {
return err
if devices, err := c.dsRegistry.GetDevices(); err != nil {
for _, device := range devices {
_ = c.dsRegistry.DeviceChangeUnsubscribe(device.DeviceId)
}
}

return nil
}

Expand Down Expand Up @@ -170,42 +173,43 @@ func (c *DeviceModule) onMqttMessage(deviceId string, channel string, message st
if err := c.dsClient.DeviceSetOutputChannelValue(device.Attributes.Dsid, map[string]int{channel: int(value)}); err != nil {
return err
}
if err := c.publishDeviceValue(&device, channel, value); err != nil {
return err
}
//if err := c.publishDeviceValue(&device, channel, value); err != nil {
// return err
//}
return nil

}

func (c *DeviceModule) onDsEvent(event digitalstrom.Event) error {
// TODO refresh the all devices and make diff
//if event.Source.IsDevice {
// // The event was triggered by a single device, then let's update it.
// device := c.deviceLookup[event.Source.Dsid]
// if err := c.updateDevice(&device); err != nil {
// return fmt.Errorf("error updating device '%s': %w", device.Name, err)
// }
// return nil
//}
//devicesIds, ok := c.zoneGroupLookup[event.Source.ZoneId][event.Source.GroupId]
//if !ok {
// log.Warn().
// Int("zoneId", event.Source.ZoneId).
// Int("groupID", event.Source.GroupId).
// Msg("No devices found for group when event received.")
// return fmt.Errorf("error when retrieving device given a zone and group ID")
//}
//
//time.Sleep(1 * time.Second)
//for _, dsid := range devicesIds {
// device := c.deviceLookup[dsid]
// if err := c.updateDevice(&device); err != nil {
// return fmt.Errorf("error updating device '%s': %w", device.Name, err)
// }
//}

return nil
}
//
//func (c *DeviceModule) onDsEvent(event digitalstrom.Event) error {
// // TODO refresh the all devices and make diff
// //if event.Source.IsDevice {
// // // The event was triggered by a single device, then let's update it.
// // device := c.deviceLookup[event.Source.Dsid]
// // if err := c.updateDevice(&device); err != nil {
// // return fmt.Errorf("error updating device '%s': %w", device.Name, err)
// // }
// // return nil
// //}
// //devicesIds, ok := c.zoneGroupLookup[event.Source.ZoneId][event.Source.GroupId]
// //if !ok {
// // log.Warn().
// // Int("zoneId", event.Source.ZoneId).
// // Int("groupID", event.Source.GroupId).
// // Msg("No devices found for group when event received.")
// // return fmt.Errorf("error when retrieving device given a zone and group ID")
// //}
// //
// //time.Sleep(1 * time.Second)
// //for _, dsid := range devicesIds {
// // device := c.deviceLookup[dsid]
// // if err := c.updateDevice(&device); err != nil {
// // return fmt.Errorf("error updating device '%s': %w", device.Name, err)
// // }
// //}
//
// return nil
//}

func (c *DeviceModule) updateDevice(deviceId string) error {
device, err := c.dsRegistry.GetDevice(deviceId)
Expand All @@ -230,23 +234,28 @@ func (c *DeviceModule) updateDevice(deviceId string) error {
Str("outputChannels", strings.Join(channels, ";")).
Msg("Updating device")

// TODO use registry
//response, err := c.dsClient.DeviceGetOutputChannelValue(device.DeviceId, outputChannels)
//if err != nil {
// return err
//}
//for _, channelValue := range response.Channels {
// value := c.invertValueIfNeeded(channelValue.Name, channelValue.Value)
// if err := c.publishDeviceValue(device, channelValue.Name, value); err != nil {
// return fmt.Errorf("error publishing device '%s' value: %w", device.Name, err)
// }
//}
outputValues, err := c.dsRegistry.GetOutputValuesOfDevice(deviceId)
if err != nil {
return err
}
outputValuesLookup := map[string]digitalstrom.OutputValue{}
for _, outputValue := range outputValues {
outputValuesLookup[outputValue.OutputId] = outputValue
}

for _, output := range outputs {
outputValue := outputValuesLookup[output.OutputId]
value := c.invertValueIfNeeded(output.OutputId, outputValue.Value)
if err := c.publishDeviceValue(&device, output.OutputId, value); err != nil {
return fmt.Errorf("error publishing device '%s' value: %w", device.Attributes.Name, err)
}
}

return nil
}

func (c *DeviceModule) publishDeviceValue(device *digitalstrom.Device, channelName string, value float64) error {
return c.mqttClient.Publish(c.deviceStateTopic(device.Attributes.Name, channelName), fmt.Sprintf("%.2f", value))
func (c *DeviceModule) publishDeviceValue(device *digitalstrom.Device, outputId string, value float64) error {
return c.mqttClient.Publish(c.deviceStateTopic(device.Attributes.Name, outputId), fmt.Sprintf("%.2f", value))
}

func (c *DeviceModule) invertValueIfNeeded(channel string, value float64) float64 {
Expand Down
72 changes: 65 additions & 7 deletions pkg/digitalstrom/api.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package digitalstrom

// Appartment structure
type Apartment struct {
ApartmentId string `mapstructure:"id"`
Attributes ApartmentAttributes `mapstructure:"attributes"`
Expand Down Expand Up @@ -100,9 +101,9 @@ type OutputAttributes struct {
Type OutputType `mapstructure:"type"`
Function string `mapstructure:"function"`
Mode OutputMode `mapstructure:"mode"`
Min float32 `mapstructure:"min"`
Max float32 `mapstructure:"max"`
Resolution float32 `mapstructure:"resolution"`
Min float64 `mapstructure:"min"`
Max float64 `mapstructure:"max"`
Resolution float64 `mapstructure:"resolution"`
}

type ButtonInputs struct {
Expand All @@ -125,9 +126,9 @@ type SensorInputsAttributes struct {
TechnicalName string `mapstructure:"technicalName"`
Type SensorInputType `mapstructure:"type"`
Mode SensorInputUsage `mapstructure:"usage"`
Min float32 `mapstructure:"min"`
Max float32 `mapstructure:"max"`
Resolution float32 `mapstructure:"resolution"`
Min float64 `mapstructure:"min"`
Max float64 `mapstructure:"max"`
Resolution float64 `mapstructure:"resolution"`
}

// Zone representation.
Expand All @@ -139,7 +140,7 @@ type Zone struct {
type ZoneAttributes struct {
Name string `mapstructure:"name"`
Floor string `mapstructure:"floor"`
OrderId float32 `mapstructure:"orderId"`
OrderId float64 `mapstructure:"orderId"`
Submodules []string `mapstructure:"submodules"`
Applications []string `mapstructure:"applications"`
ApplicationTypes []string `mapstructure:"applicationTypes"`
Expand Down Expand Up @@ -188,6 +189,63 @@ type MeteringOrigin struct {
Type string `mapstructure:"type"`
}

// Meterings
type Meterings struct {
Meterings []Metering `mapstructure:"meterings"`
}

type MeteringValues struct {
Values []MeteringValue `mapstructure:"values"`
}
type MeteringValue struct {
Id string `mapstructure:"id"`
Attributes MeteringValueAttributes `mapstructure:"attributes"`
}

type MeteringValueAttributes struct {
Value float64 `json:"value"`
}

// Status

type ApartmentStatus struct {
ApartmentId string `mapstructure:"id"`
Included ApartmentStatusIncluded `mapstructure:"included"`
}

type ApartmentStatusIncluded struct {
Devices []DeviceStatus `mapstructure:"dsDevices"`
}

type DeviceStatus struct {
DeviceId string `mapstructure:"id"`
Type string `mapstructure:"type"`
Attributes DeviceStatusAttributes `mapstructure:"attributes"`
}

type DeviceStatusAttributes struct {
FunctionBlocks []struct {
FunctionBlockId string `mapstructure:"id"`
Outputs []OutputValue `mapstructure:"outputs,omitempty"`
} `mapstructure:"functionBlocks"`
Submodules []struct {
SubmoduleId string `mapstructure:"id"`
OperationsLocked bool `mapstructure:"operationsLocked"`
} `mapstructure:"submodules"`
States []struct {
StateId string `mapstructure:"id"`
Value string `mapstructure:"value"`
} `mapstructure:"states,omitempty"`
}

type OutputValue struct {
OutputId string `mapstructure:"id"`
Value float64 `mapstructure:"value"`
Status string `mapstructure:"status"`
TargetValue float64 `mapstructure:"targetValue"`
Level int `mapstructure:"level,omitempty"`
}

// Websocket

type NotificationType string
Expand Down
Loading

0 comments on commit 3bfce83

Please sign in to comment.