openhab / openhab-addons

Add-ons for openHAB
https://www.openhab.org/
Eclipse Public License 2.0
1.86k stars 3.57k forks source link

[somfymylink] Add Somfy MyLink Binding #4438

Closed LoungeFlyZ closed 4 years ago

LoungeFlyZ commented 5 years ago

The Somfi MyLink device has an TCP/IP interface that supports the Somfy Synergy API. You send json over a TCP socket connection.

e.g. { "id": 1, "method": "mylink.move.down", "params": { "targetID": "CC104A28.1", "auth": "foobar" } }

The MyLink will send responses as well as keep alive messages in json format also.

I have not obtained API documentation from Somfy for this API yet, however have found some examples of others calling it.

e.g. https://community.smartthings.com/t/somfy-mylink/81197/23

There is also an existing integration for smartthings that might be helpful. https://github.com/bendews/smartthings-somfy-mylink

I am a developer (but not done any Java in 10+ years) , and could look at building this binding ... but thought i would post here first in case someone had looked at this already or has any guidance.

LoungeFlyZ commented 5 years ago

I am working on this currently. No ETA, but as soon as i have a first version ready ill post here with a link to it if anyone is interested.

kevineriklee commented 5 years ago

Hi there! Did you end up making any progress on this? I'm also trying to integrate a Somfy MyLink into my smart home and was going to take a stab at writing a binding. Would love to collaborate if you could use some help

mhilbush commented 5 years ago

I'm getting ready to place an order for some Somfy-motorized blinks. I was going to order the ZRTSI gateway for my Z-Wave network, but the API approach outlined here would be better, I think.

@LoungeFlyZ How's the binding coming along? Are you interested in any help with the development and/or testing?

mhilbush commented 5 years ago

Ugh. I see all the commands go through the cloud rather than from the MyLink device directly to the motor. Requiring the Internet to open or close a blind is not what I was hoping for.

mhilbush commented 5 years ago

Wait, it also looks like there's a way to control the motors without going through the cloud.

LoungeFlyZ commented 5 years ago

@mhilbush correct, i got a basic binding working locally that controls the shades via the mylink locally. It basically sends it a json payload over a socket.

@kevineriklee i got a v0.1 of the binding working on my development machine, but i'm not a great Java programmer so it was pretty tough getting started with the tools etc... But it ran.

So far i have it:

@mhilbush & @kevineriklee I would be VERY keen to collaborate on this to get it complete. Like i said above i was learning openhab bindings and java and eclipse at the time and so i am not 100% i am doing everything right :) But would LOVE to get this ready for submission to the openhab project repo. Interested? I am guessing I should put my source up on github as a starting point?

LoungeFlyZ commented 5 years ago

I have pushed some very rough work in progress to a feature branch in my fork here: https://github.com/LoungeFlyZ/openhab2-addons/tree/loungeflyz-somfymylink

@mhilbush I would love any help/assistance getting it finished and ready for PR if you are able. I can give you access to my repo if that will help etc...

mhilbush commented 5 years ago

That's pretty good progress so far @LoungeFlyZ.

All my blinds (including the MyLink) are on order at the moment, so I won't be able to do any testing. But, I'll take a look at the feature branch you posted.

LoungeFlyZ commented 5 years ago

Thanks @mhilbush. This will be my first binding, so any advice after your review would be excellent and very much appreciated.

mhilbush commented 5 years ago

@LoungeFlyZ I took a quick look at the code. Good start! There are a couple things I'd suggest as next steps.

I've migrated 7 or 8 bindings to the new build system, so if you want I can do that, as well as a few of the other things listed above. If you give me permission I should be able to push some commits to your branch.

WRT the scene thing type... Since I don't actually have a MyLink yet (at least now I have an installation date), I'm not sure how they handle scenes. Is a scene just a collection of 1 or more shades and the percent open of each shade? If so, what's the format of a scene? Is it a number or a string? If so, would it make sense to make it a channel (e.g. scene_number) on the bridge thing type? WDYT?

mhilbush commented 5 years ago

I just pushed some commits that took care of the following.

LoungeFlyZ commented 5 years ago

Thanks for the notes @mhilbush. I have invited you as a contributor if you would like to make changes. Honestly, i am not familiar with the new build system at all .. so your guidance would be very helpful.

bridge goes OFFLINE

I guess we could test for this by pulling the shades information (mylink.status.info) and seeing if it errors out. I don't think there is a handy way to detect if the bridge is online otherwise.

is there any way to get the blind status from the MyLink

Not that i am aware of. This is annoying :) It means there is no status or % open that we can show.

Is a scene just a collection of 1 or more shades and the percent open of each shade?

A scene is a collection of shades + a command for each. A command is something like Down or Up. There isn't a way to command that shades (at least the ones i have) to open or close to a certain percentage. So really scenes are just groups of commands. There is an argument to be made that they are useless in OpenHab as you can just replicate them. But in Somfy MyLink they are more like a scene button that issues sets of commands. Not ideal. In all honestly, they confused me when i was implementing this first version. I wanted to model them as a non-toggle button i.e. just a press, not an on/off as you cant tell the state of a scene either. Guidance on this with openhab would be appreciated as the model doesnt seem to fit well.

