Help with registerCapabilityListener

No, I want the ID that I entered myself, see the photo, not the ID that is unique per device.

I also don’t want to use smode but that’s the code I found somewhere that seemed interesting for this solution.

I would like to enter my device name here myself.

I want to be able to use this as follows:

  • when something is turned on or off, a capability lissener triggers automatically
  • Which is then sorted by if id= … and that I can then give more or less a target for each device later.

In summary:
in a capability lissener I want if device id = ... (eg AE_I1) and so on.

NOT: "70bc6595-e616-44bd-b33f-32c58dfc938f"
WELL: "AE_I1"

PHOTO:

You should be able to apply @Adrian_Rockall 's suggestion to the code you’re showing:

let devData = this.getData();
if (devData.id === 'AE_I1') {
  …
}

but this doesn’t work I tested it with this.log('--------------');

async onInit() {

    this.log('AE - Auto Encoder has been initialized');

    this.registerCapabilityListener('onoff', async (value) => {

      this.log('AE Device:', value);

      

    });

    this.registerCapabilityListener('my_enum_capability', async (value) => {

      this.log('Changes to :', value);

        let devData = this.getData();
        if (devData.id === 'AE_I1') {
          this.log('--------------');
        }
    });

  }

The id from the getData() is the one you assigned in the pairing, I was just saying that you should make sure each device has a unique id.

So do you see the 'Changes to :'... being logged?

Each device has a unique id but there are two identifiers:
the long one from homey itself and the one I assigned per device myself.

I want to use this function with the one I assigned myself.

You should ignore the long one that Homey assigns and pretend it doesn’t exist as that is for Homey’s internal use only.
The one you assign yourself should also be unique so you can map it back to the specific device. Also, if you use a fixed id, the pairing wizard will assume that any new device has already been added as it will have the same id as the one you already have.

If you need an identifier that defines the type of device or sub device then create another variable, such as ‘type’: ‘AE_I1’.

The getData().id is the one assigned by yourself.

So do you see the other log message?

I already have several devices in this capability and they all have a unique name see code:

async onPairListDevices() {
    return [

      // Example device data, note that `store` is optional
      // {
      //   name: 'My Device',
      //   data: {
      //     id: 'my-device',
      //   },
      //   store: {
      //     address: '127.0.0.1',
      //   },
      // },


      {
          name: 'I1 (AE)',
          data: {
            id: 'AE_I1',
          },
          capabilities: [
            "onoff"
          ],
          energy: {
            approximation: {
              usageConstant: 0, // in Watt
            },
          },
        },

      {
        name: 'I2 (AE)',
        data: {
          id: 'AE_I2',
        },
        capabilities: [
          "onoff"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'I3 (AE)',
        data: {
          id: 'AE_I3',
        },
        capabilities: [
          "onoff"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'I4 (AE)',
        data: {
          id: 'AE_I4',
        },
        capabilities: [
          "onoff"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'M1 (AE)',
        data: {
          id: 'AE_M1',
        },
      },

      {
        name: 'M2 (AE)',
        data: {
          id: 'AE_M2',
        },
      },

      {
        name: 'Q1 (AE)',
        data: {
          id: 'AE_Q1',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'Q2 (AE)',
        data: {
          id: 'AE_Q2',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'Q3 (AE)',
        data: {
          id: 'AE_Q3',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'Q4 (AE)',
        data: {
          id: 'AE_Q4',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

    ];
  }
}

module.exports = MyDriver;

with some I have to add a capability but first want to see that one works before I do it with all.

I don’t quite understand yet how I can have a reference that I know which device turns on or off see code:

this.registerCapabilityListener('my_enum_capability', async (value) => {
      this.log('Changes to :', value);
    });

i need to find something i know which device it was that turned on or off .

I would like to see a code example.

Can you confirm that the capability you specified in the example:

Is not what you are really using as the capability you assign in the pairing is

1 Like

this is to ensure that you as a user cannot turn on and explain this device yourself, but that it is possible through the app itself.

There is also no need to pair as they are virtual devices.

So the line of code you should be using to test is:

Is that what you have?

1 Like

Yes I have but then there will be in the CMD:

[log] 2021-07-21 07:28:59 [ManagerDrivers] [Driver:AE] [Device:70bc6595-e616-44bd-b33f-32c58dfc938f] AE has changed: false

I want to be able to know if it is AE_I1 or AE_I2 or….

But that does match up with any of the example code you have given. Nowhere do you show a log line with “AE has changed:” So that is coming from somewhere else.

You need to be showing your real code else we can’t see what is a mistake and what is pretend.

1 Like

device.ts

import { Device } from 'homey';

class MyDevice extends Device {

  /**
   * onInit is called when the device is initialized.
   */

  async onInit() {
    this.log('AE - Auto Encoder has been initialized');

    this.registerCapabilityListener('onoff', async (value) => {
      this.log('AE - Auto Encoder has changed:', value);
      
    });

    this.registerCapabilityListener('my_enum_capability', async (value) => {
      this.log('Changes to :', value);
    });
  }

  /**
   * onAdded is called when the user adds the device, called just after pairing.
   */

  async onAdded() {
    this.log('AE - Auto Encoder has been added');
  }

  /**
   * onSettings is called when the user updates the device's settings.
   * @param {object} event the onSettings event data
   * @param {object} event.oldSettings The old settings object
   * @param {object} event.newSettings The new settings object
   * @param {string[]} event.changedKeys An array of keys changed since the previous version
   * @returns {Promise<string|void>} return a custom message that will be displayed
   */

  async onSettings({ oldSettings: {}, newSettings: {}, changedKeys: {} }): Promise<string|void> {
    this.log('AE - Auto Encoder settings where changed');
  }

  /**
   * onRenamed is called when the user updates the device's name.
   * This method can be used this to synchronise the name to the device.
   * @param {string} name The new name
   */

  async onRenamed(name: string) {
    this.log('AE - Auto Encoder was renamed');
  }

  /**
   * onDeleted is called when the user deleted the device.
   */
  
  async onDeleted() {
    this.log('AE - Auto Encoder has been deleted');
  }
}

module.exports = MyDevice;

Driver.compose.json

{
  "name": {
    "en": "AE - Auto Encoder",
    "nl": "AE - Auto Encoder"
  },
  "class": "other",
  "capabilities": [],
  "images": {
    "small": "/drivers/p-perceptron/assets/images/small.png",
    "large": "/drivers/p-perceptron/assets/images/large.png",
    "xlarge": "/drivers/p-perceptron/assets/images/xlarge.png"
  },
  "pair": [
    {
      "id": "list_devices",
      "template": "list_devices",
      "navigation": {
        "next": "add_devices"
      },
      "options": {
        "singular": false
      }
    },
    {
      "id": "add_devices",
      "template": "add_devices"
    }
  ]
}

driver.ts

import { Driver } from 'homey';

class MyDriver extends Driver {

  /**
   * onInit is called when the driver is initialized.
   */

  async onInit() {
    this.log('AE - Auto Encoder has been initialized');
  }

  /**
   * onPairListDevic∑es is called when a user is adding a device and the 'list_devices' view is called.
   * This should return an array with the data of devices that are available for pairing.
   */

  async onPairListDevices() {
    return [

      // Example device data, note that `store` is optional
      // {
      //   name: 'My Device',
      //   data: {
      //     id: 'my-device',
      //   },
      //   store: {
      //     address: '127.0.0.1',
      //   },
      // },


      {
          name: 'I1 (AE)',
          data: {
            id: 'AE_I1',
          },
          capabilities: [
            "onoff"
          ],
          energy: {
            approximation: {
              usageConstant: 0, // in Watt
            },
          },
        },

      {
        name: 'I2 (AE)',
        data: {
          id: 'AE_I2',
        },
        capabilities: [
          "onoff"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'I3 (AE)',
        data: {
          id: 'AE_I3',
        },
        capabilities: [
          "onoff"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'I4 (AE)',
        data: {
          id: 'AE_I4',
        },
        capabilities: [
          "onoff"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'M1 (AE)',
        data: {
          id: 'AE_M1',
        },
      },

      {
        name: 'M2 (AE)',
        data: {
          id: 'AE_M2',
        },
      },

      {
        name: 'Q1 (AE)',
        data: {
          id: 'AE_Q1',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'Q2 (AE)',
        data: {
          id: 'AE_Q2',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'Q3 (AE)',
        data: {
          id: 'AE_Q3',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

      {
        name: 'Q4 (AE)',
        data: {
          id: 'AE_Q4',
        },
        capabilities: [
          "my-enum_no_on_off_capability"
        ],
        energy: {
          approximation: {
            usageConstant: 0, // in Watt
          },
        },
      },

    ];
  }
}

module.exports = MyDriver;

my_enum_no_on_off_capability.json

{
  "type": "boolean",
  "uiComponent": null,
  "uiQuickAction": true,
  "getable": true,
  "setable": false,
  "insights": false,
  "title": {
    "en": "ON / OFF",
    "nl": "ON / OFF",
    "de": "ON / OFF",
    "fr": "ON / OFF",
    "it": "ON / OFF",
    "sv": "ON / OFF",
    "no": "ON / OFF",
    "es": "ON / OFF",
    "da": "ON / OFF"
  }
}

App.ts

import sourceMapSupport from 'source-map-support';
sourceMapSupport.install();

import Homey from 'homey';
import { copyFileSync } from 'fs';

class MyApp extends Homey.App {
  
  /**
   * onInit is called when the app is initialized.
   */

  async onInit(): Promise<void> {
    this.log('App has been initialized');
    
    /** 
     * It is called when homey reboot.
    */
  }
}

module.exports = MyApp;

As I said before, you need to change ‘my_enum_capability’ to ‘my-enum_no_on_off_capability’
You are listening for the wrong capability at the moment.

Also, you say that the capability can’t be changed by the UI, but there is no where I can see that changes the capability via code. The method you use to change it will determine if the listener is fires. For example setCapabilityValue does not fire the listener.

1 Like

I just want to be able to filter with an if in the capability lissener what device it is that has been changed and to on or off.

Also corrected my mistake.

So that will work now you are listening for the correct capability, provide something changes the capability.

1 Like

Made this out of it but see if I turn on and off the right device I don’t see a line

class MyDevice extends Device {

  /**
   * onInit is called when the device is initialized.
   */

  async onInit() {
    this.log('AE - Auto Encoder has been initialized');

    this.registerCapabilityListener('onoff', async (value) => {
      this.log('AE - Auto Encoder has changed:', value);
      
    });

    this.registerCapabilityListener('my-enum_no_on_off_capability', async (value) => {
      this.log('Changes to :', value);

      let devData = this.getData();
      
      if (devData.id === 'AE_I1') {
        this.log('-------------------------');
      }
    });
  }

Just remember that registerCapabilityListener is meant to listen for changes made by the user via the UI or from code using triggerCapabilityListener.

So how are you turning on and off the device?

Again remember it will have to be a dives that registered the ‘my-enum_no_on_off_capability’.

1 Like

I have just spotted that ‘AE_I1’ registers the onoff capability. So you need to put the:

in the

section.

1 Like

I know but I have so much in my head within the driver.ts file, there are also devices that cannot be turned on or off, I apologize for this.

But I have another question, how do you actually make a device turn on or off through the app, it’s not easy, but you can see what I mean in the photo.

class MyDevice extends Device {

  /**

   * onInit is called when the device is initialized.

   */

  async onInit() {

    this.log('AE - Auto Encoder has been initialized');

    this.registerCapabilityListener('onoff', async (value) => {

      this.log('AE - Auto Encoder has changed:', value);

      

    });


    this.registerCapabilityListener('onoff', async (value) => {

      this.log('Changes to :', value);

      let devData = this.getData();

      

      if (devData.id === 'AE_I1') {

        this.log('-------------------------');

        // turn device on

      }

    });

  }

If you can help me with this I am really very far and then everything that needs to be solved is solved.

Thank you very much for your effort and time.