Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GetDeviceStatus returns null #23

Open
ChristopherSnay opened this issue Jan 21, 2024 · 2 comments
Open

GetDeviceStatus returns null #23

ChristopherSnay opened this issue Jan 21, 2024 · 2 comments

Comments

@ChristopherSnay
Copy link

ChristopherSnay commented Jan 21, 2024

The GetDeviceStatus and GetDeviceStatusAsync methods are returning null. I'm able to use the other methods just fine. I am also able to call the API directly from Postman and get the status. Any ideas why only this one would return null?

@bitapparat
Copy link

The method is trying to parse the response as Dictionary<string, string>, but the response returns complex JSON objects, not just strings. Thus, the parsing fails.

Here's an exemplary response that SmartThingsNet fails to parse:

{ "relativeHumidityMeasurement": { "humidity": { "value": 86.0, "unit": "%", "timestamp": "2024-12-21T10:37:16.262Z" } }, "temperatureMeasurement": { "temperatureRange": { "value": null }, "temperature": { "value": 6.6, "unit": "C", "timestamp": "2024-12-21T10:53:31.603Z" } }, "refresh": {}, "firmwareUpdate": {} }

@bitapparat
Copy link

I wrote a quick workaround that flattens the result into Dictionary<string, object> instead like this:

"relativeHumidityMeasurement.humidity.value": 86
"relativeHumidityMeasurement.humidity.unit": "%"
"relativeHumidityMeasurement.humidity.timestamp": {21.12.2024 10:37:16}
"temperatureMeasurement.temperature.value": 6.6
"temperatureMeasurement.temperature.unit": "C"
"temperatureMeasurement.temperature.timestamp": {21.12.2024 10:53:31}

Here's the code. Put the class into your project and change the method call from GetDeviceComponentStatus to GetDeviceComponentStatusFixed.

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using SmartThingsNet.Api;
using SmartThingsNet.Client;


static class SmartThingsNetFixes
{

    public static async Task<Dictionary<string, object>> GetDeviceComponentStatusFixedAsync(this DevicesApi devicesApi, string authorization, string deviceId, string componentId, CancellationToken cancellationToken = default(CancellationToken))
    {
        return (await GetDeviceComponentStatusFixedWithHttpInfoAsync(devicesApi, authorization, deviceId, componentId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false)).Data;
    }

    public static async Task<ApiResponse<Dictionary<string, object>>> GetDeviceComponentStatusFixedWithHttpInfoAsync(this DevicesApi devicesApi, string authorization, string deviceId, string componentId, CancellationToken cancellationToken = default(CancellationToken))
    {
        if (authorization == null)
        {
            throw new ApiException(400, "Missing required parameter 'authorization' when calling DevicesApi->GetDeviceComponentStatus");
        }

        if (deviceId == null)
        {
            throw new ApiException(400, "Missing required parameter 'deviceId' when calling DevicesApi->GetDeviceComponentStatus");
        }

        if (componentId == null)
        {
            throw new ApiException(400, "Missing required parameter 'componentId' when calling DevicesApi->GetDeviceComponentStatus");
        }

        RequestOptions requestOptions = new RequestOptions();
        string[] contentTypes = new string[1] { "application/json" };
        string[] accepts = new string[1] { "application/json" };
        string text = ClientUtils.SelectHeaderContentType(contentTypes);
        if (text != null)
        {
            requestOptions.HeaderParameters.Add("Content-Type", text);
        }

        string text2 = ClientUtils.SelectHeaderAccept(accepts);
        if (text2 != null)
        {
            requestOptions.HeaderParameters.Add("Accept", text2);
        }

        requestOptions.PathParameters.Add("deviceId", ClientUtils.ParameterToString(deviceId));
        requestOptions.PathParameters.Add("componentId", ClientUtils.ParameterToString(componentId));
        if (!string.IsNullOrEmpty(devicesApi.Configuration.AccessToken) && !requestOptions.HeaderParameters.ContainsKey("Authorization"))
        {
            requestOptions.HeaderParameters.Add("Authorization", "Bearer " + devicesApi.Configuration.AccessToken);
        }

        ApiResponse<Dictionary<string, JToken>> apiResponse = await devicesApi.AsynchronousClient.GetAsync<Dictionary<string, JToken>>("/devices/{deviceId}/components/{componentId}/status", requestOptions, devicesApi.Configuration, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
        if (devicesApi.ExceptionFactory != null)
        {
            Exception ex = devicesApi.ExceptionFactory("GetDeviceComponentStatus", apiResponse);
            if (ex != null)
            {
                throw ex;
            }
        }

        return new ApiResponse<Dictionary<string, object>>(apiResponse.StatusCode, apiResponse.Headers, FlattenDictionary(apiResponse.Data), apiResponse.RawContent);
    }

    static Dictionary<string, object> FlattenDictionary(Dictionary<string, JToken> response)
    {
        var res = new Dictionary<string, object>();
        if (response != null)
        {
            foreach (var entry in response)
            {
                FlattenJToken(entry.Key, entry.Value, res);
            }
        }
        return res;
    }
    private static void FlattenJToken(string path, JToken token, Dictionary<string, object> results)
    {
        switch (token.Type)
        {
            case JTokenType.Object:
                foreach (JProperty prop in token.Children<JProperty>())
                {
                    FlattenJToken(path + "." + prop.Name, prop.Value, results);
                }
                break;

            case JTokenType.Array:
                int index = 0;
                foreach (JToken value in token.Children())
                {
                    FlattenJToken(path + "[" + index + "]", value, results);
                    index++;
                }
                break;

            default:
                results.Add(path, ((JValue)token).Value);
                break;
        }
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants