MCO Home MH-S312 and MH-S314 - Anyone has these working properly?

Hi all,

I have been researching, for several days now, how to connect my MCO Home (some MH-312 which are 2-gang, but many more MH-314 which are 4-gang) switches to ST, reliably. I have tried numerous ST DTHs, none of which worked very well, and finally settled on the best DTH I could find, one written by hongtat and found here:

It’s by far the best DTH around - at least that I could find. It seems to have also worked perfectly for some people, and for me - well, it almost does - except that when the switch is physically pressed (any button on it) Smartthings does not seem to get to know about it until the scheduled refresh (which I have to keep at 1 minute, the minimum). Obviously this is not the best approach. With over 40 of these around the house, it means over 40 refreshes from the ST hub every minute, besides the other work it has to do… Moreover, any automation I have on these switches (e.g. two-way lighting, hot water circulation, etc.) has to wait until the refresh, an average of 30 seconds, before it starts.

Now I know, with certainty, that the switch does send something to the ST hub when physically pressed, and I know this from my current controller which is a different brand (from which I m currently migrating). Also, some out-of-the-box ST DTHs were getting “feedback” from the physical switch and updating in the app instantly - but they suffered different flaws and I had to abandon them. When a button is pressed, in Live Logging I do see this:

450cbed5-2403-4938-9857-b4ef4849bde4 9:15:29 AM: debug Parsed zw device: 13, command: 2001, payload: FF to BasicSet(value: 255) to [:]
450cbed5-2403-4938-9857-b4ef4849bde4 9:15:29 AM: debug Command () called - Dining Light 1 BasicSet(value: 255)
450cbed5-2403-4938-9857-b4ef4849bde4 9:15:29 AM: debug Event: zw device: 13, command: 2001, payload: FF

Is there any way anyone knows of that I can trap these messages coming from the switches and actually do something with them? E.g. trigger a webCoRE piston, o something I might not have thought of? Any help would be appreicated.

The basicset sounds good, I would use the Z wave Tweaker just to check what the current association settings are.

The smartthings hub has always automatically added itself to association group one when a new zwave device was added. ( and this is now mandatory under the zwave protocol for zwave plus devices.)

The switch should send the basic set command whenever it is pressed, no delays. As long as it does that, you shouldn’t need to poll the device or refresh the status.

That said, I have no idea what groovy code a DTH would need to act on that action, and, I don’t know how smartthings handles multi endpoint devices for multi channel association, and it’s entirely possible that it doesn’t handle it well, because there’s a history of that. :disappointed_relieved:

I think you’re going to need to talk to one of the expert coders who does a lot with multi endpoint Z wave devices. i’m going to tag a couple here. (As I’ve mentioned before, I can’t actually work with the groovy code because I depend on text to speech. But I do know many of the concepts of the protocol, so sometimes that can help spark some ideas.)

@orangebucket @mwav3

1 Like

Thanks @JDRoberts

I’m gonna need some guidance here please. So I go into the Z-Wave Tweaker settings, and what should I see there?

Currently, on these MCO Home switches, I just see this:

So I didn’t touch those, really, but is there something that should be set?

I’m more “one of the just about competent coders who doesn’t even have any Z-Wave devices any more, except four outlets in an Ikea bag in the corner of the front room for some reason”. I’ve only very superficial understanding of Zigbee and Z-Wave, and multi-channel just makes it worse.

I wasn’t sure (well didn’t have a clue actually) whether what was happening was typical Z-Wave Plus behaviour, or something being done by an older device to compensate for the lack of Instant Status. If nothing else it ought to be possible to use it in the spirit of a ‘Hail’ command and trigger a poll.

2 Likes

The device handler you are using is receiving unhandled commands when the button is pressed, which is what is showing in your log. That’s generated from this code:

def zwaveEvent(physicalgraph.zwave.Command cmd) {
    log.debug("Command () called - ${device.displayName} ${cmd}")
    // Handles all Z-Wave commands we aren't interested in
    [:]
}

That’s good news because like you posted it means some command is sent when a button is pressed. We need to add code so the device handler handles those commands instead of bumping them into that unhandled command method. The commands are already coming in so I don’t think we need additional associations, the handler just needs to translate them into an action. It looks like its just a basic set command. The older Jasco’s generate these commands when they associate to the Hub and are double tapped. The code from that handler captures those Basic sets as button presses:

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
    log.debug "---Double Tap--- ${device.displayName} sent ${cmd}"
	if (cmd.value == 255) {
    	createEvent(name: "button", value: "up_2x", data: [buttonNumber: 1], descriptionText: "Double-tap up (up_2x) on $device.displayName", isStateChange: true, type: "physical")
    }
	else if (cmd.value == 0) {
    	createEvent(name: "button", value: "down_2x", data: [buttonNumber: 1], descriptionText: "Double-tap down (down_2x) on $device.displayName", isStateChange: true, type: "physical")
    }
}

