nikkow / node-red-contrib-tahoma

Node-RED module to control a Somfy Tahoma box (Roller shutters...). Used for home automation flows.
Apache License 2.0
19 stars 11 forks source link

session expired - daily #26

Open bakman2 opened 4 years ago

bakman2 commented 4 years ago

The session expires every day and renders the node unusable.

Is there no way to auth/refresh the token from within the node automatically ? I see that the tokens are actually stored in the global var environment, shouldnt they be exposed to the node only ? (node.context)

HubertusH commented 4 years ago

Same issue - bu i know that the api send a new refreshtoken that can use for refresh the tokens. If the node has a internal timer to call the api eg. every day so the tokens must not refreshed manually and the session don't expire.

bakman2 commented 4 years ago

@HubertusH I have switched to homebridge as that works reliably.

I think there is some issue with the stored tokens. The session expires when I restart NR of something like it or maybe a timing issue.

nikkow commented 4 years ago

Hi,

The access token has indeed a rather low TTL (1 hr). However, the refresh token should be valid for 14 days and is actually handled by the module.

I will try to reproduce this issue, but if you happen to have any logs that might help, feel free to add them to this ticket :)

Thanks.

bakman2 commented 4 years ago

@nikkow I am not sure how to reproduce it, will look into it.

Looking in the somfy-api code:

 .then(response => {
                        this.context().global.set('somfy_api_access_token', response.data.access_token);
                        this.context().global.set('somfy_api_refresh_token', response.data.refresh_token);

                        this.axiosInstance.defaults.headers.common['Authorization'] = `Bearer ${response.data.access_token}`;

                        error.hasRefreshedToken = true;
                        return Promise.reject(error);
                    })

This returns a reject with an error that token has refreshed, is that correct ?

nikkow commented 4 years ago

Yes, in order to fall into the retry policy of the original request:

https://github.com/nikkow/node-red-contrib-tahoma/blob/32ee6a5463fc8a9f144a742e9ca84dd14a935d88/src/core/somfy-api.ts#L83-L85

ralphhendriks commented 4 years ago

I am having this same issue. I programmed a flow to operate my shutter blinds twice a day, but consistently after 2-3 days the session expires.

B.t.w. I am running NR in a Docker container (on a RPi).

I am quite a novice NR user, and I am not very familiar yet with where I can find logging that could help us diagnosing this. What can I do to provide more context to pinpoint the issues?

Update 1 Inspecting the stdout/stderr logging of my NR container, I see quite a few occurrences of the following:

(node:16) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-ze
ro exit code.
(node:16) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'finished' of undefined
    at /data/node_modules/node-red-contrib-tahoma/dist/nodes/tahoma.js:105:42
    at process._tickCallback (internal/process/next_tick.js:68:7)

Update 2

I see that the following warning is also logged when the container is started:

---------------------------------------------------------------------
Your flow credentials file is encrypted using a system-generated key.

If the system-generated key is lost for any reason, your credentials
file will not be recoverable, you will have to delete it and re-enter
your credentials.

You should set your own key using the 'credentialSecret' option in
your settings file. Node-RED will then re-encrypt your credentials
file using your chosen key the next time you deploy a change.
---------------------------------------------------------------------

I don't know if the keys are somehow stored in the credentials file (flows_cred.json). If so, maybe this warning explains that existing credentials are not readable when the Docker container is replaced by a new one (e.g. on an update).

LorenzKahl commented 4 years ago

Same problem here. Let me know if I can help and provide any details. Like @bakman2 already noted: The problem also occurs for some reason, when Node-RED is restarted.

EdClaus commented 4 years ago

Almost same problem here, just for information. Almost because I use 3 groups of 10 nodes for external screens, all used with the same config and in the same tab. However 2 groups (writing to) work for days now without any issues and one group (reading from) has the session_expired issue. And in that group sometimes they work as should and sometime they don't. Attached image is from time 12:15. Remarkable is that in a development setup this same exact situation occurs. session_expired_2020-06-30-12-15

EdClaus commented 4 years ago

An extra remark on my previous comment, just for info: after an afternoon working on other nodes in node-red suddenly all tahoma nodes gave session_expired. After a full reboot of my raspberryPi all nodes were functioning again, without any help, also the read nodes.

HubertusH commented 4 years ago

i build for me a workaround - it's not the solution! befor every call to the somfy api i check the access- and refresh_token - made a backup or a restore. the function:

var access_token = global.get('somfy_api_access_token');
var refresh_token = global.get('somfy_api_refresh_token');

var access_token_sic = global.get('somfy_api_access_token_sic');
var refresh_token_sic = global.get('somfy_api_refresh_token_sic');

// ist der Access Token leer?
if ((access_token ==="") || (access_token === undefined) || (access_token === null))
{
    access_token = access_token_sic;
    global.set('somfy_api_access_token',access_token);
}else{
    access_token_sic = access_token;
    global.set('somfy_api_access_token_sic',access_token_sic);
}

// ist der Refresh Token leer?
if ((refresh_token ==="") || (refresh_token === undefined) || (refresh_token === null))
{
    refresh_token = refresh_token_sic;
    global.set('somfy_api_refresh_token',refresh_token);
}else{
    refresh_token_sic = refresh_token;
    global.set('somfy_api_refresh_token_sic',refresh_token_sic);
}

return msg;

that prevents empty tokens after restart node-red or the flows. in my case this works nearly 100%

BR Hubertus

nikkow commented 4 years ago

Hi,

I refactored the session handling on 2.0.3. You should no longer encounter daily session expiration. However, please note that if the refresh token issued by Somfy expires, it won't be possible to automatically refresh the session. This might happen after a long period of inactivity (~14d, yet to be confirmed - this is not documented on Somfy's developer docs).

@HubertusH the new session handling does not rely on context anymore. You might want to ensure that it has no side-impacts based on your setup.

Thanks.

ljpaff commented 4 years ago

Hi All,

with version 2.0.3 I have received an email from somfy that says this:

Dear customer,

In an ongoing effort to provide the best services to our users, we monitor the traffic generated by our applications and Smart Home boxes (TaHoma and Connexoon). It appears that you are using a third-party solution, either developed by yourself or provided by an external entity (developer or community of developers not working for Somfy). Such developments are made without our willingness and, sometimes, do not respect our usage guidelines.

We are contacting you today to update the way your script or your application behaves with our API as it is overconsuming our backend resources for your own installation. To do so, please contact the provider of your solution or update your code by October 31st.

We are asking all third-party scripts or application to reduce their polling activity on our API. In particular, the GET /setup endpoint is meant to be used once and only once by end-user session and not to regularly refresh the devices data.

As we do not want every TaHoma and Connexoon users be impacted by the overuse of some individuals, we will react in the coming months and set up rate limiters and automated bans if such changes are not applied.

Thank you for your understanding.

marekhalmo commented 3 years ago

Hello everyone.. just a notion.. I get the toke expired only if i do modifications to the flows.. is this your case as well? If i don't do any mods i get the +- 14 days expiration.

Anyway.. i would love to have the option to enter the credentials to the node and let the node handle the re-authorization of token automatically. If the app can do this, i'm pretty sure that this plugin can as well.. :)