Tasker, SharpTools, and Zooper


(Shawn) #1

I’m trying to create a dimmer widget on my Android. I have the On/Off working just fine, but I want to be able to tap a - for example, and have the lights dim 10% or so. I see how to set a certain light level using setLevel, but is that the only option right now? Is there a way to make a light dim or brighten by percentages?


(Joshua Lyon (SharpTools.io Dashboard)) #2

Most of the standard lights/switches do not have a method to reduce the level by a certain amount. You can modify the device type to add your own dim up and dim down methods -or- you can use Tasker to perform this logic.

Custom Device Type

You could customize the DTH (device type handler) to add your own custom command…something like:

Make sure the new commands are available to SharpTools by adding them to the metadata { definition() { section.

metadata {
   definition(name: "Device Type", namespace: "SmartThings", author: "Cool guy") {
       //add the new commands below existing commands in the metadata definition
       command "dimDown", [ "number" ]
       command "dimUp", [ "number" ]

And create the new commands to dim up or down by the desired amount:

def dimDown(percent){
    log.debug "dimDown($percent)"
    def current_level = device.currentValue("level")
    def new_level = Math.max(current_level - percent, 0.0) //set a floor of 0
    log.debug "Current level is $current_level ...setting new level to $new_level"
    setLevel(new_level)
}
def dimUp(percent){
    log.debug "dimUp($percent)"
    def current_level = device.currentValue("level")
    def new_level = Math.min(current_level + percent, 100.0) //set a ceiling of 100
    log.debug "Current level is $current_level ...setting new level to $new_level"
    setLevel(new_level)
}

Then in SharpTools, refresh your device list and then in the Tasker → Plugins → SharpTools → A Thing, you should now have a dimDown and dimUp command you can use.

  • dimUp(10) to dim up 10%
  • dimDown(5) to dim down 5%

Custom Tasker Method

If you don’t want to mess with a custom device type handler, you can also do this in Tasker. Since you are setting up a custom widget, you could create a decrement (-) button by taking the current level, subtracting your desired amount, and then sending that with setLevel.

So, let’s say the light is set to 50% and you have your (-) action set to dim the level down by 10%, your Tasker action would do something like:

  1. Get the current level = 50
    (See the note below about subscribing to a value so you have the current value readily available)
  2. Calculate the desired level new_level = 50 - 10 = 40
    (Variable Subtract 10 with a wrap-around value of 0)
    Edit: A wrap-around of 0 doesn’t seem to work as expected, see the comments in my post below.
  3. Send the setLevel command with the new calculated value

Note: I would recommend using the approach from the Custom Widget article - subscribe to the level attribute of your desired device so you always have the current level value. Use the Variable Set command in Tasker to assign that to a global variable that you can use in other tasks.

Alternatively, you could use the SharpToolsThing: Get Attribute plugin to get the current attribute each time, but you would have a performance penalty as SharpTools goes to get the attribute value from the web. If you use a subscription, you should have the latest value cached locally that you can use.


(Shawn) #3

I only had a few minutes to try playing with this, but I had no success. I’d prefer to go the Custom Tasker Method you’re talking about, as the lights I’m controlling are already virtual dimmers, but pretty sure I screwed up with the calculating the new level part. Any chance you’d be nice enough to give an idiot a step by step on this?


(Joshua Lyon (SharpTools.io Dashboard)) #4

Can you provide some commentary on what you’ve tried so far? It would help to see a Description Export of the profile or a screenshot too.

PS. Also note that you can use the device type code I listed above even with virtual dimmers.

How to Export a Tasker Profile:

  • Ensure that Menu / Prefs / UI / Beginner Mode is unchecked
  • Go to the main screen
  • Long-click on the profile you want to export
  • Open the menu and select Export → Description

(Shawn) #5

Not using a profile is probably where I went wrong, I tried to do it in a task. The only things I’ve done so far is to make some profiles and tasks that are attached Zooper to change icons, colors, and send attributes to some icons I made. And when things didn’t with today, I deleted what I did.


(Shawn) #6

Making progress. I can pull the current level, and subtract whatever amount I want (used Flash to see the new level on screen), but now having troubles passing that new level to the bulb. Here’s an export of what I’m doing:

Attic Dim (17)
A1: Thing: Get Attribute [ Configuration:Thing: Attic Lights
Attribute: level

The following variables are set when triggered:
%st_attr_name
%st_attr_value
%st_thing_id
%st_thing_name Package:com.boshdirect.stwidgets Name:Thing: Get Attribute Timeout (Seconds):15 ]
A2: Variable Subtract [ Name:%st_attr_value Value:25 Wrap Around:0 ]
A3: Flash [ Text:%st_attr_value Long:Off ]
A4: A Thing [ Configuration:Thing: Attic Lights
Command: setLevel
Args: %st_attr_value Package:com.boshdirect.stwidgets Name:A Thing Timeout (Seconds):0 ]


(Glen King) #7

I’m new to this so forgive the obvious question: is anyone working on some sort of slider control?


(Shawn) #8

If they are, I haven’t been able to find it. But like you, I’m pretty new too.


(Shawn) #9

Ok, not I’m just confused. For grins I decided to switch devices to a wall switch that controls the regular bulbs in a ceiling fan. This worked:

Attic Dim (17)
A1: Thing: Get Attribute [ Configuration:Thing: Attic Lights
Attribute: level

The following variables are set when triggered:
%st_attr_name
%st_attr_value
%st_thing_id
%st_thing_name Package:com.boshdirect.stwidgets Name:Thing: Get Attribute Timeout (Seconds):15 ]
A2: Variable Subtract [ Name:%st_attr_value Value:25 Wrap Around:0 ]
A3: Flash [ Text:%st_attr_value Long:Off ]
A4: A Thing [ Configuration:Thing: Attic Lights
Command: setLevel
Args: %st_attr_value Package:com.boshdirect.stwidgets Name:A Thing Timeout (Seconds):0 ]

But when I put it back the Virtual Dimmer I created that controls 4 Hue bulbs, it doesn’t. I can use the setValue command though to set the value at whatever level I want, just not by going down in percent. Thoughts on this?


(Shawn) #10

Tried editing the device type now to see if that would help. Here’s what I have:

metadata {
definition (name: “Virtual Dimmer”, namespace: “”, author: “smartthings”) {
capability "Switch"
capability "Refresh"
capability "Switch Level"
command “dimDown”, [ “number” ]
command “dimUp”, [ “number” ]
}

// simulator metadata
simulator {
}

// UI tile definitions
tiles {
	standardTile("button", "device.switch", width: 2, height: 2, canChangeIcon: true) {
		state "off", label: 'Off', action: "switch.on", icon: "st.Kids.kid10", backgroundColor: "#ffffff", nextState: "on"
		state "on", label: 'On', action: "switch.off", icon: "st.Kids.kid10", backgroundColor: "#79b821", nextState: "off"
	}
	standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
		state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
	}        
    controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 2, inactiveLabel: false, backgroundColor:"#ffe71e") {
        state "level", action:"switch level.setLevel"
    }
    valueTile("lValue", "device.level", inactiveLabel: true, height:1, width:1, decoration: "flat") {
        state "levelValue", label:'${currentValue}%', unit:"", backgroundColor: "#53a7c0"
    }

	main(["button"])
	details(["button", "refresh","levelSliderControl","lValue"])
}

}

def parse(String description) {
}

def on() {
sendEvent(name: “switch”, value: “on”)
log.info “Dimmer On”
}

def off() {
sendEvent(name: “switch”, value: “off”)
log.info “Dimmer Off”
}

def setLevel(val){
log.info “setLevel $val”

// make sure we don't drive switches past allowed values (command will hang device waiting for it to
// execute. Never commes back)
if (val < 0){
	val = 0
}

if( val > 100){
	val = 100
}

if (val == 0){ // I liked that 0 = off
	sendEvent(name:"level",value:val)
	off()
}
else
{
	on()
	sendEvent(name:"level",value:val)
	sendEvent(name:"switch.setLevel",value:val) // had to add this to work if apps subscribed to
                                                // setLevel event. "Dim With Me" was one.
}

}

def refresh() {
log.info “refresh”

}

def dimDown(percent){
def current_level = device.currentValue(“level”)
def new_level = Math.max(current_level - percent, 0) //set a floor of 0
device.setLevel(new_level)
}
def dimUp(percent){
def current_level = device.currentValue(“level”)
def new_level = Math.min(current_level + percent, 99) //set a ceiling of 99
device.setLevel(new_level)

}

I used the 50 in the parameter when I was making my task, but that did nothing. I went in and changed the def dimUp(percent) to def dimUp(50), and that just tossed errors at me.

For grins I went back the one I had working on the living room switch, and changed it from the switch to just one of my Hue bulbs, and got nothing with that also. I have a headache, and give up unless someone wants to chime in.


(Joshua Lyon (SharpTools.io Dashboard)) #11

It looks like the profile export that was posted was the same one from before, but if I am following you correctly, it sounds like you changed the device in your Tasker task from your Virtual Switch (which controls the Hues) to your Physical switch and everything was working as expected.

I like that you used a Flash for the %st_attr_value – this is a great approach to debugging with Tasker!

What was the level being reported as for your virtual dimmer before and after the Variable Subtract? (You can either just add another flash before and just watch for the two different flashes, or use a Variable Set: %oldvalue to %st_attr_value right after your Thing: Get Attribute and before the Variable Subtract, then you can use a flash or notify with both values in it)

Also, can you confirm that there aren’t any differences in the commands between the working and non-working example? (For example, you’ll want to make sure you are using the same number and type of parameters and that the device name is correct)

PS. I would note that a wrap-around value of 0 doesn’t appear to work for me (it just leaves the variable unchanged), but a wrap-around value of 1 works? I’m not sure what the deal is there, but you can just add a conditional Variable Set command to fix this. (Variable Set: %st_attr_value To: 0 with the condition IF %st_attr_value < 0)

What did the SmartThings IDE Live Logs say when you sent the command from Tasker? And did you publish the device type after you made the changes and ensure the device is using your custom device type handler? Where did you get the device type code from - I don’t see “Virtual Dimmer” as an option in the IDE? (Edit: Thanks for posting the code - that makes it easier to debug!)

Edit: Also, it looks like your device type handler is already taking care of values less than 0 and greater than 100, so you don’t need to worry about the “Wrap Around” or conditionally setting the value to 0.

You can also add some logging to the dimUp and dimDown commands to make it easier to see what’s going on:

Edit2: I also corrected a few things in the code - Math.min wants a float/double for the second value and the setLevel() command should have been called directly:

def dimDown(percent){
    log.debug "dimDown($percent)"
    def current_level = device.currentValue("level")
    def new_level = Math.max(current_level - percent, 0.0) //set a floor of 0
    log.debug "Setting new level to $new_level"
    setLevel(new_level)
}
def dimUp(percent){
    log.debug "dimUp($percent)"
    def current_level = device.currentValue("level")
    def new_level = Math.min(current_level + percent, 100.0) //set a ceiling of 100
    log.debug "Setting new level to $new_level"
    setLevel(new_level)
}

(Shawn) #12

Before was 100, after the subtract was 75, so that’s right. Setting the Wrap-Around to 1 didn’t seems to do anything, but not sure what it’s supposed to do. I duplicated your screen shots, and all the values flash correctly, but they just aren’t being passed to the virtual switch correctly it seems.

I’ll try the new code from Edit 2 when I get back from getting my daughter from school and post the results. I did check out the Logs quick before I left work, and something seemed off, but didn’t have the time to really look. And I was throwing commands so quickly, it was hard to tell the events apart. I’ll do one now, and the other when I get home so I can see the difference.


(Shawn) #13

The bottom line from 3:03:55.668 PM CST is me running the task that we’re working on. The 3 lines above that are just the generic setLevel with a value set to 75. Here’s my copy of the one we’er working on:


(Shawn) #14

This worked! Would still like to know why the original task didn’t though. Here’s a copy of the event log this time:


(Joshua Lyon (SharpTools.io Dashboard)) #15

Awesome! I’m glad it’s working for you now… it is faster to make a single call to dimDown or dimUp than it is to first get the level with Thing: Get Attribute and then make another call for setLevel via A Thing, so I hopefully you will be happy with this approach.

If you want to watch the SmartThings IDE Live Logs while you trigger the event and send me a copy of that along with the logs from SharpTools, I’d be happy to look into it more with you. It would also help to see a screenshot of the A Thing : setLevel command - specifically I’m looking to make sure you are in Tasker variable mode (the tags in the action bar) and that there is only a single parameter and the parameter type is 0-9 instead of A-Z.


(Shawn) #16

I can post some stuff tomorrow, I’m done for the night lol. Ran into a glitch though. I have a profile set up to send on/off when it changes to my widget to change the color of an icon and the label text. After I got this working, my light bulb icon disappeared and was just the folder icon. I set a line on the widget to display the value of %st_attr_value, and it was the % for the light instead of on/off. Easy work around as I just changed the code to >1 for the on color, and kept =off for the other color. Just don’t get why the % comes through now though. Using the dimDown, I’m not doing anything with the %st_attr_value variable.

Question about that last sentence though. I have the single parameter set up, but in order to use the variable name (%st_attr_value) I need to use A-Z to get the alpha keyboard to pop to type it in. If I use 0-9, I have to use numbers. How can I switch that?