[RELEASE] Value Tiles - DTH for displaying webCoRE variables / Stats in a 'Thing'


#86

yes


#87

@Robin does this device show all or any of the custom values in the new SmartThings app? One of my grievances with the new app is many of devices don’t display all the data/controls - just for an example here’s an Echo Speaks device in both apps.


#88

No, the new app is not compatible with anything except the most basic standard tiles.


#89

Is it possible for the values set in the value tiles to be representative of the type of data set?

Having done a bit more research, I’m looking for ways to set the values of temperature, relative humidity, and other capabilities via this device handler so that it can expose the values I set for the devices to other systems.

I’m using this to read an API for sensor measurements (temp, lux, moisture, fertilizer), and I would like to expose those values that can be displayed else where. When I set the values to attributes, things are working, but it’s not extensible.

I hope I’m making sense with my request.


#90

You can take elements from any of the simulated device handlers, i.e. sliders, switches, multi-attribute tiles, and set the values from webCoRE yes.


#91

In case anyone is interested, here is a modification I made to allow adjustment of the variables displayed. The variables can be either integers or time.

Here is the DTH:

/*
 Value tiles with adjustment capability
*/

metadata {
 	definition (name: "Adjust Value Tiles", namespace: "guxdude", author: "Guy Renard") {
 //	capability "Actuator"
 	capability "Sensor"
 
    attribute "Value1","string"
    attribute "Value2","string"
    attribute "Value3","string"
    attribute "Value4","string"
    attribute "Increment","string"
    attribute "Label1","string"
    attribute "Label2","string"
    attribute "Label3","string"
    attribute "Label4","string"
    attribute "LabelI","string"
    attribute "GVstatus","string"
    attribute "isTime1f","enum",["true","false"]
    attribute "isTime2f","enum",["true","false"]
    attribute "isTime3f","enum",["true","false"]
    attribute "isTime4f","enum",["true","false"]
    
    command "changeValue1", ["string"]
    command "changeValue2", ["string"]
    command "changeValue3", ["string"]
    command "changeValue4", ["string"]
    command "changeIncrement", ["string"]
    command "changeLabel1", ["string"]
    command "changeLabel2", ["string"]
    command "changeLabel3", ["string"]
    command "changeLabel4", ["string"]
    command "changeLabelI", ["string"]
    command "value1Up"
    command "value1Down"
    command "value2Up"
    command "value2Down"
    command "value3Up"
    command "value3Down"
    command "value4Up"
    command "value4Down"
    command "incrementUp"
    command "incrementDown"
    command "ResetGV"
     } // End of definition
 	tiles(scale:2) {
        valueTile("Label1", "device.Label1", width: 4, height: 1, decoration: "flat") {
			state("val", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF", defaultState: true )
		}
        valueTile("Blank11", "device.Label1", width: 1, height: 1, decoration: "flat") {
			state("val", label:"", foregroundColor: "#000000", backgroundColor: "#FFFFFF", defaultState: true )
		}
        valueTile("Blank1", "device.Label1", width: 4, height: 1, decoration: "flat") {
			state("val", label:"", foregroundColor: "#000000", backgroundColor: "#FFFFFF", defaultState: true  )
		}
		valueTile("Value1", "device.Value1", width: 2, height: 2, decoration: "flat") {
			state("val", label:'${currentValue}'/*, foregroundColor: "#FFFFFF",
				backgroundColors: [ [value: -1, color: "#FF0000"], [value: 0, color: "#000000"], [value: 1, color: "#00FF00"] ]*/)
		}
    	standardTile("value1Up", "device.Value1", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value1Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value1Down", "device.Value1",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value1Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("Label2", "device.Label2", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Value2", "device.Value2", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}'/*, foregroundColor: "#FFFFFF",
				backgroundColors: [ [value: -1, color: "#FF0000"], [value: 0, color: "#000000"], [value: 1, color: "#00FF00"] ]*/)
		}
		standardTile("value2Up", "device.Value2", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value2Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value2Down", "device.Value2",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value2Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("Label3", "device.Label3", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Value3", "device.Value3", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}'/*, color: "#000000",
				backgroundColors: [ [value: -1, color: "#FF0000"], [value: 0, color: "#000000"], [value: 1, color: "#00FF00"] ]*/)
		}
		standardTile("value3Up", "device.Value3", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value3Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value3Down", "device.Value3",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value3Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("Label4", "device.Label4", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Value4", "device.Value4", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}'/*, foregroundColor: "#FFFFFF",
				backgroundColors: [ [value: -1, color: "#FF0000"], [value: 0, color: "#000000"], [value: 1, color: "#00FF00"] ]*/)
		}
		standardTile("value4Up", "device.Value4", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value4Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value4Down", "device.Value4",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value4Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("LabelI", "device.LabelI", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Increment", "device.Increment", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}'/*, foregroundColor: "#FFFFFF",
				backgroundColors: [ [value: -1, color: "#FF0000"], [value: 0, color: "#000000"], [value: 1, color: "#00FF00"] ]*/)
		}
		standardTile("incrementUp", "device.Increment", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"incrementUp", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("incrementDown", "device.Increment",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"incrementDown", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}

		// "Value1" will appear in the things view
 		main(["Value1"])
        // these tiles will appear in the Device Details view
        // (order is left-to-right, top-to-bottom)
 		details([
        "Blank11","Label1","Blank11",
        "value1Up","Value1","value1Down",
        "Blank11","Blank1","Blank11",
        "Blank11","Label2","Blank11",
        "value2Up","Value2","value2Down",
        "Blank11","Blank1","Blank11",
        "Blank11","Label3","Blank11",
        "value3Up","Value3","value3Down",
        "Blank11","Blank1","Blank11",
        "Blank11","Label4","Blank11",
        "value4Up","Value4","value4Down",
        "Blank11","Blank1","Blank11",
        "Blank11","LabelI","Blank11",
        "incrementUp","Increment","incrementDown",
        "Blank11","Blank1","Blank11"])
 	}  // End of tiles
 	preferences {
    	input name: "isTime1", type: "bool", title: "Time Flag 1", description: "Is variable 1 time?", required: true //, displayDuringSetup: true
    	input name: "isTime2", type: "bool", title: "Time Flag 2", description: "Is variable 2 time?", required: true //, displayDuringSetup: true
    	input name: "isTime3", type: "bool", title: "Time Flag 3", description: "Is variable 3 time?", required: true //, displayDuringSetup: true
    	input name: "isTime4", type: "bool", title: "Time Flag 4", description: "Is variable 4 time?", required: true //, displayDuringSetup: true
	}   // End of preferences   
 }   // End of metadata
 
 
def installed() {
	sendEvent(name: "isTime1f", value: isTime1, displayed: true)
	sendEvent(name: "isTime2f", value: isTime2, displayed: true)
	sendEvent(name: "isTime3f", value: isTime3, displayed: true)
	sendEvent(name: "isTime4f", value: isTime4, displayed: true)
}


def updated() {
	sendEvent(name: "isTime1f", value: isTime1, displayed: true)
	sendEvent(name: "isTime2f", value: isTime2, displayed: true)
	sendEvent(name: "isTime3f", value: isTime3, displayed: true)
	sendEvent(name: "isTime4f", value: isTime4, displayed: true)
}

 def changeValue1 (param1) {
 	if (isTime1) {
    	def timeVal = Date.parse("hh:mm:ss a", param1)
        def timeString = timeVal.getTimeString()
        Logger("Input is ${param1} and conversion is ${timeString}")
    	sendEvent("name":"Value1", "value":timeString)
    } else {
    	sendEvent("name":"Value1", "value":param1)
    }
}
 def changeValue2 (param2) {
 	if (isTime2) {
    	def timeVal = Date.parse("hh:mm:ss a", param2)
        def timeString = timeVal.getTimeString()
        Logger("Input is ${param2} and conversion is ${timeString}")
    	sendEvent("name":"Value2", "value":timeString)
    } else {
    	sendEvent("name":"Value2", "value":param2)    
    }
}
 def changeValue3 (param3) {
 	if (isTime3) {
    	def timeVal = Date.parse("hh:mm:ss a", param3)
        def timeString = timeVal.getTimeString()
        Logger("Input is ${param3} and conversion is ${timeString}")
    	sendEvent("name":"Value3", "value":timeString)
    } else {
    	sendEvent("name":"Value3", "value":param3)
    }
}
 def changeValue4 (param4) {
 	if (isTime4) {
    	def timeVal = Date.parse("hh:mm:ss a", param4)
        def timeString = timeVal.getTimeString()
        Logger("Input is ${param4} and conversion is ${timeString}")
    	sendEvent("name":"Value4", "value":timeString)
    } else {
    	sendEvent("name":"Value4", "value":param4)
    }
}
 def changeIncrement (param5) {
    sendEvent("name":"Increment", "value":param5)
}

def changeLabel1 (param1) {
    sendEvent("name":"Label1", "value":param1)
}
def changeLabel2 (param2) {
    sendEvent("name":"Label2", "value":param2)
}
def changeLabel3 (param3) {
    sendEvent("name":"Label3", "value":param3)
}
def changeLabel4 (param4) {
    sendEvent("name":"Label4", "value":param4)
}
def changeLabelI (param5) {
    sendEvent("name":"LabelI", "value":param5)
}

def value1Up () {
    def incVal = (device.currentValue("Increment").toInteger())
    if (isTime1) {
		timeChange("Value1",incVal)
    } else {
		valueChange("Value1",incVal)
    }
}
def value1Down () {
    def incVal = -(device.currentValue("Increment").toInteger())
    if (isTime1) {
		timeChange("Value1",incVal)
    } else {
		valueChange("Value1",incVal)
    }
}
def value2Up () {
    def incVal = (device.currentValue("Increment").toInteger())
    if (isTime2) {
		timeChange("Value2",incVal)
    } else {
		valueChange("Value2",incVal)
    }
}
def value2Down () {
    def incVal = -(device.currentValue("Increment").toInteger())
    if (isTime2) {
		timeChange("Value2",incVal)
    } else {
		valueChange("Value2",incVal)
    }
}
def value3Up () {
    def incVal = (device.currentValue("Increment").toInteger())
    if (isTime3) {
		timeChange("Value3",incVal)
    } else {
		valueChange("Value3",incVal)
    }
}
def value3Down () {
    def incVal = -(device.currentValue("Increment").toInteger())
    if (isTime3) {
		timeChange("Value3",incVal)
    } else {
		valueChange("Value3",incVal)
    }
}
def value4Up () {
    def incVal = (device.currentValue("Increment").toInteger())
    if (isTime4) {
		timeChange("Value4",incVal)
    } else {
		valueChange("Value4",incVal)
    }
}
def value4Down () {
    def incVal = -(device.currentValue("Increment").toInteger())
    if (isTime4) {
		timeChange("Value4",incVal)
    } else {
		valueChange("Value4",incVal)
    }
}
def incrementUp () {
	Logger("incrementUp")
	incrementChange(1)
}
def incrementDown () {
	Logger("incrementDown")
	incrementChange(-1)
}
def valueChange(String valString, Integer offset) {
    def targetVal = (device.currentValue(valString).toInteger())+offset
    Logger("valueChange: ${valString} Target ${targetVal}")
    sendEvent("name":valString, "value":targetVal, displayed: true)
    sendEvent(name: "GVstatus", value: valString, displayed: false, isStateChange: true)
}
void timeChange(String valString, Integer offset) {
    def targetVal = Date.parse("hh:mm:ss a", (device.currentValue(valString)))
    def targetString = ''
    Logger("timeChange: ${valString} Taerget ${targetVal}")
    targetVal.minutes = targetVal.minutes+offset
    targetString = targetVal.getTimeString()
    Logger("timeChange: targetVal=${targetVal} ; targetString=${targetString}")
    sendEvent("name":valString, "value":targetString, displayed: true)
    sendEvent(name: "GVstatus", value: valString, displayed: false, isStateChange: true)
}
def incrementChange(Integer offset) {
    def targetVal = (device.currentValue("Increment").toInteger())+offset
    if (targetVal<1) {targetVal = 1}
    sendEvent("name":"Increment", "value":targetVal, displayed: true)
    //sendEvent(name: "GVstatus", value: "Increment", displayed: false, isStateChange: true)
	Logger("incrementChange: Target ${targetVal}")
}

def ResetGV() {
    sendEvent(name: "GVstatus", value: "set", displayed: false, isStateChange: true)
}

def Logger(String logString) {
	log.info(logString)
}

After creating a device using this DTH, there are two WebCoRE pistons to make it work. One to set the initial values and one to perform updates.

Initial value piston: Change the global variables to those of your choosing and set whether the values are integer or time in the device settings.

Update piston: Change the global variables to match those in your initial value piston.

This was my first (and so far only) attempt at a DTH so hope it is useful.

Here is what it looks like on my phone. The last of the 5 values is used for the increment so you can change the values faster if desired.


Custom Alexa Alarm Piston ! Help needed
Setting a variable in an expression depending on current thermostat mode?
#92

Is there a way to change the value of a measured capability like temperature, so that it can be ingested into Action Tiles?

The only thing I need is one temperature value that is getting updated from a webhook and then I would like to show it in AT.


#93

I use a dimmer, but should be similar to this…


#94

Thank, this was very helpful for me. I now have an interface to send variables to my webCORE piston without editing the piston every time I need to change a variable. The device works great in ST classic, but not in the new ST. Is there a way to get it in both?


#95

That was exactly why I created this DTH. I had values I wanted to be able to change without editing the piston.

I don’t really use the new app so I don’t know if it is possible. I don’t really know what the differences are.


#96

ive built a few device tiles… 3 basic device handlers with set/get commands to work as
Battery, Temp and Energy devices.

I use them to pass specific values through to ActionTiles. as they appear as dedicated device types with the value i set via pistons.


#97

try the temperature tile device handler i made ?


#98

@Robin, any chance of getting a value tiles version hat works with the new ST app? I use this capability and derivatives for a lot of things. Appreciate all you do.


#99

I’m in the same boat, I’ve discovered that if you can use standard capabilities then they will natively appear in the new app (temp, on/off, battery, etc). The issue with changeValue or any other custom capability is that each would need to be defined individually in the new ST ecosystem which I have not yet tried but doesn’t seem to be going well based on the ST community. Additionally, the lose of the tile structure in the new app makes me think I should simplify some of the DTHs anyway.

@stav242 has some good examples of using standard capabilities.


#100

Thanks. I was thinking how I could use standard capabilities. I was thinking a simulated thermostat might provide a capability for value adjustment but I can’t find examples of using the standard capabilities. I will look at what @stav242 has done to see if I can extend that. Appreciate the links!


#101

I took a look at the whole CLI thing… I cant get past the 'Install it on your path and rename it to ‘smartthings’ part lol

I think I’ll just stick with Hubitat… ST have pushed out hobby coders like me by making it too complicated.


#102

Working in the Classic App, but not in the new app, does anyone have a solution? Tks!!


#103

After banging my head against this CLI thing for a couple weeks, I think I finally understand it. or I have gone insane. Hard to tell. Anyway, the following DTH works in both classic and new apps to display/change webcore global variables. This is a bit of an experiment to see if sharing actually works. Here is the DTH:

/*
 Value tiles with adjustment capability-with new app support
*/

