merdok / homebridge-miot

Homebridge plugin for devices supporting the Xiaomi miot protocol
MIT License
383 stars 62 forks source link

Add smart speaker support. #393

Closed 0x5e closed 1 year ago

0x5e commented 1 year ago

Hi, I was trying to support the smart speaker, and currently not finished yet, I faced some trouble. From logs I didn't see anything wrong, but the accessory not appeared. Could you please help review the code to see if the code style & format is correct and maybe anything I was missing to do?

This is a famous smart speaker in China named "小爱音箱Pro / Mi AI Speaker Pro".

Spec: https://home.miot-spec.com/spec/xiaomi.wifispeaker.lx06

Edit: accessory appeared as 'Not responding'.

0x5e commented 1 year ago

Here's the config and logs:

{
  "platforms": [{
    "devices": [
      {
        "name": "小爱音响Pro",
        "ip": "x.x.x.x",
        "token": "xxxxxx",
        "model": "xiaomi.wifispeaker.lx06",
        "pollingInterval": 10,
        "deepDebugLog": true,
        "micloud": {
          "username": "xxx",
          "password": "xxx",
          "country": "cn"
        },
        "buzzerControl": false,
        "ledControl": false,
        "childLockControl": false,
        "modeControl": false
      }
    ],
    "platform": "miot"
  }]
}
~/workspace/ (develop) » homebridge -D -U ~/.homebridge-dev
[2022/11/20 16:05:29] Loaded config.json with 0 accessories and 1 platforms.
[2022/11/20 16:05:29] Loaded 1 cached accessories from cachedAccessories.
[2022/11/20 16:05:29] ---
[2022/11/20 16:05:29] Loaded plugin: homebridge-miot@1.4.3
[2022/11/20 16:05:29] Registering platform 'homebridge-miot.miot'
[2022/11/20 16:05:29] ---
[2022/11/20 16:05:29] Loaded plugin: @0x5e/homebridge-tuya-platform@1.6.0-beta.37
[2022/11/20 16:05:29] Registering platform '@0x5e/homebridge-tuya-platform.TuyaPlatform'
[2022/11/20 16:05:29] ---
[2022/11/20 16:05:29] Loading 1 platforms...
[2022/11/20 16:05:29] [miot] Initializing miot platform...
[2022/11/20 16:05:29] [miot] Found cached accessory 小爱音响Pro
[2022/11/20 16:05:29] [miot] Initializing devices
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Got device configuration, initializing device with name: 小爱音响Pro
[2022/11/20 16:05:29] [miot] No accessories to remove!
[2022/11/20 16:05:29] Publishing bridge accessory (name: Homebridge, publishInfo: {
  username: 'XX:XX:XX:XX:XX:XX',
  port: undefined,
  pincode: '***-**-***',
  category: 2,
  bind: undefined,
  mdns: undefined,
  addIdentifyingMaterial: true,
  advertiser: undefined
}).
Setup Payload:
X-HM://XXXXXXXXXXXXX
Scan this code with your HomeKit app on your iOS device to pair with Homebridge:

Or enter this code with your HomeKit app on your iOS device to pair with Homebridge:

    ┌────────────┐
    │ XXX-XX-XXX │
    └────────────┘

