kdietrich / homebridge-devolo

WARNING: this repo is not maintained anymore. Homebridge plugin for Devolo Home Control
16 stars 4 forks source link

Please #4

Closed KiboOst closed 7 years ago

KiboOst commented 7 years ago

Hi, I'm a Devolo Home Control user, could you give me a few starting step to use it with json-rpc request ? I've done some php scripts gathering datas and would like to change some DHC device state regarding these datas. This can't be included into DHC, and it seems it is what you do in your code. Can't find your email, so I try here, sorry ;-) Thks

kdietrich commented 7 years ago

Have you seen https://github.com/kdietrich/node-devolo? This api allows you to authenticate, fetch devices, switch states etc. However there is no documentation available yet. You can check out homebridge-devolo that makes use of the api as an example.

KiboOst commented 7 years ago

Yes, I was digging into the code but I don't know enough javascript. It seems you should either GET or POST request, with some json data into. But can't find the url (is it https://homecontrol.mydevolo.com/remote/json-rpc ?), and if there is a need to first connect to and get any token for example. I have hard time to dig into the json structure as well. I use netatmo api and kodi json-rpc with php, will try investigate into your code. Anyway, is it all reverse-engineering ? capturing meesage for android app for example ?

KiboOst commented 7 years ago

I tried everything I could think of to send get and post to https://homecontrol.mydevolo.com/remote/json-rpc with different headers, json, etc. Never get an answer... With firebug or chrome dev I see it does use json-rpc when using web interface, so for sure what I would like to do is doable There is some documentation about the home control box server here: https://dz.prosyst.com/pdoc/mBS_SDK_8.1/modules/jsonrpc/api/fimjsonrpc.html But nothing on login

Could you at least confirm this : ?

KiboOst commented 7 years ago

Reading your code I should get an answer with this: ` $auth64 = base64_encode("$login:$password"); $url = "https://www.mydevolo.com/v1/users/uuid"; $opts = array( 'http' => array ( 'method' => 'GET', 'header' => 'Authorization: Basic '.$auth64 ) ); $context = stream_context_create($opts); $response = file_get_contents($url,false,$context);

`

But I can't get any data back. I got my uuid and gateway (serial number of the central) but even with that I can't get anywhere.

Could you point me where I'm wrong ? I know you did a lot of work to get your api working and you may not want to give your finding but please ... I could even redo such api in php for everyone. If you are willing to talk about it by email, let me know. Regards, Kib

kdietrich commented 7 years ago

First step would be to get uuid, gateway and passkey from mydevolo.com gateway. See fetchUUID, fetchGateway, fetchPasskey in https://github.com/kdietrich/node-devolo/blob/master/lib/DevoloApi.ts. Afterwards you have to retrieve your sessionid (see fetchSessionid). You can use your sessionid then to speak to your local devolo central. $url has to be the ip address of your devolo central by then, not mydevolo.com gateway.

should authorise with GET to www.mydevolo.com/v1/users/uuid with login:password as base64 response should contain user uid

This is correct.

But I can't get any data back.

Open the url you mentioned in your browser. You will get a response, won't you?

It certainly would be easier to help you if you show me your whole code.

kdietrich commented 7 years ago

btw: I've checked the code snippet you've posted and it's working fine here.

KiboOst commented 7 years ago

ok, I got problems with file_get_contents on my web hosting (ssl error msg etc). From a local easyphp, it works after enabling ssl in php.ini! go figure ...

So, I finnally got my uuid, gateway, and passkey !! Will now get further, but for sessionid I need to be on my local network, and I'm not at home. I will see later if I can do a nat from a dyndns to my box at home, should work.

Thanks for your help, invaluable indeed. Once it works I will reformat and clean code and show something. Just one question, it seems uuid and gateway (which is the box serial number) never change, right ? So storing them in a config file would avoid unnecessary request later ?

kdietrich commented 7 years ago

Glad you've got it working! 👍

Just one question, it seems uuid and gateway (which is the box serial number) never change, right ? So storing them in a config file would avoid unnecessary request later ?

Yep, afaik sessionid is the only thing that changes.

KiboOst commented 7 years ago

Hi, Got a bit further, I guess I have the sessionID (IDxxxxxEnd), but when requesting functionnalItems I got: array(2) { ["error"]=> array(2) { ["message"]=> string(20) "Session is not valid" ["code"]=> int(401) } ["jsonrpc"]=> string(3) "2.0" }

So I guess my cookie has something wrong ... Or is it possible that the sessionID isn't right for next file_get_contents ? I mean, all successive file_get_contents not being in the same php session ? Will investigate ...

kdietrich commented 7 years ago

Just an advice: Use curl instead of file_get_contents for tasks that are more complicated than a simple GET.

KiboOst commented 7 years ago

hmm, was reading some stuff on curl cookie_jar .... Will have a try, thanks.

KiboOst commented 7 years ago

Converted all with curl, fetchitems now answer: {"error":{"message":"Cannot find Module/Service with PID:","code":-32601},"jsonrpc":"2.0"} my json: $json = array("jsonrpc" => "2.0", "method" => "/getFunctionalItems", "params" => array( array("devolo.Grouping") ) );

with methode FIM/getFunctionalItems, I get Method 'getFunctionalItems(array)' not found" ...

As I get an answer, I guess I passed the cookie step ! Digging further into fetchItems and getZones !! I would though it could return device list, but it seems a bit more complicated lol !

KiboOst commented 7 years ago

AH ! Got tons of results with: $json = '{ "jsonrpc":"2.0", "id":"", "method":"FIM/getFunctionalItemUIDs", "params":"" }';

Now have to sort out commands lol ! Is there a way to have a list of all devices with their ID and name as in devolo web interface ? which could allow to trigger device by name (to be sure which is which)

kdietrich commented 7 years ago

Take a look at getZones, getDevices and getAllDevices in https://github.com/kdietrich/node-devolo/blob/master/lib/Devolo.ts.

KiboOst commented 7 years ago

ok, so I get all items of the central for each items, I get elements (the actual sensors), and fetching them give me states and such. So I think I have all now. I will now differ a bit from your code, to call states by item name and change state by item name also. Still a lot to write but the main part is done.

Just for your curiosity... Why ? I've done on my domain a php script that get sunrise/sunset/transit, and sun azimuth/elevation. Getting my home walls orientations, I know when the sun is hitting which window. With some Netatmo Presence camera, I have scripted a way to get a snapshot, and measure average luminosity of a representative crop. This script is run by a cron regularly, so I know what to do with windows shutters ! The second part was changing states on devolo central. I initially though having some scenes with different states for each windows, and calling them throw their url. It would work, but involve lot of scenes in devolo central, and would be really precise, relying on pre-register scenes and not exact value. Then, I saw your devolo homebridge plugin and though "hey, this man know how to trigger devices inside the central !!" WOW ! Here we go. And this open tons of amazing interactions !!

Just for my curiosity... What I have done here is quite easy, converting your js code to php code. But what I would know is, how the hell did you find the path to go throw all that ? I saw some months ago the fim.js was triggering some json stuff so it may be way to do it. But what about fetching passkey, the right url, etc ? What was your method to get all this running ? Really amazing job you did there !

Just hope devolo won't break it in a future update. They may release some official json api in the future. But we can do it now ahah !

All the best

KiboOst commented 7 years ago

Dude, I've turn on and off a wall plug with php !!! woohooooo !!!

KiboOst commented 7 years ago

Ah, it got funny...

try $json = '{ "jsonrpc":"2.0", "method":"FIM/getFunctionalItems", "params":[ ["devolo.Services"],0 ] }';

then fetch them.... You got all rule, their element, and can turn them on/off !!!!

just in case: timers: ["devolo.Schedules"] rules: ["devolo.Services"] scenes: ["devolo.Scene"] messages: ["devolo.Messages"]

KiboOst commented 7 years ago

Regarding rules and timers, we can get state but not change. With exact same json has the web interface I keep getting: $jsonString = '{ "jsonrpc":"2.0", "method":"FIM/setProperty", "params":[ "devolo.ScheduleControl:8","enabled", "true"]}';

{"error":{"message":"Setting property enabled for functional item devolo.ScheduleControl:8 is not allowed!","code":-32000},"jsonrpc":"2.0"}

Any idea ? How could we get operation name for that to try invokeoperation ?

KiboOst commented 7 years ago

If you want to have a look: https://github.com/KiboOst/php-devoloDHC

No error handling etc, php if not my mother language ;-) It is also my very first contribution to github, dunno really how it works yet.