Maybe we can create button presses from these events that could be recognized by Webcore or automations? Maybe even they can actually turn the device on or off by calling on() and off() methods? Its hard for me to figure out without having the device or more info. Maybe some screenshots of how the device looks in the app can help. Also, this device, how many buttons does it have? If you can take logs from each press and let me know which button it corresponds too maybe I can do something with it.

2 Likes

The OP has both the 2 button and the 4 button models.

.


.

1 Like

Its possible this whole problem could potentially be solved by just calling a refresh method when this basic set is received. The OP can try throwing this code into the DTH.

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
    refresh()
    }
1 Like

Thank you for your input, @orangebucket & @JDRoberts & @mwav3, I am very happy with the response, at least it looks like something is moving…

I will certainly try this bit - sure, it’s a workaround, but it could suffice for my needs without having to try to interpret the BasicSet commands. The entries I see in the log do not have enough information to decide WHICH button was pressed, only WHICH switch, but A button on that switch, could be any button. But someone in a different post remarked that what I am seeing in the log would have been encapsulated, and it would have had some layers of encapsulation removed before being thrown in the log, and as @mwav clearly showed, the log entries are actually generated by that bit of code in the DTH itself.

So before sending lots of log entries and info, let me try to embed that code in the DTH, and I will report what happens.

Once again, many thanks to all.

Yeah its probably not the most elegant way to handle that basic set command, but probably the easiest if it works. It will cause the state of the switch to be polled when that command comes in which should cause the status to be almost instantly updated.

Let me know how it works.

Hi @mwav3, @orangebucket, @JDRoberts

I am happy to report improvement. It’s not perfect, but it’s much better than before I inserted the code, so I am happy that thanks to you guys I’ve made a step in the right direction. These are the logs of one switch press on a switch close to the hub:

152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug Parsed zw device: 49, command: 600D, payload: 04 04 25 03 00 to MultiChannelCmdEncap(destinationEndPoint: 4, parameter: [0], sourceEndPoint: 4, command: 3, commandClass: 37, bitAddress: false) to null
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug MultiChannelCmdEncap mapped - [name:switch4, value:off]
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug MultiChannelCmdEncap called - MultiChannelCmdEncap(destinationEndPoint: 4, parameter: [0], sourceEndPoint: 4, command: 3, commandClass: 37, bitAddress: false)
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug Event: zw device: 49, command: 600D, payload: 04 04 25 03 00
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug Parsed zw device: 49, command: 600D, payload: 03 03 25 03 00 to MultiChannelCmdEncap(destinationEndPoint: 3, parameter: [0], sourceEndPoint: 3, command: 3, commandClass: 37, bitAddress: false) to null
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug MultiChannelCmdEncap mapped - [name:switch3, value:off]
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug MultiChannelCmdEncap called - MultiChannelCmdEncap(destinationEndPoint: 3, parameter: [0], sourceEndPoint: 3, command: 3, commandClass: 37, bitAddress: false)
152696b5-76d4-4596-b363-79b90da295fc 9:34:24 AM: debug Event: zw device: 49, command: 600D, payload: 03 03 25 03 00
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug Parsed zw device: 49, command: 600D, payload: 02 02 25 03 00 to MultiChannelCmdEncap(destinationEndPoint: 2, parameter: [0], sourceEndPoint: 2, command: 3, commandClass: 37, bitAddress: false) to null
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug MultiChannelCmdEncap mapped - [name:switch2, value:off]
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug MultiChannelCmdEncap called - MultiChannelCmdEncap(destinationEndPoint: 2, parameter: [0], sourceEndPoint: 2, command: 3, commandClass: 37, bitAddress: false)
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug Event: zw device: 49, command: 600D, payload: 02 02 25 03 00
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug Parsed zw device: 49, command: 600D, payload: 01 01 25 03 FF to MultiChannelCmdEncap(destinationEndPoint: 1, parameter: [255], sourceEndPoint: 1, command: 3, commandClass: 37, bitAddress: false) to null
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug MultiChannelCmdEncap mapped - [name:switch1, value:on]
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug MultiChannelCmdEncap called - MultiChannelCmdEncap(destinationEndPoint: 1, parameter: [255], sourceEndPoint: 1, command: 3, commandClass: 37, bitAddress: false)
152696b5-76d4-4596-b363-79b90da295fc 9:34:23 AM: debug Event: zw device: 49, command: 600D, payload: 01 01 25 03 FF
152696b5-76d4-4596-b363-79b90da295fc 9:34:22 AM: debug Parsed zw device: 49, command: 2001, payload: FF to BasicSet(value: 255) to null
152696b5-76d4-4596-b363-79b90da295fc 9:34:22 AM: debug refresh() called
152696b5-76d4-4596-b363-79b90da295fc 9:34:22 AM: debug Event: zw device: 49, command: 2001, payload: FF

