sendLocationEvent() causing "Event queue is full"

Prior to purchasing a Hubitat I created Ring Alarm automations on my PC with Windows 11 and C++. I therefore needed Notifications from the Ring app that was running on my Iphone (I had difficulties obtaining these notifications from the online Ring program that ran on my PC within Chrome) to do the automations. I did this by running "Link To Windows" app on my Iphone and then running the "Phone Link" program on my PC and via Bluetooth I would obtain all the notifications that got produced on my Iphone (Of course you can filter which notifications you want... I just wanted Ring Alarm notifications). These Notifications appeared in a GUI within the PC's Phone Link program and could not find a programmatic method to obtain these notifications from the Phone Link program. So for a while I OCR'd the GUI and extracted them. NOT REALIABLE!! I soon realized that these notifications got logged to a database that the Event Viewer used on the PC. I then wrote a C++ program to extract the notifications from that database with SQL. I could then do the things I wanted to do with the Ring automation I wanted to develop. Of course all the notifications could be used for these PC based automations but I was only interested in Ring. When I purchased a Hubitat not to long ago I wanted to utilize this stream of notifications on Hubitat so I wrote another program on the PC to send them to a Hubitat app called NotificationServer. This Hubitat program sends out the notifications to my client Hubitat apps with "SendLocationEvent()" . The first client I used during developing this is as follows:

definition(
    name: "Notification Client",
    namespace: "Example",
    author: "Hubi",
    description: "Impliment a client to receive NOTIFICATION's",
    category: "Convenience",
    iconUrl: "",
    iconX2Url: "")

preferences {
    section("Logging") {
        input name: "logEnable", type: "bool", title: "Enable logging?"
    }
}

def installed() {
    log.debug "installed()"
    updated()
}


def updated() {
    if (logEnable) log.debug "updated()"
    unsubscribe()
    def MyLocation = getLocation()
    log.debug "MyLocation = " + MyLocation
    subscribe(MyLocation, "NOTIFICATION", Handler)
}

def uninstalled() {
    log.debug "uninstalled()"
}

def Handler(evt) {
    log.debug "*** Entered Notification Handler ***"
        
    log.debug evt.class.methods.collect { it.name }
        
    log.debug "evt = " + evt          
    log.debug "evt.value = " + evt.value   
    log.debug "evt.name = " + evt.name
    log.debug "evt.date = " + evt.date
    log.debug "evt.source = " + evt.source  
    log.debug "evt.data = " + evt.data
    
    def Data = evt.getData()
    log.debug "evt.getData() = " + Data
    
    def Source = evt.getSource()
    log.debug "evt.getSource() = " + Source
}

This method seemed to work reliably with a few apps that I created to use these notifications. Just the last week or so I have been getting the following in my Log:

app:819 is the NotificationServer and line 153 (The Exception line) is:

When I reboot Hubitat everthing works great for a while and then I get the error. My Ring notification's average perhaps a couple every minute so I do not have a flood of information being served. This exception "LimitExceededException: Event queue is full" can be caused how? The amount of notifications being served out seems very reasonable and as far as I understand if I did not have any clients obtaining the notifiications that would be OK. Can someone give me any info so I might be able to understand what is going on and maybe I could figure out how to correct this.

I appreciate your help... Thank You

If I can't figure out why I am getting an exception on the line:

sendLocationEvent(name:"NOTIFICATION", value: NotificationConverted, data: "Ring", descriptionText: "description you want", isStateChange: true)

Then allow me to ask another question. If I want to change my server from using the sendLocationEvent() and instead use sendEvent() that is on the last line of the following:

import java.net.URLDecoder 
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import groovy.transform.Field

definition(
    name: "aServer",
    namespace: "Example",
    author: "Hubi",
    description: "Impliment a server to send NOTIFICATION's",
    category: "Convenience",
    iconUrl: "",
    iconX2Url: "")

preferences {
    section("Logging") {
        input name: "logEnable", type: "bool", title: "Enable logging?"
    }
}

def installed() {
    log.debug "installed()"
    updated()
}

def uninstalled() {
    log.debug "uninstalled()"
}

def updated() {
    log.debug "updated()"
   
    // make a map that will be sent out via sendLocationEvent()
    Map Notification = ["Title":"Ring","Body":"THIS IS A TEST","DateTime":"Thu Feb 29 02:42:17 2024"]        
    log.debug "Notification = " + Notification
    log.debug "NotificationType = " + getObjectClassName(Notification) 
    
    // convert the map to a string
    def NotificationConverted = new groovy.json.JsonBuilder(Notification).toString()
    log.debug "NotificationConvereted = " + NotificationConverted
    log.debug "NotificationConveredType = " + getObjectClassName(NotificationConverted) 
    
    // lets convert the map converted to a string back to a map for a check
    def NotificationBack = new groovy.json.JsonSlurper().parseText(NotificationConverted)
    log.debug "NotificationBack = " + NotificationBack
    log.debug "NotificationBacktype = " + getObjectClassName(NotificationBack) 

    // sends out a notification that is a map but converted to a String
//    sendLocationEvent(name:"NOTIFICATION", value: NotificationConverted, data: "Ring", descriptionText: "description you want", isStateChange: true)
    
    sendEvent(name: "Notification", value: "NotificationConverted")
}

And given the following client that worked with the original server:

definition(
    name: "aClient",
    namespace: "Example",
    author: "Hubi",
    description: "Impliment a client to receive NOTIFICATION's",
    category: "Convenience",
    iconUrl: "",
    iconX2Url: "")

preferences {
    section("Logging") {
        input name: "logEnable", type: "bool", title: "Enable logging?"
    }
}

def installed() {
    log.debug "installed()"
    updated()
}

def updated() {
    if (logEnable) log.debug "updated()"
    unsubscribe()
    def MyLocation = getLocation()
    log.debug "MyLocation = " + MyLocation
    subscribe(MyLocation, "NOTIFICATION", Handler)
}

def uninstalled() {
    log.debug "uninstalled()"
}
        
def Handler(evt) {
    log.debug "*** Entered Notification Handler ***"
        
    log.debug evt.class.methods.collect { it.name }
        
    log.debug "evt = " + evt          
    log.debug "evt.value = " + evt.value   
    log.debug "evt.name = " + evt.name
    log.debug "evt.date = " + evt.date
    log.debug "evt.source = " + evt.source  
    log.debug "evt.data = " + evt.data
    
    def Data = evt.getData()
    log.debug "evt.getData() = " + Data
    
    def Source = evt.getSource()
    log.debug "evt.getSource() = " + Source
}

How could I change the "subscribe" line to allow the handler to be called when the server executes its sendEvent()? I am guessing that is the only line that needs to be changed. If I am wrong please tell me what else needs to be done.

Thanks Again

I use location events in some of my stuff... I send them like so:

sendLocationEvent("uniqueNameHere", value: "Object value", data:"Map data stuff here")

Then on the subscribe:

subscribe(location, "uniqueNameHere", "callbackMethodHere")

Callback:

void callbackMethodHere(Event evt) {
  Map d = evt.getData()
  Object v = evt.getValue()
  ... other stuff here
}

Thanks for the info. I currently use sendLocationEvent and it works well except for the past couple of weeks I have been getting "com.hubitat.app.exception.LimitExceededException: Event queue is full, new event for location 1 is dropped" in my Log for the line of code "sendLocationEvent()". I have not got any responses as to why this could be. I can't understand how it could be full... And if it is full why discard the new queue entry instead of the oldest!? So I thought I would try SendEvent() instead of sendLocationEvent() and keep my fingers crossed.

Thanks Again

In my pursuit of replacing my sendLocationEvent() with sendEvent() in aserver I have the following question about my aClient that will be receiving the event. The event should be obtained from the "sendEvent()" with a subscribe in the aClient app:

void subscribe(InstalledAppWrapper app, handlerMethod)

What is InstalledAppWrapper and how to I get it for an app named "aServer" inside an app named "aClient".

Thanks

You can't get the InstalledAppWrapper object from another app, unless the other app is a parent or child of the first. For two separate apps, that aren't parent/child of each other you can't use this subscribe() overload. You'll need to use the example I provided above.

Hi Daniel, I saw in the documentation that said that this type of subscribe was only for Parent/Child usage but several people say that this can be done... perhaps without a subscribe? Bravenel is one that I have seen talk about this several times... and it was not with respect to Parent/Child, even though he mentioned it. All I need is an interprocess communication technique that is NOT sendLocationEvent() because I have been getting Exceptions with that. The Exception states it is full and it will not process the next newest entry!!! Throwing away the newest instead of the oldest makes NO sense to me. This problem could, of course, be a user error but I just can't see what I could have done to cause this. BTW, it works for days after rebooting and then throws the Exception? What I have done is to create my first driver to solve this. I took the simple App example in the Hubitat doc's and changed it from a switch capability to a notification capability.
This allowed me to pass a string in a command in the server and then the driver simply does a sendEvent() that my client app's can subscribe to.

If you ever come across any sendEvent() info that would allow app to app communication (NOT Parent/Child) I would appreciate you sending me a message.

Thanks for your help, very appreciated.

If you're just wanting app to app then just use http post and set up mappings in your app.

Or just dump the Ring spyware entirely and integrate the devices directly to Hubitat. Most of their stuff is just plain Z-wave devices. The motion, contact sensors, and keypad all work with Hubitat directly, and then you're not sending every time you come and go from your house back to Amazon for their data collection.

2 Likes

Daniel, I started out with sending a http post's from Windows 11 to a URI that is generated from the app on installation. So every time I re-install or add an app I had to go back to the PC and add/modify the program sending the http post. When I got to about 3rd app on the Hubitat that needed Notification's from the PC I wanted to come up with a scheme in which I did not have to go back and modify the PC server. So I bought into having an app called NotificationServer on the Hubitat that got the actual notifications from the PC with a post but then the NotificationServer I wanted to have a communication that was more of a broadcast... so any body that subscribed could get the notifications without changing the server. Now, what you recommended about forgetting this Notification scheme and go with a more direct way with Hubitat is a more straight forward idea. But pre-Hubitat I already used this method on the PC and when I got the Hubitat I just kept going. I actually use the Ecobee Suite and therefore could do away with my Notification stuff with a little effort. Appreciate your response and I have things to consider. Thanks