athombv / homey-apps-sdk-issues

This issue tracker is for Homey Developers using the Apps SDK.
21 stars 4 forks source link

capabilitiesObj is null on creation of a device #23

Closed daneedk closed 5 years ago

daneedk commented 5 years ago

(V2 rc9) The Heimdall code triggers on adding a device to Homey to see if the device qualifies to be used by Heimdall.

This code is run:

        api.devices.on('device.create', async(id) => {
            console.log('New device found!')
            const device = await api.devices.getDevice({id: id.id})
            console.log(device)
            await this.addDevice(device);
        });
addDevice(device) {
        if ( 'alarm_motion' in device.capabilitiesObj ) {
^line 163

full code here

and produces the following error:

(node:19597) UnhandledPromiseRejectionWarning: TypeError: Cannot use 'in' operator to search for 'alarm_motion' in null
    at Heimdall.addDevice (/app.js:163:29)
    at t.api.devices.on (/app.js:132:24)
    at <anonymous>

This is the device information from the console.log(device) capabilitiesObj is null here.

{
  __athom_api_type: 'HomeyAPI.ManagerDevices.Device',
  id: '0ab4751e-910a-4e45-be77-08008dd5cfc1',
  name: 'Multisensor 6',
  driverUri: 'homey:app:com.aeotec',
  driverId: 'ZW100',
  zone: '9919ee1e-ffbc-480b-bc4b-77fb047e9e68',
  iconObj: null,
  settings: 
   { zw_node_id: '6',
     zw_manufacturer_id: '134',
     zw_product_type_id: '2',
     zw_product_id: '100',
     zw_secure: '0',
     zw_battery: '0',
     zw_device_class_basic: 'BASIC_TYPE_ROUTING_SLAVE',
     zw_device_class_generic: 'GENERIC_TYPE_SENSOR_MULTILEVEL',
     zw_device_class_specific: 'SPECIFIC_TYPE_ROUTING_SENSOR_MULTILEVEL',
     zw_firmware_id: '',
     zw_wakeup_interval: 3600,
     zw_wakeup_enabled: false,
     zw_group_1: '1' },
  settingsObj: false,
  class: 'sensor',
  capabilities: 
   [ 'measure_battery',
     'alarm_motion',
     'alarm_tamper',
     'measure_temperature',
     'measure_luminance',
     'measure_humidity',
     'measure_ultraviolet' ],
  capabilitiesObj: null,
  flags: [ 'zwave' ],
  ui: { components: undefined },
  ready: null,
  available: null,
  repair: null,
  unpair: null,
  speechExamples: [],
  images: [],
  insights: [],
  color: null,
  data: undefined,
  icon: undefined,
  virtualClass: undefined,
  capabilitiesOptions: undefined,
  unavailableMessage: undefined }

I have not seen this behaviour before and not sure if it's related to https://github.com/athombv/homey-apps-sdk-issues/issues/19

robertklep commented 5 years ago

@nhassink and I are running into a similar issue using this code:

for (let capability of device.capabilities) {
  device.makeCapabilityListener(capability, ...);
}

For newly-created devices, it crashes on the call to device.makeCapabilityListener:

TypeError: Cannot read property 'onoff' of null
   at t.value (/node_modules/athom-api/dist/index.js:1:1060479)
   at Object.module.exports [as createSwitch] (/lib/devices/switch.js:57:11)
   at HomekitApp.addDevice (/app.js:165:42)
   at t.api.devices.on (/app.js:45:12)
   at <anonymous>
   at process._tickCallback (internal/process/next_tick.js:189:7)

In other parts of the app, it crashes because device.capabilitiesObj (which, I assume, is being used by makeCapabilityListener) is null.

WeeJeWel commented 5 years ago

It's by design that this object can be null in some scenarios. You should wait for a device.update event.

As for the crashing of athom-api, please report that issue here: https://github.com/athombv/homey-web-api-issues/issues

robertklep commented 5 years ago

Can you elaborate on "some scenarios"?

daneedk commented 5 years ago

Yeah, some documentation would be welcome....

daneedk commented 5 years ago

Also, I don't need to know when a device is updated, I need to know when a new device is created. I don't understand there is a message emitted when a new device is created but it isn't entirely created, you have to wait some more and then it will completely created. Why isn't the event emitted after the full, succesfull creation of a device. I'm no programmer, but that would make sense to me.

WeeJeWel commented 5 years ago

A device's lifecycle is actually quite complex and some properties online exist when the device is ready.

As for the documentation, the Web API is still experimental and unfinished.

daneedk commented 5 years ago

And how do I know if a device is ready? This:

        api.devices.on('device.ready', async(id) => {
            console.log("device is ready")
        });

doesn't trigger...

robertklep commented 5 years ago

I'm also interested to hear how to determine when (not so much if) a device is ready. Right now, we're using a workaround by waiting for the first device.update event from each device, but that feels like a hack.