iRobot Roomba Thinking Cleaner Driver?

Hi All,

I've just spent the past 3 days moving everything from SmartThings to Hubitat and just finding the last few devices which have drivers missing.

I have a Thinking Cleaner addon plate to make my Roomba "Smart", someone on the SmartThings side wrote a SmartApp to control it which works for the most part but it hasnt been ported over to Hubitat yet. Now I'm able to do a tiny bit of coding but not even looked into SmartThings/Hubitat code for the most part so no clue on what changes are needed.

All I really need the below code editing to work on Hubitat, I'm personally not bothered about anything other than a simple on/off switch for the vac.

Can anyone help?


definition(
 	name: "Thinking Cleaner",
	namespace: " ",
	author: "Sidjohn1",
	description: "Handles polling and job notification for Thinking Cleaner",
	category: "Convenience",
	iconUrl: "http://cdn.device-icons.smartthings.com/Appliances/appliances13-icn.png",
	iconX2Url: "http://cdn.device-icons.smartthings.com/Appliances/appliances13-icn@2x.png",
	iconX3Url: "http://cdn.device-icons.smartthings.com/Appliances/appliances13-icn@3x.png",
	singleInstance: true)

preferences {
	page name:"pageInfo"
}
def pageInfo() {
	return dynamicPage(name: "pageInfo", title: "Thinking Cleanerer", install: true, uninstall: true) {    
	section("About") {
		paragraph "Thinking Cleaner(Roomba) smartapp for Smartthings. This app monitors you roomba and provides job notifacation"
		paragraph "${textVersion()}\n${textCopyright()}"    
	}
		def roombaList = ""
			settings.switch1.each() {
			try {
				roombaList += "$it.displayName is $it.currentStatus. Battery is $it.currentBattery%\n"
			}
            catch (e) {
                log.trace "Error checking status."
                log.trace e
            }
        }
		if (roombaList) {
			section("Roomba Status:") {
				paragraph roombaList.trim()
			}
		}
		section("Select Roomba(s) to monitor..."){
			input "switch1", "device.ThinkingCleaner", title: "Monitored Roomba", required: true, multiple: true, defaultValue: false, submitOnChange: true
		}
		section(hideable: true, hidden: true, "Auto Smart Home Monitor..."){
			input "autoSHM", "bool", title: "Auto Set Smart Home Monitor?", required: true, multiple: true, defaultValue: false, submitOnChange: true
			paragraph"Auto Set Smart Home Monitor to Arm(Stay) when cleaning and Arm(Away) when done."
		}
		section(hideable: true, hidden: true, "Event Notifications..."){
			input "sendPush", "bool", title: "Send as Push?", required: false, defaultValue: true
			input "sendSMS", "phone", title: "Send as SMS?", required: false, defaultValue: null
			input "sendRoombaOn", "bool", title: "Notify when on?", required: false, defaultValue: false
			input "sendRoombaOff", "bool", title: "Notify when off?", required: false, defaultValue: false
			input "sendRoombaError", "bool", title: "Notify on error?", required: false, defaultValue: true
			input "sendRoombaBin", "bool", title: "Notify on full bin?", required: false, defaultValue: true
		}
	}
}

def installed() {
	log.trace "Installed with settings: ${settings}"
	initialize()
}

def updated() {
	log.trace "Updated with settings: ${settings}"
	unschedule()
	unsubscribe()
	initialize()
}

def initialize() {
	log.info "Thinking Cleanerer ${textVersion()} ${textCopyright()}"
	subscribe(switch1, "switch.on", eventHandler)
	subscribe(switch1, "switch.off", eventHandler)
	subscribe(switch1, "status.error", eventHandler)
	subscribe(switch1, "bin.full", eventHandler)
	subscribe(location, "sunset", pollRestart)
	subscribe(location, "sunrise", pollRestart)
	schedule("22 4 0/1 1/1 * ? *", pollOff)
	pollOff
    
}

def eventHandler(evt) {
	def msg
	switch (evt.value) {
		case "error":
			sendEvent(linkText:app.label, name:"${evt.displayName}", value:"error",descriptionText:"${evt.displayName} has an error", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "${evt.displayName} has an error"
			msg = "${evt.displayName} has an error"
			if (sendRoombaError == true) {
				if (settings.sendSMS != null) {
					sendSms(sendSMS, msg) 
				}
				if (settings.sendPush == true) {
					sendPush(msg)
				}
			}
			schedule("39 0/15 * 1/1 * ?", pollErr)
		break;
		case "on":
			sendEvent(linkText:app.label, name:"${evt.displayName}", value:"on",descriptionText:"${evt.displayName} is on", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "${evt.displayName} is on"
			msg = "${evt.displayName} is on"
			schedule("15 0/1 * 1/1 * ?", pollOn)
			if (sendRoombaOn == true) {
				if (settings.sendSMS != null) {
					sendSms(sendSMS, msg) 
				}
				if (settings.sendPush == true) {
					sendPush(msg)
				}
			}
            if (settings.autoSHM.contains('true') ) {
            	if (location.currentState("alarmSystemStatus")?.value == "away"){
			sendEvent(linkText:app.label, name:"Smart Home Monitor", value:"stay",descriptionText:"Smart Home Monitor was set to stay", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "Smart Home Monitor was set to stay"
			sendLocationEvent(name: "alarmSystemStatus", value: "stay")
			state.autoSHMchange = "y"
                }
            }
		break;
		case "full":
			sendEvent(linkText:app.label, name:"${evt.displayName}", value:"bin full",descriptionText:"${evt.displayName} bin is full", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "${evt.displayName} bin is full"
			msg = "${evt.displayName} bin is full"
			if (sendRoombaBin == true) {
				if (settings.sendSMS != null) {
					sendSms(sendSMS, msg) 
				}
				if (settings.sendPush == true) {
					sendPush(msg)
				}
			}
		break;
        
		case "off":
			sendEvent(linkText:app.label, name:"${evt.displayName}", value:"off",descriptionText:"${evt.displayName} is off", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "${evt.displayName} is off"
			msg = "${evt.displayName} is off"
			if (sendRoombaOff == true) {
				if (settings.sendSMS != null) {
					sendSms(sendSMS, msg) 
				}
				if (settings.sendPush == true) {
					sendPush(msg)
				}
			}
			schedule("22 4 0/1 1/1 * ? *", pollOff)
		break;
	}
}

def pollOn() {
	def onSwitch1 = settings.switch1.currentSwitch.findAll { switchVal ->
		switchVal == "on" ? true : false
	}
	settings.switch1.each() {
		if (it.currentSwitch == "on") {
			state.pollState = now()
			it.poll()
			runIn(80, pollRestartOn, [overwrite: true])
		}
	}
	if (onSwitch1.size() == 0) {
		unschedule(pollOn)
		if (settings.autoSHM.contains('true') ) {
			if (location.currentState("alarmSystemStatus")?.value == "stay" && state.autoSHMchange == "y"){
				sendEvent(linkText:app.label, name:"Smart Home Monitor", value:"away",descriptionText:"Smart Home Monitor was set back to away", eventType:"SOLUTION_EVENT", displayed: true)
				log.trace "Smart Home Monitor was set back to away"
				sendLocationEvent(name: "alarmSystemStatus", value: "away")
				state.autoSHMchange = "n"
			}
		}
	}
}

def pollOff() {
    def offSwitch1 = settings.switch1.currentSwitch.findAll { switchVal ->
		switchVal == "off" ? true : false
	}
	settings.switch1.each() {
		if (it.currentSwitch == "off") {
			state.pollState = now()
			it.poll()
            runIn(3660, pollRestart, [overwrite: true])
		}
	}
	if (offSwitch1.size() == 0) {
		unschedule(pollOff)
	}
}

def pollErr() {
	def errSwitch1 = settings.switch1.currentStatus.findAll { switchVal ->
		switchVal == "error" ? true : false
	}
	settings.switch1.each() {
		if (it.currentStatus == "error") {
			state.pollState = now()
			it.poll()
		}
	}
	if (errSwitch1.size() == 0) {
		unschedule(pollErr)
	}
}
def pollRestartOn() {
	def t = now() - state.pollState
		if (t > 660000) {
			unschedule(pollOn)
			schedule("16 0/1 * 1/1 * ?", pollOn)
			sendEvent(linkText:app.label, name:"Poll", value:"Restart",descriptionText:"Polling Restarted", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "Polling Restarted"
        }
}

def pollRestart(evt) {
	def t = now() - state.pollState
		if (t > 4200000) {
			unschedule(pollOff)
			schedule("23 4 0/1 1/1 * ? *", pollOff)
			sendEvent(linkText:app.label, name:"Poll", value:"Restart",descriptionText:"Polling Restarted", eventType:"SOLUTION_EVENT", displayed: true)
			log.trace "Polling Restarted"
        }
}

private def textVersion() {
    def text = "Version 1.5.1"
}

private def textCopyright() {
    def text = "Copyright © 2015 Sidjohn1"
}

Just to update this a little more, someone's also written code for Homebridge too:

Not sure if that's easier to convert, for now I have the worlds most terrible hack of calling the clean/dock URL from Rule Machine, not ideal as it has no status reporting etc

Can anyone advise?