Samsung TV fast SOAP poll (can I reduce hub load overhead?)

For a specific reason, I need a high-speed polling service to track volume on a Samsung TV. I've searched everywhere, and while there's a slick WebSocket interface for sending (some) commands, there's no documented way to receive volume events. The only way to get volume levels is via a SOAP call.

Right now, this polling runs every 5 seconds if the TV is on and there haven’t been any volume changes in the last 10 minutes. If a volume event occurred within the last 10 minutes, it polls every 1 second. During an active volume change, it bumps to 500ms for about 10 seconds.

I’m looking for a code review to see if there’s a way to reduce hub overhead — not a discussion about why this approach sucks since this is how Home Assistant does it too.

The dirty details are here at line 524, but the basics for initial discussion are:

@Field static final Integer VOLUME_POLL_DELAY = 1000
@Field static final Integer VOLUME_POLL_INACTIVITY_DELAY = 5000
@Field volatile static Map<Long,Map> g_cachePollVolumeMap = [:]
// this is called 'again' after the callback so loops
void pollVolume(Boolean initialize=false) {
    if (g_cachePollVolumeMap[devId]==null || initialize) {

      // ... cache a SOAP structure for use in the hubAction. only build it once.

    }
    Map pollData = g_cachePollVolumeMap[devId]

    // Use sendHubCommand because it is faster and lower overhead then normal http stack    
    def hubAction = new hubitat.device.HubAction([
        method: "POST",
        path: "/upnp/control/AVTransport1",
        body: pollData.body,
        headers: pollData.headers
    ], null, [callback: pollVolumeCallback])
    // There is no error try/catch with sendHubCommand. So use a watchdog to restart if callback doesn't happen.
    sendHubCommand(hubAction)
    // A watchdog if we have problems.
    runInMillis((VOLUME_POLL_INACTIVITY_DELAY + 2000) as Integer, "pollVolumeWatchdog")    
}

void pollVolumeWatchdog(String descriptionText="watchdog timer expired") {
    // ... do some watchdog stuff in the case we have an error    
}    

void pollVolumeCallback(hubResponse) {
    try {
        Map msg = parseLanMessage(hubResponse.description)
         
        // ... do checks if volume changed and do events on that change, then figure out poll rate.

    } catch (Exception e) {    
        pollVolumeWatchdog(e.message)
        return
    }
	// remove our function delay, and never allow lower than 250ms.
	Integer runInMillisDelay = Math.max((pollData?.runInMillis ?: VOLUME_POLL_DELAY) - (now() - (pollData?.timestamp ?: 0)), 250)

	runInMillis(runInMillisDelay as Integer, "pollVolume")
}

The other way is to use Hubithings Replica Samsung TV driver. This gets the data from SmartThings when it is updates. Quite a bit faster. Hubithings replica subscribes to SmartThings then device events (i.e., volume). It is a reduced hub load.

This is the HubiThings OCF driver that I maintain, volume does not move in any realtime with SmartThings. It will delay up the volume to the cloud after a refresh, which when done via a remote control doesn't happen. There is no method on any platform that describes an event ability for audio. :frowning:

For context, I tossed all my aging Logitech IoT remotes, and developed a volume tracking 'volumePattern' event that I can use for control of IoT devices. For example, if you press volume up,down,up,down the driver tracks "+ - + -" and will issue an event that I watch with webCoRE. I do the same for a Bose Soundtouch 600 which does realtime event on a websocket on my living room system, but I just have a standalone SamsungTV in another room and want todo the same.

For this to work, I need exact volume track with really no delay (sub 500ms).

I was using a Home Assistant todo this but as stated above, they are doing the same thing, I just have plenty of HE cpu cycles to do it on the device itself, instead of having a multi-hub solution.