[2022/11/20 16:05:29] Homebridge v1.6.0-beta.4 (HAP v0.11.0) (Homebridge) is running on port 60275.
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Found cached device information: xiaomi.wifispeaker.lx06
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Model known: xiaomi.wifispeaker.lx06!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initializing device!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Creating device instance by model: xiaomi.wifispeaker.lx06!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a .DS_Store device! Device class could not be found: ../modules/.DS_Store/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a airconditioner device! Device class could not be found: ../modules/airconditioner/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a airer device! Device class could not be found: ../modules/airer/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a airfryer device! Device class could not be found: ../modules/airfryer/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a airmonitor device! Device class could not be found: ../modules/airmonitor/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a airpurifier device! Device class could not be found: ../modules/airpurifier/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a bathheater device! Device class could not be found: ../modules/bathheater/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a camera device! Device class could not be found: ../modules/camera/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a ceilingfan device! Device class could not be found: ../modules/ceilingfan/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a coffeemachine device! Device class could not be found: ../modules/coffeemachine/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a cooker device! Device class could not be found: ../modules/cooker/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a curtain device! Device class could not be found: ../modules/curtain/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a custom device! Device class could not be found: ../modules/custom/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a dehumidifier device! Device class could not be found: ../modules/dehumidifier/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a fan device! Device class could not be found: ../modules/fan/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a freshairsystem device! Device class could not be found: ../modules/freshairsystem/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a generic device! Device class could not be found: ../modules/generic/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a heater device! Device class could not be found: ../modules/heater/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a humidifier device! Device class could not be found: ../modules/humidifier/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a kettle device! Device class could not be found: ../modules/kettle/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a light device! Device class could not be found: ../modules/light/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a outlet device! Device class could not be found: ../modules/outlet/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a oven device! Device class could not be found: ../modules/oven/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Not a robotcleaner device! Device class could not be found: ../modules/robotcleaner/devices/xiaomi.wifispeaker.lx06.js
[2022/11/20 16:05:29] [miot] [小爱音响Pro] It is a speaker device! Found device class at ../modules/speaker/devices/xiaomi.wifispeaker.lx06.js!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initializing device services
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Device services: [
  "speaker",
  "play-control"
]
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initializing device properties
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Device properties: [
  "speaker:volume",
  "speaker:mute",
  "play-control:playing-state"
]
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initializing device actions
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initializing device events
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initial properties to monitor: [
  "speaker:volume",
  "speaker:mute"
]
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Successfully created a Speaker device! It is a Mi AI Speaker Pro.
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Found cached accessory for this device! Unregistering it first!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Initializing accessory!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Creating Speaker accessory for device 小爱音响Pro!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Found accessory class at ../modules/speaker/SpeakerAccessory.js!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Accessory successfully initialized!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Final properties to monitor: [
  "speaker:volume",
  "speaker:mute"
]
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Registering 1 accessories!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Everything looks good! Initiating property polling!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Log in to MiCloud!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Log in to MiCloud with username xxx. Request timeout: 5000 milliseconds.
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login step 1
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login step 1 result: OK - &&&START&&&{"serviceParam":"{\"checkSafePhone\":false,\"checkSafeAddress\":false,\"lsrp_score\":0.0}","qs":"%3Fsid%3Dxiaomiio%26_json%3Dtrue","code":70016,"description":"登录验证失败","securityStatus":0,"_sign":"xxx","sid":"xiaomiio","result":"error","captchaUrl":null,"callback":"https://sts.api.io.mi.com/sts","location":"https://account.xiaomi.com/fe/service/login?_json=true&sid=xiaomiio&qs=%253Fsid%253Dxiaomiio%2526_json%253Dtrue&callback=https%3A%2F%2Fsts.api.io.mi.com%2Fsts&_sign=xxx%3D&serviceParam=%7B%22checkSafePhone%22%3Afalse%2C%22checkSafeAddress%22%3Afalse%2C%22lsrp_score%22%3A0.0%7D&showActiveX=false&theme=&needTheme=false&bizDeviceType=","pwd":0,"child":0,"desc":"登录验证失败"}
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login step 2
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login step 2 result: OK - &&&START&&&{"qs":"%3Fsid%3Dxiaomiio%26_json%3Dtrue","ssecurity":"xxx","code":0,"passToken":"xxx","description":"成功","securityStatus":0,"nonce":xxx,"userId":xxx,"cUserId":"xxx","result":"ok","psecurity":"xxx","captchaUrl":null,"location":"https://sts.api.io.mi.com/sts?d=xxx&ticket=0&pwd=1&p_ts=1668931529000&fid=0&p_lm=1&auth=xxx&m=1&_group=DEFAULT&tsl=0&p_ca=0&p_ur=CN&p_idc=China&nonce=xxx&_ssign=xxx","pwd":1,"child":0,"desc":"成功"}
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login step 3
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login step 3 result: OK - ok
[2022/11/20 16:05:29] [miot] [小爱音响Pro] (MiCloud) Login successful!
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Using server country: cn
[2022/11/20 16:05:29] [miot] [小爱音响Pro] Successfully connected to MiCloud! Setting up miot device from MiCloud connection!
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Fetching device info from the MiCloud!
[2022/11/20 16:05:30] [miot] [小爱音响Pro] (MiCloud) Encrypted request https://api.io.mi.com/app/home/device_list - {"dids":["xxx"]}
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Got device info from MiCloud:
{
  "did": "xxx",
  "token": "xxx",
  "longitude": "0.0",
  "latitude": "0.0",
  "name": "Mi AI Speaker Pro",
  "pid": "0",
  "localip": "x.x.x.x",
  "mac": "XX:XX:XX:XX:XX:XX",
  "ssid": "xxx",
  "bssid": "XX:XX:XX:XX:XX:XX",
  "parent_id": "",
  "parent_model": "",
  "show_mode": 1,
  "model": "xiaomi.wifispeaker.lx06",
  "adminFlag": 1,
  "shareFlag": 0,
  "permitLevel": 16,
  "isOnline": true,
  "desc": "Device online ",
  "extra": {
    "isSetPincode": 0,
    "pincodeType": 0,
    "fw_version": "1.82.5",
    "needVerifyCode": 0,
    "isPasswordEncrypt": 0
  },
  "uid": xxx,
  "pd_id": 1233,
  "password": "",
  "p2p_id": "",
  "rssi": -44,
  "family_id": 0,
  "reset_flag": 0
}
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Connected to device: xiaomi.wifispeaker.lx06
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Doing initial property fetch.
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Preparing property poll!
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Splitting properties into chunks. Number of chunks: 1. Chunk size: 14
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Chunks:  [
 [
  "speaker:volume",
  "speaker:mute"
 ]
]
[2022/11/20 16:05:30] [miot] [小爱音响Pro] (MiCloud) Encrypted request https://api.io.mi.com/app/miotspec/prop/get - {"params":[{"did":"xxx","siid":2,"piid":1},{"did":"xxx","siid":2,"piid":2}]}
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Successfully saved device info!
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Successfully updated property chunk! RAW: [{"did":"xxx","siid":2,"piid":1,"value":6,"code":0,"updateTime":1668931438,"exe_time":0},{"did":"xxx","siid":2,"piid":2,"value":true,"code":0,"updateTime":1668931438,"exe_time":0}]
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Property speaker:volume value changed to ---> 6
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Property speaker:mute value changed to ---> true
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Got initial device properties:
[
  "speaker:volume: 6",
  "speaker:mute: true"
]
[2022/11/20 16:05:30] [miot] [小爱音响Pro] Starting property polling.
[2022/11/20 16:05:40] [miot] [小爱音响Pro] Preparing property poll!
[2022/11/20 16:05:40] [miot] [小爱音响Pro] Splitting properties into chunks. Number of chunks: 1. Chunk size: 14
[2022/11/20 16:05:40] [miot] [小爱音响Pro] Chunks:  [
 [
  "speaker:volume",
  "speaker:mute"
 ]
]
[2022/11/20 16:05:40] [miot] [小爱音响Pro] (MiCloud) Encrypted request https://api.io.mi.com/app/miotspec/prop/get - {"params":[{"did":"xxx","siid":2,"piid":1},{"did":"xxx","siid":2,"piid":2}]}
[2022/11/20 16:05:40] [miot] [小爱音响Pro] Successfully updated property chunk! RAW: [{"did":"xxx","siid":2,"piid":1,"value":6,"code":0,"updateTime":1668931438,"exe_time":0},{"did":"xxx","siid":2,"piid":2,"value":true,"code":0,"updateTime":1668931438,"exe_time":0}]
[2022/11/20 16:05:40] [miot] [小爱音响Pro] Device properties updated:
[
  "speaker:volume: 6",
  "speaker:mute: true"
]
0x5e commented 1 year ago

Bad news, seems we are not able to use SmartSpeaker and Speaker. https://github.com/homebridge/homebridge/issues/2553

merdok commented 1 year ago

Thanks for the PR, but as you already noticed the Smart Speaker accessory is not really working with homebridge. You could instead use the SWITCH accessory as the main service, which at least would give you controls over your device by using stateless buttons (Play, Pause, etc) and eventually volume by using a lightbulb or fan accessory, but you will not be able to display the currently playing media.

0x5e commented 1 year ago

OK, thanks for the suggest, I will update.

0x5e commented 1 year ago

The volume now can be controlled through Lightbulb Service, and Play/Pause/Next/Previous works with StatlessSwitch too. Mute is not working so I removed.

And there's still one issue I can't solved. The volume property I get from Mi Cloud is an old value, it will be updated after about 60s in my test. This is a server-side or device-side issue I think.

merdok commented 1 year ago

Thanks for that! I think we can merge it. I guess about the volume we cannot do anything, the device needs to sync the volume with the server and just then we can retrieve it...

merdok commented 1 year ago

I did some optimizations to the Speaker module, could you please sync the latest code from the repo and see if still everything works?

0x5e commented 1 year ago

Sure I will test when I'm at home.