QuickSander / homebridge-mieleathome

Apache License 2.0
37 stars 7 forks source link

"refresh token" seems to succeed, but subsequent API calls fail with "Unauthorized" #7

Closed MichelRabozee closed 3 years ago

MichelRabozee commented 3 years ago

Hello Sander,

I know that you are working on the refresh token system, so maybe this is normal at this time: after a few hours (1h10 here) of the token use, a "refresh token" occurs and seems to succeed, but subsequent API calls fail with "Unauthorized":

[25/01/2021 22:27:10] [Miele] Refreshing token...
[25/01/2021 22:27:10] [Miele] Token succesfully refreshed and saved in persistent storage.
[25/01/2021 22:27:16] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/000116035470/state failed with status 401: "Unauthorized".
[25/01/2021 22:27:16] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/mac-001D63FFFE0203B4/state failed with status 401: "Unauthorized".
[25/01/2021 22:28:16] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/000116035470/state failed with status 401: "Unauthorized".
[25/01/2021 22:28:16] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/mac-001D63FFFE0203B4/state failed with status 401: "Unauthorized".

However, just restarting the homebridge instance makes the API calls succeed without manually reentering new tokens (hence, I do not know if the plugin uses te initially manually provided ones or the "refreshed" ones):

[25/01/2021 23:40:23] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/000116035470/state failed with status 401: "Unauthorized".
[25/01/2021 23:41:23] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/000116035470/state failed with status 401: "Unauthorized".
[25/01/2021 23:41:23] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/mac-001D63FFFE0203B4/state failed with status 401: "Unauthorized".
[25/01/2021 23:42:23] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/000116035470/state failed with status 401: "Unauthorized".
[25/01/2021 23:42:23] [Miele] Miele API request https://api.mcs3.miele.com/v1/devices/mac-001D63FFFE0203B4/state failed with status 401: "Unauthorized".
[25/01/2021 23:42:33] [Homebridge UI] Homebridge restart request received
[25/01/2021 23:42:33] [Homebridge UI] UI / Bridge settings have not changed; only restarting Homebridge process
[25/01/2021 23:42:33] [HB Supervisor] Sending SIGTERM to Homebridge
[25/01/2021 23:42:33] Got SIGTERM, shutting down Homebridge...
[25/01/2021 23:42:38] [HB Supervisor] Homebridge Process Ended. Code: 143, Signal: null
[25/01/2021 23:42:43] [HB Supervisor] Restarting Homebridge...
[25/01/2021 23:42:43] [HB Supervisor] Starting Homebridge with extra flags: -I
[25/01/2021 23:42:43] [HB Supervisor] Starting Homebridge with custom env: {"NODE_OPTIONS":"--trace-warnings"}
[25/01/2021 23:42:43] [HB Supervisor] Started Homebridge v1.2.5 with PID: 74383
[25/01/2021 23:42:43] Loaded config.json with 0 accessories and 2 platforms.
[25/01/2021 23:42:43] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-camera-ffmpeg@3.0.3
[25/01/2021 23:42:44] Registering platform 'homebridge-camera-ffmpeg.Camera-ffmpeg'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-config-ui-x@4.36.0
[25/01/2021 23:42:44] Registering platform 'homebridge-config-ui-x.config'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-contactnotifier@0.0.6
[25/01/2021 23:42:44] Registering accessory 'homebridge-contactnotifier.ContactNotifier'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-daikin-local@2021.4.1
[25/01/2021 23:42:44] Registering accessory 'homebridge-daikin-local.Daikin-Local'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-http-switch@0.5.34
[25/01/2021 23:42:44] Registering accessory 'homebridge-http-switch.HTTP-SWITCH'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-mieleathome@2.0.1
[25/01/2021 23:42:44] Registering platform 'homebridge-mieleathome.Miele@home'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-outsidetemperature@0.0.2
[25/01/2021 23:42:44] Registering accessory 'homebridge-outsidetemperature.OutsideTemperature'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-platform-wemo@2.9.1
[25/01/2021 23:42:44] Registering platform 'homebridge-platform-wemo.BelkinWeMo'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-roomba2@1.2.0
[25/01/2021 23:42:44] Registering accessory 'homebridge-roomba2.Roomba2'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-script2@0.3.0
[25/01/2021 23:42:44] Registering accessory 'homebridge-script2.Script2'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:44] Loaded plugin: homebridge-sonytvremote@10.1.3
[25/01/2021 23:42:44] Registering accessory 'homebridge-sonytvremote.SonyTV'
[25/01/2021 23:42:44] ---
[25/01/2021 23:42:45] Loaded plugin: homebridge-videodoorbell@0.2.9
[25/01/2021 23:42:45] Registering platform 'homebridge-videodoorbell.Video-doorbell'
[25/01/2021 23:42:45] ---
[25/01/2021 23:42:45] Loaded plugin: homebridge-watervolume@0.0.2
[25/01/2021 23:42:45] Registering accessory 'homebridge-watervolume.WaterVolume'
[25/01/2021 23:42:45] ---
[25/01/2021 23:42:45] Loading 2 platforms...
[25/01/2021 23:42:45] [Corniche Homebridge-Three Config] Initializing config platform...
[25/01/2021 23:42:45] [Corniche Homebridge-Three Config] Running in Service Mode
[25/01/2021 23:42:45] [Miele] Initializing Miele@home platform...
[25/01/2021 23:42:45] [Miele] Loading accessory data from cache: Lave-vaisselle
[25/01/2021 23:42:45] [Miele] Loading accessory data from cache: Lave-linge
Setup Payload:
X-HM://0024AOUT1H5JD
Enter this code with your HomeKit app on your iOS device to pair with Homebridge:

    ┌────────────┐     
    │ 499-82-453 │     
    └────────────┘     

[25/01/2021 23:42:45] Homebridge v1.2.5 is running on port 51809.
[25/01/2021 23:42:45] [Miele] Discovered device: id: mac-001D63FFFE0203B2, name: Four, model: 
[25/01/2021 23:42:45] [Miele] Ignoring unsupported device. Device: "Four" with raw type value: 12.
[25/01/2021 23:42:45] [Miele] Discovered device: id: 000127334912, name: Taque, model: 
[25/01/2021 23:42:45] [Miele] Ignoring unsupported device. Device: "Taque" with raw type value: 14.
[25/01/2021 23:42:45] [Miele] Discovered device: id: mac-001D63FFFE0203B4, name: Lave-vaisselle, model: 
[25/01/2021 23:42:45] [Miele] Re-creating existing accessory with data from cache: Lave-vaisselle
[25/01/2021 23:42:45] [Miele] Discovered device: id: 000116035470, name: Lave-linge, model: 
[25/01/2021 23:42:45] [Miele] Re-creating existing accessory with data from cache: Lave-linge
[25/01/2021 23:42:45] [Miele] Discovered device: id: mac-00124B0005AB4D8B, name: Frigo, model: 
[25/01/2021 23:42:45] [Miele] Ignoring unsupported device. Device: "Frigo" with raw type value: 19.
QuickSander commented 3 years ago

I believe I tested this, apparently not. ☹️

I see I store the token in memory during construction of the HTTP get request which leaves the old token in memory.

MichelRabozee commented 3 years ago

No worries, this plugin becomes really efficient and useful, keep up the good work, with no rush !

QuickSander commented 3 years ago

Your current token should be valid for 29 more days assuming it refreshed yesterday.

QuickSander commented 3 years ago

:tada: This issue has been resolved in version 2.1.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

crissmil commented 3 years ago

Hello Sander,

Just like Michel, I worked at first attempt after installation but it doesn't any more: "[Miele@home] Miele API request https://api.mcs3.miele.com/v1/devices?language=en failed with status 401:"Unauthorized"."

updated to v 2.1.1

I made several attempts with new tokens in config file w/out success.

Any idea what I should do?

MichelRabozee commented 3 years ago

Hi, did you restart the homebridge instance itself ?

crissmil commented 3 years ago

Yes, I restarted homebridge because I was getting error code 500 from getService state of devices. After that it is keeps getting "Unauthorized"

crissmil commented 3 years ago

Now I installed back my previous plugin "miele-hood" @talsalis and it is working using the same token... but it doesn't have auto token refresh option. I tried many times to generate new access tokens and refresh tokens in terminal but no luck. Are they anywhere stored the old tokens and cannot get rid of them?

QuickSander commented 3 years ago

The token in your config.json, if that token works in the miele-hood plugin, you can put that one also in this plugin without mentioning clientId or clientSecret or refreshToken.

Then browse to your ~/.homebridge/persist directory and remove the Miele@home.Token.json file.

This should make the plugin function exactly like ventilation hood. If not it could be I broke something in the ventilation hood part as I cannot test that since I have no ventilation hood. Please check if this is working for you, if so we can make the refresh working.

The fact that you retried several times and still fail is because the plugin will always use the version from disk if there is one on disk. Do you maybe have a log of the failure to refresh (preferably with debug enabled for Homebridge)

crissmil commented 3 years ago

I dont'have a ~/.homebridge directory. I am using UI plugin on Raspberrypi. Can u pls tell me where can I find the persist folder?

QuickSander commented 3 years ago

Log in to your raspberry pi using ssh. Then: cd ~/.homebridge/persist rm Miele@home.*

Or login via Config-UI-X: Select "Terminal" from the 3-dots menu and do the same.

crissmil commented 3 years ago

pi@raspberrypi:~ $ cd ~/.homebridge/persist bash: cd: /home/pi/.homebridge/persist: No such file or directory

QuickSander commented 3 years ago

Could yo check the path displayed in config-UI-X on the bottom left? There it states your "storage path"

crissmil commented 3 years ago

found it! /var/lib/homebridge/persist deleted Miele@home.token restarting homebridge now...

crissmil commented 3 years ago

It is working.

[Miele@home] Discovered devices: [ '000160710124', '000703279459' ] [1/27/2021, 11:15:27 PM] [Miele@home] Discovered device: id: 000160710124, name: Steam&Microwave Oven, model: DGM7440 [1/27/2021, 11:15:27 PM] [Miele@home] Ignoring unsupported device. Device: "Steam&Microwave Oven" with raw type value: 45. [1/27/2021, 11:15:27 PM] [Miele@home] Discovered device: id: 000703279459, name: Coffee machine, model: CVA7440 [1/27/2021, 11:15:27 PM] [Miele@home] Ignoring unsupported device. Device: "Coffee machine" with raw type value: 17.

I am trying to use it for 2 miele devices: esspresso and oven. Just power on/off for the moment. I managed to modify "miele-hood" @talsalis for this purpose and now I am trying same thing here...

QuickSander commented 3 years ago

If you have the clientID and secret and refresh token correctly filled it should refresh correctly. Especially since 2.1.0 after 1h. From then on, it will try to / should use the new refreshed token. (At least for my config it worked)

crissmil commented 3 years ago

Thanks. I will check and revert in 1 hr

crissmil commented 3 years ago

I am getting again error 500 when trying to getStatus(callback):

[1/27/2021, 11:41:29 PM] [Miele@home] Status Body -> {"code":500,"message":"GENERIC_TECHNICAL_ERROR (Error-ID: a99cdfd8e8b005b6)"} [1/27/2021, 11:41:30 PM] TypeError: Cannot read property 'value_raw' of undefined at Request._callback (/usr/lib/node_modules/homebridge-mieleathome/src/mieleHoodPlatformAccessory.ts:130:21) at Request.self.callback (/usr/lib/node_modules/homebridge-mieleathome/node_modules/request/request.js:185:22) at Request.emit (events.js:315:20) at Request. (/usr/lib/node_modules/homebridge-mieleathome/node_modules/request/request.js:1154:10) at Request.emit (events.js:315:20) at IncomingMessage. (/usr/lib/node_modules/homebridge-mieleathome/node_modules/request/request.js:1076:12) at Object.onceWrapper (events.js:421:28) at IncomingMessage.emit (events.js:327:22) at endReadableNT (internal/streams/readable.js:1327:12) at processTicksAndRejections (internal/process/task_queues.js:80:21) [1/27/2021, 11:41:30 PM] Got SIGTERM, shutting down Homebridge... [1/27/2021, 11:41:35 PM] [HB Supervisor] Homebridge Process Ended. Code: 143, Signal: null [1/27/2021, 11:41:40 PM] [HB Supervisor] Restarting Homebridge...

Same call is working fine on "miele-hood" @talsalis... I don't know what am I missing...

QuickSander commented 3 years ago

My first hunch is that the refresh token is not belonging to the token you have entered. On the other hand, I would expect unauthorised then instead.

crissmil commented 3 years ago

I found it. in mieleHoodPlatformAccessory.js: this.url = settings_1.DEVICES_INFO_URL + '/' + accessory.context.device.modelNumber;

should be replaced by: this.url = settings_1.DEVICES_INFO_URL + '/' + accessory.context.device.uniqueId;

QuickSander commented 3 years ago

I'll push a new version with this fix. Thanks!

Exi1986 commented 3 years ago

Hello, i don´t know if its here correct; after i installed the new Version i got this.

My Token ist from Thuersday last week.

Error: connect ETIMEDOUT 137.117.150.39:443 at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) { errno: -110, code: 'ETIMEDOUT', syscall: 'connect', address: '137.117.150.39', port: 443, config: { url: 'https://api.mcs3.miele.com/v1/devices?language=de', method: 'get', headers: { Accept: 'application/json, text/plain, /', Authorization: 'Bearer DE_788e01442801d30d0edc77ea0ad848ec', 'Content-Type': 'application/json', 'User-Agent': 'axios/0.21.1' }, transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 0, adapter: [Function: httpAdapter], xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, validateStatus: [Function: validateStatus], data: undefined }, request: <ref 1> Writable { _writableState: WritableState { objectMode: false, highWaterMark: 16384, finalCalled: false, needDrain: false, ending: false, ended: false, finished: false, destroyed: false, decodeStrings: true, defaultEncoding: 'utf8', length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, onwrite: [Function: bound onwrite], writecb: null, writelen: 0, afterWriteTickInfo: null, buffered: [], bufferedIndex: 0, allBuffers: true, allNoop: true, pendingcb: 0, prefinished: false, errorEmitted: false, emitClose: true, autoDestroy: true, errored: null, closed: false }, _events: [Object: null prototype] { response: [Function: handleResponse], error: [Function: handleRequestError] }, _eventsCount: 2, _maxListeners: undefined, _options: { maxRedirects: 21, maxBodyLength: 10485760, protocol: 'https:', path: '/v1/devices?language=de', method: 'GET', headers: [Object], agent: undefined, agents: [Object], auth: undefined, hostname: 'api.mcs3.miele.com', port: null, nativeProtocols: [Object], pathname: '/v1/devices', search: '?language=de' }, _ended: true, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 0, _requestBodyBuffers: [], _onNativeResponse: [Function (anonymous)], _currentRequest: ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: false, _last: true, chunkedEncoding: false, shouldKeepAlive: false, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, socket: [TLSSocket], _header: 'GET /v1/devices?language=de HTTP/1.1\r\n' + 'Accept: application/json, text/plain, /\r\n' + 'Authorization: Bearer DE_788e01442801d30d0edc77ea0ad848ec\r\n' + 'Content-Type: application/json\r\n' + 'User-Agent: axios/0.21.1\r\n' + 'Host: api.mcs3.miele.com\r\n' + 'Connection: close\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: noopPendingOutput], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, path: '/v1/devices?language=de', _ended: false, res: null, aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: 'api.mcs3.miele.com', protocol: 'https:', _redirectable: [Circular 1],

  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype]
},
_currentUrl: 'https://api.mcs3.miele.com/v1/devices?language=de',
[Symbol(kCapture)]: false

}, response: undefined, isAxiosError: true, toJSON: [Function: toJSON] }

QuickSander commented 3 years ago

Seems like a temporary connection failure / loss on Miele's side or your side.

Does it continue to run? Maybe a next poll request does succeed.

To my opinion not related to a token issue. In your case it is even unable to reach the remote server.

Exi1986 commented 3 years ago

Yes i think i found the problem of this :-) Thank you for your great work!!

bsoener commented 3 years ago

Why does this error message come up when I enter it in the terminal? can someone help me out?

pi@raspberrypi:~ $ curl -X POST -d client_id=redacted -d grant_type=authorization_code -d redirect_uri=http://localhost:8592 -d vg=nl-NL -d client_secret=redacted -d code=DE_df572da52e6746g963fd19e81c252fb53&state=1 https://api.mcs3.miele.com/thirdparty/token [1] 11999 -bash: https://api.mcs3.miele.com/thirdparty/token: No such file or directory pi@raspberrypi:~ $ curl: no URL specified! curl: try 'curl --help' or 'curl --manual' for more information

[1]+ Exit 2 curl -X POST -d client_id=redacted -d grant_type=authorization_code -d redirect_uri=http://localhost:8592 -d vg=nl-NL -d client_secret=redacted -d code=redacted pi@raspberrypi:~ $

MichelRabozee commented 3 years ago

The "&state=1" is extraneous. Do not put it on the command line.

bsoener commented 3 years ago

thanks. have saved it

MichelRabozee commented 3 years ago

OK, I removed the info from my message. I suggest you edit yours to remove the client ID, client secret and tokens :-)

QuickSander commented 3 years ago

The "&state=1" is extraneous. Do not put it on the command line.

I need to remove that from the readme. I added it there since I will need to do it when token retrieval is automated/guided setup process.