# Developer Web API Playground - Notes of geeky oneliners

**URL:** <https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392>\
**Category:** Developers\
**Created:** [January 13, 2020, 9:08pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392 "2020-01-13T21:08:40Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dijker](https://avatars.discourse-cdn.com/v4/letter/d/b9bd4f/32.png) [@Dijker](https://community.homey.app/u/Dijker)\
**Post date:** [January 13, 2020, 9:08pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/1 "2020-01-13T21:08:40Z")

</div>

For the developers and geeks that want to investigate their Homey’s config.

Run from [Homey Developer Tools](https://developer.athom.com/tools/api-playground)

I write this to remember what I did but also to inspire others that I know are better JS developer that can do more magic. (and hope they share to inspire!)

WARNING: Be Careful! you can ruïne your config by deleting the wrong objects from there! Only use it if you know what you are doing !

```
// Get Trigger counts for Flows
Homey.flow.getFlows().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.triggerCount}), {}));

// Get broken flows
// Run and search for the result true
Homey.flow.getFlows().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.broken}), {}));

// Or Get broken flows
// Run and only the broken flows are returned ;-)
Homey.flow.getFlows().then(f => Object.values(f).reduce((r,b)=> Object.assign(r, b.broken ? {[b.name]:b.broken} : ''), {}) );

// Search for disabled flows: by Le_Cactus
Homey.flow.getFlows().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.enabled}), {}));

// Get All installed Apps with versions
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, 
{[b.name]:b.version}), {}));

// Get Available Updates for Apps in AppStore
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.updateAvailable}), {}));

// Get Devices Names and IDs for Towanda
Homey.devices.getDevices().then(f => Object.values(f).reduce((r,b)=>Object.assign(r,{[b.name]:b.id}), {}));

// List Zone names and parent
Homey.zones.getZones().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.parent}), {}));;

// Get list all Apps with Auto Update setting
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.autoupdate}), {}));

// Get list Auto Update list disabled
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, !b.autoupdate ? {[b.name]:b.autoupdate} : '' ), {}));

// Get list Auto Update list enabled
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, b.autoupdate ? {[b.name]:b.autoupdate} : '' ), {}));

// Disable Auto Update on All Apps
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, b.autoupdate ? Homey.apps.updateApp( { id : b.id , "app" : { "autoupdate" : false }} ) : {[b.name]:b.autoupdate}), {}));

// Disable All Apps
// Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, b.enabled ? Homey.apps.disableApp( { id : b.id} ) : {[b.name]:b.enabled}), {}));

// Enable All Apps
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, !b.enabled ? Homey.apps.enableApp( { id : b.id} ) : {[b.name]:b.enabled}), {}));

// Some ZigBee Queries Online devices:
// online receiveWhenIdle name modelId type 
Homey.zigBee.getState().then(f => Object.values(f.nodes).reduce((r,b)=> Object.assign(r, b.online ? {[b.name]:b.type} : ''), {}) );
// receiveWhenIdle => name 
Homey.zigBee.getState().then(f => Object.values(f.nodes).reduce((r,b)=> Object.assign(r, b.receiveWhenIdle ? {[b.name]:b.type} : ''), {}) );
// receiveWhenIdle => modelId
Homey.zigBee.getState().then(f => Object.values(f.nodes).reduce((r,b)=> Object.assign(r, b.receiveWhenIdle ? {[b.modelId]:b.type} : ''), {}) );
```

---

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 13, 2020, 9:48pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/2 "2020-01-13T21:48:08Z")

</div>

Cool, thanks for sharing! For the new apps example, is it possible to exclude the ones where there are no updates? (NULL)

Think this would be possible then to set up in Homeyscript to trigger eg. every day(?).

---

<div class="post-metadata">

**Author:** ![Le\_Cactus](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/le_cactus/32/9727_2.png) [@Le\_Cactus](https://community.homey.app/u/Le_Cactus)\
**Post date:** [January 14, 2020, 4:34pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/3 "2020-01-14T16:34:12Z")

</div>

Thanks, very usefull!

Used this one in search for disabled flows:

Homey.flow.getFlows().then(f =\> Object.values(f).reduce((r,b)=\>Object.assign(r, {[b.name]:b.enabled}), {}));

---

<div class="post-metadata">

**Author:** ![Morgan](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/morgan/32/15416_2.png) [@Morgan](https://community.homey.app/u/Morgan)\
**Post date:** [August 12, 2020, 8:43am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/4 "2020-08-12T08:43:26Z")

</div>

//Get SDK version of Apps - SDK v2 and higher needed for Homey firmware 5.x  
Homey.apps.getApps().then(f =\> Object.values(f).reduce((r,b)=\>Object.assign(r, {[b.name]:b.sdk}), {}));

---

<div class="post-metadata">

**Author:** ![Koktail](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/koktail/32/51498_2.png) [@Koktail](https://community.homey.app/u/Koktail)\
**Post date:** [March 12, 2021, 8:35am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/5 "2021-03-12T08:35:54Z")

</div>

Get all devices in json from a specific app:

```auto
var promise = 

Homey.devices.getDevices()
.then(f => {
   return Object.values(f).filter((device) => device.driverUri === 'homey:app:com.mi.flora');
  });

Promise.resolve(promise).then(devices => console.log(JSON.stringify(devices)));

```

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [March 12, 2021, 8:53am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/6 "2021-03-12T08:53:07Z")

</div>

> [@Koktail](#):
>
> `Promise.resolve(promise).then(…)`

This can be shortened to `promise.then(…)` 🙂

Or this:

```auto
Homey.devices.getDevices()
.then(f => {
   return Object.values(f).filter((device) => device.driverUri === 'homey:app:com.mi.flora');
})
.then(devices => console.log(JSON.stringify(devices)));

```

---

<div class="post-metadata">

**Author:** ![Peter\_Kawa](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/peter_kawa/32/173848_2.png) [@Peter\_Kawa](https://community.homey.app/u/Peter_Kawa)\
**Post date:** [March 28, 2021, 6:16pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/7 "2021-03-28T18:16:21Z")

</div>

Thanks! I was looking for this, but now I found it 😉

---

<div class="post-metadata">

**Author:** ![tb1962](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/tb1962/32/7888_2.png) [@tb1962](https://community.homey.app/u/tb1962)\
**Post date:** [May 23, 2021, 6:40am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/8 "2021-05-23T06:40:08Z")

</div>

I would like to add one of my favorites. It’s not a one liner but still useful.  
This script lists all unused flows along with its folder path.

**However be carefull if you want to use this script to remove all unused flows. Flows may be used from HomeyScript or set as favorite**. This script only list flows that has a ‘Start as flow’ trigger and for which it can’t find a flow with a flowcard to trigger.

```
'use strict';
const folders = await Homey.flow.getFlowFolders(); 
const flowsDic = await Homey.flow.getFlows();
const flows = Object.values(flowsDic)
const triggers = flows.map(f => f.actions.filter(a => a.uri === 'homey:manager:flow' && 
                                                      a.id === 'programmatic_trigger').map(a => a.args.flow)).flat()
function getFolder(id) {
  if (folders[id]) {
    if (folders[id].parent) {
      return `${getFolder(folders[id].parent)} > "${folders[id].name}"`
    }
    return `"${folders[id].name}"`
  }
  return '';
}
log(`Searching in ${flows.length} flows\n---------------------\n`)
flows.filter(f => f.trigger.uri === 'homey:manager:flow' && 
                  f.trigger.id === 'programmatic_trigger' &&  
                  !triggers.find(t => t.id === f.id)
            ).forEach(flow => log(`${getFolder(flow.folder)} > ${flow.name}`));
```

---

<div class="post-metadata">

**Author:** ![Peter\_Kawa](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/peter_kawa/32/173848_2.png) [@Peter\_Kawa](https://community.homey.app/u/Peter_Kawa)\
**Post date:** [October 17, 2021, 9:37pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/9 "2021-10-17T21:37:43Z")

</div>

Has anyone a hint how to get the device onoff history by cli?  
Preferrably of all onoff devices at once 😁

 ![Screenshot_20211016-174527_Homey](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/0/6/066ddacfaeadefbcecef66b9a14b338fba531ef7.jpeg)

---

<div class="post-metadata">

**Author:** ![Dijker](https://avatars.discourse-cdn.com/v4/letter/d/b9bd4f/32.png) [@Dijker](https://community.homey.app/u/Dijker)\
**Post date:** [October 15, 2022, 11:02am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/10 "2022-10-15T11:02:38Z")

</div>

Check if your Apps are SDK 2 and if they have Updates available

```auto
// Search and display app SDk version. 3 is OK, 2 is deprecated
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r,b.sdk == 2 ? {[b.name]:b.updateAvailable} : ''), {}));

// Some other simple one-liners
// Get All installed Apps with versions
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.version}), {}));

// Get Available Updates for Apps in AppStore
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, {[b.name]:b.updateAvailable}), {}));

// Get list Apps on SDK 2 list disabled
Homey.apps.getApps().then(f => Object.values(f).reduce((r,b)=>Object.assign(r, b.sdk === 2 ? {[b.name]:b.sdk} : '' ), {}));

```

---

<div class="post-metadata">

**Author:** ![torarnv](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/torarnv/32/83065_2.png) [@torarnv](https://community.homey.app/u/torarnv)\
**Post date:** [August 25, 2023, 11:40pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/11 "2023-08-25T23:40:17Z")

</div>

How are you guys using `await` in the Web API playground? I’m just getting `await is only valid in async functions and the top level bodies of modules`

---

<div class="post-metadata">

**Author:** ![RonnyW](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/ronnyw/32/10879_2.png) [@RonnyW](https://community.homey.app/u/RonnyW)\
**Post date:** [August 26, 2023, 6:05am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/12 "2023-08-26T06:05:01Z")

</div>

Sounds as if you are using arrow functions. Define as async, then you can use await inside.

myHandler( async () =\>{  
await … ();  
});

---

<div class="post-metadata">

**Author:** ![robertklep](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/robertklep/32/160628_2.png) [@robertklep](https://community.homey.app/u/robertklep)\
**Post date:** [August 26, 2023, 6:07am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/13 "2023-08-26T06:07:19Z")

</div>

Wrap your code with an IIFE:

```auto
void async function() {
  await ...;
}();

```

---

<div class="post-metadata">

**Author:** ![torarnv](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/torarnv/32/83065_2.png) [@torarnv](https://community.homey.app/u/torarnv)\
**Post date:** [August 26, 2023, 8:16am UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/14 "2023-08-26T08:16:39Z")

</div>

Awesome, that worked @robertklep !

```auto
void async function() {
  const devices = await Homey.devices.getDevices(); 
  for (const device of Object.values(devices)) {
    console.log(device.name);
  }
}();

```

---

<div class="post-metadata">

**Author:** ![mroek](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/mroek/32/38044_2.png) [@mroek](https://community.homey.app/u/mroek)\
**Post date:** [March 31, 2024, 12:35pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/15 "2024-03-31T12:35:23Z")

</div>

Getting both the version number _ **and** _ the channel (live or test) can be useful, so I modified the “Get all installed apps” query to include that as well:

`Homey.apps.getApps().then(f => Object.values(f).reduce((r, b) => {return Object.assign(r, {[b.name]: {version: b.version,channel: b.channel}});}, {}));`

---

<div class="post-metadata">

**Author:** ![Dijker](https://avatars.discourse-cdn.com/v4/letter/d/b9bd4f/32.png) [@Dijker](https://community.homey.app/u/Dijker)\
**Post date:** [April 29, 2024, 7:46pm UTC](https://community.homey.app/t/developer-web-api-playground-notes-of-geeky-oneliners/24392/16 "2024-04-29T19:46:01Z")

</div>

```auto
// Disable ALL (standard) Flows 
Homey.flow.getFlows().then(f => Object.values(f).reduce((r,b)=> Object.assign(r, b.enabled ? Homey.flow.updateFlow( { id : b.id , "flow" : { "enabled" : false }} ): {[b.name]:b.enabled} ), {}) );
// Disable ALL Advanced Flows 
Homey.flow.getAdvancedFlows().then(f => Object.values(f).reduce((r,b)=> Object.assign(r, b.enabled ? Homey.flow.updateAdvancedFlow( { id : b.id , "advancedflow" : { "enabled" : false }} ): {[b.name]:b.enabled} ), {}) );

```
