Generic Component Central Scene Switch and Generic Component Button -- how to use

I am looking to create a generic component child device that can be commanded by the user. I tried adding Generic Component Button, but there is no Push, Hold, Release button, so this appears to only be trigger able via code.
So next, I tried a Generic Component Central Scene which does have the commands I am looking for, however, I cannot figure out how to use it. I tried added the function "componentPush(child, button)" but the method is never called when I click the Push button in the child device.

What am I doing wrong? How do we use the child device types?

The Generic Component device type only updates state based on a parent device (or app) calling parse.
When a Command is called in a Generic Component device, eg On, the parent device is called in this way: "parent?.componentOn(this.device)".
No logic is executed inside the Component device.
The Generic Component Button not having Commands would be expected, it is supposed to receive events from the parent, not send them.
It would be easy to make your own Generic Component driver that does have Commands, see this official example, but what you might be looking for are the Virtual Device drivers instead?

Thanks. I suspected the same for the button, but the generic component central scene switch has push command, but it does not seem to make calls to parent.componentPush()

Just checked the Central Scene switch, that Component device doesn't seem to follow the same pattern that all other Component devices do, the Push command sends the event directly and never call the parent. I think your best, and only, bet if you want a Component style driver with the Push command calling the Parent is to write your own.

Hi, I have the same problem, I have a driver that do the integration with tuya smart app. It create all devices and it works great but for scene it create generic switch that trigger scene correctly but I would like to use events with those switch in webcore. Webcore just never receive any update from those so it never trigger the event. I have access to the driver code so I was wondering what code to add to just send the status update to webcore or something? It could just be a kind of 'status changed' to be able to trigger the event, since the switch act like a motion sensor (ON is triggering scene and off just do nothing and status stay blank, so ON is like a button that can be pushed multiple times). Thanks!

As long as the attribute 'switch' is changing, then you can write a rule based on the switch. It will likely turn on then momentarily turn off, if it is operating as a momentary switch.

I found how to update the status, the only weird things is that webcore optimization must be off as it always tell it ll give nothing to flip the switch so it do nothing… don’t know why!

Is this code you are writing in a driver? If so, you call something like:

def componentOn(child) {
    child.sendEvent([name:“switch”, value:“on”] ) 
    child.runIn(2, “off”)
}

def componentOff(child) {
    child.sendEvent([name:“switch”, value:“off”] ) 
}

Now, if there is something optimizing the status change, and it is incorrectly missing that you turned it on, and back off, you might be able to fix this with:

def componentOn(child) {
    child.sendEvent([name:“switch”, value:“on”, isStateChange: true] ) 
    child.unschedule(“off”)
    child.runIn(2, “off”)
}

def componentOff(child) {
    child.sendEvent([name:“switch”, value:“off”, isStateChange: true] ) 
}

The isStateChange force the event to be published, even if the state in the device already was set to on. This is helpful if the button is press 4 times really fast, and you need to pick up all four presses. It is important in this case that the off event is not sent multiple time to avoid spamming the event bus with on/off events that are all out of sequence. Since the rf event is delayed, we only want one off event sent after all the button presses. In this way, it will turn on 4 times, the off 2 seconds after 4th press. Normally, you can turn off just milliseconds after, but again, there is no need to spam bomb the event bus, so throttling it for 2 seconds after last on event ensures you aren’t doubling down on events that don’t affect the outcome.

Hi, Thanks for your post, its awsome! I just have a question, its working well except for the off function... I m not a dev so not sure on how to modify it...I was able to do for the first pat but the function "off" is not recognized... and the ComponentOff contain not the code for the scene switch that I try to fix... Thats why I just made a line to make it off inside the componentOn function... I ll try to solve it but if you have an idea it would help me!
Thanks again!
**I replaced the "Off" by the function and seem to work but not sure its the good way to do it...

Your code is wrong. gefChildDevice(deviceNetworkId) gets the child device. It requires a lookup operation which takes a little bit of time, in terms of cpu cycles.

