Json_attributes not functioning properly with command_line sensor integration

Hi there,

Because there’s no integration for the Voltcraft SEM6000 power switch/measurement device, I’m trying to implement an Expect script I found at htt ps://github.com/Heckie75/voltcraft-sem-6000) which is able to output JSON data. I’m using the command_line integration as a sensor.

As the device outputs multiple values (voltage/ampere/watts/powerfactor among others), I thought it would be wise to use the json_attributes, just like the documentation linked above describes:

The example shows how you can retrieve multiple values with one sensor (where the additional are attributes) by using value_json and json_attributes .

This is my current configuration:

sensor:
  - platform: command_line
    name: koelkast
    json_attributes:
      - voltage
      - ampere
      - watts
      - power_factor
      - total
    command: '/usr/local/bin/sem-6000.exp AB:CD:12:34:56:78 1234 --status --json'
    command_timeout: 30
    value_template: '{{ value_json.status }}'  

The output of the sem-6000.exp script is as followed:

homeassistant@raspberrypi:~ $ sem-6000.exp 2C:AB:33:01:11:D7 1590 --status --json
{
  "device" : null,
  "status" : {
    "power" : 1,
    "voltage" : 228,
    "ampere" : 0.013,
    "watts" : 0.59,
    "frequency" : 50,
    "power_factor" : 0.20,
    "total" : 0.0
  },
  "settings" : null,
  "schedulers" : null,
  "countdown" : null,
  "randommode" : null,
  "data_per_hour" : [
  ],
  "data_per_day" : [
  ],
  "data_per_month" : [
  ]
}
homeassistant@raspberrypi:~ $

By using value_template: '{{ value_json.status }}' I expected HA would select only the JSON dictionary under the key status. And I expected json_attributes would extract the keys used in that option from the status dictionary.

Unfortunately, I’m getting an entity sensor.fridge with the value {'power': 1, 'voltage': 227, 'ampere': 0.013, 'watts': 0.635, 'frequency': 50, 'power_factor': 0.22, 'total': 0.0} and the only state attributes the entity contains is friendly_name.

So it seems value_template works, but json_attributes does not work :slightly_frowning_face: There are also no other entities like sensor.fridge_watts to be found in the Developer Tools.

I’ve tried to add some extra debug logging to the source file, especially between lines 103 and 128. According to this logging, it seems self._attributes is empty after the mapping.

So my theory is: the value_template is applied after HA tries to map the json_attributes over the initial value. But that doesn’t make sense, especially when the example from the documentation shows a similar example as what I’m trying, right?

My question to you all: is my theory remotely correct? Does anyone have experience with this json_attributes and the command_line sensor integration? And does anyone know what I’m doing wrong? I thought it would be rather simple…

My HA version is 0.112.3 and runs on a Raspberry Pi in a venv.

Hello, welcome to the community!

Unfortunately, that’s now how json attributes work. The json attributes are always pulled from the root json. So with that being said, the correct configuration would be:

sensor:
  - platform: command_line
    name: koelkast
    json_attributes:
      - status
    command: '/usr/local/bin/sem-6000.exp AB:CD:12:34:56:78 1234 --status --json'
    command_timeout: 30
    value_template: '{{ value_json.status.total }}'  

I added .total to your value_template so that the sensor itself updates when the attributes update.

EDIT: Then to grab attributes from your newly created sensor…

state_attr('sensor.koelkast', 'status').power

or

state_attr('sensor.koelkast', 'status')['power']
3 Likes

Thanks!

I see. Is that a (semi) recent change? As you explicitely say “now”, I assume it used to work differently in the past. I’m also wondering, would the last example from the sensor.command_line documentation also fail now?

Thanks! Now I’ve got my 5 variables working and graphing!

Nope, it’s always worked that way. There are other integrations that added a ‘attributes_path’ field to dive in further but this integration does not have that.

Seeing that you can’t see the json that datetime.py produces, its hard to say.

I’m attempting to do something very similar but no luck getting the attributes to populate.

  - platform: command_line
    name: openuv_custom # use same name as official integration to make swapping easier but could cause conflict if integration enabled again.
    unit_of_measurement: "UV index"
    scan_interval: 900 # 900 = 15min
    json_attributes:
      - result.uv
      - result.uv_max
    command: "curl -X GET 'https://api.openuv.io/api/v1/uv?lat=50.661972&lng=-120.271317' -H 'x-access-token: 1234567'"
    value_template: '{{ value_json.result.uv }}'

The state gets update with the uv value as expected but no attributes show up when I inspect the sensor in Developer Tools > States. I’ve tried various methods including value_json.result.uv and others.

image

Probably because the attributes aren’t actually getting populated the methods in this thread for accessing them aren’t returning results either.

Obviously I’m doing something wrong but can’t see what.

source json:

{
    "result": {
        "uv": 4.0549,
        "uv_time": "2020-09-14T18:19:47.620Z",
        "uv_max": 4.9869,
        "uv_max_time": "2020-09-14T19:57:51.829Z",
        "ozone": 268.5,
        "ozone_time": "2020-09-14T18:04:15.383Z",
        "safe_exposure_time": {
            "st1": 41,
            "st2": 49,
            "st3": 66,
            "st4": 82,
            "st5": 132,
            "st6": 247
        },
        "sun_info": {
            "sun_times": {
                "solarNoon": "2020-09-14T19:57:51.829Z",
                "nadir": "2020-09-14T07:57:51.829Z",
                "sunrise": "2020-09-14T13:37:16.681Z",
                "sunset": "2020-09-15T02:18:26.977Z",
                "sunriseEnd": "2020-09-14T13:40:39.455Z",
                "sunsetStart": "2020-09-15T02:15:04.204Z",
                "dawn": "2020-09-14T13:04:14.070Z",
                "dusk": "2020-09-15T02:51:29.588Z",
                "nauticalDawn": "2020-09-14T12:24:44.979Z",
                "nauticalDusk": "2020-09-15T03:30:58.679Z",
                "nightEnd": "2020-09-14T11:43:02.384Z",
                "night": "2020-09-15T04:12:41.275Z",
                "goldenHourEnd": "2020-09-14T14:20:27.182Z",
                "goldenHour": "2020-09-15T01:35:16.476Z"
            },
            "sun_position": {
                "azimuth": -0.5509677802559169,
                "altitude": 0.6680640570273015
            }
        }
    }
}

Got it working by listing a single json_attribute with result (the top level json object).

  - platform: command_line
    name: openuv_custom # use same name as official integration to make swapping easier but could cause conflict if integration enabled again.
    unit_of_measurement: "UV index"
    scan_interval: 900 # 900 = 15min
    json_attributes:
      - result
    command: "curl -X GET 'https://api.openuv.io/api/v1/uv?lat=50.661972&lng=-120.271317' -H 'x-access-token: 1234567'"
    value_template: '{{ value_json.result.uv }}'

Then uv and uv_max were accessible via the method discussed in this thread.

{{ state_attr('sensor.openuv_custom', 'result').uv }}

However, is there not a way to select just specific values via json_attributes section like I was attempting? For example, if I just want uv and uv_max returned as attributes for this command_line sensor. I’ve seen examples elsewhere but could not get them to work.

commandline sensor assumes the json is at the root level. The way you have it is the only option.

Have you tried the Rest Sensor? It’s built for doing what you’re attempting to do with curl.

You can specify json_attributes_path with that. Yours would look like:

json_attributes_path: "$.result"
json_attributes:
- uv
- uv_max
1 Like

Lame, but thanks for the answer!

I am using REST sensor for something else but I require some way to control the interval at which it makes the calls to stay under API request limits, hence using command_line which supports scan_interval

Looking at the documentation for the REST sensor it does not official list scan_interval but uses it in one of the examples. Any idea if it’s actually supported? I can play around but would rather not push my request numbers up further artificially if I can avoid it.

sensor:
# Steam Controller
  - platform: rest
    name: Steam System Data
    resource: http://192.168.1.105/status.xml
    json_attributes_path: "$.response"
    scan_interval: 15
    value_template: 'OK'
    json_attributes:
      - "usr0"
      - "pot0"
      - "temp0"
      - "time0"

rest does too, doc’s might not explicitly say that… but it does support it.

1 Like

Excellent, thanks!

Hello All

For a total newbie on this, anyone has the time to fill me in on this step by step?
I´ve bought 3 of those way back ago and it would be nice to intergrate those into Home Assistant

I read this but i didint get it Im afraid.

Can please someone help me?

Kindest

Steven