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


#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.


#106

It was a bit of a headache but it turned out the biggest problem is I had to start from scratch. Editing an existing DTH didn’t work as there is some cache issue. But I got the process down now, I think. Really glad it worked for you.

I thought I used double quotes everywhere. Where was it messed up for you?


#107

I’m going to try and apply it to a device that displays my WAN IP. I need to rework my current piston and won’t need the adjustment aspect.

I did not go through line by line, I copied to notepad first, did a replace all changing “curly”
double quotes to straight double quotes (if that makes sense). It happens sometimes with copy/paste of code.

Update: Removed all the new app capabilities except TextA and TextB to display my IP Address, worked like a charm. Going to remove B as well…IP Address is somewhat redundant since the device name is also displayed.