metadata {
 	definition (name: "Adjust Integer Values", namespace: "guxdude", author: "guxdude" ,"vid": "7f05b788-4020-3d65-9977-a76c6ebb049e","mnmn": "SmartThingsCommunity"
    					) { 
        capability "dictionaryfabric11101.adjustTextA"
		capability "dictionaryfabric11101.adjustIntegerA"
        capability "dictionaryfabric11101.adjustTextB"
		capability "dictionaryfabric11101.adjustIntegerB"
        capability "dictionaryfabric11101.adjustTextC"
		capability "dictionaryfabric11101.adjustIntegerC"
        capability "dictionaryfabric11101.adjustTextD"
		capability "dictionaryfabric11101.adjustIntegerD"

		capability "Health Check"
        capability "Refresh"
        
        attribute "GVstatus", "string"
 //       attribute "stepA", "number"

    	command "value1Up"
    	command "value1Down"
    	command "value2Up"
    	command "value2Down"
    	command "value3Up"
    	command "value3Down"
    	command "value4Up"
    	command "value4Down"
        
 //       command "changeStep", ["number"]

		command ResetGV
     } // End of definition
     
    tiles(scale:2) {
        valueTile("Label1", "labelA", width: 4, height: 1, decoration: "flat") {
			state("val", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF", defaultState: true )
		}
        valueTile("Blank11", "labelA", width: 1, height: 1, decoration: "flat") {
			state("val", label:"", foregroundColor: "#000000", backgroundColor: "#FFFFFF", defaultState: true )
		}
        valueTile("Blank1", "labelA", width: 4, height: 1, decoration: "flat") {
			state("val", label:"", foregroundColor: "#000000", backgroundColor: "#FFFFFF", defaultState: true  )
		}
		valueTile("Value1", "valueA", width: 2, height: 2, decoration: "flat") {
			state("val", label:'${currentValue}')
		}
    	standardTile("value1Up", "valueA", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value1Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value1Down", "valueA",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value1Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("Label2", "labelB", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Value2", "valueB", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}'/*, foregroundColor: "#FFFFFF",
				backgroundColors: [ [value: -1, color: "#FF0000"], [value: 0, color: "#000000"], [value: 1, color: "#00FF00"] ]*/)
		}
		standardTile("value2Up", "valueB", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value2Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value2Down", "valueB",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value2Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("Label3", "labelC", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Value3", "valueC", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}')
		}
		standardTile("value3Up", "valueC", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value3Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value3Down", "valueC",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value3Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}
        valueTile("Label4", "labelD", width: 4, height: 1, decoration: "flat") {
			state("default", label:'${currentValue}', foregroundColor: "#000000", backgroundColor: "#FFFFFF" )
		}
        valueTile("Value4", "valueD", width: 2, height: 2, decoration: "flat") {
			state("default", label:'${currentValue}')
		}
		standardTile("value4Up", "valueD", width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label: '', action:"value4Up", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_up.png"
			state "", label: ''
		}
		standardTile("value4Down", "valueD",  width: 2, height: 2, canChangeIcon: false, decoration: "flat") {
			state "default", label:'', action:"value4Down", 
            icon:"https://raw.githubusercontent.com/tonesto7/nest-manager/master/Images/Devices/heat_arrow_down.png"
			state "", label: ''
		}

		// "Value1" will appear in the things view
 		main(["Value1"])
        // these tiles will appear in the Device Details view
        // (order is left-to-right, top-to-bottom)
 		details([
        "Blank11","Label1","Blank11",
        "value1Up","Value1","value1Down",
        "Blank11","Blank1","Blank11",
        "Blank11","Label2","Blank11",
        "value2Up","Value2","value2Down",
        "Blank11","Blank1","Blank11",
        "Blank11","Label3","Blank11",
        "value3Up","Value3","value3Down",
        "Blank11","Blank1","Blank11",
        "Blank11","Label4","Blank11",
        "value4Up","Value4","value4Down",
        "Blank11","Blank1","Blank11"])

 	}  // End of tiles
    
 	preferences {
      //  input name: "GVup", type: "boolean", title: "Updated", description: "Settings updated", required: true, defaultValue: false
	}   // End of preferences   
 }   // End of metadata
 
 
def installed() {
    sendEvent(name: "valueA", value: 0, displayed: false)
    sendEvent(name: "valueB", value: 0, displayed: false)
    sendEvent(name: "valueC", value: 0, displayed: false)
    sendEvent(name: "valueD", value: 0, displayed: false)

    sendEvent(name: "labelA", value: "Value A", displayed: false)
    sendEvent(name: "labelB", value: "Value B", displayed: false)
    sendEvent(name: "labelC", value: "Value C", displayed: false)
    sendEvent(name: "labelD", value: "Value D", displayed: false)

    sendEvent(name: "GVstatus", value: "start", displayed: false, isStateChange: true)
}

def updated() {
    sendEvent(name: "GVstatus", value: "update", displayed: false, isStateChange: true)
}

def setValueA(value) {
    valueChange("valueA", value)

/*
    sendEvent(name: "valueA", value: value, displayed: false)
    sendEvent(name: "GVstatus", value: "valueA", displayed: false, isStateChange: true)
*/
}

