Xiaomi mi wifi plug & air purifier

So… painfully… I am still struggling…

I have managed to run su - homeassistant. which changes the user to homeassistant@hassbian:

As pi@hassbian or homeassistant@hassbian when I run source svr/homeassistant/bin/activate it returns:

-su: /svr/homeassistant/bin/activate: No such file or directory
EDIT:
Please see the below


I think that I have managed to successfully install construct in the right location. But I am still getting the same error as above.

Apologies, I am a complete and utter n00b. I have finally got it all up and running and am so very happy! If anyone runs into the same trouble and wants a hand feel free to msg me!

Thanks for all of the help!!

Has anyone ever managed to get around the original issue of having more than one plug running?

Congratulations! I can see on your screenshot you wasn’t inside of the python-virtualenv. :wink:

I don’t know much about python, home assistant and I cannot test the suggestion on my own. Nevertheless:

https://github.com/xavV/xiaomi/blob/master/xiaomi/protocol.py

I suspect the “@staticmethod” annotation of the method key_iv(). Can you remove all the @staticmethod annotations of the file and restart home assistant? In the best case the checksum error will be gone. Please report! :slight_smile:

Hi, apologies I have only just had a chance to test! (I am based in New Zealand) Thank you so much for your help and trying to get this working!! I replaced the protocol.py located in homeassistant/xiaomi with your version the result was:

2017-07-13 20:45:27 ERROR (Thread-1) [homeassistant.util.yaml] while scanning for the next token
found character '\t' that cannot start any token
  in "/home/homeassistant/.homeassistant/configuration.yaml", line 101, column 44
2017-07-13 20:45:27 ERROR (MainThread) [homeassistant.bootstrap] Error loading /home/homeassistant/.homeassistant/configuration.yaml: while scanning for the next token
found character '\t' that cannot start any token
  in "/home/homeassistant/.homeassistant/configuration.yaml", line 101, column 44

It works fine without the additional switches in the yaml. But as soon as I add the following below the working switch:

  - platform: xiaomiplug
host: xx.xx.xxx.xxx
name: Spare Plug
token: {token redacted}
  - platform: xiaomiplug
host: xx.xx.xxx.xxx
name: Lounge Lamp
token: {token redacted}

Then its back to error logs and having to sudo reboot out of PuTTY.

Can you try again by removing the complete line? You left the tab in front of the annotation. You are safe if you remove the linebreak also. I hope your configuration.yaml is indented properly:

  - platform: xiaomiplug
      host: xx.xx.xxx.xxx
      name: Spare Plug
      token: {token redacted}
  - platform: xiaomiplug
      host: xx.xx.xxx.xxx
      name: Lounge Lamp
      token: {token redacted}

For clarification: https://gist.github.com/syssi/4da06e2c2d1e897984b0c53778cc4da4

Apologies I was being perhaps a little lazy with my pasting. I have my yaml configured in the second version below.

When I input the suggested format above:

switch:
  - platform: xiaomiplug
      host: 10.39.167.132
      name: Bedroom Heater
      token: 611b12ecbf1cbfdf3270b6a3ec689cb6
  - platform: xiaomiplug
      host: 10.39.167.147
      name: Spare Plug
      token: 4c7f07159d7f566def6e57be95a00c4a 
  - platform: xiaomiplug
      host: 10.39.167.102
      name: Lounge Lamp
      token: 7020d183d02942cc939b7bbab0047902	

The error it returns is:

2017-07-13 22:02:47 ERROR (Thread-1) [homeassistant.util.yaml] mapping values are not allowed here
  in "/home/homeassistant/.homeassistant/configuration.yaml", line 100, column 11
2017-07-13 22:02:48 ERROR (MainThread) [homeassistant.bootstrap] Error loading /home/homeassistant/.homeassistant/configuration.yaml: mapping values are not allowed here
  in "/home/homeassistant/.homeassistant/configuration.yaml", line 100, column 11

Then when I use the following (which is how it works with one single socket):

switch:
  - platform: xiaomiplug
    host: {IP Here}
    name: Bedroom Heater
    token: {Token Here}    
  - platform: xiaomiplug
    host: {IP Here}
    name: Spare Plug
    token: {Token Here}    
  - platform: xiaomiplug
    host: {IP Here}
    name: Lounge Lamp
    token: {Token Here}    

Returns:

2017-07-13 22:04:42 ERROR (Thread-1) [homeassistant.util.yaml] while scanning for the next token
found character '\t' that cannot start any token
  in "/home/homeassistant/.homeassistant/configuration.yaml", line 110, column 44
2017-07-13 22:04:42 ERROR (MainThread) [homeassistant.bootstrap] Error loading /home/homeassistant/.homeassistant/configuration.yaml: while scanning for the next token
found character '\t' that cannot start any token
  in "/home/homeassistant/.homeassistant/configuration.yaml", line 110, column 44

Oh, I have misinterpreted the error message. It’s complaining about a tab (“\t”) which isn’t allowed. Please check your yaml file for tabs and replace it with spaces? And you are right. The correct format is:

switch:
  - platform: xiaomiplug
    host: 
    name: Bedroom Heater
    token: 
  - platform: xiaomiplug
    host: 
    name: Spare Plug
    token: 
  - platform: xiaomiplug
    host: 
    name: Lounge Lamp
    token: 

The following errors have been logged this session:

2017-07-13 22:42:03 WARNING (Thread-3) [netdisco.ssdp] Error fetching description at http://10.39.167.135:2869/upnphost/udhisapi.dll?content=uuid:61bd8d86-6c61-46a5-9d35-e6bc7c93b7a2
2017-07-13 22:42:13 ERROR (Thread-3) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'658fe26a4191a3e5e0a136b52f77bf62'
    parsing -> checksum
2017-07-13 22:42:13 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2709, in _parse
    return self.subcon._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 1565, in _parse
    obj = self.cases.get(key, self.default)._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2267, in _parse
    hash2 if not isinstance(hash2,bytes) else hexlify(hash2), ))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'658fe26a4191a3e5e0a136b52f77bf62'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/core.py", line 1023, in _event_to_service_call
    yield from service_handler.func(service_call)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/components/switch/__init__.py", line 105, in async_handle_switch_service
    yield from switch.async_turn_on()
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/switch/xiaomiplug.py", line 84, in turn_on
    self._switch.start()
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 139, in start
    return self.send("set_power", ["on"])
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 127, in send
    m = Message.parse(data)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 165, in parse
    return self.parse_stream(BytesIO(data), context, **kw)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 176, in parse_stream
    return self._parse(stream, context, "parsing")
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 849, in _parse
    subobj = sc._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2713, in _parse
    raise e.__class__("%s\n    %s" % (e, path))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'658fe26a4191a3e5e0a136b52f77bf62'
    parsing -> checksum
2017-07-13 22:42:24 ERROR (Thread-1) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'3aee1113c952f8777990f2c5bbbfb910'
    parsing -> checksum
2017-07-13 22:42:24 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2709, in _parse
    return self.subcon._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 1565, in _parse
    obj = self.cases.get(key, self.default)._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2267, in _parse
    hash2 if not isinstance(hash2,bytes) else hexlify(hash2), ))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'3aee1113c952f8777990f2c5bbbfb910'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/core.py", line 1023, in _event_to_service_call
    yield from service_handler.func(service_call)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/components/switch/__init__.py", line 105, in async_handle_switch_service
    yield from switch.async_turn_on()
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/switch/xiaomiplug.py", line 84, in turn_on
    self._switch.start()
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 139, in start
    return self.send("set_power", ["on"])
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 127, in send
    m = Message.parse(data)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 165, in parse
    return self.parse_stream(BytesIO(data), context, **kw)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 176, in parse_stream
    return self._parse(stream, context, "parsing")
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 849, in _parse
    subobj = sc._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2713, in _parse
    raise e.__class__("%s\n    %s" % (e, path))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'3aee1113c952f8777990f2c5bbbfb910'
    parsing -> checksum
2017-07-13 22:42:25 ERROR (Thread-9) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'e29069321fb78a07f9a33f2ad952df49'
    parsing -> checksum
2017-07-13 22:42:25 ERROR (Thread-9) [custom_components.switch.xiaomiplug] Got exception while fetching the state: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'e29069321fb78a07f9a33f2ad952df49'
    parsing -> checksum
2017-07-13 22:42:25 ERROR (Thread-8) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'9cadfbfc8e5182bf03610cdc50163c4a'
    parsing -> checksum
2017-07-13 22:42:25 ERROR (Thread-8) [custom_components.switch.xiaomiplug] Got exception while fetching the state: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'9cadfbfc8e5182bf03610cdc50163c4a'
    parsing -> checksum
2017-07-13 22:42:38 ERROR (Thread-5) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'b9fb0bd5ffa8e882ba55b41258ca6c9d'
    parsing -> checksum
2017-07-13 22:42:38 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2709, in _parse
    return self.subcon._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 1565, in _parse
    obj = self.cases.get(key, self.default)._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2267, in _parse
    hash2 if not isinstance(hash2,bytes) else hexlify(hash2), ))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'b9fb0bd5ffa8e882ba55b41258ca6c9d'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/core.py", line 1023, in _event_to_service_call
    yield from service_handler.func(service_call)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/components/switch/__init__.py", line 105, in async_handle_switch_service
    yield from switch.async_turn_on()
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/switch/xiaomiplug.py", line 84, in turn_on
    self._switch.start()
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 139, in start
    return self.send("set_power", ["on"])
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 127, in send
    m = Message.parse(data)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 165, in parse
    return self.parse_stream(BytesIO(data), context, **kw)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 176, in parse_stream
    return self._parse(stream, context, "parsing")
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 849, in _parse
    subobj = sc._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2713, in _parse
    raise e.__class__("%s\n    %s" % (e, path))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'b9fb0bd5ffa8e882ba55b41258ca6c9d'
    parsing -> checksum
2017-07-13 22:42:41 ERROR (Thread-1) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'2d8d2397d357ee0be5186fdaa7259b72'
    parsing -> checksum
2017-07-13 22:42:41 ERROR (MainThread) [homeassistant.core] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2709, in _parse
    return self.subcon._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 1565, in _parse
    obj = self.cases.get(key, self.default)._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2267, in _parse
    hash2 if not isinstance(hash2,bytes) else hexlify(hash2), ))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'2d8d2397d357ee0be5186fdaa7259b72'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3.4/asyncio/tasks.py", line 233, in _step
    result = coro.throw(exc)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/core.py", line 1023, in _event_to_service_call
    yield from service_handler.func(service_call)
  File "/srv/homeassistant/lib/python3.4/site-packages/homeassistant/components/switch/__init__.py", line 105, in async_handle_switch_service
    yield from switch.async_turn_on()
  File "/usr/lib/python3.4/asyncio/futures.py", line 388, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.4/asyncio/tasks.py", line 286, in _wakeup
    value = future.result()
  File "/usr/lib/python3.4/asyncio/futures.py", line 277, in result
    raise self._exception
  File "/usr/lib/python3.4/concurrent/futures/thread.py", line 54, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/switch/xiaomiplug.py", line 84, in turn_on
    self._switch.start()
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 139, in start
    return self.send("set_power", ["on"])
  File "/home/homeassistant/.homeassistant/xiaomi/xiaomi.py", line 127, in send
    m = Message.parse(data)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 165, in parse
    return self.parse_stream(BytesIO(data), context, **kw)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 176, in parse_stream
    return self._parse(stream, context, "parsing")
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 849, in _parse
    subobj = sc._parse(stream, context, path)
  File "/srv/homeassistant/lib/python3.4/site-packages/construct/core.py", line 2713, in _parse
    raise e.__class__("%s\n    %s" % (e, path))
construct.core.ChecksumError: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'2d8d2397d357ee0be5186fdaa7259b72'
    parsing -> checksum
2017-07-13 22:42:57 ERROR (Thread-9) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'8ce1ae0d401bc9a21fefce037cd26b00'
    parsing -> checksum
2017-07-13 22:42:57 ERROR (Thread-9) [custom_components.switch.xiaomiplug] Got exception while fetching the state: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'8ce1ae0d401bc9a21fefce037cd26b00'
    parsing -> checksum
