hsakoh / switchbot-mqtt

SwitchBot MQTT Home Assistant add-on
MIT License
30 stars 1 forks source link

Unable to fetch devices: "Sequence contains no matching element" #3

Closed ravishivt closed 10 months ago

ravishivt commented 10 months ago

(This project is very exciting, thanks for bridging a pretty large gap for SwitchBot.)

I'm having trouble getting started with this add-on. I installed it via the HAOS add-on method on RPi 4, added the SwitchBot API keys and ngrok details into the config, and restarted the add-on. When I attempt to fetch the devices using the UI, I get an infinite spinner. See below for the logs (w/ sanitized device IDs). From the logs, I see the add-on fetches all three devices successfully but fails to parse what it needs out of the response.

The SwitchBot products I own are as follows. My goal is to expose+control my curtains via HomeAssistant (I think this would be supported by this add-on but correct me if wrong).

20:39:46 warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35] No XML encryptor configured. Key {60b6215b-a087-4d1b-97cb-49f5ff7d24cf} may be persisted to storage in unencrypted form.
20:39:46 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://[::]:8098
20:39:46 info: Microsoft.Hosting.Lifetime[14] Now listening on: http://[::]:8099
20:39:46 info: Microsoft.Hosting.Lifetime[0] Application started. Press Ctrl+C to shut down.
20:39:46 info: Microsoft.Hosting.Lifetime[0] Hosting environment: Production
20:39:46 info: Microsoft.Hosting.Lifetime[0] Content root path: /app/
20:40:09 info: SwitchBotMqttApp.Logics.DeviceConfigurationManager[0] device configuration file missing.
20:40:11 trce: SwitchBotMqttApp.Logics.SwitchBotApiClient[0] Send GET,devices
20:40:12 trce: SwitchBotMqttApp.Logics.SwitchBotApiClient[0] Response GET,https://api.switch-bot.com/v1.1/devices,{"statusCode":100,"body":{"deviceList":[{"deviceId":"D9F1XXXXX","deviceName":"West Bedroom, North Window Left","enableCloudService":true,"hubDeviceId":"FF06XXXXXX","curtainDevicesIds":["D9F1XXXXXX"],"calibrate":true,"group":false,"master":true,"openDirection":"left"},{"deviceId":"F2A2XXXXXX","deviceName":"West Bedroom, West Window Left","enableCloudService":true,"hubDeviceId":"FF06E03A67C7","curtainDevicesIds":["F2A2XXXXXX"],"calibrate":true,"group":false,"master":true,"openDirection":"left"},{"deviceId":"FF06XXXXXX","deviceName":"SwitchBot Hub 2-1","deviceType":"Hub 2","enableCloudService":true,"hubDeviceId":"000000000000"}],"infraredRemoteList":[]},"message":"success"}
20:40:12 warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100] Unhandled exception rendering component: Sequence contains no matching element System.InvalidOperationException: Sequence contains no matching element    at System.Linq.ThrowHelper.ThrowNoMatchException()    at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)    at SwitchBotMqttApp.Logics.DeviceConfigurationManager.<>c__DisplayClass8_0.<LoadDevicesAsync>b__0(Devicelist d) in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Logics\DeviceConfigurationManager.cs:line 66    at System.Linq.Enumerable.SelectArrayIterator`2.ToList()    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)    at SwitchBotMqttApp.Logics.DeviceConfigurationManager.LoadDevicesAsync(DevicesConfig currentData, CancellationToken cancellationToken) in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Logics\DeviceConfigurationManager.cs:line 66    at SwitchBotMqttApp.Pages.DeviceConfiguration.FetchSwitchBotApi() in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Pages\DeviceConfiguration.razor.cs:line 40    at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)    at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
20:40:12 fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111] Unhandled exception in circuit 'dtQl4z5awnCYRtfOw26vaRkD2gYSZLmEoJutQsmQc4I'. System.InvalidOperationException: Sequence contains no matching element    at System.Linq.ThrowHelper.ThrowNoMatchException()    at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)    at SwitchBotMqttApp.Logics.DeviceConfigurationManager.<>c__DisplayClass8_0.<LoadDevicesAsync>b__0(Devicelist d) in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Logics\DeviceConfigurationManager.cs:line 66    at System.Linq.Enumerable.SelectArrayIterator`2.ToList()    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)    at SwitchBotMqttApp.Logics.DeviceConfigurationManager.LoadDevicesAsync(DevicesConfig currentData, CancellationToken cancellationToken) in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Logics\DeviceConfigurationManager.cs:line 66    at SwitchBotMqttApp.Pages.DeviceConfiguration.FetchSwitchBotApi() in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Pages\DeviceConfiguration.razor.cs:line 40    at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)    at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
hsakoh commented 10 months ago

The absence of the DeviceType is the cause of the error.

{
    "deviceId": "D9F1XXXXX",
    "deviceName": "West Bedroom, North Window Left",
    "enableCloudService": true,
    "hubDeviceId": "FF06XXXXXX",
    "curtainDevicesIds": [
        "D9F1XXXXXX"
    ],
    "calibrate": true,
    "group": false,
    "master": true,
    "openDirection": "left"
}

It's possible that there may be some API-related reasons, such as lack of support for Curtain v3.

For the conventional curtain, the following response is returned.

{
    "deviceId": "FFF9XXXXXXXX",
    "deviceName": "My Curtain",
    "deviceType": "Curtain",
    "enableCloudService": true,
    "hubDeviceId": "CA08XXXXXXXX",
    "curtainDevicesIds": [
        "FFF9XXXXXXXX"
    ],
    "calibrate": true,
    "group": false,
    "master": true,
    "openDirection": "right"
}

To address the issue of DeviceType being missing, we are planning to create a temporary version that will treat DeviceType as "Curtain" when absent. Please bear with us for a while.

hsakoh commented 10 months ago

@ravishivt I released version v1.0.3. Added the 'EnforceDeviceTypes' option. You can forcibly overwrite the Device ID and type of curtain v3 as follows. Please give it a try! image

hsakoh commented 10 months ago

Track similar issues https://github.com/OpenWonderLabs/homebridge-switchbot/issues/816

ravishivt commented 10 months ago

Beautiful, it works! Thanks for the quick patch here! Sounds like this workaround won't be necessary once SwitchBot fixes their APIs.

Screenshot 2023-09-09 at 11 37 53 PM
hsakoh commented 10 months ago

https://github.com/OpenWonderLabs/SwitchBotAPI/issues/241

paolodc95 commented 1 month ago

Hi, I'm having the same error. This is the response from the /devices GET

{
    "body": {
        "deviceList": [
            {
                "calibrate": true,
                "curtainDevicesIds": [
                    "C0C626B7B977"
                ],
                "deviceId": "C0C626B7B977",
                "deviceName": "Tenda studio",
                "deviceType": "Curtain3",
                "enableCloudService": true,
                "group": false,
                "hubDeviceId": "F63D5924C3DF",
                "master": true,
                "openDirection": "left"
            },
            {
                "deviceId": "CF420E85326A",
                "deviceName": "Lock Pro",
                "deviceType": "Smart Lock Pro",
                "enableCloudService": true,
                "group": false,
                "hubDeviceId": "F63D5924C3DF",
                "lockDevicesIds": [
                ],
                "master": true
            },
            {
                "calibrate": true,
                "curtainDevicesIds": [
                    "DB030D640972"
                ],
                "deviceId": "DB030D640972",
                "deviceName": "Tenda camera",
                "deviceType": "Curtain3",
                "enableCloudService": true,
                "group": false,
                "hubDeviceId": "F63D5924C3DF",
                "master": true,
                "openDirection": "left"
            },
            {
                "deviceId": "DBEBFBD305EE",
                "deviceName": "Tastiera",
                "deviceType": "Keypad Touch",
                "enableCloudService": true,
                "hubDeviceId": "F63D5924C3DF",
                "keyList": [
                    {
                        "createTime": 1695206534000,
                        "id": 11,
                        "iv": "iv",
                        "name": "code",
                        "password": "password",
                        "status": "normal",
                        "type": "permanent"
                    }
                ],
                "lockDeviceId": "CF420E85326A"
            },
            {
                "calibrate": true,
                "curtainDevicesIds": [
                    "E9A06C92E251",
                    "F2D8713E6DD5"
                ],
                "deviceId": "E9A06C92E251",
                "deviceName": "Tenda salotto",
                "deviceType": "Curtain3",
                "enableCloudService": true,
                "group": true,
                "hubDeviceId": "F63D5924C3DF",
                "master": true,
                "openDirection": "left"
            },
            {
                "calibrate": false,
                "curtainDevicesIds": [
                    "E9A06C92E251",
                    "F2D8713E6DD5"
                ],
                "deviceId": "F2D8713E6DD5",
                "deviceName": "Curtain 3 D5",
                "deviceType": "Curtain3",
                "group": true,
                "hubDeviceId": "000000000000",
                "master": false,
                "openDirection": "right"
            },
            {
                "deviceId": "F63D5924C3DF",
                "deviceName": "Hub Mini",
                "deviceType": "Hub Mini2",
                "enableCloudService": true,
                "hubDeviceId": "000000000000"
            },
            {
                "deviceId": "F9265F23C5F3",
                "deviceName": "Bot",
                "deviceType": "Bot",
                "enableCloudService": true,
                "hubDeviceId": "F63D5924C3DF"
            }
        ],
        "infraredRemoteList": [
        ]
    },
    "message": "success",
    "statusCode": 100
}

and this is the error message from the log page:

fail: SwitchBotMqttApp.Logics.DeviceConfigurationManager[0] LoadDevicesAsync error. System.InvalidOperationException: Sequence contains no matching element    at System.Linq.ThrowHelper.ThrowNoMatchException()    at System.Linq.Enumerable.First[TSource](IEnumerable`1 source, Func`2 predicate)    at SwitchBotMqttApp.Logics.DeviceConfigurationManager.<>c__DisplayClass9_0.<LoadDevicesAsync>b__0(Devicelist d) in C:\github\hsakoh\switchbot-mqtt\src\SwitchBotMqttApp\Logics\DeviceConfigurationManager.cs:line 86    at System.Linq.Enumerable.SelectArrayIterator`2.ToList()    at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)    at SwitchBotMqttApp.Logics.DeviceConfigurationManager.LoadDevicesAsync(DevicesConfig currentData, CancellationToken cancellationToken)
hsakoh commented 1 month ago

@paolodc95 An exception is occurring because the list includes devices with unknown DeviceTypes that are not in the API specifications. Specifically, the Hub Mini2.

Since the API specifications for this device are unknown, please temporarily add it to the add-on configuration to interpret it as a Hub Mini.

EnforceDeviceTypes:
  - DeviceId: F63D5924C3DF
    DeviceType: Hub Mini

image

Just for reference, could you let me know the model number of the Hub Mini2 device? (Is it possible that the Matter-compatible version of the Hub Mini responds this way?) Since new devices are added relatively frequently, I am considering changing the implementation to log unknown devices and avoid causing exceptions.

hsakoh commented 1 month ago

@paolodc95 I have released version 1.0.14, which changes the specification to log unknown device types and continue processing without causing exceptions when retrieving the device list. This should prevent errors without any additional action, but if you want to recognize the Hub Mini, please refer to the previous comment and specify EnforceDeviceTypes.

paolodc95 commented 1 month ago

@hsakoh Thank you very much! The hub mini 2 is the new version that support matter, as you said. It came in bundle with the new smart lock pro just released (https://www.switch-bot.com/products/switchbot-lock-pro?variant=44773327241383)