ASH 2200 with USB-WDE1-2 supported?

I don’t understand this statement.

If you are worried about making sure OH knows your script is still running, then there are lots of ways it can figure that out without needing to poll for its online status, particularly if you used MQTT.

I use the following to determine and alert when my external scripts and services go offline:

First I created a Group:

Group:Switch:AND(ON, OFF) gSensorStatus

Then I create an Online Item to track the online status of a single server or device I care about. When I’m receiving messages via MQTT then I just subscribe to the same topic and any message received on the topic will set the online status to ON. then I use an exipre binding config to make the Item turn OFF when it hasn’t been updated after a certain period of time.

Switch vCerberos_SensorReporter_Online "Cerberos sensorReporter [MAP(admin.map):%s]"
    <network> (gSensorStatus)
    { mqtt="<[mosquitto:status/sensor-reporters:command:OFF:.*cerberos sensorReporter is dead.*],<[mosquitto:status/cerberos/heartbeat/string:command:ON]", expire="11m,command=OFF" }

The above Item subscribes to one of the topics sensorReporter (see link above) publishes to periodically and expires when no message is received for 11 minutes.

If you can’t do something like this you will need a rule to update the Online Item. See the Generic Is Alive Deisgn Pattern for one approach.

Then I have the following rules which will send an alert to me when any member of gSensorStatus goes OFF along with an alert when OH restarts and in the morning listing all the offline devices.

import java.util.concurrent.locks.ReentrantLock
import java.util.Map

val ReentrantLock statusLock = new ReentrantLock
val Map<String, Timer> timers = newHashMap

rule "A sensor changed its online state"
when
	Item gSensorStatus received update
then
    try {
    	statusLock.lock
    	Thread::sleep(100)
    	val recentUpdates = gSensorStatus.members.filter[sensor|sensor.lastUpdate("mapdb") != null && sensor.lastUpdate("mapdb").isBefore(now.minusSeconds(1).millis)]

    	recentUpdates.forEach[sensor|
    		val alerted = gOfflineAlerted.members.filter[a|a.name==sensor.name+"_Alerted"].head
    		if(alerted == null) logError("admin", "Cannot find Item " + sensor.name+"_Alerted")
    		
    		if(alerted != null && alerted.state == sensor.state && timers.get(sensor.name) == null){
    			val currState = sensor.state
    			// wait a few seconds and check again before sending alert
    			timers.put(sensor.name, createTimer(now.plusSeconds(15), [|
    				if(sensor.state == currState) {
		    			aInfo.sendCommand(transform("MAP", "admin.map", sensor.name) + " is now " + transform("MAP", "admin.map", sensor.state.toString) + "!")
		    			alerted.postUpdate(if(sensor.state == ON) OFF else ON)   					
    				}
    			]))
    		}
    	]
    }
    catch(Exception e){
    	logError("admin", "Error processing an online status change: " + e.toString)
    }
    finally {
    	statusLock.unlock
    }
end
 
rule "Reminder at 08:00 and system start"
when
	Time cron "0 0 8 * * ? *" or
	System started
then
    val message = new StringBuilder 
    
    val offline = gSensorStatus.members.filter[sensor|sensor.state != ON]
    if(offline.size > 0) {
    	message.append("The following sensors are offline: ")
    	offline.forEach[sensor|
    		message.append(transform("MAP", "admin.map", sensor.name))
    		message.append(", ")
            gOfflineAlerted.members.filter[a|a.name==sensor.name+"_Alerted"].head.postUpdate(ON)
    	]
    	message.delete(message.length-2, message.length)
    	aInfo.sendCommand(message.toString)
    }
end 

Everything is event driven and therefore requires no polling.