I have a device with 7 capabilities. There are 4 custom list types in the detail view. They only differ by name. Each list has 4 items with ‘alternatives’. I also added the ‘supportedValues’ filter just so I’d have it. I use emit_event() to select the initial value for each list. All the emits show up in the log, but only the first list attribute gets initialized. If I reorder the emits, only the new first list attribute gets initialized. I’m only seeing this behavior with the lists. It’s scary to think I could be bogging down the hub with such a simple task. Has anyone seen this before? Do I need to reduce complexity? There’s also some simple logging.
Hi, @nmpu, that is a strange behavior I haven’t seen when I initialize several capabilities.
Could you share the snippet code of those events and the corresponding logs, please?
Note: Please, include the capabilities ID, I’d like to check their configuration.
I tried a bunch of stuff including lengthy delays between events. That didn’t solve the problem.
I have 4 custom capabilities and was emitting the same initial value (0) for all 4. Only the first would take. The solution was to force state_change = true
. Unless ST implements similar logic internally, I recommend all initial values be routed through a function like:
local function my_emit(device, event)
event.state_change = true
device:emit_event(event)
end
Once I isolated the root cause, I went back and emitted 4 different values. I then tried simply emitting alternating values. Both work. Somewhere in the ST code there must be a check for change of state. I would have expected uninitialized to always be considered a change of state. Apparently, that’s not how it works. Somehow the last emitted value for a different capability enters into the logic.
2-4 FAIL
device:emit_event(fanDimmer.mode(0))
device:emit_event(livingDimmer.mode(0))
device:emit_event(kitchenDimmer.mode(0))
device:emit_event(diningDimmer.mode(0))
WORKS
device:emit_event(fanDimmer.mode(0))
device:emit_event(livingDimmer.mode(1))
device:emit_event(kitchenDimmer.mode(0))
device:emit_event(diningDimmer.mode(1))
CUSTOM CAPABILITY
{
"name": "fan dimmer 113",
"attributes": {
"mode": {
"schema": {
"type": "object",
"properties": {
"value": {
"type": "integer",
"minimum": 0,
"maximum": 3
}
},
"additionalProperties": false
},
"setter": "setMode"
}
},
"commands": {
"setMode": {"name": "setMode",
"arguments": [{
"name": "value",
"schema": {"type": "integer", "minimum": 0, "maximum": 3},
"optional": false
}]
},
"nextMode": {"name": "nextMode",
"arguments": []}
}
}
CUSTOM PRESENTATION
{
"id": "dictionaryorigin49938.fanDimmer113",
"dashboard": {
"states": [
{
"label": "{{mode.value}}",
"alternatives": [
{"key": 0, "value": "Off", "type": "inactive"},
{"key": 1, "value": "Fast"},
{"key": 2, "value": "Medium"},
{"key": 3, "value": "Slow"}
]
}
],
"actions": [
{
"displayType": "pushButton",
"pushButton": {"command": "nextMode"}
}
]
},
"detailView": [
{
"label": "Fan",
"displayType": "list",
"list": {
"command": {
"name": "setMode",
"argumentType": "integer",
"alternatives": [
{"key": "0", "value": "Off", "type": "inactive"},
{"key": "1", "value": "Fast"},
{"key": "2", "value": "Medium"},
{"key": "3", "value": "Slow"}
]
},
"state": {
"value": "mode.value",
"valueType": "integer",
"alternatives": [
{"key": "0", "value": "0"},
{"key": "1", "value": "1"},
{"key": "2", "value": "2"},
{"key": "3", "value": "3"}
]
}
}
}
]
}
PROFILE
name: 'test'
components:
- id: main
capabilities:
- id: dictionaryorigin49938.fanDimmer113
version: 1
- id: dictionaryorigin49938.livingDimmer113
version: 1
- id: dictionaryorigin49938.kitchenDimmer113
version: 1
- id: dictionaryorigin49938.diningDimmer113
version: 1
- id: dictionaryorigin49938.bathOff113
version: 1
- id: switch
version: 1
- id: switchLevel
version: 1
categories:
- name: Fan
This is a simple LAN device that I’m using for visual proof-of-concept.
Stating the obvious, it seems like it might be getting a bit confused by the attributes having the same name.
I’ve always avoided this because the legacy ecosystem seems to have a flat namespace - a createEvent
/ sendEvent
in a Groovy DTH only includes the attribute name without a capability name - and I envisaged problems while it is still around.
Yes, what I’m doing is a little weird. By reusing the same attribute name, I can also reuse the same generic handlers.
function command_setMode(driver, device, command)
device:emit_event(capabilities[command.capability].mode(command.args.value))
end
function command_nextMode(driver, device, command)
local t = (device.state_cache[command.component][command.capability].mode.value + 1) % 4
device:emit_event(capabilities[command.capability].mode(t))
end
The next step will get even wilder. Basically, for each device, I plan to display other nearby devices on the same presentation. This means that an attribute change on one device will also need to trigger emits for any other devices which display (mirror) that attribute.