Getting the device by its id takes a long time

Hi Robert,

I’ve tested it both in AF and in real life clicking my on/off wireless switch. Testing it right now and each switch-click takes about one second to execute, even if I click e.g multiple times trying to speed up the dimming.

I have timed the other elements in my code and they execute more or less immediately.

If you’re sure the issue is with await Homey.devices.getDevice(), have you tried removing the $skipCache property entirely? So:

const plafond11 = await Homey.devices.getDevice({id: '755de4f1-cc89-4b02-b845-636b9b06d052'});

Yes, I have. That is how I started until I found that there was a cache option hoping that to be my solution.

I have even tried to store the return value in a global variable and use that instead, but this didn’t work either since the return value is converted into a text object.

If I could perform that entire block as an async and then await its completion it might become fast enough, but this is outside of my knowledge in homey scripting.

You (somewhat) can:

const plafonds = await Promise.all([
  Homey.devices.getDevice({$skipCache: false, id: '755de4f1-cc89-4b02-b845-636b9b06d052'}),
  Homey.devices.getDevice({$skipCache: false, id: '07b91ff5-17ee-4772-b76a-ddebcdc515d2'}),
  Homey.devices.getDevice({$skipCache: false, id: '3c541407-073e-49ce-91f1-923b4b36ed84'}),
])
1 Like

Tnx Robert!

That was enough to shorten the time to a resonable latency. It would have been nice to avoid it at all though :innocent:.

Btw, how do you tell the forum editor to format the code the way you do it?

You use the </> button on the toolbar for preformatted text. So paste in the text, select it and then click on the </> button.

1 Like

Tnx Adrian!

I thought that I already tried that option. Obviously I did something in error :blush:

1 Like

In case someone finds this topic and is interested. Here is my current full (test)code that now works quite well. It is triggered by a ā€˜on button was pressed’.

// Plafond Steps - DIM
// Dim (ikea)lights in 5 steps based on their ID's and global variable 'plafondDim'.
// Choose a plafondDim value between 5 and 100 to turn the lights on and 0 to turn them off.

// Specify the device ID for the specific lamps in the plafond. I wish that we could look up the ID's in the device advanced section.....

console.log("starting getdevice()")
const plafond = await Promise.all([
    Homey.devices.getDevice({$skipCache: false, id: '755de4f1-cc89-4b02-b845-636b9b06d052'}),
    Homey.devices.getDevice({$skipCache: false, id: '07b91ff5-17ee-4772-b76a-ddebcdc515d2'}),
    Homey.devices.getDevice({$skipCache: false, id: '3c541407-073e-49ce-91f1-923b4b36ed84'}),
]);
console.log("ended getdevice()");

const plafondDim = global.get('plafondDim');

if (plafondDim > 20)
{
    global.set('plafondDim', plafondDim - 20);
} else {
    global.set('plafondDim', 100);
}

// TODO: replace with a loop
plafond[0].setCapabilityValue('dim', plafondDim/100);
plafond[1].setCapabilityValue('dim', plafondDim/100);
plafond[2].setCapabilityValue('dim', plafondDim/100);

return plafondDim;
1 Like

Just an example of how you can use the device name instead of its ID

/*
 * In this script we turn a light on.
 */

// User input 
var myLight = "Plafond1"; /* enter the exact device name */
// User input end

// Get all devices
const devices = await Homey.devices.getDevices();

  // Loop over all devices
  for (const device of Object.values(devices)) {
  if (device.name == myLight) {
 
    // If this device is a light (class)
    // Or this is a 'What's plugged in?'-light (virtualClass)
    if (device.class === 'light' || device.virtualClass === 'light' || device.class == 'button') {
    log(`\nTurning '${device.name}' on...`);

    // Turn the light on by setting the capability `onoff` to `true`
    await device.setCapabilityValue('onoff', true)
      .then(() => log('OK'))
      .catch(error => log(`Error:`, error));
    }
  }
}
return(true);
1 Like

just in addtion cause I don’t see the buildin filter too often and hope it is permanently optimized in comparison to fetch all devices and loop through.

const devices = await Homey.devices.getDevices({ filter: {name: 'Droide'} });
Object.values(devices).forEach(device => {
log(device.name + ':', device.id)
});
1 Like

Hi Peter,

For single occasional runs this should probably be nice. However, my concern is that you need to fetch all of the registered/connected devices and then filter out the ones you want to perform an operation on each time you run the script.

As I mentioned in my first post those three device fetches took between 1-2 seconds to complete and for a script that reacts on multiple button presses this was therefor not working well.

I will try and see how long getdevices() takes using your suggested way though. Maybe it does some magic in the background that might not take as long to complete…?

Hi Joka,

Interesting. I’ll try this out as well and time it the next time I can sit down and experiment with my lights.

I was told by my family that they didn’t like it when the lights start to erratically flash for 15 minutes before finding the bug. I was also able at times to hang the script engine so the homey essentially stopped working. So I better do script tests when I’m home alone :innocent:.

I like performace tests:

Bulid a view setup flows:

const device_name = (typeof args[0] === 'string')
? args[0]
: 'dummy';

let device_id
const devices = await Homey.devices.getDevices({ filter: {name: device_name} });
_.forEach(devices, device => {
log(device.name + ':', device.id)
device_id = device.id
});

return device_id

Be carefull, you should start the flow from your mobile to get a real life stop time.

Play with the filter, in my test I found out that the filter is 8-10 times faster in compression to collect all devices and loop through. Depends on the amount of devices of course.

It takes 0.09 sec to identify the id by name of the device.

2 Likes

Wow, that makes a huge difference, it’s around 1sec faster than looping over all devices. (I have 281 devices).
Thanks for digging into this.

// run 1
TurnLightOn start 2022-07-09T12:59:25.988Zs
TurnLightOn_FilterDevices runtime: 2022-07-09T12:59:26.517Zs
471ms
TurnLightOn_LoopOverDevices runtime: 2022-07-09T12:59:27.219Zs
1769ms

// run 2
TurnLightOn start 2022-07-09T13:12:29.312Zs
TurnLightOn_FilterDevices runtime: 2022-07-09T13:12:29.929Zs
617ms
TurnLightOn_LoopOverDevices runtime:2022-07-09T13:12:30.813Zs
1501ms

Screenshot from 2022-07-09 15-31-25

Oh, and, you can start a flow like this too:

Screenshot from 2022-07-09 12-40-21

1 Like

It might be that we’re talking about this issue to further our understanding of HomeyScript, for which I absolutely support that. However, if we’re concretely discussing how to relatively dim some lights based on input, it feels better to just use flow cards?

1 Like

Hi Articate,

In normal cases your card would probably be fine. Since this is about two plafonds with three lamps each my dimming ā€˜algorithm’ needs to do more than a simple fixed value dimming. The 20% I used was more of a testing value and not evident in my test code above.

Good call though.

So you’re going to scale a max dim for each individual plafond or something? Like, that some plafond can go to 100%, but others only to 70%? and then if you dim 20% from 100% that’s 80%, but 20% from 70% would be 56% instead of 50%, is that what you want to achieve?

I need to experiment a bit to see where I will land with how the dimming algorithm will work in the end.

Since each plafond has 3 ikea lamps there is lots of room for how to execute the dimming. In my last dimming step only one of the 3 lamps is lit 5% (ikea lamps turns off lower than that) and that is a perfect level for movie nights or similar where only a guide light is necessary. On the other hand the 3 lamps in the plafond at 100% each serves its purpose as well. Everything between those levels and number of lamps will take some time to figure out since I only want to deal with no more than 4-6 levels to work with.

I have two of these plafonds in my living room but only one is ā€˜smart’ at the moment and since they each cover half of the room I want to come up with something smart in the end. I’m also considering replacing one of the lamps with its rgbw version to get a bit more variety at night. Time will tell…

Hi @Joka
I just thought of the fact the Papertrails app, can log time in ms;
so no stopwatch or timestamp-script-cards are needed for measuring flowcards or scripts :upside_down_face:

.
log:

2022-07-14 16:04.43.430		TurnLightOn start (script-monitor)
2022-07-14 16:04.43.937		TurnLightOn_FilterDevices - runtime (script-monitor )
2022-07-14 16:04.45.053		TurnLightOn_LoopOverDevices - runtime  (script-monitor )

That’s true but especially for this case I like to get a notification directly with the calculated runtime.

1 Like