Replace the three instances with one call:
def child = getChildDevice(deviceNetworkId)
Then use the child device reference.

child.parse([[name:”switch”, value:”on” …. ]])
child.unschedule(“parse”)
child.runIn(2, “parse”, [[name:”switch”, value:”off” …. ]])

The problem with this solution (relying on parse) is that you cannot cancel the off — you must cancel the parse method. . So instead, it is best to call the off method of the child.

Since this is a virtual switch, there is an off method.

child.parse([[name:”switch”, value:”on” …. ]])
child.unschedule(“off”)
child.runIn(2, “off”)

To make this more complete, it should probably look like this:

def componentOn(dw) {
    def child = getChildDevice(dw.deviceNetworkId)
    child.parse([[name:”switch”, value:”on” …. ]])
    child.unschedule(“off”)
    child.runIn(2, “off”)
}

def componentOff(dw) {
    def child = getChildDevice(dw.deviceNetworkId)
    child.parse([[name:”switch”, value:”off” …. ]])
}

I typed this on my iPhone, so there are likely to be some minor typos or errors.

Thanks! I ll try that! For the componentoff, is it bad if I let it empty (for virtual switch) ? It looks like implemented for real switch but for generic component it just return a log... So if I let it as is would it be a problem since the componenton return the off event and the off switch would never get touched and even if flipped it would just return nothing?

Then use this one:

This way, you are sending the on event to be parsed, then sending the off event 2 seconds later to be parsed.

Just know that the off button is useless without the componentOff() method and that also means that rules cannot turn off the switch.

Of course, the switch is already a momentary, so the off doesn’t need to be commandable.

Yes, it exists a command off but just not taking account of generic switch… thanks a lot for your help!

you may want to put the unschedule fore the the parse, and the runIn, to ensure the off is not called a fraction before.

Hi, sorry to be back again with another question! :slight_smile: But, now the problem is that I would like to use those scene switches in alexa as trigger... and alexa only use contact or motion sensor as trigger routine! So I would like to add motion or contact to my child generic switch component...
I just added the same lines in the turn on part and replaced the switch on by contact open... All I need is to send contact open at same time the switch is turned on... and close the contact the same way the switch is doing... (contact follow switch, open on on and closed on off). My tuya account is been reactivated so it could be the reason it does not works but I would like to know if I forgot something! Soon my account will be back and I could test better...
Thanks!

Add capability ContactSensor to you list of capabilities, and in your code, when you call parse([[name:”switch”, value”on”]])
Replace it with:

parse([
        [name:”switch”, value:”on”],
        [name:”contact”, value: “open”]
])

And for
parse([[name:”switch”, value”off”]])
Replace it with:

parse([
        [name:”switch”, value:”off”],
        [name:”contact”, value: “close”]
])

The problem with this is that because you are using a generic driver, you don’t have the ability to add capabilities and therefore you don’t have the ability to send both of these events. At this point, you’re gonna need to create a custom driver.

1 Like

Hi, thanks, I tried it and its not working but I changed the Generic switch to generic switch/contact and then it proceed the contact state but alexa still not discover the sensor, just the switches. Dont know if its normal ...

Generic is different than component. When using generic, there is not parent device to receive commands (which you aren’t using) but also, I believe instead of child.parse you want to call child.sendEvent, as I had originally posted before I realized that component devices used parse. And parse received an array of events, whereas sendEvent only sends one event so you will use something like:
child.sendEvent([name:”contact”, value:”open”])

Hi, I have a question, I am able to make all of this working, exept one thing, when my smart life scene are triggered from the app, hubitat seem not to be aware of it... Is there a way to check within the driver if the scene trigger event is sent from the tuya api ? I would like to add the capability to the driver but I would like to be sure that the event is there before to try... I see a MQTT connexion but hard to figure if this event in particular is submitted...
Thanks!