Forum Replies Created
-
AuthorPosts
-
codahqParticipantAfter you install the device handler in the web IDE under device handlers you need to create a new device from the devices section.
There is a button to create a new device. Choose the device handler you just installed. It should be at the bottom of the list under device types.
After that is done you can switch to the app to configure it.
From the app go to the device and then go to the settings cogwheel and you should find the stuff you need to fill in.
You don’t need to change any code in the device handler. You do need to flash my firmware if you want real-time updates from the physical garage button. In the OG device’s web config I added a field for SmartThings hub IP.
- This reply was modified 5 years, 10 months ago by codahq.
codahqParticipantOh, by the way… For those of you have who have been using the device handler in SmartThings up to this point the only thing this changes is that instead of having to wait up to 5 minutes for SmartThings to poll the OpenGarage the firmware on the OpenGarage tells SmartThings (and Hubitat) when a change has occurred so they know immediately when the door has opened or closed.
This is much better for automations. For example, I have an automation that if the Garage Door has opened in the last 5 minutes and then the back garage door opens AND it’s dark a subset of lights turns on. It makes it so my wife never has to walk into a dark home when she arrives home. (Yes, there are other ways to do this with presence sensors. No lectures, please.)
codahqParticipantHello, everyone. It’s been a really long time since this thread has had any action. Jeff seems to have gotten busy and this finally came up on my list of priorities so I made a version of the firmware that supports SmartThings (and Hubitat).
The code for the firmware can be found here:
https://github.com/codahq/OpenGarage-FirmwareThe code for the SmartThings device handler can be found here:
https://github.com/codahq/smartthings_codahq/blob/master/devicetypes/codahq/opengarage-io-handler.src/opengarage-io-handler.groovyThe code for the Hubitat device handler can be found here (this will probably change locations if Hubitat introduces a github integration):
https://raw.githubusercontent.com/codahq/hubitat_codahq/master/devicestypes/opengarage-io-handler.groovySame concept to install as previously mentioned in this thread for the device handler. The only difference now is that in your OpenGarage firmware settings you need to go to Integrations and you need to specify the IP and port of your SmartThings (or Hubitat) hub.
For example, my SmartThings hub is at:
192.168.1.10:39500 (39500 is the default port)My Hubitat hub is at:
192.168.1.11:39501 (39501 is the default port)I’ve been using it for a couple of days. Hopefully it will work out for you guys.
- This reply was modified 5 years, 11 months ago by codahq. Reason: Updated links
codahqParticipantI don’t see any activity on lawrence-jeff on github so if Jeff is working on it it’s not committed yet.
I haven’t tested but I’m pretty sure you can still install my device handler and it will work as it did before. The problem is that SmartThings won’t know if you control the OpenGarage from the hardware button until SmartThings polls again. That’s the optimization that we needed a firmware change to fix. So, you can still use the current handler it just doesn’t update the garage door is open or closed for up to 5 minutes if you don’t do it through SmartThings.
It’s here. You don’t need the SmartApp. Just the device handler.
https://github.com/codahq/opengarage.io-handler/blob/master/OpenGarage.io-handler.groovy
codahqParticipant@kculhane It is definitely for everybody but it is not ready yet. Don’t install it until we give you an okay.
Also, I think what Jeff is getting at is if we do this change correctly on the firmware for ST we may be able to get away from doing one-off changes for every integration we need.
@lawrence_jeff This is very interesting to me. Maybe what we setup in the GUI is something like the ability to choose POST or GET and then just provide a URL and then maybe even provide a way to add more of them and we can store the webhook configuration in an array. This way we could configure as many as we wanted until we ran out of memory or hit some imposed limit or something (like 5 or 10).To your other question, yes, it is absolutely reasonable for us to want to send the data that we need so we don’t have to turn around and make another call right back and ask for it. I was just trying to make it as least impacting as possible. I would actually want essentially the same payload we get on calling “/jc” actually. Specifically the mac address, door, and vehicle. I can get the rest of the values from “/jc” if I need them.
To support 2 OGs in ST wouldn’t be via port, URL or payload. ST does this based off of the connecting device’s packet or TCP/IP connection information probably. It looks at the MAC address of the connection I think but it doesn’t send that information along to me. It just uses it to route and then drops it. I would be able to configure multiple OGs in ST though by giving each OG in STs the correct physical MAC address of each physical OG. Then the routing would work and each virtual device in ST would get the appropriate packets from that same URL and port.
Let me know if that makes sense.
codahqParticipantIt seems to work perfectly.
codahqParticipantAwesome, let’s do http://10.10.10.225:39500/ for now. Thanks!
codahqParticipant@lawrence_jeff Ah, sorry for the confusion. It isn’t anything you have to handle in the request on the firmware side. If you are setting up the device in SmartThings it was something very specific that you have to do on the hub side. It was so specific in fact that I programmed around it making it easier for user by filling in values that work programmatically using the IP and port and then later putting the MAC address in there when it’s available from a response from the OG. The values had to be manipulated in a special way and wasn’t intuitive at all.
For the firmware’s part it really is as simple as just the one header, the JSON payload and the destination address of http://[internal_st_hub_ip]:39500/ I think. The rest I’ll include as a write-up or something of how you have to configure the ST hub side. It’s actually very simple for the user now.
By the way, the listening port on the ST hub is apparently variable so I made a printout on the ST side for the user to be able to see what it is. On the firmware side don’t append 39500 as a hardcode and let the user provide a string containing the the entire URL I think just to be safe.
Please let me know if I haven’t cleared things up.
- This reply was modified 6 years, 10 months ago by codahq.
codahqParticipantI guess I didn’t realize that the current integration calls weren’t HTTPS. I would prefer not to go through IFTTT but that is an option. There is probably a way for an IFTTT recipe to perform a GET to any given URL. Maybe the Maker channel does that already. I think MQTT or any proxy server is a lot of requirement to add because to me it feels like this should be more simple.
How hard is it to do a HTTP POST with a JSON payload? I did some messing around and I was able to get the more complicated method of receiving local requests without going through the ST website. Everybody around the ST forums made it sound very complicated but it wasn’t bad. I was able to get a device handler to receive local requests. The trick was that the device network ID of the OG had to match the MAC address without the octet separator and it had to be in all caps. Then it was as easy as doing a POST in Postman to http://[internal_st_hub_ip]:39500/. The request had no authentication. It had just one header with Content-Type as “application/json” and then a body in JSON.
The JSON it is expecting in the POST to do a refresh is { “refresh”: true }.I wrote this new local functionality into my device handler already. I had to change a few things in the current device handler to get this to work. For example, when an outbound request is made from the device the response is only routed to the correct device handler if the device’s device network ID is the IPinHex:PortinHex. I found out that routing also works if you use the MAC address as I described above. However, to receive inbound requests the device’s device network ID MUST be the MAC and not the IP:PORT so I adapted the code to use the IP:PORT until it could get the MAC from a “/jc” call and then fill it in so it could receive requests.
Here is the link to the updated device handler.
https://github.com/codahq/opengarage.io-handler/blob/master/OpenGarage.io-handler.groovy
codahqParticipantI did some searching around and I found a similar project that uses this approach. I think this will be okay. I have implemented a SmartApp already for this approach if you can get the firmware to call the URL.
Here is the code for the SmartApp.
https://github.com/codahq/opengarage.io-handler/blob/master/OpenGarage.io-smartapp.groovy
In postman (or something similar) I was able to hit the URL that this SmartApp provided and SmartThings was responding appropriately and refreshing data from the device. @lawrence_jeff Can you make a firmware change then? Please let me know if you have any questions.
Here is the URL the OG would need to GET:
https://${base_api_url}/api/smartapps/installations/${app_instance_id}/do_update?access_code=${access_token}So, in the UI of the OG they would need to provide the base api URL, the app instance ID and the access token or alternatively just this entire URL with their info already in place.
codahqParticipantThe more I think about it the more I wonder if we shouldn’t just have the openGarage tell SmartThings when a refresh needs to happen and then the SmartThings can go ask the OpenGarage what values it has. I think this will work the best with the least amount of change on both sides.
So, maybe:
https://${baseUrl}/api/smartapps/installations/${app.id}/needs_update?access_token=${state.accessToken}
Or something like that? What do you think?
codahqParticipant@lawrence_jeff Yes, it does. It is pretty simple to register a URL for events if the URL is hosted on the SmartThings platform. Apparently it gets a little harder when you try to have a local device make calls at the SmartThings hubs directly.
If you want to add something to the firmware that would be awesome. Here is some documentation here.
http://docs.smartthings.com/en/latest/smartapp-web-services-developers-guide/tutorial-part1.html
Essentially you would need to make a HTTP GET for each action to:
https://${baseUrl}/api/smartapps/installations/${app.id}/${action}?access_token=${state.accessToken}The base URL will change depending on where you got hosted when you log into SmartThings first so it might be one of about 10 values. For example, mine is “graph-na02-useast1.api.smartthings.com” but my brother’s who lives only 30 miles away is different. The ${app.id} is the unique ID given to the SmartApp when it is setup in SmartThing’s API. This is different for every instance of the app. The action is whatever we decide we want to implement. I would suggest at a bare minimum we have a “open” and “close” action. ${state.accessToken} is an OAUTH token that you have to generate after installing the SmartApp.
Please note, I am calling this part of the SmartThings integration a SmartApp instead of a Device Handler because from what I understand you can’t do this type of thing in a Device Handler. I could be wrong on that but that’s the gist after looking at a view examples. Full disclaimer, I am not an expert at SmartThings on any level. My first experience writing code for the platform is for the OpenGarage. I know this will work though… I setup a quick example to make sure I could hit the API and change the statuses on a virtual device with the following SmartApp code. This was mostly taken from another example I found on the SmartThings forum and modified to work for our purposes.
/** * OpenGarage SmartApp * * Copyright 2018 Ben Rimmasch * */ definition( name: "HTTP Open/Close Endpoint", namespace: "me.bendy.opengarage", author: "Ben Rimmasch", description: "Creates an HTTP motion endpoint for your OpenGarage", category: "Convenience", iconUrl: "https://need.an.icon.com/badly.png", iconX2Url: "https://need.an.icon.com/[email protected]" ) preferences { page(name: "selectDevices", install: false, uninstall: true, nextPage: "viewURL") { section("Allow endpoint to control this thing...") { input "og", "capability.doorControl", title: "Which door controller is the OpenGarage?", required: true label title: "Assign a name", required: false mode title: "Set for specific mode(s)", required: false } } page(name: "viewURL", title: "viewURL", install: true) } def installed() { log.debug "Installed with settings: ${settings}" } def updated() { log.debug "Updated with settings: ${settings}" unsubscribe() } mappings { path("/open") { action: [ GET: "openAction" ] } path("/close") { action: [ GET: "closeAction" ] } } void openAction() { log.debug "Updated with settings: ${settings}" og?.open() } void closeAction() { log.debug "Updated with settings: ${settings}" og?.close() } def generateURL() { createAccessToken() ["https://graph.api.smartthings.com/api/smartapps/installations/${app.id}/open", "?access_token=${state.accessToken}"] } def viewURL() { dynamicPage(name: "viewURL", title: "HTTP Motion Endpoint", install:!resetOauth, nextPage: resetOauth ? "viewURL" : null) { section() { generateURL() paragraph "Open: https://graph.api.smartthings.com/api/smartapps/installations/${app.id}/open?access_token=${state.accessToken}" paragraph "Close: https://graph.api.smartthings.com/api/smartapps/installations/${app.id}/close?access_token=${state.accessToken}" } } }
codahqParticipant@Alonzo By the way, the polling I added is for every 5 minutes. I could add 1 minute but SmartThings has rate limits against device handler’s execution time and discourages frequent polling especially when doing it the way that I did it. I’ve been polling the last couple of days at 5 minutes and it feels good enough for me anyway.
We can actually get away from polling if we want by having the OG send an update to the SmartThings hub but it would require a firmware change and I’m just too lazy to try to get the firmware compiling again. Maybe if you bug Ray or Jeff they’ll add it. It’s already very similar to the IFTTT and Blynk integrations.
codahqParticipantI added vehicle presence support today. Knock yourselves out.
codahqParticipantI made some more changes today. Instead of (or perhaps alongside) polling the OG for state I put logic in the device handler to refresh state before it blindly performs an open or close. If the door is found to be out of synchronization it updates the status and then decides whether or not the button should be pressed.
I have implemented a way to poll the OG to synchronize its state as well but I don’t know if it’s best practice so I’m checking around before I push that change.
I’m also considering implementing switch functionality so that an OG can be shared to Google Home through the SmartThings integration. It would be weird to use because you would be saying something like… “Hey, Google… turn on the garage door”. I tried creating an OOB automation with the OG’s device handler in it but for security reasons any routines with doors in them won’t share through the integration. I haven’t attempted the switch hack yet. There might be other weird restrictions that prevent it.
codahqParticipantI had issues with this handler as well. I found a couple of problems but namely the methods in the device handler to convert the IP address to hex do not support IPs in the form of 10.*.*.* and other internal IP addresses. Here is a fork of Ian’s work that fixes this issue.
https://github.com/codahq/opengarage.io-handler/blob/master/OpenGarage.io-handler.groovy
-
AuthorPosts