Notifications - Text & Sound

Hi,

I am not a developer but I am writing my own apps or drivers for simple tasks.
So I wonder if it is possible to use the internal notification method with my apps ?

I see that by installing built-in "notifications" app , I can create text notifications on my phone based on rules.
That is also possible using the rule machine.

https://docs.hubitat.com/index.php?title=Notifications

But how can I write my own apps that send text notifications ?
If I want to use Pushover, I can write a http method to trigger notifications through my pushover account. But how to do that with official Hubitat mobile app ?

I also wonder how to send notifications through sound/music devices using a custom voice from Amazon Polly.
I can call texttospeech with custom voice as:
def ss = textToSpeech(e1, "Filiz")
def str2 = ss.inspect()
and this returns the URI for the sound file.
But how can I play it on my selected sound device ?

Btw, is it also possible to select custom voice for built-in apps like Notifications or Rule Machine ?

thanks

Apps don't deal with that low of a level of device communication directly. They use standard commands exposed by the driver, and the driver handles those details. For example, to send a notification to the Hubitat mobile app on your phone, the Notifications app in Hubitat just uses the deviceNotify() command on your mobile app device (the one you choose in the Notifications app and the one that gets created when you associate the app with your hub). You can do the same in your custom app. It (or the Notifications app) doesn't really need to know details about the exact device, just that it supports this command--a standard part of the Notification capability that deivers like this implement. If you want to do something else with notifications, you'll need to find or write a custom (or stock) driver--or at least that's better than trying to do something at the app level specifically. Hubitat has a Pushover driver built in, so if you want Pushover notifications insted, you'll just need to set that up and use that device instead of (or in addition to) the Hubitat mobile app notification device.

Speech is different. A lot of speech devices support commands that can play tracks from a URL, so I'd experiment with yours first to see if you can figure something out. Off the top of my head, I think playTrack() is probably what you want, passing the URL as a parameter. Testing this from the device page is probably easier if you can get such a URL, but in an app you can also call this command--or whatever you find that works--on your device. (As you may know, you need a "reference" to a device to do this--from an input where a user chooses this device. The command name matches the Groovy method name.)

2 Likes

thanks. actually , that was what I'm looking for. Because I am writing my own simple drivers and I want to know how to send a push notification to phones (through the Hubitat mobile app)

so I need to learn how to use deviceNotify() and playTrack()
where can I find documentation about these ?

1 Like

If you're writing a driver, you will have to implement the commands yourself. You will likely not be able to implement either in a way that sends notifications to the Hubitat mobile app. If hi want that, you'll have to use a Hubitat mobile app device that gets created on you hub with the built-in Mobile App Device driver. (I don't know of any API for this.)

I'm not sure what your actual goal is, however. Are you sure you don't want to write a custom app that can sens notifications to anything, including the Hubitat mobile app (but really whatever the user selects)? Generally, you'd write an app to perform an automation (which can be a lot of things, including sending a notification when something happens) or a driver to tell Hubitat how to communicate with a device, generally one it doesn't already know about (or when you don't like the built-in driver behavior).

If your goal is indeed an app, you don't have to worry about the implementation of these commands; again, that's the driver. You just call them from your app, and like with any device (Hubitat's device model abstracts specific details away from apps so things can be fairly standardized), the driver takes care of actually doing it.

actually I am just writing simple apps / drivers for my specific requirement. I am not writing for any other user.
So I just want to initiate a notification to myself using the official Hubitat mobile app.

I am coming from Smartthings hub and there we had the commands "sendPush()" and "sendPushMessage()" for this purpose.
Sİnce, Hubitat apps like "Notifications" can initiate a notification to mobile app, I am sure there is a low level command for this purpose also on Hubitat.
How these apps start a push notification ?

Btw, I am also "ok" to use the notification method selected by the user. But how do I call this function without using "notifications" app ?
I don't want to create individual notifications through that app for my own drivers. Because if I go that path, I have to create "new notification" for each trigger I need.

Where can I get information about low level commands like deviceNotify() and playTrack() ?
their usage and parameters...

I still think it would be helpful to revisit the app vs. driver question. I really think what you're looking for is a custom app. How were you using these commands on SmartThings? You were probably using a SmartApp, whether it was a built-in one, a custom one, or a webCoRE piston (so also a custom SmartApp). It's been a while, but I think the biggest difference is just that sendPush() was just a command you could call by itself from anywhere in a SmartApp. Hubitat works a bit differently: there is a "Notification" capability devices can provide, which requires that they implement a deviceNotification() command that takes one string parameter, the notification text. (I'm pretty sure this wasn't available in DTHs on SmartThings, but if it was, you'll definitely need an app instead on Hubitat, since as on SmartThings, you cannot call methods on one device directly from another device on Hubitat.)

If you are familiar with SmartThings (or Hubitat) app development, this is how pretty much any device works in an app: say you have a device selected with the "Switch" capability, which requires implementing the on() and off() methods or a "SwitchLevel" (dimmer) device that requires setLevel(). Once you have a reference to that device from an input in an app/SmartApp, you can call setLevel(50), for example, on that device to send the command. Same thing here: get a reference to the device, then call deviceNotify("Your notification text") on it. The driver for the device--in this case, Hubitat's built-in driver for their mobile app device--handles the details on how the push notifications are actually implemented on the device (mobile app). So think of this as a device method or capability command--which it is--and not a built-in (Smart)App feature.

It sounds like this is what you really want--not to get into driver development, in which case it's your responsibility to implement these commands in whatever way you want (but doing something with Hubitat's in-app notifications isn't really within the realm of easy possibility--this would be more like if you're writing your own mobile app and want it to get notifications, or if you want a third-party notification solution that doesn't have a Hubitat driver already).

1 Like

thanks. what I understand from you wrote is that I can call deviceNotify("Your notification text") from my device or app. But before that I need to refer to a notification device.
So in that case, can I do this:
1.- add input to the preferences of the app/driver to select a notification device
2.- where I need to send a notification, use the selected device with deviceNotify() command

how can I implement this ?
a 2 line example would be nice

btw, is it deviceNotify() or deviceNotification() ?

Like on SmartThings, devices cannot reference other devices directly (though there are some exceptions with parent/child relationships). To get a reference to a device, you'll need a SmartApp/app. So, what you want is something like this in an app:

input name: "myDevice", type: "capability.notification", title: "Choose notification device:"

and then you can call a command like this somewhere else in the app:

myDevice.deviceNotification("This is my notification text")

Also, it is indeed deviceNotification(), but I always forget, so apolgies for probably typing it both ways above depending on what I thought was correct at that time. :slight_smile: The Capability List docs show the command names (and the capability names you can use to select for devices that implement them), if you haven't seen this already.

1 Like

thanks.
but if I can't do it on a device (device can not reference another device), then how can I achieve this from my device ?

my final target is to make a virtual device which would represent a server at home.
I have that part of the code ready. The device actually uses the hub to ping a configured IP address and shows is status (up/down) with Presence capability.
Now I want to add a notification to the device, so that when the ping fails, it would send a notification to my phone.

From what I know, only apps can communicate with other devices/driver where a device/driver can only talk to its parent (device or app) or a child device.

In your app config section, you could use something like this to select a single or multiple notification devices:

input "notifyDevices", "capability.notification", multiple: true,
	title: "Choose your notification devices"

Then you can use a function to send the text notifications in your app (the .each call is only needed if you select multiple devices... "multiple: true"... otherwise you can use the single device command like @bertabcd1234 posted above):

def notify(text){
	notifyDevices.each{
		it.deviceNotification(text)
	}
}

In my use case, I have a child device the app creates that does various stuff and allows me to put that info on a tile on a dashboard.. but when the device needs to send a notification, it will call its parent function:

parent.notify("Your notification message")
1 Like

thanks. how can I make my app parent of my device ?
is it possible to do that without creating the device from the app ?

if not, how can I create a child device from my app ?
a simple code that would do this would be helpful

Child devices can only be created by an app or another device (i.e., you can't take over an existing device as a child, nor can one device or app be a direct child of more than one app/device). However, I'm still not sure that's what you want. If your goal is to send the user (or yourself) a notification when your own device becomes a certain state, then I'd say you have two options:

  1. Leave it to the user to configure an app that that does what they want since there is apparently already a device that can be monitored for this purpose--e.g. create a rule triggered by a state change for that switch, with actions that send a notification under your desired conditions. The disadvantage here is that it requires additional setup on the part of the user, but it's arbitrarily flexible. Since this is already possible at the platform level, your app/driver doesn't need to do anything here; or

  2. Allow the user to select a notification device in your app, then use the user's selected device(s) to send the notification (see either of the snippets above). Your app would then have the logic to implement when this notification should happen (e.g., by subscribing to events from your switch device).

Or both. :smiley:

A child device must be created from the parent, otherwise it will not be associated as a parent/child relationship. If you make the child device "isComponent: true" the child device cannot be manually deleted, it can only be deleted using code in the parent device.

Here is a function I use to create children for one of my apps:

def createChildDevice(childName) {
    log.debug "Running createChildDevice"
    if(!getChildDevice(childName)) {
        log.debug "In createChildDevice - Child device not found - Creating device: ${childName}"
        def driverName = "Virtual Keypad"
        def driverNameSpace = "mbarone" //only required if child device namespace is different from parent
        try {
            addChildDevice(driverNameSpace, driverName, childName, 1234, ["name": "${childName}", isComponent: false])
            log.debug "In createChildDevice - Child device has been created! (${childName})"
        } catch (e) {
			log.debug "App unable to create child device - ${e}" 
		}
    } else {
		log.debug "Device (${childName}) already exists."
    }
}

I would take a look at several apps that do similar things you want and take a look at their code to help you out... this is how I started with my Hubitat apps/drivers.

Alternatively, you could just create the driver, which performs as you need and use Rule Machine to monitor the value and send notifications for your specific scenarios. Really depends on your skills and how much time you want to spend developing this for your use case.

1 Like

thanks.
I know I'm asking for too much but can you give me a simple app code which would just create a child device given a "ip address" and a "name" as parameter ?

I don't need the app to hold record of created child devices. just take 2 parameters from user and create a child device.

I don't understand the difference of these 2.
what happens when I allow the user to select a notification device in my app ?
who will tell the notification device what message to be sent ?
btw, since I am not interested in writing an app, this option is not an option for me. I am just writing a device. because I need it to be a "device"

Blockquote
I don't need the app to hold record of created child devices. just take 2 parameters from user and create a child device.

When you create a child device from an app or another device, the parent will technically hold the record for this child device making them connected/not able to separate. That is kind of the point of using the parent/child app or driver method that these are now tied together for additional/more complex functionality and organization.

I would create the child device (with the name given) from the parent app.. then inside the child device, you can set the ip. This is how i handle a few parent/child drivers i have written. You can also send specific/custom settings from the app to the child device, but this takes more steps and more code in the app and driver to make it work.

Blockquote
btw, since I am not interested in writing an app, this option is not an option for me. I am just writing a device. because I need it to be a "device"

If this is the direction you want (at least for now), I would just write the driver that you need to fulfill your "device" requirements (which seems like you are mostly there) and use Rule Machine to monitor your custom device attributes/states and manage your notifications based on logic in RM or using another notifications app.

take a look at this code. in order to get around that issue. i made a notification device HANDLER that you can parse strings and therefore pass it messages in various strings..
via notifications

I don'T want to use RM or other app for notification purpose. Because I will create several of these virtual devices and I don't want to create several RM rules for them. Besides, with 1 rule , I won't be able to handle all of my notification needs per device. I will need at least 3 rules per device.
Considering I will have around 7-8 of these virtual devices, it means creating over 20 rules.

Why not handle the notification within my device ?
I really don't understand why sending notification is a taboo for Hubitat users/developers.
why am I being pushed to use a separate rule machine or notification app where I could just handle it with a line in my device driver ?

I'm sorry if this sounds too harsh for you but that's what I felt. :frowning:

for now I can see the most simple approach for my need is to create a simple app that would create child devices.
if you can supply me a very basic app code which would just create children when I enter name, that would be great.

ok. but how can I call this device from my device ?
as noted in this thread , devcies can not call other device. so ?

you send it a notification (as it is a standard notification device handler). that is the crux of it.. the communiction method is notifications then you parse them and do whatever you like.

you put a selection for a notification device in your device.. as an input, pick the other notification handler and then pass it whatever you like in a message.