It includes the full refresh log of course. Turning the switch off is much the same, except the first entry (chronologically), which is:

152696b5-76d4-4596-b363-79b90da295fc 9:36:14 AM: debug Event: zw device: 49, command: 2001, payload: 00

There seems to be no information on which channel/surce endpoint it is that has been toggled.

The problem is that:

a) A whole refresh takes a while, especially on 4-gang switches, up to 2 seconds. It’s good enough for certain automations (e.g. circulating hot water when entering a bathroom), not so much for others (e.g. 2/3-way lighting).

b) If a user presses multiple of these at one go (e.g presses 1,2 & 3 on a 4-gang switch, tends to happen in real life), the hub seems unable to process so many refreshes, and might easily show only 1 or 2 of the pressed switches going on (in Smartthings app). Again this may be related to the overall load generated by refreshes. The only way to be sure that the app reflects the correct status of the device is to leave approx. 6 seconds in between button presses, which is not realistic.

Does anyone think there is a more efficient way of handling this than a refresh?

So I quoted this as perhaps it might be worth looking into, but as I said - I see nothing in the logs that identifies WHICH button was pressed on the device, so that may be a little hard, unless there is some way of extracting more detailed information than that shown by the log (I am sure this information is being received from the switch somehow - otherwise how would they have worked on my current non-Smartthings controller?).

In any case - many thanks in advance!

EDIT

I improved the functionality a little by commenting out the following line in the code:

//if (lastRefreshed && (now() - lastRefreshed < 5000)) return

As I realised that is where the 6 seconds was coming from. Behaves much better now, though still a little slow because of the speed of the refresh (device sends a message to hub to inform it what happened, and hub asks it to kindly send a full report of the status of all its children, which the deice duly sends… you get my point)…

1 Like

This thread on Openhab reveals some more clues how this switch works:

According to it, each button is capable of direct association to another Zwave Device. Also, the “gateway” (in our case the Smartthings hub itself) is associated in group 1, the lifeline group, by default.

So what’s happening now is the hub is associated with the device only in group 1. When a button is pressed, it’s detected by the hub as a BasicSet command with an on or off value (0 for off, 255 for on). The problem with that is that any of the two up buttons create the same on response here, and the two down buttons create the same off response. Code can be added to create a button with “up” and “down” values, but the problem is the same up press will be triggered with either up button being pressed, likewise for the down press with either down button being pressed. The hub will have no idea which down button was pressed when it triggers the “down” button, and there does not appear to be a way around that.

Polling will be a good workaround to update status, but Smartthings is a cloud based hub, using Groovy in the cloud, so it won’t be instant. In fact, Smartthings is looking at getting away from Groovy and the IDE all together. Most programmers don’t use Groovy anymore, and the only reason I understand it somewhat (I’m not a professional developer) is from Java programming classes I took in college 20 years ago. Combine those issues with this particular switch and it gets even worse, because its only supported command class is BasicSet. Take a look at the specifications for this switch - Product Command Classes versus a newer switch Product Command Classes and you will see the difference. Although this switch looks cool and futuristic, in terms of Zwave command processing its ancient. New Zwave devices use Central Scene control for button presses, which are different for each button, and even each press (held, released, double tap, etc), sent instantly, and can easily be decoded by Smartthings with some coding to interpret the central scene command. This switch doesn’t have that.

The nature of the way Smartthings runs will inevitably create processing delays. This switch and smartthings are far from an ideal pairing. Using the refresh() will help, but the delay built into the refresh() method was to cut down on excessive processing from too many refresh commands. Removing the delay will allow for more refreshes, but that’s more processing needed. If those delays are not acceptable, a cloud based hub like Smartthings probably isn’t the best choice, and one should look into a hub that processes commands and automations locally like Hubitat, OpenHab, or Homeassistant.