def setValueB(value) {
    valueChange("valueB", value)

/*

    sendEvent(name: "valueB", value: value, displayed: false)
    sendEvent(name: "GVstatus", value: "valueB", displayed: false, isStateChange: true)
*/
}

def setValueC(value) {
    valueChange("valueC", value)

/*

    sendEvent(name: "valueC", value: value, displayed: false)
    sendEvent(name: "GVstatus", value: "valueC", displayed: false, isStateChange: true)
*/
}

def setValueD(value) {
    valueChange("valueD", value)

/*

    sendEvent(name: "valueD", value: value, displayed: false)
    sendEvent(name: "GVstatus", value: "valueD", displayed: false, isStateChange: true)
*/
}

def setLabelA(value) {
	textChange("labelA", value)

/*
    sendEvent(name: "labelA", value: value, displayed: false)
    sendEvent(name: "GVstatus", value: "labelA", displayed: false, isStateChange: true)
*/
}

def setLabelB(value) {
	textChange("labelB", value)
}

def setLabelC(value) {
	textChange("labelC", value)
}

def setLabelD(value) {
	textChange("labelD", value)
}

def value1Up () {
	def newVal = (device.currentValue("valueA").toInteger())+1
    valueChange("valueA", newVal)
/*
    def incVal = (device.currentValue("Increment").toInteger())
    if (isTime1) {
		timeChange("Value1",incVal)
    } else {
		valueChange("Value1",incVal)
    }
*/
}
def value1Down () {
	def newVal = (device.currentValue("valueA").toInteger())-1
    valueChange("valueA", newVal)
}
def value2Up () {
	def newVal = (device.currentValue("valueB").toInteger())+1
    valueChange("valueB", newVal)
}
def value2Down () {
	def newVal = (device.currentValue("valueB").toInteger())-1
    valueChange("valueB", newVal)
}
def value3Up () {
	def newVal = (device.currentValue("valueC").toInteger())+1
    valueChange("valueC", newVal)
}
def value3Down () {
	def newVal = (device.currentValue("valueC").toInteger())-1
    valueChange("valueC", newVal)
}
def value4Up () {
	def newVal = (device.currentValue("valueD").toInteger())+1
    valueChange("valueD", newVal)
}
def value4Down () {
	def newVal = (device.currentValue("valueD").toInteger())-1
    valueChange("valueD", newVal)
}

def valueChange(String valString, Integer newval) {
    // def targetVal = (device.currentValue(valString).toInteger())+offset
    
    // reset to avoid losing sync with WebCoRE
    ResetGV()
    Logger("valueChange: ${valString} Target ${newval}")
    sendEvent("name":valString, "value":newval, displayed: true)
    sendEvent(name: "GVstatus", value: valString, displayed: false, isStateChange: true)
}

def textChange(String valString, String newval) {
    Logger("valueChange: ${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)
}

This is the piston for setting/updating the global variables from this device.

Once you copy, paste and publish the DTH, create a device using it. Then you will need to edit the piston to use your new device and the variables you want to view/change. Hope it is helpful.

EDIT: Forgot to mention, in order to add this device to webcore, you need to look under capability 2 “refreshable devices”. Also, note this only supports integer values at this time.

EDIT2: Very slight modification to the DTH to help avoid getting stuck if changing values too fast for webcore to keep up.


#104

I would love to be able to test this but i’m getting an odd error when creating the DTH.

Groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method physicalgraph.device.CapabilityService#syncCustomCapabilityWithDuplo. Cannot resolve which method to invoke for [null] due to overlapping prototypes between: [class physicalgraph.device.Capability] [class physicalgraph.device.cache.CapabilityDTO]

Maybe a copy paste issue?

Edit: I was finally able to save, had to a replace with ASCII double quotes.


#105

You are the man. I’m happy to see that someone has figured out the custom attributes piece. Makes my somewhat more optimistic for the future of ST in general.

I didn’t adjust the piston other than to switch to local variables for testing purposes. Values loaded correctly upon initial piston test. Piston also successfully ran and updated following a value adjustment. Reflected in both new and classic apps.