2017-07-13 22:42:57 ERROR (Thread-8) [xiaomi.xiaomi] got error when receiving: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'1e67c2dc1e6d59fae232dc6eb49ce751'
    parsing -> checksum
2017-07-13 22:42:57 ERROR (Thread-8) [custom_components.switch.xiaomiplug] Got exception while fetching the state: wrong checksum, read b'ffffffffffffffffffffffffffffffff', computed b'1e67c2dc1e6d59fae232dc6eb49ce751'
    parsing -> checksum

A pity. My guess was wrong. I cannot help from here, sorry.

Good news: I found a proper piece of code here: https://github.com/rytilahti/python-mirobo/blob/master/mirobo/protocol.py

I think the context[‘_’][‘token’] parts will do the magic and fix the checksum error. The best approach would be to extend the mirobo component by an additional device (xiaomi wifi plug). The quick and dirty solution is a merge of the protocol.py into @xavV component.

I have done some work: https://github.com/syssi/xiaomiplug

Can you test the component? It’s untested. You have to remove the old implementation (xiaomi folder & custom_component/switch/xiaomiplug.py) and use the new one. The new component is now called “xiaomiplug”.

3 Likes

Working fine for me.

I have two WIFI devices: a smart socket and a smart strip.
I tested both of them and switch with correct states from Xiaomi Mi Home and Home Assistant.

THANKS a lot

1 Like

Please update the component. The current state of the plug is polled again now.

Updated and keeps working. Although it takes almost 20 seconds to update state in Home Assistant when my “smart strip” is switched from “Mi Home” app. I don’t know if it took less before or it’s the same.

By the way: I’ve been experimenting a little with the miio command line and it seems to me that both smart socket and smart strip have temperature sensors in addition to switch status.

When I try:

miio --control MY_STRIP_IP --method get_prop --params ‘[“power”,“temperature”]’

it answers:

INFO Attempting to control 192.168.1.218

INFO Got result:
[
“on”,
46.22
]

So it seems that it measures internal temperature.
¿Any way that this sensor could be incorporated?

The below are my sensors for a air purifire
You may refer to it.

  • platform: command_line
    name: Air Purifier Humidity
    command: miio --control 192.168.0.15 --method get_prop --params ‘[“humidity”]’
    unit_of_measurement: “%”
    value_template: ‘{{ value | replace(“INFO”,"") | replace(“Attempting to control 192.168.0.15”,"") | replace(“Got result:”,"") | replace("[","") | replace("]","") | replace(" “,”") }}’
    scan_interval: 120

  • platform: command_line
    name: Air Purifier PM 2.5
    command: miio --control 192.168.0.15 --method get_prop --params ‘[“aqi”]’
    unit_of_measurement: “㎍/m³”
    value_template: ‘{{ value | replace(“INFO”,"") | replace(“Attempting to control 192.168.0.15”,"") | replace(“Got result:”,"") | replace("[","") | replace("]","") | replace(" “,”") }}’
    scan_interval: 120

  • platform: command_line
    name: Air Purifier Power
    command: miio --control 192.168.0.15 --method get_prop --params ‘[“power”]’
    value_template: ‘{{ value | replace(“INFO”,"") | replace(“Attempting to control 192.168.0.15”,"") | replace(“Got result:”,"") | replace("[","") | replace("]","") | replace(" “,”") }}’
    scan_interval: 120

  • platform: command_line
    name: Air Purifier Mode
    command: miio --control 192.168.0.15 --method get_prop --params ‘[“mode”]’
    value_template: ‘{{ value | replace(“INFO”,"") | replace(“Attempting to control 192.168.0.15”,"") | replace(“Got result:”,"") | replace("[","") | replace("]","") | replace(" “,”") }}’
    scan_interval: 120

2 Likes

I will provide the temperature as attribute. Do you know more interesting attributes? The plug does not provide a power consumption, right? The zigbee version does report the power consumption f.e.

1 Like

The interval is unchanged. Good to know the state is populated properly again.

Thanks, that was my “Plan B” if it couldn’t be done elseway. But it seems to me that this way we are throwing too many “requests” to the same device: one via the python component to retrieve the power state another one for each property… An optimal way could be to retrieve all of them in a single call providing the array of params in the same request…

Thanks any way.