Question regarding setInterval

Good evening

I’m having issues with understanding the usage of setInterval. (and just to be sure, I’m a complete Nodejs newbie)
I have created a driver that is polling data from an api so this is my device.js file

    async onInit() {
        this.log('MyDevice has been initialized');

        if (this.hasCapability('measure_outside_temperature') === false) {
            // You need to check if migration is needed
            // do not call addCapability on every init!
            await this.addCapability('measure_outside_temperature');
        }
   
        const settings = this.getSettings();
        let username = this.homey.settings.get('username');
        let password = this.homey.settings.get('password');
        this.wemApi = new WemApi(username, password);
        await this.wemApi.initializeSession();
        let temperature = await this.wemApi.getIndoorTemperature(this.getData().id)
        this.setCapabilityValue('measure_temperature', temperature.NumericValue).catch(this.error);
        let outsideTemperature = await this.wemApi.getOutsideTemperature(this.getData().id)
        this.setCapabilityValue('measure_outside_temperature', outsideTemperature.NumericValue).catch(this.error);
    }

I’ve already tried replacing this with

    async onInit() {
        this.log('MyDevice has been initialized');

        if (this.hasCapability('measure_outside_temperature') === false) {
            // You need to check if migration is needed
            // do not call addCapability on every init!
            await this.addCapability('measure_outside_temperature');
        }
        this.homey.setInterval(async () => {
            await this.getData();
        }, 60000);
}
async getData() {
        try {
            const settings = this.getSettings();
            let username = this.homey.settings.get('username');
            let password = this.homey.settings.get('password');
            this.wemApi = new WemApi(username, password);
            await this.wemApi.initializeSession();
            let temperature = await this.wemApi.getIndoorTemperature(this.getData().id)
            this.setCapabilityValue('measure_temperature', temperature.NumericValue).catch(this.error);
            let outsideTemperature = await this.wemApi.getOutsideTemperature(this.getData().id)
            this.setCapabilityValue('measure_outside_temperature', outsideTemperature.NumericValue).catch(this.error);
            // this.setUnavailable();
        } catch {

        }
    }

But at this point I’m noticing that getData() is triggered almost constantly.

A second question is where the setInterval is put in the most ideal place?
Should I put it in the app.js file or can it be put in the driver itself?

That’s because you named your method to match an existing SDK method, and now you’re calling your own method recursively:

let temperature = await this.wemApi.getIndoorTemperature(this.getData().id)

You’re now logging in every 60 seconds. If sessions can live longer, log in and create a session in app.js and use that from your device (not driver) implementations:

// app.js
onInit() {
  let username = this.homey.settings.get('username');
  let password = this.homey.settings.get('password');
  this.wemApi = new WemApi(username, password);
  await this.wemApi.initializeSession();
}

// device.js
let temperature = await this.homey.app.wemApi.getIndoorTemperature(this.getData().id)

Hi Robert

Thanks for the info, one last issue I have is that the info is not getting updated in the app.
I tried using setSettings call but the values did not get updated.

I do see the new values in the console tho.

Thanks

What info?

I’m querying an api to get the latest reading from a thermostat, but the latest readings do not appear in the app. When I check the readings, it say that it was updated 4 hours ago (even if the data is queried every minute)
image

For now this is the current code I have

    async onInit() {
        this.log('MyDevice has been initialized');

        if (this.hasCapability('measure_temperature.outside') === false) {
            // You need to check if migration is needed
            // do not call addCapability on every init!
            await this.addCapability('measure_temperature.outside');
        }
        this.homey.setInterval(async () => {
            await this.getProductionData();
        }, 60000);
        let username = this.homey.settings.get('username');
        let password = this.homey.settings.get('password');
        this.wemApi = new WemApi(username, password);
        await this.wemApi.initializeSession();
    }

    async getProductionData() {
        try {
            let temperature = await this.wemApi.getIndoorTemperature(this.getData().id)
            this.setCapabilityValue('measure_temperature', temperature.NumericValue).catch(this.error);
            let outsideTemperature = await this.wemApi.getOutsideTemperature(this.getData().id)
            this.setCapabilityValue('measure_temperature.outside', outsideTemperature.NumericValue).catch(this.error);
        } catch {

        }
    }

Are you sure you’re getting updated values from the API? Also, empty catch statements will swallow all errors, so at least put a this.log() or this.error() inside them to provide feedback:

try {
  …
} catch(e) {
  this.log(e);
}

The session was created to late and that is why the data was not shown.
Thanks for hinting the catch part!

Hi Robert

I did some changes and released my first version but for some reason the temperatures are not being updated when it is installed (and not run into production).
When the app starts, there are initial values, but afterwards no new updates appear.

When running in development, the api is showing the values in the console Homey-Wemportal/device.js at main · reyntjensw/Homey-Wemportal · GitHub

There must still be something I’m doing wrong.
Do you know what?

Thanks

No idea why it’s not working, the code looks good (especially if the correct values are also being shown in console). Does the issue with the values not updating happen on all platforms (mobile, web)? Do they also not update when you stop and restart the app (or force-reload the web app)?

Just checked, no updates are coming in when the app is restarted.
Is there a way to write some logs to Homey so I can do some debugging when it is installed?

Nope. You can start a V8 inspector in your app by adding this to onInit in your app:

require('inspector').open(9229, '0.0.0.0');

Then connect to it from a Chrome browser by navigating to chrome://inspect

That allows you to the debug code (set breakpoints, inspect the stack, etc).

I’ve added the inspector to the code, but in the background the routines are still running and returning the correct values.
It looks like the values are just not being updated in the interface, but I have no clue why it is not working.

I assume that other apps are showing their updated values in the interface?

They are indeed updating as it should.
I also did a PTP on the Homey but that did not resolve the issue

Perhaps ask around on the #developers channel of the Homey Community Slack.

I think I found the issue, when adding a await in front of the this.setCapabilityValue this issue got resolved.

That sounds like setCapabilityValue() has an implementation issue… :thinking: It shouldn’t really matter if you wait for the promise to complete or not.

But glad to read you solved your problems :smiley: