Changing state of device in Homey without triggering it?

I have a socket device (S) that’s triggered externally by two remote switches (A and B), but doesn’t have the ability to report its state. I have added the device to Homey by mirroring the signal from one of the switches (A), so when I press that, the device turns on in Homey. And I can control the device from Homey, as it emulates switch A’s signals. To ensure Homey is always reporting the right state, I’ve separately connected switch B to Homey, and created a flow so that whenever B is turned on, so is S.
However, this results in the device S receiving duplicated “turn on” signals, one from B, and one from Homey when B triggers the “S is on” flow. Which in turn brings S into “adjust dim level” mode, fading up and down :slight_smile:

How can I update the state of the device in Homey, without triggering it as well? setCapabilityValue seems to do both.

It looks like KaKu/Nexa 433MHz gear?
I solved this issue by pairing the remote switches to Homey as well, and cut the direct coupling between the devices.
So only Homey responds to the switches, and operates the light.

Yepp, Nexa 433Mhz. I’ve been hesitant to cut the direct coupling between the devices, as if Homey is down I can no longer control my lights. Also, Homey seems to have very buggy or poor 433 reception (Poor 433 Mhz reception) so removing the direct connection would make the switches more flakey, and even non-responding at times :frowning:

Is there really no way to update the logical state of the Homey side of things without also triggering the capability?

The device.setCapabilityValue(‘capability’) shouldn’t trigger anything and if the new state is the same as the old state then nothing changes.

The device.setCapabilityValue(‘capability’) shouldn’t trigger anything and if the new state is the same as the old state then nothing changes.

But the new state is new from Homey’s point of view.

The light is off in Homey, and the light itself. I have then turned it on externally, and want to inform Homey about this, since the device itself doesn’t do state reporting. But doing so, results in Homey thinking I want to turn it on from Homey, sending the light an additional “turn on” message, when the light itself it already on. And this duplicate “turn on” message, results in the light going into “choose dim level” mode.

But have you tried using the function I mentioned?
That shouldn’t trigger anything, it will just set the state of the Homey capability.

I use that all the time when I detect a device has changed state. I call setCapabilityValue and it just turns on / off the Homey capability without triggering anything.

To actually simulate a user interaction that triggers the change code needs the triggerCapabilityListener function.

But I see from other posts that you are maybe doing this in script and not an app, so maybe the outcome is different there.

Ah, yeah, that could be. I want to do it as an automation, via e.g.:

const devices = await Homey.devices.getDevices();
for (const device of Object.values(devices)) {
  if (device.id != '<id>')
    continue;
  log(`\nTurning '${device.name}' on...`);

  await device.setCapabilityValue('onoff', true)
    .then(() => log('OK'))
    .catch(error => log(`Error:`, error));
}

And this definitely turns the device physically on, if it’s off in Homey prior to that.

Perhaps it’s a bug in the Nexa app then, or in GitHub - athombv/node-homey-rfdriver: This module helps developers create RF (433MHz, 868MHz, Infrared) apps for Homey. which it is based on, in that it sends an RF signal from the setCapabilityValue callback instead of the triggerCapabilityListener callback?

You’re using the Web API, not the app SDK. The methods are named the same, but they do different things internally.

I don’t think you can set a capability value from the Web API without triggering flows.

Ah, I see. So I need to write an app (unless it exists) that exposes a flow card that updated the state of another device I guess? Does flow cards support other devices as inputs?

Hmm, now I’m confused as I have just seen this in the documentation:
As a convenience Homey will automatically run Flow trigger cards with specific IDs when you call Device#setCapabilityValue() for a custom capability.

So, I think it is me getting mixed up, because when a device notifies the app of a change I use setCapabilityValue to set the state, which triggers the flows, but in your case it is triggering the flows that is causing the problem as you are using them as the control mechanism.

Right, I’m not writing an app, where you would react to the detected device change via whatever API/protocol that uses, and update the Homey state via setCapabilityValue.

I’m trying to update Homey’s state for device A in an automation (flow, advanced flow, HomeyScript), in response to another device B turning on/triggering (the remote control device), without actually sending any messages from Homey to device A, because I know that it’s already on (because B also turns A on out of band of Homey).

Looked like Flow Utilities App for Homey | Homey might support this, but I can’t find the card for the advertised “- Turn (specific) devices in Zone on”.

Thinking about this some more, what I want is actually to trigger flows as well, and any other thing that would normally respond to the device being turned on, except the code that triggers it to send an RF signal to the HW device. Taking this basic device example:

class Device extends Homey.Device {
  async onInit() {
    this.registerCapabilityListener("onoff", async (value) => {
      await DeviceApi.setMyDeviceState({ on: value });
    });

    DeviceApi.on('state-changed', (isOn) => {
      this.setCapabilityValue('onoff', isOn).catch(this.error);
    });
  }
}

There must be something inside Homey’s machinery that prevents setCapabilityValue from recursing back into the "onoff" capability listener. While still triggering other listeners such as flows, or the Web UI.

I want to do the same thing, but externally from the app that provides these devices, since that app can not track multiple remotes tied to a single device.

Trying to create an app to tests this, I don’t see any way to iterate all the devices from the SDK APIs? And this gives me zero drivers, presumably because it only returns the drivers of my app? console.log(this.homey.drivers.getDrivers());

That’s correct, you need to use the Web API for that: HomeyAPI - Homey Web API

That’s correct, you need to use the Web API for that: HomeyAPI - Homey Web API

And the Web API’s setCapabilityValue doesn’t have a way to avoid triggering the device’s own listener AFAICT.

  • I don’t want to disconnect the direct HW mapping from the switches to the device, as they respond faster than Homey, and Homey has shown to be flakey for 433, sometimes not even responding it all. Plus, I want my home to work at a basic level (turn off and on lights with switches) even if Homey is down.
  • From what I can tell, I can’t use the Homey APIs in flows or otherwise (neither the Web API, nor the App SDK), to work around this, by updating the state without triggering the device itself (while still triggering flows etc).

Any other ideas?

Write a specific app for your specific device?

Hehe, yeah, I guess that would work, although it seems a bit overkill all the time there’s an official (and closed source) Nexa app already: Nexa App for Homey | Homey

Plus, the whole reason I bought a Homey instead of awakening my 5 year old Home Assistant monster was that I wanted a system where everything (most stuff) worked :sweat_smile: So far I’ve spent just as much time debugging, diving through code, and patching existing apps as I used to do with the HA setup, with the only difference that Homey is a more closed system that I can’t easily modify/patch if needed :anguished:

I do appreciate the help though :heartbeat: the forum here, and Bruce from Homey’s support, is giving me hope. I’m not giving up just yet :slightly_smiling_face:

Okey, so the difference between the App SDK and the Web API, is that the App SDK device’s setCapabilityValue stores the new state locally, and triggers updateCapabilityValue, which takes care of running flows, updating UI, etc, but importantly does not trigger the _onSetCapabilityValue that feeds back into the capability listeners of the device, which in turn would result in communicating with the HW.

The Web API’s setCapabilityValue on the other hand feeds into ManagerDevices which plumbs into the core Device’s setCapabilityValue, which triggers _onSetCapabilityValue before updateCapabilityValue.

I’ve filed Expose ManagerDevices updateCapabilityValue to update Homey without triggering setCapabilityValue listeners · Issue #47 · athombv/homey-web-api-issues · GitHub to ask for a updateCapabilityValue in the Web SDK.

1 Like