syssi/xiaomi_raw

aiid

joseant opened this issue · 11 comments

Hello.
How can I call to action?

Some miot devices has aiid example:
{"method":"action","params":{"did":"X","siid":2,"aiid":7,"in":[]},"id":123}

in python-miio

get_property_by(siid, piid) returns a single property, useful for testing with miiocli

set_property_by(siid, piid, value, value_type) allows setting one, value_type is optional and will be used for casting to correct type before passing the value to send().

**call_action(name, params) calls an action with the given parameters, anything inside mapping that has aiid is considered an action.

call_action_by(siid, aiid, params) allows calling arbitrary actions, useful especially for command-line use and testing.**

syssi commented

Could you provide an example miot device model / miot spec file which uses aiid's?

syssi commented

You could try something like this:

switch:
  - platform: template
    switches:
      smart_plug_switch:
        unique_id: smart_plug_switch
        value_template: "{{ state_attr('sensor.smart_plug', 'power') }}"
        availability_template: "{{ not is_state('sensor.smart_plug', 'unavailable') }}"
        turn_on:
          service: xiaomi_miio_raw.sensor_raw_command
          data:
            entity_id: sensor.smart_plug
            method: action
            params:
              - did: power
                siid: 2
                aiid: 1
                value: true
        turn_off:
          service: xiaomi_miio_raw.sensor_raw_command
          data:
            entity_id: sensor.smart_plug
            method: action
            params:
              - did: power
                siid: 2
                aiid: 1
                value: false

Hello.

I have tried as script, but it is not working:

script:
  pecera_alimenta_peces:
    alias: pecera_alimenta_peces
    sequence:
    - service: xiaomi_miio_raw.sensor_raw_command
      data:
        entity_id: sensor.pecera
        method: action
        params:
        - did: feed
          aiid: 1
          siid: 4
          value: false
    mode: single
    icon: mdi:shaker

The device is this: hfjh.fishbowl.v2

And the protocol:

  ## Properties ##
          siid 4: piid: 1 (mcu-type): (uint8, unit: none) (acc: ['read', 'notify'])
                  {'value': 0, 'description': 'None'}
                  {'value': 1, 'description': 'One'}
          siid 4: piid: 2 (ledboard-model): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                  {'value': 0, 'description': 'Sun'}
                  {'value': 1, 'description': 'Color'}
                  {'value': 2, 'description': 'Stream'}
          siid 4: piid: 3 (ledboard-brightness): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                  Range: [0, 100, 1]
          siid 4: piid: 4 (): (uint32, unit: rgb) (acc: ['read', 'notify', 'write'])
                  Range: [0, 16777215, 1]
          siid 4: piid: 5 (ledboard-color): (uint32, unit: rgb) (acc: ['read', 'notify', 'write'])
                  Range: [0, 16777215, 1]
          siid 4: piid: 6 (ledboard-stream): (uint16, unit: none) (acc: ['read', 'notify', 'write'])
                  Range: [0, 360, 1]
          siid 4: piid: 7 (ledboard-speed): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                  Range: [0, 100, 1]
          siid 4: piid: 8 (ledboard-time-switch): (bool, unit: none) (acc: ['read', 'notify', 'write'])
          siid 4: piid: 9 (ledboard-time-open): (string, unit: none) (acc: ['read', 'notify', 'write'])
          siid 4: piid: 10 (ledboard-time-close): (string, unit: none) (acc: ['read', 'notify', 'write'])
          siid 4: piid: 11 (feed-time-switch): (bool, unit: none) (acc: ['read', 'notify', 'write'])
          siid 4: piid: 12 (feed-time): (string, unit: none) (acc: ['read', 'notify', 'write'])
          siid 4: piid: 13 (feed-num): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                  Range: [1, 30, 1]
          siid 4: piid: 14 (key-switch): (bool, unit: none) (acc: ['read', 'notify', 'write'])
          siid 4: piid: 15 (feed-time-week): (uint8, unit: none) (acc: ['read', 'notify', 'write'])
                  Range: [0, 127, 1]
          siid 4: piid: 16 (feed-record): (string, unit: none) (acc: [])
          siid 4: piid: 17 (log): (string, unit: none) (acc: [])

  ## Actions ##
          siid 4: aiid 1 set-feed-single: in: [13] -> out: []

  ## Events ##
          siid 4: eiid 1 (feed-record): (args: [16])
          siid 4: eiid 2 (log-up): (args: [17])
