Maker API New Features

Dan, thanks I missed that. Teach me to post without having any coffee in the morning.

Hi - not sure if this is the appropriate place to put this - not sure if this is a problem in Maker API or expected behavior. Also, bear with me if I describe anything incorrectly - just learning this system.

I'm working with the Abode Security system driver being developed by @endorphin_junkie. The driver captures events from my abode security system (such as contact closure events) correctly - they appear in Events for the Abode device using that driver.
The SendEvents lines in the driver include isStateChange : true.
Here's one of those lines:
sendEvent(name: alert_name, value: alert_value, descriptionText: message, type: alert_type, displayed: true, isStateChange: true)

I would like to use Maker API to send these events via HTTP Post, but they are not showing up in Maker. In the Maker API settings, I saw that it was only subscribed to events related to two attributes defined in the driver. I also read that Maker API requires events to have a capability (associate with a capability?) , so added the ContactSensor capability to the driver. It then shows up in subscribed Events, but Maker still doesn't log or send these events.

When I look at device events via
http://[Hub IP]/apps/api/[Maker App ID]/devices/[Device ID]/events?access_token=[my token]
I see the events but it says "isStateChange" : null. Not sure why the value of isStateChange isn't making it to Maker API.

Here's one of the events from the above URL:
{"device_id":"[device ID]","label":"Abode System","name":"Front Door","value":"Closed","date":"2020-04-01T14:52:45+0000","unit":null,"isStateChange":null,"source":"DEVICE"}

Any thoughts?

Thanks!

I added these lines to the driver but the events still aren't making it through Maker API.

capability 'ContactSensor'
attribute 'alert_name', 'String'

I believe Maker API is going to work best with Standard Capabilities (I.e. attributes and commands.) If the drivers you are using are not implementing standard capabilities fully, the it is unlikely to work well with Maker API.

It appears you’re trying to add a standard capability, but the question remains, has it been properly implemented in the driver to raise the correct events? “alert_name” is not a standard attribute of a Contact Sensor. “contact” is the correct attribute for a Contact Sensor. This is described in the Hubitat Developer documentation.

I would encourage you to ask the developer to make the appropriate changes to their integration to implement Standard Capabilities, instead of custom attributes and commands. This will allow the integration to work with the rest of the standard Hubitat Apps, including Maker API.

1 Like

Thank you - I'll pass this on!

It appears that's because the driver isn't publishing an event for an attribute titled alert_name, it's publishing an event for "Front Door"

That should be a string of "alert_name" or "contact" not the name of the device that is opened or closed. If the device is intended to monitor multiple contact sensors, then it should have child devices for each sensor. That's the only way you're going to get it to work right. The name is in reference to the attribute, not the device that is opening or closing. In this case, you;d have to have an attribute of "Front Door" to get it to work correctly.

I was able to figure this out because in the driver, both alert_name and alert_value are not strings, but are variables.

sendEvent(name: alert_name, value: alert_value, descriptionText: message, type: alert_type, displayed: true)

Unless alert_name is being set to "contact", then this is never going to work correctly.

1 Like

Thank you!

Not sure if I understood that last bit - are you saying change the name of the variable to "contact" or set the value of the variable to "contact" - or something else? But it seems from what you said that child devices would still be needed for each actual sensor?

Yes, if you're trying to monitor multiple doors and windows from a home security system, then the integration will need to create a child "Contact Sensor" device for each of them. This is really the best way to make these sensors appear as standard "Contact Sensor" devices within Hubitat. Once those child devices exist, every App within Hubitat can just use them.

Got it - thank you.

The name of the event has to correspond to whatever attribute you are reporting the event for. In this case, the name is "Front Door" but there is no attribute name "Front Door". That's why you won't see a POST message from the Maker API. A real event is not generated because there is no corresponding attribute.

1 Like

Okay - so the child device would be front door, and the event would be called "contact" because that's a standard attribute of ContactSensor?

Also - does the driver create a single child device of type contactsensor - and then I create multiple devices from that driver for each sensor? Or does the driver have to have a separate child device defined for each one in my particular system?

There is usually one Parent Driver, which would interrogate the Alarm system via an API. This would return the names of all of the alarm system’s sensors. For each sensor returned, a Child “Generic Component Contact Sensor” Device would be created. Then, any time the Parent received new data from the alarm system, it would update the status of the corresponding child device.

Hubitat already has a driver that can be used by a parent device, called “Generic Component Contact Sensor” for the children.

These are events being passed along from the Abode system. They don't map to fixed attributes. It's from one event stream to another. I passed them in as information for the user, if they wanted to see all security-related events in a single location.

Why can Maker API see the events but not use them? If Maker API is logging the events, it has access to them, right? I'm new to Maker API so forgive me.

Yes, this is what I proposed to him before-- we create a mapping of virtual devices for each type of device on the Abode system. He said he didn't want all that, so I was trying to find a way to help him get this event data directly, rather than relaying it through child devices.

Personally, I totally understand the child device model and can do that. But I'm curious why events must map to attributes to be seen. Or not seen, because Maker API can see them... but can't use them? Just thinking from a data flow perspective that seems odd.

I'm not suggesting this would be true for all events. I'm saying why can't an App say "I want to see all events from X driver" and not have every one of them map to an attribute. I would hate to change 20 attributes for a single action just to make all those fields available :frowning:

Maker API, like all Hubitat Apps is based on the architecture of "Capabilities". Capabilities define the Command and Attributes that a device has. Apps, subscribe to the events from devices. Events are generated by devices when they update an attribute with the sendEvent() call. Apps expect devices to implement standard Capabilities. This is the only way they know what to expect to receive from a device. This is how the entire platform is architected.

Right now, your events are things like "Front Door" open/close. "Front Door", while descriptive, is not a standard attribute. In the driver I looked at earlier, you have not even defined it as a custom attribute in the driver. Therefore, it will not persist. If you refresh the device details page, you'll notice the "Front Door" will disappear from the screen until the next time an event is generated. A true attribute will stick around when the page is refreshed. Also, custom attributes should not contain white space or special characters.

So, I would recommend you simply implement a Composite Device Driver (i.e. Parent/Child.) You could look at one I recently wrote that makes use of the built-in Hubitat "Generic Component Contact Sensor" driver, as this will allow you to only need to release and maintain the Parent Driver (your existing driver should be able to turned into a Parent Driver fairly easily.)

Take a look at this driver as an example, as I based on some of Mike Maxwell's example code that I pulled together from the forum threads. It is a little complicated due to the complexity of the device that I wrote it for. Pay attention to the 'fetchChild()' call, specifically this line from the parse() routine. This line of code (and the fetchChild() routine inside the driver as well) will create and update a child device using Hubitat's Generic Component Contact Sensor driver. Subsequent calls will only update the child.

                //update contact sensor child device
                fetchChild("Contact Sensor", index).parse([[name:"contact", value: value, descriptionText:"contact set to ${value}"]])

Hope this helps.

I understand that. If you look at the driver it already has a child device that was necessary for triggering Return from Away.

And I totally get that a huge HubConnect-style map-every-device-between-both-hubs would play better into the ecosystem. I don't doubt that. But I'm curious if there is any way to provide a data stream from a driver to an app that doesn't require creating hundreds of child devices that serve no purpose other than to relay a message?

My goal is to make the timeline events from Abode visible alongside the timeline events in HSM. That's all I intended to accomplish (and it works)

@hokfujow wanted to get to the same events from Maker API so I was curious why they wouldn't be available.

That is not how Hubitat events work. You cannot have an event for a non-declared attribute. No app will ever be able to subscribe to them.

You don't have to do that. If you only want to sync the alarm state, that is all you have to sync. But the driver shouldn't publish events that have no added value to the Hubitat system. What good are they if you can't do anything with them. Publishing an event named "Front Door" doesn't mean anything in Hubitat.

refer back to the post you replied to:

What does doing that accomplish though? What will you use it for? You can't access the events from any other apps to do anything with. If it's just to keep a record, there are much easier ways of accomplishing that that without having to publish events to Hubitat.

Hi - just to clarify. As I'm new to this, I didn't entirely understand what this meant. I thought what this meant is that I need to create individual devices myself for each and every sensor - which sounded like a lot of work. I'm still not totally clear on how this happens - but it sounds like the driver creates the child devices based on what is available - rather than my coding each one separately as I thought.