For anyone who is interested, I created a new DTH for time values. Not pretty but it works. I use this for my sprinkler control so I can modify start times in the app. This one only works in the new app as I didn’t copy my old DTH into this one.
screenshot:
DTH:
/*
Time tiles with adjustment capability-with new app support
*/
metadata {
definition (name: "Adjust Time Values", namespace: "guxdude", author: "guxdude"
,"vid": "bcccec64-8bbc-3719-829f-a00a0ac8072f","mnmn": "SmartThingsCommunity"
) {
capability "dictionaryfabric11101.adjustTextA"
capability "dictionaryfabric11101.adjustHourA"
capability "dictionaryfabric11101.adjustMinuteA"
capability "dictionaryfabric11101.adjustTextB"
capability "dictionaryfabric11101.adjustHourB"
capability "dictionaryfabric11101.adjustMinuteB"
capability "dictionaryfabric11101.adjustTextC"
capability "dictionaryfabric11101.adjustHourC"
capability "dictionaryfabric11101.adjustMinuteC"
capability "dictionaryfabric11101.adjustTextD"
capability "dictionaryfabric11101.adjustHourD"
capability "dictionaryfabric11101.adjustMinuteD"
// Need 3 more start times
capability "Health Check"
capability "Refresh"
attribute "GVstatus", "string"
attribute "currentMeridianA", "string"
attribute "currentMeridianB", "string"
attribute "currentMeridianC", "string"
attribute "currentMeridianD", "string"
attribute "enableTimeA","enum",["true","false"]
attribute "enableTimeB","enum",["true","false"]
attribute "enableTimeC","enum",["true","false"]
attribute "enableTimeD","enum",["true","false"]
command ResetGV
command "changeTimeA", ["string"]
command "changeTimeB", ["string"]
command "changeTimeC", ["string"]
command "changeTimeD", ["string"]
} // End of definition
tiles(scale:2) {
} // End of tiles
preferences {
input (
name: "meridianAP", type: "enum", title: "AM/PM A", description: "Morning or afternoon", required: true,
options: ["AM": "A Morning (AM)", "PM": "A Afternoon (PM)"]
// defaultValue not actually set until user enters so not usefull: , defaultValue: "AM"
)
input (
name: "meridianBP", type: "enum", title: "AM/PM B", description: "Morning or afternoon", required: true,
options: ["AM": "B Morning (AM)", "PM": "B Afternoon (PM)"]
// defaultValue not actually set until user enters so not usefull: , defaultValue: "AM"
)
input (
name: "meridianCP", type: "enum", title: "AM/PM C", description: "Morning or afternoon", required: true,
options: ["AM": "C Morning (AM)", "PM": "C Afternoon (PM)"]
// defaultValue not actually set until user enters so not usefull: , defaultValue: "AM"
)
input (
name: "meridianDP", type: "enum", title: "AM/PM D", description: "Morning or afternoon", required: true,
options: ["AM": "D Morning (AM)", "PM": "D Afternoon (PM)"]
// defaultValue not actually set until user enters so not usefull: , defaultValue: "AM"
)
input name: "enableTimeAP", type: "bool", title: "Time A Enable", description: "Use time A start?", required: true //, displayDuringSetup: true
input name: "enableTimeBP", type: "bool", title: "Time B Enable", description: "Use time B start?", required: true //, displayDuringSetup: true
input name: "enableTimeCP", type: "bool", title: "Time C Enable", description: "Use time C start?", required: true //, displayDuringSetup: true
input name: "enableTimeDP", type: "bool", title: "Time D Enable", description: "Use time D start?", required: true //, displayDuringSetup: true
} // End of preferences
} // End of metadata
def installed() {
sendEvent(name: "currentMeridianA", value: "AM", displayed: false)
setHourA(12)
setMinuteA(0)
// buildTimeA()
sendEvent(name: "currentMeridianB", value: "AM", displayed: false)
setHourB(12)
setMinuteB(0)
// buildTimeB()
sendEvent(name: "currentMeridianC", value: "AM", displayed: false)
setHourC(12)
setMinuteC(0)
// buildTimeC()
sendEvent(name: "currentMeridianD", value: "AM", displayed: false)
setHourD(12)
setMinuteD(0)
// buildTimeD()
sendEvent(name: "GVstatus", value: "start", displayed: false, isStateChange: true)
}
def updated() {
sendEvent(name: "currentMeridianA", value: meridianAP, displayed: false)
sendEvent(name: "currentMeridianB", value: meridianBP, displayed: false)
sendEvent(name: "currentMeridianC", value: meridianCP, displayed: false)
sendEvent(name: "currentMeridianD", value: meridianDP, displayed: false)
sendEvent(name: "enableTimeA", value: enableTimeAP, displayed: false)
sendEvent(name: "enableTimeB", value: enableTimeBP, displayed: false)
sendEvent(name: "enableTimeC", value: enableTimeCP, displayed: false)
sendEvent(name: "enableTimeD", value: enableTimeDP, displayed: false)
//log.debug("UPDATED: HourA= ${device.currentValue("currentMeridianA")}")
sendEvent(name: "hourA", value: device.currentValue("hourA"), unit: device.currentValue("currentMeridianA"), displayed: false)
buildTimeA()
sendEvent(name: "hourB", value: device.currentValue("hourB"), unit: device.currentValue("currentMeridianB"), displayed: false)
buildTimeB()
sendEvent(name: "hourC", value: device.currentValue("hourC"), unit: device.currentValue("currentMeridianC"), displayed: false)
buildTimeC()
sendEvent(name: "hourD", value: device.currentValue("hourD"), unit: device.currentValue("currentMeridianD"), displayed: false)
buildTimeD()
sendEvent(name: "GVstatus", value: "update", displayed: false, isStateChange: true)
}
def buildTimeA() {
def timeString = device.currentValue("hourA").toString() + ":" + ((device.currentValue("minuteA")<10)? "0" : "" ) + device.currentValue("minuteA").toString() + " " + device.currentValue("currentMeridianA")
//log.debug("BUILD: HourA= ${device.currentValue("hourA")}")
//log.debug("BUILD: timestring: $timeString")
setTimeA(timeString)
}
def buildTimeB() {
def timeString = device.currentValue("hourB").toString() + ":" + ((device.currentValue("minuteB")<10)? "0" : "" ) + device.currentValue("minuteB").toString() + " " + device.currentValue("currentMeridianB")
setTimeB(timeString)
}
def buildTimeC() {
def timeString = device.currentValue("hourC").toString() + ":" + ((device.currentValue("minuteC")<10)? "0" : "" ) + device.currentValue("minuteC").toString() + " " + device.currentValue("currentMeridianC")
setTimeC(timeString)
}
def buildTimeD() {
def timeString = device.currentValue("hourD").toString() + ":" + ((device.currentValue("minuteD")<10)? "0" : "" ) + device.currentValue("minuteD").toString() + " " + device.currentValue("currentMeridianD")
setTimeD(timeString)
}
def changeTimeA(value) {
def newHour = (value.substring(0,value.indexOf(":"))).toInteger()
def newMinute = (value.substring(value.indexOf(":")+1,value.indexOf(" "))).toInteger()
def newMeridian = (value.substring(value.indexOf(" ")+1)).toString()
//log.debug("CHANGE A: value: $value; hour: $newHour; minute: $newMinute; meridian: $newMeridian")
// Only set times if all values are valid
if ((newHour>0) && (newHour<13) && (newMinute>=0) && (newMinute<=60) && ((newMeridian=="AM") || (newMeridian=="PM"))) {
sendEvent(name: "currentMeridianA", value: newMeridian, displayed: false)
setMinuteA(newMinute)
setHourA(newHour)
}
}
def changeTimeB(value) {
def newHour = (value.substring(0,value.indexOf(":"))).toInteger()
def newMinute = (value.substring(value.indexOf(":")+1,value.indexOf(" "))).toInteger()
def newMeridian = (value.substring(value.indexOf(" ")+1)).toString()
// Only set times if all values are valid
if ((newHour>0) && (newHour<13) && (newMinute>=0) && (newMinute<=60) && ((newMeridian=="AM") || (newMeridian=="PM"))) {
sendEvent(name: "currentMeridianB", value: newMeridian, displayed: false)
setMinuteB(newMinute)
setHourB(newHour)
}
}
def changeTimeC(value) {
def newHour = (value.substring(0,value.indexOf(":"))).toInteger()
def newMinute = (value.substring(value.indexOf(":")+1,value.indexOf(" "))).toInteger()
def newMeridian = (value.substring(value.indexOf(" ")+1)).toString()
// Only set times if all values are valid
if ((newHour>0) && (newHour<13) && (newMinute>=0) && (newMinute<=60) && ((newMeridian=="AM") || (newMeridian=="PM"))) {
sendEvent(name: "currentMeridianC", value: newMeridian, displayed: false)
setMinuteC(newMinute)
setHourC(newHour)
}
}
def changeTimeD(value) {
def newHour = (value.substring(0,value.indexOf(":"))).toInteger()
def newMinute = (value.substring(value.indexOf(":")+1,value.indexOf(" "))).toInteger()
def newMeridian = (value.substring(value.indexOf(" ")+1)).toString()
// Only set times if all values are valid
if ((newHour>0) && (newHour<13) && (newMinute>=0) && (newMinute<=60) && ((newMeridian=="AM") || (newMeridian=="PM"))) {
sendEvent(name: "currentMeridianD", value: newMeridian, displayed: false)
setMinuteD(newMinute)
setHourD(newHour)
}
}
def setTimeA(value) {
textChange("labelA", value)
}
def setTimeB(value) {
textChange("labelB", value)
}
def setTimeC(value) {
textChange("labelC", value)
}
def setTimeD(value) {
textChange("labelD", value)
}
def setHourA(value) {
setHourGeneral(value, "hourA", "currentMeridianA")
buildTimeA()
}
def setHourB(value) {
setHourGeneral(value, "hourB", "currentMeridianB")
buildTimeB()
}
def setHourC(value) {
setHourGeneral(value, "hourC", "currentMeridianC")
buildTimeC()
}
def setHourD(value) {
setHourGeneral(value, "hourD", "currentMeridianD")
buildTimeD()
}
def setHourGeneral( value, whichHour, whichMeridian) {
//log.debug("SetHourGeneral: value: $value; hour=$whichHour; meridian=$whichMeridian")
def hourVal = (device.currentValue(whichHour).toInteger())
// reset to ensure we don't get out of sync with WebCoRE piston
ResetGV()
//log.debug("hourVal: $hourVal ; value: $value")
if (hourVal==11) {
if (value==12) {
toggleUnit(whichHour, whichMeridian)
}
}
if (hourVal==12) {
if (value==11) {
toggleUnit(whichHour, whichMeridian)
}
}
//log.debug("SETHOUR: Updated hourVal: $hourVal")
if (value>12) {
sendEvent(name: whichHour, value: 1, unit: device.currentValue(whichMeridian), displayed: false)
} else if (value<1) {
sendEvent(name: whichHour, value: 12, unit: device.currentValue(whichMeridian), displayed: false)
} else {
sendEvent(name: whichHour, value: value, unit: device.currentValue(whichMeridian), displayed: false)
}
}
def setMinuteA(value) {
setMinuteGeneral(value, "hourA", "minuteA", "currentMeridianA")
buildTimeA()
}
def setMinuteB(value) {
setMinuteGeneral(value, "hourB", "minuteB", "currentMeridianB")
buildTimeB()
}
def setMinuteC(value) {
setMinuteGeneral(value, "hourC", "minuteC", "currentMeridianC")
buildTimeC()
}
def setMinuteD(value) {
setMinuteGeneral(value, "hourD", "minuteD", "currentMeridianD")
buildTimeD()
}
def setMinuteGeneral( value, whichHour, whichMinute, whichMeridian) {
//log.debug("SETMINUTE: minuteVal: $value")
// reset to ensure we don't get out of sync with WebCoRE piston
ResetGV()
if (value==60) {
valueChange(whichMinute, 0)
setHourGeneral((device.currentValue(whichHour)+1), whichHour, whichMeridian)
} else if (value<0) {
valueChange(whichMinute, 59)
setHourGeneral((device.currentValue(whichHour)-1), whichHour, whichMeridian)
} else {
valueChange(whichMinute, value)
}
}
def toggleUnit( whichHour, whichMeridian) {
if (device.currentValue(whichMeridian)=="AM") {
sendEvent(name: whichHour, value: device.currentValue(whichHour), unit: "PM", displayed: false)
sendEvent(name: whichMeridian, value: "PM", displayed: true)
} else {
sendEvent(name: whichHour, value: device.currentValue(whichHour), unit: "AM", displayed: false)
sendEvent(name: whichMeridian, value: "AM", displayed: true)
}
}
def valueChange(String valString, Integer newval) {
Logger("valueChange: ${valString} Target ${newval}")
sendEvent("name":valString, "value":newval, displayed: true)
// Don't flag integer value changes to minimize triggering piston
// sendEvent(name: "GVstatus", value: valString, displayed: false, isStateChange: true)
}
def textChange(String valString, String newval) {
Logger("textChange: ${valString} Target ${newval}")
sendEvent("name":valString, "value":newval, displayed: true)
sendEvent(name: "GVstatus", value: valString, displayed: false, isStateChange: true)
}
//def changeStep(Integer newval) {
//valueA
//}
def ResetGV() {
sendEvent(name: "GVstatus", value: "clear", displayed: false, isStateChange: true)
}
def Logger(String logString) {
log.info(logString)
}
Piston to capture updates: