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

Implement push server for xioami miio gateways #1288

Closed
wants to merge 37 commits into from

Conversation

starkillerOG
Copy link
Contributor

@starkillerOG starkillerOG commented Jan 9, 2022

with many thanks to @bskaplou to figuring out how most of this stuff worked.
This is based on his work in PR: #709

Tested to work with magnet door sensor lumi.sensor_magnet.aq2

To do:

  • implement other models where pushes are known
  • ability to register external callback on subdevice for HomeAssistant porpuse
  • implement pushes for gateway alarm (triggering)
  • Do some more code cleanup

Discussion about retrieving the encrypted_token:
#699 (comment)

Test script:

import logging
import asyncio
from miio import Gateway, PushServer

_LOGGER = logging.getLogger(__name__)
logging.basicConfig(level="INFO")

gateway_ip = "192.168.1.IP"
token = "TokenTokenToken"


async def asyncio_demo(loop):
    def gateway_callback(action, params):
        _LOGGER.info("Gateway '%s' callback, params: '%s'", action, params)

    def subdevice_callback(action, params):
        _LOGGER.info("Subdevice '%s' callback, params: '%s'", action, params)
    
    push_server = PushServer(gateway_ip)
    gateway = Gateway(gateway_ip, token, push_server=push_server)
    
    await push_server.start()

    await loop.run_in_executor(None, gateway.alarm.install_push_callbacks)
    gateway.Register_callback("DEMO_CB", gateway_callback)

    await loop.run_in_executor(None, gateway.discover_devices)
    
    for device in gateway.devices.values():
        device.Register_callback("DEMO_CB", subdevice_callback)
        await loop.run_in_executor(None, device.install_push_callbacks)
    
    _LOGGER.info("Listening")
    
    await asyncio.sleep(60)

    push_server.stop()
    gateway.close()

if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio_demo(loop))

@codecov-commenter
Copy link

codecov-commenter commented Jan 12, 2022

Codecov Report

Merging #1288 (3734821) into master (31c5d74) will decrease coverage by 1.20%.
The diff coverage is 27.33%.

@@            Coverage Diff             @@
##           master    #1288      +/-   ##
==========================================
- Coverage   84.18%   82.98%   -1.21%     
==========================================
  Files         135      136       +1     
  Lines       13348    13739     +391     
  Branches     1485     3266    +1781     
==========================================
+ Hits        11237    11401     +164     
- Misses       1900     2119     +219     
- Partials      211      219       +8     
Impacted Files Coverage Δ
miio/gateway/devices/subdevice.py 32.96% <20.51%> (-3.92%) ⬇️
miio/push_server.py 27.09% <27.09%> (ø)
miio/gateway/gateway.py 44.67% <28.94%> (-2.93%) ⬇️
miio/gateway/alarm.py 45.45% <29.41%> (-10.11%) ⬇️
miio/__init__.py 100.00% <100.00%> (ø)
miio/gateway/gatewaydevice.py 69.23% <100.00%> (+2.56%) ⬆️
...integrations/airpurifier/zhimi/airpurifier_miot.py 80.73% <0.00%> (-1.80%) ⬇️
...o/integrations/vacuum/roborock/vacuumcontainers.py 75.79% <0.00%> (-0.92%) ⬇️
miio/protocol.py 88.42% <0.00%> (ø)
...ions/vacuum/dreame/tests/test_dreamevacuum_miot.py 100.00% <0.00%> (ø)
... and 9 more

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@starkillerOG starkillerOG changed the title W.I.P. Implement push server for xioami miio gateways Implement push server for xioami miio gateways Jan 19, 2022
@starkillerOG
Copy link
Contributor Author

starkillerOG commented Jan 19, 2022

I think this is ready for merging.
Everything is tested and works.

Only improvement would be if we could figure out how to get the encrypted_token from the normal token.
For now the encrypted_token is needed as a argument to the gateway intialize function for this to work.
That will require users to do packet sniffing of the MiHome app while creating an automation in order to figure out what there encrypted_token is (for now the only way I know of to get this token).
I will write detailed instructions to do this when I make the HomeAssistant PR to include this functionality.

This will allow for motion sensors, door sensors, buttons, cubes etc to be added to HomeAssistant as devices that will get instant pushes when an event happens.

@starkillerOG
Copy link
Contributor Author

@rytilahti could you revieuw this and merge?

@starkillerOG
Copy link
Contributor Author

HomeAssistant Pull Request is here: home-assistant/core#64726

@starkillerOG
Copy link
Contributor Author

Home Assistant documentation PR is here: home-assistant/home-assistant.io#21309

@starkillerOG
Copy link
Contributor Author

@rytilahti this is now fully tested and the HomeAssistant PRs to implement this new code are also finished.
Could you please revieuw this?
I would like to move forward with this and actually get this into HomeAssistant.

@starkillerOG
Copy link
Contributor Author

starkillerOG commented Jan 24, 2022

I just found a way to get the "encrypted token":


from miio.protocol import Utils

token = "TokenTokenToken"

def calculated_token_enc(token):
    token_bytes = bytes.fromhex(token)
    encrypted_token = Utils.encrypt(token_bytes, token_bytes)
    encrypted_token_hex = encrypted_token.hex()
    return encrypted_token_hex[0:32]

print(calculated_token_enc(token))

It works for the tokens of both my 2 gateways.

@starkillerOG
Copy link
Contributor Author

@rytilahti could you revieuw this?

@rytilahti
Copy link
Owner

Hi @starkillerOG, sorry for the silence, I've been really busy and this PR is not a small one. I'll write some feedback to you asap to get this moving onward!

@starkillerOG
Copy link
Contributor Author

@rytilahti gentile reminder if you could have a look at this PR since a lot of users are waiting for this.

@starkillerOG
Copy link
Contributor Author

@rytilahti Could you have a look at this PR?
I think it will improve the user experiance a lot.
Potentially we could use this for all Miio devices (not only the gateway).
I think this will also work for direct wifi devices like robot vacuums.

@starkillerOG
Copy link
Contributor Author

@rytilahti could you please have a look and merge?
It's been almost 4 months and this PR is tested and working and would add support for a lot of new devices.

@starkillerOG
Copy link
Contributor Author

@rytilahti I have moved the push_server.py directly under miio and genaralized it a bit.
I have also just tested it again, and everyting still works.

I am really bad at writing tests, sorry...
Maybe you or someone else could write some tests?
(of course I tested all this code with real devices, but I mean I am bad at writing mocking tests...)

@starkillerOG
Copy link
Contributor Author

@rytilahti I think I processed all your feedback of the first round or commented on it.
Could you go for another round?

@starkillerOG
Copy link
Contributor Author

@rytilahti Could you have a second look for feedback?
I would really like to get this merged.

@wormi4ok
Copy link

Any updates here? I'm looking forward to this functionality!

@starkillerOG
Copy link
Contributor Author

@wormi4ok it is ready from my end, just waiting on @rytilahti.
@rytilahti could you please merge this so I can continue with the work in HomeAssistant.
If we want furter improvements/changes I am more than happy to make them in new PRs no problem.
Just really want to see this moving allong since it has been stale for basically 4 months.

@rytilahti
Copy link
Owner

@starkillerOG, would you be open for a call on the homeassistant discord or elsewhere to discuss about this PR? I feel that having a synchronous discussion would be so much more efficient than communicating through github comments :-)

@starkillerOG
Copy link
Contributor Author

@rytilahti yea sure tomorrow around 20:00 (UTC+2) good for you?

@starkillerOG
Copy link
Contributor Author

New split out PR can be found here: #1446

@rytilahti
Copy link
Owner

As #1446 #1459 are merged now, I think this can be closed, too!

@rytilahti rytilahti closed this Jul 17, 2022
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

Successfully merging this pull request may close these issues.

4 participants