Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose ManagerDevices updateCapabilityValue to update Homey without triggering setCapabilityValue listeners #47

Open
torarnv opened this issue Aug 27, 2023 · 3 comments

Comments

@torarnv
Copy link

torarnv commented Aug 27, 2023

Some devices do not have the ability to report their state, for example the Nexa series of "dumb" 433 sockets/dimmers. To reflect the device's state in Homey, we rely on the remote control signal, which is used both to listen for changes, as well as control the device.

A common practice in this case is that the remote control and device are directly paired, outside of Homey, so that if Homey is down, or has issues receiving 433 signal, the lights still work. This would potentially result in the device receiving duplicate state changes, e.g.:

  1. Remote turns on light
  2. Light receives signal from remote, turns on device
  3. Homey receives signal from remote, turns on device
  4. Homey sees that device is turned on, sends signal to turn on
  5. Light receives signal to turn on again, when it's already on, potentially triggering a "choose dim level mode", or similar

Luckily, a Device implemented using the App SDK doesn't have this problem of recursing back to its capability listener when calling setCapabilityValue:

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);
    });
  }
}

Because it only results in updating locale state, and emitting updateCapabilityValue so that Homey can react to the state change. All good so far 😃

Now, consider a scenario where a device is controlled by two remotes, both directly paired to the device outside of Homey. In that case, the Homey device is only set up to "mirror" one of the remote controls. The other remote control is paired to Homey as a plain remote control, without being tied to anything. To tie the remote control to the light, we need to use Flows/HomeyScript. But unlike the case above with the App SDK, the Web SDK setCapabilityValue function recurses back into the light device's capability listener, resulting in duplicated "turn on" signals, as in point 5 above.

This is where a updateCapabilityValue in the Web SDK would be useful, so it can be used in HomeyScript automations. Hope this can be added! 🤞🏻

@torarnv
Copy link
Author

torarnv commented Sep 18, 2023

One possible implementation would be the following two commits:

The functionality builds on the existing machinery inside home-core for updating capability values, which takes care of updating the UI, running flows, etc. – i.e. all the things you want to happen in reaction to a device changing its state in the eyes of Homey. Except, importantly, when hitting the app device's _onUpdateCapabilityValue in the homey-apps-sdk-v3, the app only updates its local state, and doesn't trigger capability listeners like _onSetCapabilityValue would have.

The latter would have resulted in the app trying to set the state of the external device to match the new capability value, but the whole reason we've updated the capability value is because we know it has already changed externally. And letting the app change the state of the external device (again) would be treated by the device as "go into dim level setting".

In my case I use this new API to update the Homey state when I detect that a secondary controller button has changed the state of the external device directly, and then reflect that in Homey:

image

With the HomeyScript just posting to the Web API's '/device/:deviceId/capability/:capabilityId/update' endpoint.

The plumbing all the way to the Homey Web API JS SDK porcelain has been left out for now.

@JacobArrow
Copy link

JacobArrow commented Dec 29, 2023

Bump!
I have the exact same issue as mentioned above, and I would really benefit from this implementation :)

@jancihr
Copy link

jancihr commented Jan 19, 2024

the same here with many KAKU wall switches directly linked to KAKU relays for light control. It would be even easier for users (me) if KAKU end devices would support setting its on/off state without triggering it in the flows interface directly :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants