How to use the "on" press from my dimmer to sequentially turn on lights

I’m struggling to get this working - most of my logic is sound, but I have no way to subscribe to the actual button press.

 /**
 *  Great Room Toggle
 *
 *  Copyright 2015 Jeff Zellen
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */
definition(
    name: "Great Room Toggle",
    namespace: "",
    author: "Jeff Zellen",
    description: "Cycles through light switch modes",
    category: "Convenience",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")


preferences {
    section("Select Devices") {
        input "switch1", "capability.switch", title: "Select Light Switch"
        input "light1", "capability.switch", title: "Select Light"
        input "light2", "capability.switch", title: "Select Light"
        input "light3", "capability.switch", title: "Select Light"
        input "light4", "capability.switch", title: "Select Light"
	}
}

def installed() {
	state.count = 0
	log.debug "Installed with settings: ${settings}"
	initialize()
}

def updated() {
	log.debug "Updated with settings: ${settings}"

	unsubscribe()
	initialize()
}

def initialize() {
	subscribe switch1, "switch.Off", offHandler
    subscribe switch1, "switch.On", onHandler
}


def onHandler(evt) {
	log.debug state.count
    if (state.count < 4) {
    	state.count = state.count + 1
    }
	log.debug state.count
    if (state.count >= 1) {
    	light1.on()
    }
    if (state.count >= 2) {
    	light2.on()
    }
    if (state.count >= 3) {
    	light3.on()
    }
    if (state.count >= 4) {
    	light4.on()
    }
}

def offHandler(evt) {
    if (state.count > 0) {
    	state.count = state.count - 1
    }
	log.debug state.count
    if (state.count < 1) {
    	light1.off()
    }
    if (state.count < 2) {
    	light2.off()
    }
    if (state.count < 3) {
    	light3.off()
    }
    if (state.count < 4) {
    	light4.off()
    }
}

That’s it… Any thoughts? Do I need to modify the dimmer to pass more info? Is that possible?

Can you expand on this, please? I’m not sure I understand the problem.
What type of “button” and/or events are you watching for? What type of “dimmer”, I guess, based on the title…?

1 Like

Exact model of the actual dimmer you’re using? And the device handler? (Formerly called “smart device type.”)

1 Like

Not sure this logic is going to do what you want.
While the dimmer switch may have discreet physical actions for on and off (ie a paddle with up being on and down being off), repeatedly hitting on will not cause the device to issue “on” updates to ST, the updates are issued when the switch changes state, further ST devices work in the same manner, only state changes are issued to ST smartApps.
The latter can be changed in the device, I do not believe the former can.

So what I really want is to know when the discrete button press occurs. There is a physical button in my paddle switch that actuates when I press “on”. It seems ST only knows when the output state of the device changes. The dimmer is the GE/Jasco in-wall style.

metadata {
	// Automatically generated. Make future change here.
	definition (name: "Dimmer Switch", namespace: "smartthings", author: "SmartThings") {
		capability "Switch Level"
		capability "Actuator"
		capability "Indicator"
		capability "Switch"
		capability "Polling"
		capability "Refresh"
		capability "Sensor"

		fingerprint inClusters: "0x26"
	}

	simulator {
		status "on":  "command: 2003, payload: FF"
		status "off": "command: 2003, payload: 00"
		status "09%": "command: 2003, payload: 09"
		status "10%": "command: 2003, payload: 0A"
		status "33%": "command: 2003, payload: 21"
		status "66%": "command: 2003, payload: 42"
		status "99%": "command: 2003, payload: 63"

		// reply messages
		reply "2001FF,delay 5000,2602": "command: 2603, payload: FF"
		reply "200100,delay 5000,2602": "command: 2603, payload: 00"
		reply "200119,delay 5000,2602": "command: 2603, payload: 19"
		reply "200132,delay 5000,2602": "command: 2603, payload: 32"
		reply "20014B,delay 5000,2602": "command: 2603, payload: 4B"
		reply "200163,delay 5000,2602": "command: 2603, payload: 63"
	}

	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
			state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
			state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
			state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
			state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
		}
		standardTile("indicator", "device.indicatorStatus", inactiveLabel: false, decoration: "flat") {
			state "when off", action:"indicator.indicatorWhenOn", icon:"st.indicators.lit-when-off"
			state "when on", action:"indicator.indicatorNever", icon:"st.indicators.lit-when-on"
			state "never", action:"indicator.indicatorWhenOff", icon:"st.indicators.never-lit"
		}
		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: 3, inactiveLabel: false) {
			state "level", action:"switch level.setLevel"
		}

		main(["switch"])
		details(["switch", "refresh", "indicator", "levelSliderControl"])
	}
}

def parse(String description) {
	def item1 = [
		canBeCurrentState: false,
		linkText: getLinkText(device),
		isStateChange: false,
		displayed: false,
		descriptionText: description,
		value:  description
	]
	def result
	def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
	if (cmd) {
		result = createEvent(cmd, item1)
	}
	else {
		item1.displayed = displayed(description, item1.isStateChange)
		result = [item1]
	}
	log.debug "Parse returned ${result?.descriptionText}"
	result
}

def createEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "physical"
	}
	result
}

def createEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "physical"
	}
	result
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStartLevelChange cmd, Map item1) {
	[]
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd, Map item1) {
	[response(zwave.basicV1.basicGet())]
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "physical"
	}
	result
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	result[0].descriptionText = "${item1.linkText} is ${item1.value}"
	result[0].handlerName = cmd.value ? "statusOn" : "statusOff"
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "digital"
	}
	result
}

def doCreateEvent(physicalgraph.zwave.Command cmd, Map item1) {
	def result = [item1]

	item1.name = "switch"
	item1.value = cmd.value ? "on" : "off"
	item1.handlerName = item1.value
	item1.descriptionText = "${item1.linkText} was turned ${item1.value}"
	item1.canBeCurrentState = true
	item1.isStateChange = isStateChange(device, item1.name, item1.value)
	item1.displayed = item1.isStateChange

	if (cmd.value >= 5) {
		def item2 = new LinkedHashMap(item1)
		item2.name = "level"
		item2.value = cmd.value as String
		item2.unit = "%"
		item2.descriptionText = "${item1.linkText} dimmed ${item2.value} %"
		item2.canBeCurrentState = true
		item2.isStateChange = isStateChange(device, item2.name, item2.value)
		item2.displayed = false
		result << item2
	}
	result
}

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
	def value = "when off"
	if (cmd.configurationValue[0] == 1) {value = "when on"}
	if (cmd.configurationValue[0] == 2) {value = "never"}
	[name: "indicatorStatus", value: value, display: false]
}

def createEvent(physicalgraph.zwave.Command cmd,  Map map) {
	// Handles any Z-Wave commands we aren't interested in
	log.debug "UNHANDLED COMMAND $cmd"
}

def on() {
	log.info "on"
	delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def off() {
	delayBetween ([zwave.basicV1.basicSet(value: 0x00).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def setLevel(value) {
    def level = Math.min(value as Integer, 99)
	delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def setLevel(value, duration) {
    def level = Math.min(value as Integer, 99)
	def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60)
	zwave.switchMultilevelV2.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration).format()
}

def poll() {
	zwave.switchMultilevelV1.switchMultilevelGet().format()
}

def refresh() {
	zwave.switchMultilevelV1.switchMultilevelGet().format()
}

def indicatorWhenOn() {
	sendEvent(name: "indicatorStatus", value: "when on", display: false)
	zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
}

def indicatorWhenOff() {
	sendEvent(name: "indicatorStatus", value: "when off", display: false)
	zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
}

def indicatorNever() {
	sendEvent(name: "indicatorStatus", value: "never", display: false)
	zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()
}

def invertSwitch(invert=true) {
	if (invert) {
		zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 4, size: 1).format()
	}
	else {
		zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 4, size: 1).format()
	}
}

Its the GE/Jasco Smart In-Wall Dimmer. I did tweek the deivce handler to possibly improve things. But it hasn’t helped. I changed the “canBeCurrentState” to true.

metadata {
	// Automatically generated. Make future change here.
	definition (name: "Zellen Dimmer Switch", namespace: "Zellen", author: "Jeff Zellen") {
		capability "Switch Level"
		capability "Actuator"
		capability "Indicator"
		capability "Switch"
		capability "Polling"
		capability "Refresh"
		capability "Sensor"
        capability "Button"

		fingerprint inClusters: "0x26"
	}

	simulator {
		status "on":  "command: 2003, payload: FF"
		status "off": "command: 2003, payload: 00"
		status "04%": "command: 2003, payload: 04"
		status "10%": "command: 2003, payload: 0A"
		status "33%": "command: 2003, payload: 21"
		status "66%": "command: 2003, payload: 42"
		status "99%": "command: 2003, payload: 63"

		// reply messages
		reply "2001FF,delay 5000,2602": "command: 2603, payload: FF"
		reply "200100,delay 5000,2602": "command: 2603, payload: 00"
		reply "200119,delay 5000,2602": "command: 2603, payload: 19"
		reply "200132,delay 5000,2602": "command: 2603, payload: 32"
		reply "20014B,delay 5000,2602": "command: 2603, payload: 4B"
		reply "200163,delay 5000,2602": "command: 2603, payload: 63"
	}

	tiles {
		standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
			state "on", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
			state "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
			state "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"on"
			state "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"off"
		}
		standardTile("indicator", "device.indicatorStatus", inactiveLabel: false, decoration: "flat") {
			state "when off", action:"indicator.indicatorWhenOn", icon:"st.indicators.lit-when-off"
			state "when on", action:"indicator.indicatorNever", icon:"st.indicators.lit-when-on"
			state "never", action:"indicator.indicatorWhenOff", icon:"st.indicators.never-lit"
		}
		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: 3, inactiveLabel: false) {
			state "level", action:"switch level.setLevel"
		}

		main(["switch"])
		details(["switch", "refresh", "indicator", "levelSliderControl"])
	}
}

def parse(String description) {
	def item1 = [
		canBeCurrentState: true,
		linkText: getLinkText(device),
		isStateChange: false,
		displayed: false,
		descriptionText: description,
		value:  description
	]
	def result
	def cmd = zwave.parse(description, [0x20: 1, 0x26: 1, 0x70: 1])
	if (cmd) {
		result = createEvent(cmd, item1)
	}
	else {
		item1.displayed = displayed(description, item1.isStateChange)
		result = [item1]
	}
	log.debug "Parse returned ${result?.descriptionText}"
    log.debug "Jeff: ${item1?.value}"
	result
}

def createEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "physical"
	}
	result
}

def createEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "physical"
	}
	result
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStartLevelChange cmd, Map item1) {
	[]
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelStopLevelChange cmd, Map item1) {
	[response(zwave.basicV1.basicGet())]
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "physical"
	}
	result
}

def createEvent(physicalgraph.zwave.commands.switchmultilevelv1.SwitchMultilevelReport cmd, Map item1) {
	def result = doCreateEvent(cmd, item1)
	result[0].descriptionText = "${item1.linkText} is ${item1.value}"
	result[0].handlerName = cmd.value ? "statusOn" : "statusOff"
	for (int i = 0; i < result.size(); i++) {
		result[i].type = "digital"
	}
	result
}

def doCreateEvent(physicalgraph.zwave.Command cmd, Map item1) {
	def result = [item1]
	log.debug item1
    log.debug cmd.value
	item1.name = "switch"
	item1.value = cmd.value ? "on" : "off"
	item1.handlerName = item1.value
	item1.descriptionText = "${item1.linkText} was turned ${item1.value}"
	item1.canBeCurrentState = true
	item1.isStateChange = isStateChange(device, item1.name, item1.value)
	item1.displayed = item1.isStateChange

	if (cmd.value >= 5) {
		def item2 = new LinkedHashMap(item1)
		item2.name = "level"
		item2.value = cmd.value as String
		item2.unit = "%"
		item2.descriptionText = "${item1.linkText} dimmed ${item2.value} %"
		item2.canBeCurrentState = true
		item2.isStateChange = isStateChange(device, item2.name, item2.value)
		item2.displayed = false
		result << item2
	}
	result
}

def zwaveEvent(physicalgraph.zwave.commands.configurationv1.ConfigurationReport cmd) {
	def value = "when off"
	if (cmd.configurationValue[0] == 1) {value = "when on"}
	if (cmd.configurationValue[0] == 2) {value = "never"}
	[name: "indicatorStatus", value: value, display: false]
}

def createEvent(physicalgraph.zwave.Command cmd,  Map map) {
	// Handles any Z-Wave commands we aren't interested in
	log.debug "UNHANDLED COMMAND $cmd"
}

def on() {
	delayBetween([zwave.basicV1.basicSet(value: 0xFF).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def off() {
	delayBetween ([zwave.basicV1.basicSet(value: 0x00).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def setLevel(value) {
    def level = Math.min(value as Integer, 99)
	delayBetween ([zwave.basicV1.basicSet(value: level).format(), zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def setLevel(value, duration) {
    def level = Math.min(value as Integer, 99)
	def dimmingDuration = duration < 128 ? duration : 128 + Math.round(duration / 60)
	zwave.switchMultilevelV2.switchMultilevelSet(value: level, dimmingDuration: dimmingDuration).format()
}

def poll() {
	zwave.switchMultilevelV1.switchMultilevelGet().format()
}

def refresh() {
	zwave.switchMultilevelV1.switchMultilevelGet().format()
}

def indicatorWhenOn() {
	sendEvent(name: "indicatorStatus", value: "when on", display: false)
	zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format()
}

def indicatorWhenOff() {
	sendEvent(name: "indicatorStatus", value: "when off", display: false)
	zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 3, size: 1).format()
}

def indicatorNever() {
	sendEvent(name: "indicatorStatus", value: "never", display: false)
	zwave.configurationV1.configurationSet(configurationValue: [2], parameterNumber: 3, size: 1).format()
}

def invertSwitch(invert=true) {
	if (invert) {
		zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 4, size: 1).format()
	}
	else {
		zwave.configurationV1.configurationSet(configurationValue: [0], parameterNumber: 4, size: 1).format()
	}
}

This is the exact situation I am trying to find a solution for. Can this be done by adding an attribute to the device? Maybe by triggering an attribute update on each press? But then I need to trigger the return to a neutral state between presses. Or do I move the sequencing to the device and remove it from the smartapp by indexing the count attribute?

OK. Because I rely on a text to speech reader, i can’t actually look at your code, but it sounds like you’re trying to do something similar to the “double tap” smartapp, so that one tap on the switch does one thing and two taps does something else. But you want to have many distinct patterns. 4 lights on. (I’m not sure if you’re also turning them off.)

Hmmm…

First question: what controls the electricity to each light?

If these are 4 dumb bulbs all on the same load controlled by one switch (whether it’s this dimmer or a different smart switch) then you can’t do what you’re asking.

If these are 4 smart bulbs, maybe. Or 4 different smart switches and this is a 5th.

(A person is going to have difficulty pressing for exactly the right amount of time, though.)

I would consider using smart bulbs and either a zone control switch with multiple physical buttons or just using a dashboard app on a cheap tablet, like SmartTiles. (This was created by a community member, but has official recognition from smartthings, and so is hosted at the smart things site and has a one button install procedure.)

1 Like

Looking at this specific switch, it is relying on the concept of “long press” or “held” with a time duration to set a single value that it returns. It’s not really a double tap switch.

I believe this is what @Mike_Maxwell is referring to.

Basically the state change occurs when you lift your finger from the paddle. At that point the physical switch determines how long the hold was for, and calculates the value based on that. I believe that single value is what might then be returned to smartThings. (I think this is how Dim with Me works.) But meanwhile, the current has already been increased on the load that is controlled by the switch.

1 Like

Yes. Sort-of. I want one press to turn on the hardwired light that is attached to the dimmer switch directly (and that works by default). And then I want with each successive SINGLE tap, to add a light. I have several lamps in the room that we typically don’t turn on, but would sequence on as needed. Essentially, each one is less likely to get used and would be further down the list. I know that sounds insane, but its how the furniture and the lamps are laid out.

Each additional light is a dumb-bulb wired into a [SmartPower Outlet][1] The primary overhead light is on a GE/Jasco Dimmer (linked above).

I’d be okay with using an app, but I’m the only tech savvy person in my house. My wife is decidedly NOT going to pick up an app. She’s not totally keen on the whole thing to begin with. The only thing that lets me keep adding intelligence to the home is the convenience of it. It all needs to work like a normal wall switch, otherwise she’ll have it all torn out.

So far, the dimmer works as advertised, its just the additional lamps.
[1]: https://shop.smartthings.com/#!/products/smartpower-outlet

Because your dimmer controls the load to light 1, even if your code worked you’d be changing its dim state in order to control the others, plus a person will find it really fidgety, low XAF.

The point of a dashboard is that you can use it as a wall mount control panel, showing only the devices you want. So good xAF for most adults, but not necessarily good for little kids.

In your situation, I personally would leave the dimmer as is and add the SmartenIT 3 toggle to control the other 3.

1 Like

The line you need to change in the device is isStateChange: true. This will force ST to sent an on/off event irrespective of ST’s stored device state. However we have yet to determine if the device always sends an event when actuated or only reports the device status changes.
Since you already have a debug line in there to show you the events that the device is producing, I suspect that the dimmer is only reporting state changes, otherwise you would see debug lines every time the dimmer on/off paddles were actuated.

1 Like

Mike,

There’s also a Lutron patent issue, this device hasn’t licensed instant status.

1 Like

Quite right. I was hoping that would fire the event to ST. I think based on the DoubleTap this might be possible. I’m going to try it tonight and update later.

Yes, but I have a few of these (switches), not dimmers. The ST device does report physical status changes in a round about way.
@muppet1856, so if the ST device isn’t showing stat debug logs every single time you press on, this isn’t going to work. The limitation being in the actual dimmer hardware…

1 Like

Thats the good news, it is reporting EVERY time! It sound like tweaking the DT smart app is the way to go. I didn’t realize that I could subscribe to the eventHandler instead of the state.

I don’t think you need the double tap app.
You need to change the device line isStateChange: true, this will force ST to send the on event every time the dimmer sends it.
Right now it’s only sending on, if the current state is off.
I would also remove canBeCurrentState…
Your app should work after this.

1 Like

Mike,

Since this is a dimmer switch, Each successive tap is still going to also change the brightness on light 1, though, right? There’s no way to leave light 1 at, say, 50% brightness while also turning on lights 2-4.

So the dimmer value doesn’t change with each press. You bring up an interesting challenge re: the long press for dimmer. It MIGHT add a light with the long press. (Initial thought is it will, but I will verify.)

IMHO, I would stick with the short press (which shouldn’t change the dimmer level) and your current cycle approach first, get that working then tune up the finer points.
Remember that the initial on event will turn the dimmer on, this would be state count 0, and shouldn’t trigger any of the additional lights, there is no need to react to the initial on event, since the dimmer will already be on.
Also maybe the off event should turn off all the lights at once, currently you have to cycle through each one to turn them off individually.

1 Like