syssi commented

@rezmus It's possible to call aiid's from the local network or it's cloud only?

@syssi depends. most actions you are just cmds with action method sent to device, they should work from local. some actions are special handled only by cloud code, not really passed to device as cmd (for example action to open gh/alexa rtsp stream for some cams).

many actions using "in" params are not well described by spec files, you need to log device to get proper format.

If I use in python-miio
miiocli miotdevice --ip 192.0.3.171 --token xxx raw_command call_action "[{'did': 'feed_fish', 'siid': 4, 'aiid': 1}]"

That return this:
[182, 4, 0]

And the action is working fine.

Finally it is working if I use this:

alias: pecera_alimenta_peces
sequence:
  - service: xiaomi_miio_raw.sensor_raw_command
    data:
      entity_id: sensor.pecera
      method: call_action
      params:
        - did: feed
          siid: 4
          aiid: 1
mode: single
icon: 'mdi:shaker'

The only thing I get an error, but the action works:


2021-04-11 17:59:00 ERROR (MainThread) [homeassistant.components.script.pecera_alimenta_peces] pecera_alimenta_peces: Error executing script. Unexpected error for call_service at pos 1: 'int' object is not subscriptable
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 359, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 559, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1480, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1515, in _execute_service
    await handler.job.target(service_call)
  File "/config/custom_components/xiaomi_miio_raw/sensor.py", line 132, in async_service_handler
    yield from getattr(device, method["method"])(**params)
  File "/config/custom_components/xiaomi_miio_raw/sensor.py", line 338, in async_command
    await self._try_command(
  File "/config/custom_components/xiaomi_miio_raw/sensor.py", line 240, in _try_command
    return result and (result[0] == "ok" or result[0]["code"] == 0)
TypeError: 'int' object is not subscriptable
2021-04-11 17:59:00 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [140228354349616] 'int' object is not subscriptable
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 143, in handle_call_service
    await hass.services.async_call(
  File "/usr/src/homeassistant/homeassistant/core.py", line 1480, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1515, in _execute_service
    await handler.job.target(service_call)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 264, in service_handler
    await script_entity.async_turn_on(
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 375, in async_turn_on
    await coro
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 392, in _async_run
    return await self.script.async_run(variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 1195, in async_run
    await asyncio.shield(run.async_run())
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 341, in async_run
    await self._async_step(log_exceptions=False)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 359, in _async_step
    await getattr(self, handler)()
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 559, in _async_call_service_step
    await service_task
  File "/usr/src/homeassistant/homeassistant/core.py", line 1480, in async_call
    task.result()
  File "/usr/src/homeassistant/homeassistant/core.py", line 1515, in _execute_service
    await handler.job.target(service_call)
  File "/config/custom_components/xiaomi_miio_raw/sensor.py", line 132, in async_service_handler
    yield from getattr(device, method["method"])(**params)
  File "/config/custom_components/xiaomi_miio_raw/sensor.py", line 338, in async_command
    await self._try_command(
  File "/config/custom_components/xiaomi_miio_raw/sensor.py", line 240, in _try_command
    return result and (result[0] == "ok" or result[0]["code"] == 0)
TypeError: 'int' object is not subscriptable
syssi commented

Good job! We could try to make the expected response configurable. Do you know the meaning of the 3 values?

Not really, always return [182, 4, 0] each time I run the action

syssi commented

Please call the action tomorrow again. Is it always [182, 4, 0] or did some portion increase?

still the same:
[182, 4, 0]