[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.