Using Maker API - how to receive events?

Hi,

I used to work at Wink and while there wrote a dashboard view for their Android app (screenshot included). I was never able to get it released during my time there -- something I hope might happen now that they're going to start charging users..

Anyway, I'm just doing some digging into how hard it'd be to write an open source native Android app and the MakerAPI seems like what I'm looking for with 1 major exception - receiving instant updates when they happen.

I see the "URL to send device events to by POST" setting but that doesn't make sense to me.. if I've got several tablets running this app - all connected to my hubitat hub - this doesn't seem like it could work. Not to mention that an Android device generally isn't reachable directly from the hub by URL.

Is there some kind of event subscription logic -- using a keep-alive web connection that could work? Or, what about being able to receive push notifications for device changes? That's how Wink updated it's Android device.

Anyway, I was hoping not to do any polling as that seemed pretty inefficient.. and without polling frequently updates wouldn't feel very quick to respond.

Please let me know

thanks
joe

edit:

what about being able to receive push notifications for device changes?

By this I mean a silent push notification -- you don't actually see anything on the device but the app can handle the notification and update the UI

I know homebridge can do this. Instant changes. Not sure how.

Ooooohhh. I love these type of topics.

Maker API is nice but you will probably need to think of things a different way or have a custom Hubitat app created to handle communication. I don’t know if pushing events directly to a phone though is possibile via http. I’ve never tried it. But if it is writing a custom app to push events would probably be best.

There are two situations that you can look at.

On the same LAN. In this situation your app can subscribe to the websocket and watch for events. This is real time and a really good way to keep the dashboard updated. Then when you want to send an event such as turning on a light you can send it via maker or a custom app that will listen to your requests (not hard to code).

Off the LAN. I don’t think you can have access to the websocket off the LAN so the dashboard would poll every 5 seconds using the cloud links to get the updates to device states. Then same as above you would push the events through the cloud endpoint to your app or maker API to control them.

As you can tell I’ve been thinking about this a lot lately. Was playing around with react native earlier today just to dabble in creating an app.

thanks for the quick replies!!

I've worked on a few different Android app which needed to get updates from a server immediately so polling wasn't an option.

  • 1 company used websockets which was probably the best/most efficient option. The app would basically connect keeping the socket open when the UI was visible and send keepalives every few seconds. I think that could work remotely as well as long as we can reach the hub from the Internet
  • another company relied completely on google push messages (GCM or FCM as it's called today). This was an Instant Messenger app so messages needed to get delivered and surprisingly the silent push notifications worked very reliably. Ultimately, every Android device has it's own keep-alive connection to Google and it's much easier to use their connection vs creating our own
  • Wink also used push notifications through a 3rd party library, pubnub. It's not a free service though and it's easy enough to just use Google's push notifications for free.

Unfortunately, I know very little of the server-side of things so I was really hoping the MakerAPI or something else would have this already built.

Anyway, I'd love to hear any other ideas or thoughts on this.

Interesting topic... You may want to have a discussion with Hubitat’s @chuck.schwer. He understands Hubitat’s architecture better than anyone I know (probably because he wrote most of it! :wink:)

1 Like

HE has an eventstream you can tap into (websocket). There are quite a few posts about it on here if you search. It is awesome. I'm using it to develop a cool html/css/javascript dashboard. You can listen for events (streamed as JSON) and then run your script accordingly. You can also request the summary of a specific device or all devices from the server using Maker API and then parse the response.

Hope it helps and good luck!

But the eventstream websocket is local only, right? I'm assuming he wants his app to work even when not at home. I don't believe there is any "push" that will work outside of LAN, which is where, unfortunately, I think the only option HE currently offers is polling.

That being said, back in the old days, before we had websockets, we used to do "long polling" (comet) where you make a call, keep it open till it times out (or you receive a message) and you reopen whenever it either times out or you receive a message. It's still very inefficient, but better than regular polling.

Yes, true. Good point and well made :smiley:

Is using a VPN an option? Something lightweight like WireGuard? Will the websockets stuff work over that?

Another thought is maybe MQTT messaging... connect to a secure broker. There's a beta MQTT app for HE in progress. I'm doing that for owntracks communication right now..

It sounds like he's trying to setup something to be a simple solution for a mobile app, sounds like it would meet the needs of people asking for a "simple app like Wink that doesn't require a PhD." Once you're asking people to setup a VPN or an MQTT broker, I'm thinking that won't meet the OP's needs.

2 Likes

@jpage4500 - Well, the folks over at Sharptools have managed to figure this out. They do have the advantage of using a central cloud server platform to host their web-based users from. This would keep the updates going to one cloud server and then being disseminated to all of the web clients that are active. Sharptools is pretty impressive and responsive.

You could create an OAuth2 based App on Hubitat, that should allow your custom Mobile App to connect to the Hubitat Cloud and retrieve a token via an authorization process, in the same way that Amazon Alexa, Google Home, SharpTools, and even the Hubitat Mobile App does. Once your App is connected through cloud.hubitat.com, you should be able to read and write data bidirectionally. Handling multiple client apps (i.e. mobile phones) might be interesting, as you'd have to create some sort of connection manager to make sure all actively connected devices receive asynchronous updates as events come into your custom Hubitat OAuth2 Hub App.

Just thinking out loud... :thinking:

4 Likes

Since he was talking about writing his own Android app adding a public facing MQTT broker seems less challenging a task and once set up trivial for others to use. There are cloud providers like cloudMQTT - but then you've potentially added a subscription cost back into the mix.

For this specific case I think @csteele's idea is the way to go. Of course then you are back being reliant on the the "cloud" again and subject to the fortunes/whims of Hubitat. Likely (and appropriately) they would want to monetize any service hanging off their cloud.

Wow - it's awesome to see so much support. I'm glad I picked Hubitat!

the eventstream websocket is local only, right?

actually, the more i think about it my primary interest is just for use in wall-mounted tablets around the house.. so, all traffic would be local anyway. It would be cool if it also worked on phones from anywhere but that wouldn't be as important at least for me.

HE has an eventstream you can tap into (websocket)

I'll search for this - thanks for all of the suggestions!

Just be aware that Hubitat’s event stream webSocket is not a published tool for end users. While Hubitat has not indicated that they would lock it down, they have mentioned that it is subject to change as necessary. I use it with Node Red to collect data for InfluxDB/Grafana and it does work very well.

Hubitat’s preferred method is to use their published Maker API. Although, as you know, it can only publish updates automatically to a single device. I wonder what would happen if one chose to use a LAN broadcast IP address? I have no idea if that would work, or how much negative impact it would have on a home LAN? :thinking:

2 Likes

If it worked, and turned out to be detrimental, one could always put the HE and the tablets on their own VLAN with a subnet mask that permitted a small yet sufficient number of hosts.

1 Like

I was just going to post and ask if/how to use this from another device on the network. The documents I found so far seem to reference some utility methods that are part of the apps/drivers which reside on the Hubitat as I understand it.

I did see the URL 'ws://192.168.1.10/eventsocket' mentioned in one of the posts and I figured when I got time I could try to connect to it. But, would it even work without any kind of authentication? The connection would come from outside of the hubitat.

Hubitat’s preferred method is to use their published Maker API. Although, as you know, it can only publish updates automatically to a single device

I was thinking about how to implement that.. I'm not used to accepting incoming connections on a mobile device but I guess there's no reason it couldn't work as long as I can determine my IP address (to tell the hub). But, yeah, the single device/IP only limitation wouldn't make this super useful for multiple dashboards that are all active.

I tried to think about something 'else' which could accept these event notifications and then push them out to other devices that are listening.. but, that seems like it could get complicated quick. I'm comfortable writing the Android app part but not anything server-related (I've been a mobile-only developer for far too long lol)


