Catch Notification Speak Event Text

Im using the Notifications app to have the speakers alert when there is a temperature/moisture warning. Works except when Google Minis go to sleep,

For other speaker alerts, Ive resorted to a Node-Red endpoint that you send the text/track and it will attempt to wake the Minis up, set the volume, and then attempt to play the announcement. This is seemingly working good, and keeps 4 extra lines of crud out of every rule I have (lovely).

Unfortunately, the notification app does not have the ability to POST, so I was thinking I make a Virtual Speaker, and watch that in Node-Red. When it triggers, I take the speech text and post it to the Node-Red Alert endpoint and push it through the wake up routine.

Watching the speaker event come through Node-Red I can see it playing, but I cant see what it is playing. Thoughts on intercepting the notification and redirecting it to Node-Red?

I probably explained this at like 85% clarity .. coffee needed

@erktrek

So why not do the notifications directly in Node-RED using something like this?

2 Likes

I've been playing with sync'ing hub variables to multiple hubs and node red ([Beta] Hub Variable Sync). Should be the same idea just using the notification as the driver....

1 Like

Also you could do something like @bertabcd1234 recommended.

1 Like

Looks like I re-invented the wheel with my google notifier ... including building a queue with q-gate.

Yeah .. I probably can/will move these triggers/alerts directly into Node-Red. The path of least resistance appears to be going that way.

2 Likes

Virtual Notification Device/Driver would work too .. The madness never ends!

1 Like

I know right?
:exploding_head:

1 Like

I could, maybe (?), watch the variable and then post, but at that point I could just make a Rule or move it to NodeRed .. unless Im not following you idea?

Moving the notification stuff and other cloud calls to NR seems like a good way to go if you can swing it. Reduces likelihood of resource issues on the HE hub itself. This is one of the reasons I'm using NR in the first place..

Not everything cloud is only on NR however - I am still using the Alexa skill for exposing certain devices to Alexa for basic control. Should note I am ALSO using an NR Alexa node for even greater control - like custom commands based on which Echo device is used AND to prevent teenagers from listening to their dots beyond bedtime (my daughter is SOO irritated at me for this).

I was actually thinking the same mechanism from how I'm doing the variables could be used in a new small app that just shuttled the notification over to nodeRed.

1 Like

If you set this up as a notification device

Notify nodeRed
/*
* Notify nodeRed
*
*  Licensed Virtual the Apache License, Version 2.0 (the "License"); you may not use this file except
*  in compliance with the License. You may obtain a copy of the License at:
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
*  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
*  for the specific language governing permissions and limitations under the License.
*
*  Change History:
*

*/
import java.text.SimpleDateFormat
import groovy.transform.Field
import java.net.URLEncoder
static String version()	{  return '0.0.1'  }

metadata {
	definition (
			name: "Notify nodeRed", 
			namespace: "thebearmay", 
			description: "Simple driver to act as a destination for notifications to be forwarded to nodeRed",
			author: "Jean P. May, Jr.",
			importUrl:"https://raw.githubusercontent.com/thebearmay/hubitat/main/xxxxxx.groovy",
            singleThreaded: true
		) {
			capability "Notification"
            capability "Configuration"

			}   
		}

	preferences {
		input("debugEnable", "bool", title: "Enable debug logging?")
            input "nrServer","text", title:"<b>NodeRed Server path</b> (i.e. http://192.168.x.x:1880)", submitOnChange: true
            input "nrPath", "text", title:"<b>NodeRed Endpoint path</b> (i.e. /notifications)", submitOnChange:true
            input "nrEnabled", "bool", title:"Enable Send to NodeRed", submitOnChange:true, defaultValue:false

	}

	void installed() {
		if (debugEnable) log.trace "installed()"
		configure()
	}

	void updated(){
        if (debugEnable) log.trace "updated()"
		if(debugEnable) runIn(1800,logsOff)

    }

	void configure() {
		if (debugEnable) log.trace "configure()"

	}

void deviceNotification(notification){
	if (debugEnable) log.debug "deviceNotification entered: ${notification}" 
    if(nrEnabled){
        notification = URLEncoder.encode(notification, "UTF-8")
        sendNR(notification)
    }

}    

void sendNR(notification){

	Map requestParams =
	[
        uri: "$nrServer$nrPath/$notification",
        body: []
	]

    if(debugEnabled) log.debug "$requestParams"

    asynchttpGet("getResp", requestParams, [src:"nrNotify"])     
}

void getResp(resp, data) {
    try {
        if(debugEnabled) log.debug "$resp.properties - ${data['cmd']} - ${resp.getStatus()}"
        if(resp.getStatus() == 200 || resp.getStatus() == 207){
            if(resp.data) 
                returnString = resp.data
            else returnString = "status:${resp.getStatus()}"
        } else 
            log.error "Bad status returned ${resp.getStatus()}"
    } catch (Exception ex) {
        log.error ex.message
    }


}

	void logsOff(){
		device.updateSetting("debugEnable",[value:"false",type:"bool"])
	}

	void push() {
        	configure()
	}

and using a http in node in nodeRed with method set to GET, and a path that agrees with what you enter into the driver you should be able to get notifications from HE into nodeRed.

1 Like

Argh - ninja'd by @thebearmay's mad tech skillz.. Oh well - here is my take on the same thing. I adapted @bertabcd1234's driver and am using "post". I haven't done this in a while so am a bit rusty.

In HE:

  1. copy and paste the driver below into a new driver that can be added in the "Drivers Code" section of the HE Nav menu.
  2. Create a virtual device and select "virtual notification (user)" as the driver.
  3. Configure the new device like this... subbing [node-red] for actual address

Then in Node-RED using an "http-in" node do something like this:

You can test in HE by typing in some text in the "Device Notification" box and clicking the title part (it's actually a button).

Results should show up in the msg.payload along with some other properties you can ignore.

HE custom driver - Virtual Notification Device for Node-RED

metadata {
    definition (name: "Virtual Notification Device", namespace: "RMoRobert", author: "Robert Morris") {
        capability "Notification"
        capability "Actuator"
    }
       
   preferences {
       input( name: "nodeRedAddr",type:"string",title: "Node-RED server address", description:"The location of the Node-RED server including port #.", defaultValue:"http://[Node-RED ip address]:[port]")
       input( name: "nodeRedPath",type:"string",title: "Node-RED path", description:"", defaultValue:"/notify")
       input(name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true)
       input(name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true)
   }
}

void installed() {
   log.debug "installed()"
   initialize()
}

void updated() {
   log.debug "updated()"
   initialize()
}

void initialize() {
   log.debug "initialize()"
   Integer disableTime = 1800
   if (logEnable) {
      log.debug "Debug logging will be automatically disabled in ${disableTime} seconds"
      runIn(disableTime, "debugOff")
   }
}

void debugOff() {
   log.warn "Disabling debug logging"
   device.updateSetting("logEnable", [value:"false", type:"bool"])
}

void deviceNotify() {
}

void myAsynchttpHandler(resp, data) {
   if (logEnable) log.debug "HTTP ${resp.status}"
  // whatever you might need to do here (check for errors, etc.),
   if (logEnable) log.debug "HTTP ${resp.body}"
}


void deviceNotification(notificationText) {
	if (logEnable) log.debug "deviceNotification(notificationText = ${notificationText})"
    sendEvent(name: "deviceNotification", value: notificationText, isStateChange: true)
   
   Map params = [
      uri:  nodeRedAddr,
      contentType: "application/json",  // or whatever
      path: nodeRedPath,
      body: [notificationText: notificationText],  // this will get converted to a JSON
      timeout: 15
   ]
   asynchttpPost("myAsynchttpHandler", params)

}

2 Likes

I'll probably change my code over to POST now that I've seen how nodeRed is handling it...

1 Like

Yeah I was worried about funky chars etc.. also very long strings.

That is solid ..

1 Like

@thebearmay @erktrek This notification proxy driver (or whatever it is in reality) is AMAZEBALLS

2 Likes

Download the Hubitat app