One other possibility is based on the Openhab thread, direct association from this switch to other Zwave devices is possible for each button. That could lead to faster processing, but programming would need to be added to allow setting associations in groups 2 - 5. I have association programming setup for groups 2 and 3 in this switch if you want to see how it looks - smartthingscode/ge-46201-on-off-switch.groovy at master · mwav3/smartthingscode · GitHub . Additional programming would be needed for groups 4 and 5.

Direct association though has its own issues with status updates, etc where the hub is left out of the process.

1 Like

This is why I suggested step one should be querying the device (probably with the zwave tweaker) to find out what the current association groups are.

Also note that it might be using ONLY group one if it’s sending the endpoint information as a parameter value. That’s how it’s done in multi channel association.

BTW, you mentioned “two up and two down.” Normally this particular device is handled as 4 individual momentary buttons, each as a toggle for a separate target, which works because that’s how the basicset works: it’s implicitly a toggle. Of course that gets screwed up when you try sending the command through the hub since you might then want to use the event for something other than a zwave basic command. So just one more complication that the smartthings architecture adds that another hub might not have. :thinking:

2 Likes

This is the concept document for multi channel association in zwave

Give me a second and I will see if I can find the byte structure

1 Like

Ok, this is old, But includes a detailed analysis by the person who wrote the Z wave Tweaker, so hopefully it will be helpful. You can compare what is written in the following thread to the tweaker itself to see if anything has changed over the years.

Anyway, the point of including these two links is that if the MCO device is using multi channel association, it likely only needs the hub in group one and then it’s expecting the hub to use the endpoint information.

Also note that the byte structure Assumes that either the trigger device or the Target device or both can have multiple endpoints. That’s explained in the first link I gave. If I recall correctly, the smartthings overlay reversed the usual order of these, so people tend to get really confused, but the link I provided in this post should clear that up. hopefully. :thinking:

1 Like

I’ve found the zwave tweaker was optimized for the classic app. Can it still do all this in the new app? I saw it seemed to only have partial functionality now.

I really don’t have a good understanding of how multichannel association works. I think it will allow association to other zwave devices, but I don’t see if there’s a way for the hub to decode which button was pressed if you try to add the hub as an association for each group.

1 Like

If it’s using multi channel association, Both the trigger and the target are encoded in the byte structure for the wrapper around the basic set command. See the link above with all the details.

Now when the association group is triggered, the device should send one instance of the relevant command(s) (e.g. a BASIC_SET) that is not encapsulated, plus another two instances of the command(s), each encapsulated within a MultiChannelCmdEncap() wrapper to the appropriate endpoint destination.

But you have a point: I have no idea how you get to the wrapper in a smartthings context. Or if you even can.

As far as what the Tweaker does or doesn’t do under the current V3 app, I don’t know for sure, you would need to ask in that thread. But I know there are still people using it with the new app.

[BETA] Z-Wave Tweaker

1 Like

Well then there’s hope to getting something beyond just these basicset commands by actually associating the hub to the other channels and then decoding the encapsulated methods. This handler uses the multichannel wrapper to do that it looks like - SmartThings/fibaro-dimmer-2.groovy at master · codersaur/SmartThings · GitHub

Still, without the device, I don’t think I’d be able to figure all that programming out.

1 Like

Good point, I didn’t think about doing it that way with the hub in each association group, but you’re right, that should give you access to the wrappers.

Can I just say here that programming for the smartthings environment is really confusing if you’re used to a typical Z wave hub? Thank goodness for people like you who have actually done it, I would’ve given up along time ago! LOL! :laughing:

1 Like

The work of many developers over the years is the only way I could figure this out, and your high level knowledge of zwave @JDRoberts.

It’s too bad so many have left for other platforms and that’s left a big void to fill. Every now and then I think about moving things off but when i spend an entire day figuring out how to mirror devices in Home Assistant, when it’s a simple automation here, I decide to stay put with Smartthings. It’s still easier for me to update code for these device handlers then figure out home assistant. How long it will all last and what the future holds is anyone’s guess. Whatever happens i’m still thankful i ditched Wink and got this Smartthings hub and for the excellent community here.

1 Like

I only have the MCO Home 2 gang switch, they do work for me. Associations (single/multi-channel) are automatically added to report the actual switch status (on/off) when the switch is pressed physically.

I have seen others reporting it works on the 4 gang switch as well.

Does the real-time status reporting work on the 2-gang switch for you?

2 Likes