mhilbush commented 5 years ago

@LoungeFlyZ I haven't made any additional changes since I pushed the commits earlier -- thought you might want to look over my changes. Then we can decide what to do next.

i am not familiar with the new build system at all

The conversion is pretty mechanical. The first one takes a while. But after you've done 7 or 8, it goes pretty quickly. 😉

It means there is no status or % open that we can show.

That's not good. Is there a mylink.status.position command? I saw that somewhere when I was googling around.

I also saw a mylink.move.to. I wonder what that does...

I guess we could test for this by pulling the shades information (mylink.status.info) and seeing if it errors out.

There also seems to be a keepalive (ping) method. So, if you finish the persistent connection functionality that's already in the code but commented out, you can go ONLINE when the connect/reconnect is successful, and go OFFLINE when the connection drops, or when the ping times out.

It sure would be nice if Somfy would send me that spec!!!

scenes

So, is the list of commands that makes up the scene stored in the MyLink, and you just send it the scene ID? Or, do you have to send it the individual move commands for each shade?

LoungeFlyZ commented 5 years ago

@mhilbush ok great. i'll take a deeper look tonight and get it building at my end to make sure i understand it :)

mylink.status.position

Not that I have seen unfortunately. mylink.move.to sounds interesting. Where did you see that?

I saw a smartthings binding that 'faked' percentage by allowing you to configure the time it took to go from 0% to 100% and then used that timing to guestimate how long to go Up/Down for before issuing the Stop command. Hacky, but may be the only option if % open is desired.

There also seems to be a keepalive (ping) method

Yes, if you open a socket and listen to it you will periodically get ping json messages back from the hub. Good point.

It sure would be nice if Somfy would send me that spec!!!

I have also tried to get this from them and it's aways a dead end. I'll try and hit them up on twitter again.

is the list of commands that makes up the scene stored in the MyLink

Yes.

send it the scene ID

I believe so yes. I can't remember if i tested this when building the binding however. I remember trying to model a stateless button in the binding to replicate how a scene works and being confused about how to do that or if it was possible.

I will pull your changes tonight and test it out. Thanks a lot for the guidance on this. I really wanted to get this submitted, but given my noobness with java/openhab wasn't sure what else needed to be done first and i didnt get around to it.

mhilbush commented 5 years ago

Not that I have seen unfortunately. mylink.move.to sounds interesting. Where did you see that?

Saw it in a SmartThings post here. A screen snip of part of the spec's ToC. All the more reason to get the spec!

Yes, if you open a socket and listen to it you will periodically get ping json messages back from the hub.

Yep, if no ping or connection closed, then bridge goes OFFLINE. There also may be a ping request method (see ToC in above link) that could accomplish the same thing...

scene

So, instead of a thing for each scene, what about a String or Number channel on the bridge? Sending a command to an item linked to the scene channel will cause the bridge handler to send the command to invoke the scene. That way, when you add or delete scenes you don't have to mess with scene things.

I will pull your changes tonight and test it out.

Sounds good. I built the binding, installed it, and created a bridge thing and a shade thing. That's about all I could do until I get a MyLink (which I think is coming on Thursday).

I see you're in Seattle. Great place! I spent three years out there in the mid-90s. Spent time in Redmond, and on Lake Washington Blvd in Bellevue across the street from Yarrow Point. Loved it out there!

LoungeFlyZ commented 5 years ago

I'll try out the .to and ping commands to see if they work. I'll let you know. I got in touch with Somfy about the API docs today. They emailed me back asking for more information, which i will provide, and so hopefully that will result in us getting the spec!

Lake Washington Blvd

Ha! that is where i am sitting right now. In an office in Carillon Point, Kirkland on Lake Washington Blvd! Small world.

LoungeFlyZ commented 5 years ago

Ok good news. After hours of struggling with eclipse and and the new build system I managed to get my local dev build working & the mylink binding added and running.

Discovery worked ...

2019-05-14_23-41-26

Controlling a shade also worked ...

2019-05-14_23-57-29

Finally, i set up a rule to lower a shade if I pressed a keypad button on my Lutron Radio RA2 keypad. Pretty happy with that for the night.

Next steps are adding all the bits about online/offline for the bridge etc... I think that would be handy. I didnt know it, but my mylink was going on and off the network due to poor wifi coverage and so an "offline" status would have been helpful to know that.

LoungeFlyZ commented 5 years ago

@mhilbush i pushed another commit that includes a bridge status online/offline implementation. It's not "great" in that it opens a connection and "pings" the mylink periodically, vs. keeping a socket open. The mylink behaves strangely with a persistent socket and seems to have issues with multiple being open etc... So i went with the simpler approach for now until i get more detail on the API and how it should be used. Let me know what you think.