KiboOst commented 7 years ago

Hi, Would you have idea to find how to enable/disable rules ? Have FIM/setProperty (always got not allowed), invokeOperation with different param. There is also not only FIM/ but some HAM and HAM2

but HAM2/setRuleActiveState always return result null Found some doc here: http://dz.prosyst.com/pdoc/mBS_SDK_8.0/modules/automationengine/api-json/ham_jsonrpc.html I would be able to trigger a mode holiday which switch rules and shedules on/off

If you have any pointer...

kdietrich commented 7 years ago

Have you tried creating two scenes in Devolo which activate/deactivate the rules and trigger them via homebridge?

What I have done here is quite easy, converting your js code to php code. But what I would know is, how the hell did you find the path to go throw all that ? I saw some months ago the fim.js was triggering some json stuff so it may be way to do it. But what about fetching passkey, the right url, etc ? What was your method to get all this running ? Really amazing job you did there !

Thanks! The devolo app is a good starting point to reverse engineer and to find out how the authentification part works. After that lots of network sniffing and trial 'n error was involved. ;)

KiboOst commented 7 years ago

No, I don't have homebridge install, I look json request in chrome dev tool.

kdietrich commented 7 years ago

Yeah, but have you tried triggering scenes via CURL, which activate/deactivate your rules?

KiboOst commented 7 years ago

Yes, works with invokeOperation 'start' I have update https://github.com/KiboOst/php-devoloDHC for scenes and http devices support

kdietrich commented 7 years ago

I guess you can use that as a workaround: Create a rule R1. Create a scene S1 that enables R1 and a scene S2 that disables R1. Trigger S1 and S2 via curl in order to enable/disable R1. Let me know if this works! :)

KiboOst commented 7 years ago

Yes, this works great. But I would avoid creating tons of scenes just for that :-) What question me now is if we can set device value for range type, like opening a shutter at 20%. If it use invokeOperation it should work, but can't get setProperty to work. I have no device actually like that to check it. I guess thermostat, hue, dimmer, qubino shutter etc works like that.

KiboOst commented 7 years ago

Hi, I've just rewrite my code to set it as a class, to avoid using php session variables and mess with other user scripts. https://github.com/KiboOst/php-devoloDHC Let me know what you think, if we can find new stuff and share them, all great.

KiboOst commented 7 years ago

Hi, Actually, we login to dhlp/portal/light, which doesn't provide setProperty authorization Did you tried to login to dhp/portal/fullLogin ? I did bt always got invalid session as json answer.

kdietrich commented 7 years ago

Did you tried to login to dhp/portal/fullLogin ?

AFAIK won't make a difference, because both use the same json-rpc to invoke commands.

KiboOst commented 7 years ago

Sure, but why the browser is allowed to setProperty and not our apis :/

KiboOst commented 7 years ago

Ok, make a big difference indeed. Got php/curl to fully login on dhp/portal/fullLogin, and all works, setProperty etc ! I guess we could even create new devices lol! But will never go this route in the api, too risky.

Did you get your authentification method from the android apk ? It is totally different from fullLogin.

kdietrich commented 7 years ago

Sure, but if you're going the fullLogin route you're basically scraping the devolo.com webinterface. And this is something I would avoid because every change will break your code.

KiboOst commented 7 years ago

Well, fullogin and light login both use exact same json-rpc commands. fulllogin just allow more commands. So yes, they can change web interface authentication more easily than android and iOS one.

But I don't see them changing it on purpose for a few guys using a custom API. It also provide more value for their products for a few people wanting more.

And I still hope that sooner than later, I will put all this work to trash because an official API will see the day.

I also can subclass my API to provide light login in case fulllogin fails. Only turning on/off rules and timers won't work then, not a drama.

kdietrich commented 7 years ago

I'm closing this for now. Feel free to open a new issue if you have other questions.