TP Link struggles: Switch is available, but sensor UNavailable

Tags: #<Tag:0x00007f32636e1f08> #<Tag:0x00007f32636e1da0> #<Tag:0x00007f32636e1cb0>

I have ~12 TP-Link switches and outlets (HS100 and HS200) set up, added to HASSIO via the Integrations section rather than manually in the configuration.yaml file. I have avoided the manual config (i.e. listing all the IPs + names) method mostly due to this comment though I do not know if this is true. I would like to get them working as sensors so I can use the sensor outputs as triggers for various things.

I have copied the template sensor configuration directly from here, changing out the placeholder switch name for my own (switch.island) which is a HS200.

I’m aware of the issue (though not a solution) for TP Link devices periodically becoming unavailable, as discussed in this Git issue/thread, but believe this is a separate issue because according to its history, this particular switch (switch.island) rarely experiences this ‘unavailable’ issue.

Here is my set up:

Template Sensor config:

sensor:
  - platform: template
    sensors:
      my_tp_switch_amps:
        friendly_name_template: "{{ states.switch.island.name}} Current"
        value_template: '{{ states.switch.island.attributes["current_a"] | float }}'
        unit_of_measurement: 'A'
      my_tp_switch_watts:
        friendly_name_template: "{{ states.switch.island.name}} Current Consumption"
        value_template: '{{ states.switch.island.attributes["current_power_w"] | float }}'
        unit_of_measurement: 'W'
      my_tp_switch_total_kwh:
        friendly_name_template: "{{ states.switch.island.name}} Total Consumption"
        value_template: '{{ states.switch.island.attributes["total_energy_kwh"] | float }}'
        unit_of_measurement: 'kWh'
      my_tp_switch_volts:
        friendly_name_template: "{{ states.switch.island.name}} Voltage"
        value_template: '{{ states.switch.island.attributes["voltage"] | float }}'
        unit_of_measurement: 'V'
      my_tp_switch_today_kwh:
        friendly_name_template: "{{ states.switch.island.name}} Today's Consumption"
        value_template: '{{ states.switch.island.attributes["today_energy_kwh"] | float }}'
        unit_of_measurement: 'kWh'

Relevant Error Logs:

Could not render template my_tp_switch_amps: UndefinedError: 'mappingproxy object' has no attribute 'current_a'
6:45 AM components/template/sensor.py (ERROR)

Could not render template my_tp_switch_volts: UndefinedError: 'mappingproxy object' has no attribute 'voltage'
6:45 AM components/template/sensor.py (ERROR)

Could not render template my_tp_switch_watts: UndefinedError: 'mappingproxy object' has no attribute 'current_power_w'
6:45 AM components/template/sensor.py (ERROR)

Could not render template my_tp_switch_total_kwh: UndefinedError: 'mappingproxy object' has no attribute 'total_energy_kwh'
6:45 AM components/template/sensor.py (ERROR)

Could not render template my_tp_switch_today_kwh: UndefinedError: 'mappingproxy object' has no attribute 'today_energy_kwh'
6:45 AM components/template/sensor.py (ERROR)

I do have exactly the same problem. I have integrated the HS100 switches via configuration.yaml file, though.
hass installed on raspbian.

Would be grateful for any hint.

So I was mistaken on my hardware type - I thought I had HS100 and HS200’s but I actually have HS103’s (the cheaper version). Apparent;y, only the HS110’s supports energy monitoring. A few helpful redditors helped get me corrected here.

This link where I grabbed my sensor template config is old apparently. Even so, it erroneously claims the 103’s are “supported devices” but I guess they were just talking about the integration rather than energy monitoring. I went ahead and ordered a 110, since I want to use energy monitoring to notify me when my washer is finished.

This is why I cringe every time I see someone post a link to HA’s documentation. For example, the HS100 is listed under "Supported devices; " scroll to the bottom re: energy monitoring, and it clearly states, “for supported devices.” This tells me the HS100 is capable of extracting energy data, yet when I created a sensor template, my readings were at zero, and my dryer is running, plugged into HS100.

I hear ya. But in the end, my understanding is that HA documentation is open to edits from the community via git. I have not contributed - so until I do, I’ll reserve my own criticism of the documentation.

I ended up getting a HS110 for my washer and some cheaper etekcity outlets for other minor devices. I’ve been able to extract energy from these fine so far - good luck!

1 Like

Wow, those Etekcity WiFi smart plugs are inexpensive. I’d buy a bunch of them, but I haven’t found any indication that they can work directly with HA. I’m not really interested in depending on, maintaining an account on, and sharing my data with yet another cloud service.