side-note - i made a mistake in my first post.. I said Wink uses PubNub which piggybacked off of push notifications.. I remembered last night that PubNub instead is more like a websocket connection - except the connection is to their servers which aren't free.. anyway.. just wanted to correct that

woo-hoo! I found a little command-line tool to test websocket connections from my macbook: GitHub - vi/websocat: Command-line client for WebSockets, like netcat (or curl) for ws:// with advanced socat-like functions

I ran it and did a couple of actions to a door with a smart lock and open/close sensor:

~/Downloads$ websocat ws://192.168.0.202/eventsocket
-- locked door --
{"source":"DEVICE","name":"lock","displayName":"Porch Lock","value":"locked","unit":null,"deviceId":2,"hubId":null,"locationId":null,"installedAppId":null,"descriptionText":"Porch Lock was locked via key or thumbturn [physical]"}

-- unlocked door --
{"source":"DEVICE","name":"lock","displayName":"Porch Lock","value":"unlocked","unit":null,"deviceId":2,"hubId":null,"locationId":null,"installedAppId":null,"descriptionText":"Porch Lock was unlocked via key or thumbturn [physical]"}
{"source":"APP","name":"RM","displayName":null,"value":"Porch Lock lock unlocked","unit":null,"deviceId":null,"hubId":null,"locationId":null,"installedAppId":5,"descriptionText":null}

-- closed door --
{"source":"APP","name":"RM","displayName":null,"value":"Triggered","unit":null,"deviceId":null,"hubId":null,"locationId":null,"installedAppId":5,"descriptionText":null}
{"source":"DEVICE","name":"contact","displayName":"Patio Door","value":"closed","unit":null,"deviceId":67,"hubId":null,"locationId":null,"installedAppId":null,"descriptionText":"Patio Door was closed"}
4 Likes

Now you're on your way! Please keep us updated on the progress of your native Android App. If you're planning on sharing this work with the community, perhaps you'd consider developing with a toolset that allows for both Android and iOS Apps? Some of us are iOS users around here :wink:

4 Likes

Or seriously considering heading that way.

My ~3.5 year old original Pixel is on its last legs. I'm debating between getting the Pixel 4a when its released or the new iPhone SE.

You might also consider using "/logsocket" instead - a lot less cruft to sort through.

I use "node" (and "forever") to run a Javascript to pull (and archive) the "warn" and "error" messages from my logs.