Page 1 of 1
Python Plugin - how to replicate a curl statement in a plugin
Posted: Monday 05 February 2018 12:16
by malarcy
Hi - looking at the possibility of developing a plugin for the Blink Home Monitoring Camera's - there's a couple of libraries out there (a python one - unfortunately it depends heavily on the requests module so I can't just use that) There is also good docs on driving Blink via curl, so between the two sources I think I have enough info.
For now, my needs are simple - I just want to be able to ARM/DISARM the motion sense on a camera - I could do this via a separate python script - calling the library / requests - but I am sure I will want to build on it so am tempted to go down the plugin route.
I am however struggling with the Domoticz.Connection and subsequent sends - I can't get the syntax correct to produce the required "packet"
The curl command to emulate is (for authentication - you get an auth token returned to use in the next calls)
curl -H "Host: prod.immedia-semi.com" -H "Content-Type: application/json" --data-binary '{ "password" : "your blink password", "client_specifier" : "iPhone 9.2 | 2.2 | 222", "email" : "your blink login/email" }' --compressed
https://rest.prod.immedia-semi.com/login
I have tried both an HTTPS and JSON protocol
Any suggestions?
For reference on the work done so far by others:
https://github.com/MattTW/BlinkMonitorProtocol
https://github.com/fronzbot/blinkpy
Re: Python Plugin - how to replicate a curl statement in a plugin
Posted: Monday 05 February 2018 12:38
by febalci
hi @malarcy,
in Plugin Framework you can always use urrlib; but that means not using the native plugin framework connections. It will work anyway.
If you are using native TCP-IP/HTTP connection, you have to send a header; check
https://github.com/domoticz/domoticz/bl ... es/HTTP.py for an example.
Or if you are using TCP-IP/JSON or TCP-IP/None connection, you have to deal with raw incoming HTTP messages. What i did for a connection in the plugin is like:
Code: Select all
wsHeader = "GET /standing_order/websocket HTTP/1.1\r\n" \
"Host: www.seismicportal.eu\r\n" \
"User-Agent: Domoticz/1.0\r\n" \
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" \
"Accept-Language: en-US,en;q=0.5\r\n" \
"Accept-Encoding: gzip, deflate\r\n" \
"Sec-WebSocket-Version: 13\r\n" \
"Origin: http://www.seismicportal.eu\r\n" \
"Sec-WebSocket-Extensions: permessage-deflate\r\n" \
"Sec-WebSocket-Key: qqMLBxy==\r\n" \
"DNT: 1\r\n" \
"Connection: keep-alive, Upgrade\r\n" \
"Pragma: no-cache\r\n" \
"Cache-Control: no-cache\r\n" \
"Upgrade: websocket\r\n\r\n"
and use 'Connection.Send(self.wsHeader)' in onconnect. Please be aware that this header is for a websocket connection, you have to correct it according to your needs. You have to convert '{ "password" : "your blink password", "client_specifier" : "iPhone 9.2 | 2.2 | 222", "email" : "your blink login/email" }' to binary before putting it in to your header. Also i believe it should be POST, not GET on your situation.
"Accept-Encoding: gzip, deflate\r\n" \ wll handle the compressed option.
Re: Python Plugin - how to replicate a curl statement in a plugin
Posted: Monday 05 February 2018 13:04
by malarcy
Thanks for the quick response and the pointers - some more options there - if I can use the framework I will - if not - will fall back to urllib (or probably urllib2 for the flexibility)
In the case of the HTTP.py example - I see the header getting constructed - thats useful.
The auth sequence is a POST (you are correct), its JSON, I would need to specify that as a "body" section of the send (assuming that can be done).
More playing later on today
Malarcy
Re: Python Plugin - how to replicate a curl statement in a plugin
Posted: Monday 05 February 2018 14:06
by febalci
@malarcy:
Check
https://github.com/domoticz/domoticz/bl ... istener.py for a POST example; which uses:
Code: Select all
self.httpClientConn.Send({"Status":"200 OK", "Headers": {"Connection": "keep-alive", "Accept": "Content-Type: text/html; charset=UTF-8"}, "Data": data})
, so you can send body section in 'Data'
Re: Python Plugin - how to replicate a curl statement in a plugin
Posted: Monday 05 February 2018 17:12
by malarcy
OK - got it authenticating and I can read back the token etc. via the framework - thanks for the help on that - found that if I didn't tell the server I would accept gzipped content then it returns uncompressed - how very civil of it - will need to deal with gzip'ed content if I got as far as retrieving thumbnails or videos from the cloud service.
Now looking at the logic in the onMessage section - there's a fair amount of "discovery" that needs to go on at startup - and I would kind of like to handle all that in the onConnect - is there anyway of specifying a different call back handler for a given "send" - if not I guess I just need to parse out the setup and discovery (enumeration of cameras, etc.) - just makes that piece of code heavier than I would like.
In normal running the onMessage handler will be perfect for dealing with periodic status refreshes and response to commands.
More experimentation later.
Malarcy
Re: Python Plugin - how to replicate a curl statement in a plugin
Posted: Tuesday 06 February 2018 6:12
by Dnpwwo
@malarcy,
Most devices have an element of 'discovery' to them, previously I have triggered the discovery in the onConnect then used the responses as a 'state machine' to drive next steps.
Have a look at:
its an easy approach an quite robust to handle cases where remote devices become unavailable and disconnect followed by reconnection.