Have you found a way to monitor and control them directly from HA?

They work just fine for me in HA - here is the config. The extraction of the energy data is the same as for the TP-Link integration.

Etekcity WiFi smart plugs run on the VeSync app. I don’t know how to verify my data on these plugs is staying local, but after I got the outlets set up on the app and integrated into HA, I just deleted the app. I guess it’s possible HA is sending data back to their cloud service, via the VeSync integration. How would I verify this?

1 Like

Thanks for the quick reply!

Looking at the VeSync integration at the link you posted, I see this:

# Example configuration.yaml entry
vesync:
  username: YOUR_USERNAME
  password: YOUR_PASSWORD

This suggests that the integration requires you to set up an account on the VeSync server, which in turn suggests it is logging on for you and retrieving data from the VeSync server, not from your local devices.

The way the TP-Link integration works, you still start with their “Kasa” app, but you can skip the step to set up an account on their server. Once the device is connected to your local WiFi network, you’re done with the app and HA takes over talking directly to the device.

The only problem is that the HA integration for TP-Link has trouble auto-detecting the devices, and keeps throwing “unavailable” errors. The Kasa app doesn’t seem to suffer from these same issues, so in my case I kept it installed.

The ideal would be a combination; Etekcity prices, a direct connection to HA, and an integration which works as well as Kasa. Not sure we’re going to see that.

I should add that, as much as I hate using another third-party cloud, some people might actually prefer that. For one thing, if HA dies when you’re away from home, you have a backup way to manage the devices.

That makes sense re the Etekcity reach back because of the login info in the HA config. Shucks.

Re: the TP Link unavailable errors, I initially let HA auto-discover all my TP link devices - which are the bulk of my system. When in auto-discover mode, I had the “unavailable” error pretty frequently, though I was never able to discern a pattern.

Someone on here suggested deleting the TP-Link integration from the Integrations page and starting over - this time setting static IPs on all the devices, and listing them in the config like the below. This has almost eliminated the unavailable error - for me at least.

Now, I had no idea you could skip that step in the Kasa app during setup…so all my TP link stuff is still connected to their servers. As you note, the Kasa app is a good back up - and I have not converted my wife to the HA app yet - so she is still using Kasa…like a peasant. :slight_smile:

tplink:
  discovery: false
  switch:
    - host: 192.168.1.241   #air_comp       mac: XX:XX:XX:XX:XX:XX
1 Like

I mentioned this in another thread; for me hard-coding the IP addresses in the config didn’t help. In fact, with auto-discovery off, once they went “unavailable” they rarely came back. I actually have better luck with auto-discovery on. At least they don’t stay unavailable for as long.

I did assign them reserved IP addresses in my router from the start, like I do for all IoT devices. Someone suggested this may also help with reliability.

Any update on this? I have tried both hard-coding the TP-Link IP addresses as well as letting HA auto-discover…both will return multiple entities as ‘unavailable.’ With every update to HA I pray that is fixes the problem but nothing yet. PLEASE FIX THIS!

2 Likes

hello

last release HA 0.117.x still have problem with tplink hs110 switches.
only switch on/off is available, but all measurements still generate following message:

Logger: homeassistant.helpers.event
Source: helpers/template.py:423
First occurred: 10:21:09 (25 occurrences)
Last logged: 10:21:10

Error while processing template: Template("{{ states.switch.prise_tplink_five.attributes["current_a"] | float }}")
Error while processing template: Template("{{ states.switch.prise_tplink_five.attributes["current_power_w"] | float }}")
Error while processing template: Template("{{ states.switch. prise_tplink_five.attributes["total_energy_kwh"] | float }}")
Error while processing template: Template("{{ states.switch.prise_tplink_five.attributes["voltage"] | float }}")
Error while processing template: Template("{{ states.switch.prise_tplink_five.attributes["today_energy_kwh"] | float }}")
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 421, in async_render
    render_result = compiled.render(kwargs)
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 1090, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.8/site-packages/jinja2/environment.py", line 832, in handle_exception
    reraise(*rewrite_traceback_stack(source=source))
  File "/usr/local/lib/python3.8/site-packages/jinja2/_compat.py", line 28, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
  File "/usr/local/lib/python3.8/site-packages/jinja2/sandbox.py", line 384, in getitem
    return obj[argument]
jinja2.exceptions.UndefinedError: 'None' has no attribute 'attributes'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 518, in async_render_to_info
    render_info._result = self.async_render(variables, **kwargs)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 423, in async_render
    raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: UndefinedError: 'None' has no attribute 'attributes'

