Device Commands - Block UI

I'm trying to build out some programming options for DSC panels in the Envisalink Integration.
Unfortunately the panel is cumbersome and slow when sending keystrokes and commands to it. There are pauses I have to use between commands to make a thing happen. It can take more than 10 seconds.

If you didn't know this, you might try to execute the same command while the previous iteration was still being performed.

Do we have any way, at the UI of the device driver, to disable buttons for commands?

Because the available commands (and therefore the command ui buttons) are set in metadata, I don't think you can dynamically enable/disable them. Have you considered just ignoring the commands if they come in too quickly. I did this on my Samsung button driver to ignore the extra button pushed event that was causing issues. Unfortunately I seemed to have deleted that driver from github because the issue was resolved in the built in driver but it essentially did this:

Where
state.lastCommandSent simply stores the value for the last time someone successfully issued the command.
delta stores the difference in time between now and the last time the command was pushed.
waitPeriod is a numeric input variable where you can customize the amount of time that consecutive commands will be ignored (in seconds).

def command() {
 
   def delta = (now() - (state.lastCommandSent ?: 0)) / 1000
   //log.debug delta
   if(delta > waitPeriod){
        commands to execute
        state.lastCommandSent = now()
   }
   else{
       do nothing or log something...whatever
    }
1 Like

I was hoping it would be made easy for me by platform. :frowning:
Thanks for the advice, without custom parsing for Telnet and this limitation, it's going to take some gymnastics to deal with the inherent properties of telnet on this platform.

A little obtuse; however, you could use a user command interface that queues the commands (like I currently queue TTS messages to a speaker) with a time between. How I would work it:

  • The user interface would use push(number) for the varying commands. The number would map to the various commands. Example in the switch would be queue(command, delayAfter)
  • Each push number would relate to a command and a delay. That would be sent to the queue.
  • The queue would include the command and the delay after.
    I have a good queue example (for audio) simplified from my actual code below. It works great for TTS and would be adaptable for this application.
def playTrackAndResume(trackUri, volume=null) {
	addToQueue(trackUri, duration)
}

def addToQueue(trackUri, duration){
	duration = duration + 3
	playData = ["trackUri": trackUri, 
				"duration": duration.toInteger()]
	state.playQueue.add(playData)

	if (state.playingUrl == false) {
		state.playingUrl = true
		runInMillis(100, startPlayViaQueue)
	} else {
		runIn(1, playViaQueue)
	}
}

def startPlayViaQueue(data) {
	if (state.playQueue.size() == 0) { return }
	playViaQueue()
}

def playViaQueue() {
	if (state.playQueue.size() == 0) { return }
	def playData = state.playQueue.get(0)
	state.playQueue.remove(0)
	execPlay(playData.trackUri)	// This would be you actual command
	runIn(playData.duration, playViaQueue)
}

I believe Doug is trying to avoid the user sending multipe commands when they become impatient with the response time of the panel. Queuing the commands would still result in multiple unintentional command executions.

That can also be avoided using a timer and a state.lastButton.

  • set the state.lastButton when the button is pressed.
  • check this each time the button is depressed.
  • do a runIn(time, nullStateLastButton)
  • nullStateLastButton would set stateLastButton to null.

Add the queue for different commands, and you have a full solution. Not complete code, but relative simple.

Dave

Essentially the same as above which it doesn't look like something that Doug wants to do.

I'm using a state variable to store the 'programmingMode' kind of like stephack's suggestion.
I don't need a timer to reset, because the reason I need to block execution is awaiting the callback from telnet.

Thanks everyone