[ST Edge] Is it possible to emit_event() too much at one time?

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.

1 Like

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.

Any update on this issue? I’m running into a similar issue where I have a shade and I want to update both the shade level and the open/close state of the shade and yet the second device:emit_event seems to be ignored, unless there is a control event in between.

device:emit_event(capabilities.windowShadeLevel.shadeLevel(shadeLevel))
if shadeLevel == 0 then
      device:emit_event(capabilities.windowShade.windowShade('closed'))
else
      device:emit_event(capabilities.windowShade.windowShade('open'))
end

The code above works properly, the code below doesn’t update the windowShade status after updating the shadeLevel.

device:emit_event(capabilities.windowShadeLevel.shadeLevel(100))
device:emit_event(capabilities.windowShade.windowShade('open'))

I have a similar issue: I created two customized sliders and emit the initial state of both, but only the first one works. However, if I update the state of the second slider later in other functions, the second slider state would update and the capability in UI would appear solid color.

Hi, @jackj
Did you assign a different attribute name for each of those custom capabilities?

Hello,

I assigned the same attribute name for different named capabilities. But from reading the above comments, it seems like we have to name different attribute names even though the capabilities are named differently. So I tried it and it works now. thanks!

Just curious if there is any way we can use the same attribute name for different capabilities. There are occasions that might need identical capabilities for different parameters, like a couple of sliders, etc.