When can we expect the problem to be FIXED ?

Thanks

1 Like

Have same problem…

Hello

I ‘ve found a way to bypass the problem on HS110 on measurement collection.

I just focus on current, voltate and power (in W) value. To have better measurement of energy (Wh value), utility_meter can be used, and easy.

Switch must be declared via kasa application. HA will collect data using command_line through a shell scrip, and then sensor can be created for measurment.

Steps :

Declare switch HS110 on kasa application : keep username/password which will grant you access to datas, and add devices

Find manually from ‘terminal’ token dedicated to your account, and devices declared. This is done one.
I use json_pp which provide formatted stdout display.

$ curl --silent --request POST "https://eu-wap.tplinkcloud.com/ HTTP/1.1" --data '{ "method": "login", "params": { "appType": "Kasa_Android", "cloudUserName": "your email address", "cloudPassword": "your password", "terminalUUID": "" } }' --header "Content-Type: application/json" | json_pp
{
   "error_code" : 0,
   "result" : {
      "countryCode" : "AU",
      "token" : "TOKEN_HERE",
      "accountId" : "9999999",
      "email" : "your email address",
      "regTime" : "2020-08-07 06:34:01"
   }
}
$

Collect mannualy all device ID under your account (done once)

$ curl --silent --request POST "https://wap.tplinkcloud.com?token=TOKEN_HERE HTTP/1.1" --data '{"method":"getDeviceList"}' --header "Content-Type: application/json" | json_pp | jq .result.deviceList | grep deviceId
    "deviceId": "8006A10329AE277779257435873C99B81C6A3880",
    "deviceId": "80062D685B7681CDD0E1247589257EFA1C9551E6",
    <snip>
$

Create a shell script for each device under /config/ that will collect measurements values, for example curl_tplink_one.sh, change right (chmod 744 or chmod u+x)

curl -s --request POST "https://wap.tplinkcloud.com/?token=TOKEN_HERE HTTP/1.1" --data '{"method":"passthrough", "params": {"deviceId": "YOUR_DEVICE_HERE", "requestData": "{\"emeter\":{\"get_realtime\":null}}" }}' --header "Content-Type: application/json" | jq '.result.responseData' | sed -e 's#\\\"#"#g; s#^\"##; s#\"$##' | jq .emeter
{
  "get_realtime": {
    "voltage_mv": 234947,
    "current_ma": 199,
    "power_mw": 30013,
    "total_wh": 1781,
    "err_code": 0
  }
}

Note that voltage, current and power are ‘milli’ value, ie voltage = 234947/1000=234,947 Volts, etc…

Add on configuration.yaml file:

1- Command_line sensor for each device

  - platform: command_line
    name: cli_prise_tplink_one
    json_attributes:
      - get_realtime
    command: './curl_tplink_one.sh'
    command_timeout: 30
    value_template: '{{ value_json["get_realtime"] }}'
    scan_interval: 300

2- Specific sensor (volt, current, power) for each device

  - platform: template
    sensors:
      cli_prise_tplink_one_amps:
        friendly_name_template: "Prise TP-LINK HS110 One Current Amperage"
        value_template: '{{ ( states.sensor.cli_prise_tplink_one.attributes.get_realtime["current_ma"] | float /1000 ) | round(2) }}'
        unit_of_measurement: 'A'
      cli_prise_tplink_one_watts:
        friendly_name_template: "Prise TP-LINK HS110 One Current Consumption W"
        value_template: '{{ ( states.sensor.cli_prise_tplink_one.attributes.get_realtime["power_mw"] | float /1000 ) | round(2) }}'
        unit_of_measurement: 'W'
      cli_prise_tplink_one_total_energy_kwh:
        friendly_name_template: "TP-LINK HS110 One Total Consumption kWh"
        value_template: '{{ ( states.sensor.cli_prise_tplink_one.attributes.get_realtime["total_wh"] | float /1000 ) | round(2) }}'
        unit_of_measurement: 'kWh'
      cli_prise_tplink_one_volts:
        friendly_name_template: "Prise TP-LINK HS110 One Voltage" 
        value_template: '{{ ( states.sensor.cli_prise_tplink_one.attributes.get_realtime["voltage_mv"] | float /1000 ) | round(2) }}'
        unit_of_measurement: 'V'

This should work correctly.

Sometimes, you need to check if token has not been changed by kasa application. This arrive once for me. Then, you just need to modify new token on ALL shell scrip file.

What is possible to do create a command_line script to check first the token and then send request to kasa application for each device.

I know, that it is a little heavy, but I don’t find another way, even on community.

Hope this help this nice community.