LoungeFlyZ commented 5 years ago

Bit more done to correct some of the reported issues @mhilbush.

Still to do:

mhilbush commented 5 years ago

Well done!!!

I'll do a pull in the AM, then take another pass thru the code.

On May 17, 2019 8:40:08 PM Chris Johnson notifications@github.com wrote:

Bit more done to correct some of the reported issues @mhilbush.

convert to the new build system reorganize package structure to help keep things organized -- suggest to create handler, model, config, and discovery packages create separate config classes for bridge, scene, and shade things (see question about scenes below) remove getter/setter methods from Configuration(es) class and make fields public (this is considered a best practice by maintainers) add @NonNullByDefault annotation to class definitions (also considered best practice by maintainers) avoid catching the raw Exception (another best practice). Catching RuntimeException is considered ok in certain circumstances. -~~ there's some work to do to manage the thing status based on the bridge status (for example, if the bridge goes OFFLINE, the things should go OFFLINE since they will be unable to perform actions without the bridge)~~ is there any way to get the blind status from the MyLink? If so, in the handler we could use the REFRESH command at startup to get the status -sadly not. RTS is not bidirectional. some Java source files need license headers and Javadocs to openHAB standards XML files need formatting (tabs) to openHAB standard fix issues from static code analysis report

Still to do:

scene handling

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

mhilbush commented 5 years ago

Still to do: scene handling

@LoungeFlyZ One other thought on scenes...

If you decide to make a channel on the bridge thing for the scene, then, since you can get the list of scenes from the MyLink, you can use that list of scenes to create State Options on the channel. That would enable you to select a scene from a list using the Selection widget in the sitemap and/or the Selection widget in HABpanel.

If you decide to go down that path, I can point you to a couple examples of how to do this.

mhilbush commented 5 years ago

@LoungeFlyZ A couple other things I noticed.

LoungeFlyZ commented 5 years ago

Thanks @mhilbush. I like the idea you have around the scenes being a channel. I feel like that is a better model than an actual thing. Could you point to an example of that i could look at?

Tabs. I will go and wash my mouth out with soap immediately! I have no idea how those got in there! Gah!

Others all make sense.

mhilbush commented 5 years ago

There are two bindings you can look at as examples of state options: kodi and squeezebox.

So, once you created the channel set up on the BridgeHandler, to set the State Options for that channel you would do something like this. I might've missed a detail or two, but this is the essence of what you need to do.

Once this is in place, in a sitemap you could define a widget like this, and the selection list would be populated with the list of scenes you pulled from the MyLink.

Selection item=ItemLinkedToSceneChannel
LoungeFlyZ commented 5 years ago

@mhilbush ok great. i'll give that a shot and see how it goes.

previous suggestions from this morning are all complete.

mhilbush commented 5 years ago

@LoungeFlyZ One other thing I noticed... If you remove the bridge thing, the discovery service continues to periodically poll the mylink for devices. I think you also need to deactivate the discovery service in the bridge handler's dispose method.

LoungeFlyZ commented 5 years ago

@mhilbush yes i found that today too. Should be sorted out now. I did a couple of commits that tidy up the thing status when the bridge goes online/offline too.

mhilbush commented 5 years ago

@LoungeFlyZ I pulled the latest. Are you sure the issue I mentioned above is resolved. The bridge handler dispose method unregisters the discovery service here, but it doesn't deactivate it (e.g. discovery.deactivate()).

LoungeFlyZ commented 5 years ago

@mhilbush oh i see what you mean now! got it. (i think) https://github.com/LoungeFlyZ/openhab2-addons/commit/383116bd5ed61920c5866effc94786c87de3d798

mhilbush commented 5 years ago

@LoungeFlyZ A couple other things I noticed...

LoungeFlyZ commented 5 years ago

@mhilbush thanks for the suggestions.

fromJason throws a JsonSyntaxException, so you never get to the code that checks for error -fixed perhaps inspect the response for the presence of "error" (Gson has APIs for that), then handle as an error, otherwise call fromJson using the response type you expect - agreed. done. Why is it timing out even though it gets a response? - fixed Reduce log level from ERROR in above (ERROR is reserved for Framework-level errors). This is probably an INFO -fixed Reduce log level from INFO in above (these types of messages are usually logged at DEBUG). -fixed Why return something from sendPing if you don't intend to check it. Make it void? -fixed Consider reducing read timeout when waiting for a response from mylink, since openHAB and MyLink will be on a fast network -reduced to 5 seconds.

mhilbush commented 5 years ago

Nice! I'll give it a whirl this week. Actually getting blinds installed on Tuesday, so I'll be able to do more with the MyLink. It's pretty useless if you don't have any motors to pair with it, as it's not possible to complete the setup without at least one motor to pair.

mhilbush commented 5 years ago

BTW, did they ever send you the API spec?

LoungeFlyZ commented 5 years ago

@mhilbush they didn't send me it, but i still got it :) email me and we can privately discuss.

LoungeFlyZ commented 5 years ago

Completed: