larsbeck / HomematicIp

This package allows to query the HomematicIp REST and WebSocket endpoint.
MIT License
7 stars 2 forks source link

[Unsupported device] PUSH_BUTTON #4

Closed DevEddy closed 5 years ago

DevEddy commented 5 years ago

Hi Lars,

one more unsupported device.

{
    "id": "3014F711A000019709AA9C51",
    "homeId": "21edcd0f-2b62-4b28-b0fb-e8476834d493",
    "label": "Wandtaster",
    "lastStatusUpdate": 0,
    "type": "PUSH_BUTTON",
    "functionalChannels": {
        "0": {
            "label": "",
            "deviceId": "3014F711A000019709AA9C51",
            "index": 0,
            "groupIndex": 0,
            "functionalChannelType": "DEVICE_BASE",
            "groups": [
                "072abd4a-aa66-44b9-9743-b2c9bd13ff80"
            ],
            "unreach": null,
            "lowBat": null,
            "routerModuleEnabled": false,
            "routerModuleSupported": false,
            "rssiDeviceValue": null,
            "rssiPeerValue": null,
            "configPending": false,
            "dutyCycle": null
        },
        "1": {
            "label": "",
            "deviceId": "3014F711A000019709AA9C51",
            "index": 1,
            "groupIndex": 1,
            "functionalChannelType": "SINGLE_KEY_CHANNEL",
            "groups": [
                "2ca09bf8-3892-4b9e-897e-6a938dc5db69"
            ]
        },
        "2": {
            "label": "",
            "deviceId": "3014F711A000019709AA9C51",
            "index": 2,
            "groupIndex": 1,
            "functionalChannelType": "SINGLE_KEY_CHANNEL",
            "groups": [
                "2ca09bf8-3892-4b9e-897e-6a938dc5db69"
            ]
        }
    },
    "oem": "eQ-3",
    "manufacturerCode": 1,
    "firmwareVersion": "1.4.2",
    "updateState": "UP_TO_DATE",
    "firmwareVersionInteger": 66562,
    "liveUpdateState": "LIVE_UPDATE_NOT_SUPPORTED",
    "availableFirmwareVersion": "1.4.2",
    "serializedGlobalTradeItemNumber": "3014F711A000019709AA9C51",
    "modelType": "HMIP-WRC2",
    "modelId": 261,
    "permanentlyReachable": false
}

-- Eddy

larsbeck commented 5 years ago

Hi Eddy,

I have added support for PushButton devices. Actually, I think this is a device that is also an actor, not only a sensor. If so, would it help if you could programmatically push that button?

Lars

DevEddy commented 5 years ago

Hi Lars,

yeah, thanks

-- Eddy

DevEddy commented 5 years ago

Hi Lars,

sorry, I hadn't time to test it out. I get the following error:

System.TypeInitializationException: The type initializer for 'HomematicIp.Data.EnumToType' threw an exception. ---> System.ArgumentException: An item with the same key has already been added. Key: PUSH_BUTTON
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
   at HomematicIp.Data.EnumToType..cctor() in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Data/EnumToType.cs:line 11
   --- End of inner exception stack trace ---
   at HomematicIp.Data.EnumToType.get_Map() in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Data/EnumToType.cs:line 11
   at HomematicIp.Data.EnumToType.GetType(Object o, String raw) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Data/EnumToType.cs:line 15
   at HomematicIp.Data.JsonConverters.AbstractListConverter`2.ReadJson(JsonReader reader, Type objectType, List`1 existingValue, Boolean hasExistingValue, JsonSerializer serializer) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Data/JsonConverters/AbstractListConverter.cs:line 30
   at Newtonsoft.Json.JsonConverter`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at HomematicIp.Services.HomematicService.GetCurrentState(CancellationToken cancellationToken) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Services/HomematicService.cs:line 54

I'll try to figure out what's going on.

-- Eddy

DevEddy commented 5 years ago

In the list, before it will be converted to the map I can see the PUSH_BUTTON twice:

image

larsbeck commented 5 years ago

Hi Eddy,

please check out the commit I just pushed. It should be fixed there.

Lars

DevEddy commented 5 years ago

Hi Lars, thanks for the fast action, now I'll get the following:

Newtonsoft.Json.JsonSerializationException: Could not create an instance of type HomematicIp.Data.HomematicIpObjects.Channels.DeviceSabotageChannelBase. Type is an interface or abstract class and cannot be instantiated. Path 'label', line 2, position 10.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewObject(JsonReader reader, JsonObjectContract objectContract, JsonProperty containerMember, JsonProperty containerProperty, String id, Boolean& createdFromNonDefaultCreator)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at HomematicIp.Data.JsonConverters.AbstractListConverter`2.ReadJson(JsonReader reader, Type objectType, List`1 existingValue, Boolean hasExistingValue, JsonSerializer serializer) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Data/JsonConverters/AbstractListConverter.cs:line 31
   at Newtonsoft.Json.JsonConverter`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at HomematicIp.Data.JsonConverters.AbstractListConverter`2.ReadJson(JsonReader reader, Type objectType, List`1 existingValue, Boolean hasExistingValue, JsonSerializer serializer) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Data/JsonConverters/AbstractListConverter.cs:line 31
   at Newtonsoft.Json.JsonConverter`1.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   at HomematicIp.Services.HomematicService.GetCurrentState(CancellationToken cancellationToken) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp/Services/HomematicService.cs:line 54
   at HomematicIp.Console.Program.Main(String[] args) in /Users/eschaefer/Documents/GitHub/HomematicIp/src/HomematicIp.Console/Program.cs:line 74

-- Eddy

larsbeck commented 5 years ago

Hi Eddy,

the latest commit should fix this.

Lars

DevEddy commented 5 years ago

Hi Lars, yep it's fixed. I've got another device... issue is on the way.

PS: Could you short explain how you figured out what to do to fix this based on the stack trace?

Thank you.

-- Eddy

larsbeck commented 5 years ago

Sure. DeviceSabotageChannelBase is an abstract class. It had an attribute (SINGLE_KEY_CHANNEL) attached which tells the system that whenever it sees a channel of this type, it should try to create an instance of the class which has this very attribute. Since that class is abstract, it cannot be instantiated. I create a new non-abstract class, inheriting from DeviceSabotageChannelBase and put the attribute there.

So basically there are different "channels" that are all in the same Json array. A "type" property holds the information what kind of channel was serialized. This information is then used to find the appropriate class to deserialize an entry in the channel list. This construct is also found in other parts of the system, not only channels.