Closed Cardo1 closed 4 years ago
Hi @Cardo1,
Could you please let me know what your geographic region is?
When I swapped the login mechanism to Somfy's OAuth for reliability during maintenance windows, I reverse engineered the Australian/Singaporian Somfy app for its access token, and it's possible that a different one be used in other markets.
I might have made this plugin Connexoon RTS specific for the APAC market. It's difficult to test for because I don't have an account or devices in other regions.
Let me know, and I will look further.
Thanks for responding.
I’m in the UK, so probably Europe?
Thanks.
Could you point me to the Somfy app that you are using to control the Somfy devices on your phone?
Alright so the good news is that the app has the same ID as the one on the Australian App Store so the codebase should be the same.
Could you send the logs surrounding the failure, making sure that your credentials are redacted?
Here we go. Hopefully I haven't redacted too much...
[10/28/2019, 2:07:12 PM] [My Connexoon Hub] Failed to login { message: 'error.invalid.grant', data: [], uid: 'hex stuff' }
[10/28/2019, 2:07:12 PM] [My Connexoon Hub] Failed to get device list { message: 'error.invalid.grant', data: [], uid: 'hex stuff' }
[10/28/2019, 2:07:12 PM] [My Connexoon Hub] StatusCodeError: 400 - {"message":"error.invalid.grant","data":[],"uid":"hex stuff"}
at new StatusCodeError (/usr/local/lib/node_modules/homebridge-connexoon/node_modules/request-promise-core/lib/errors.js:32:15)
at Request.plumbing.callback (/usr/local/lib/node_modules/homebridge-connexoon/node_modules/request-promise-core/lib/plumbing.js:104:33)
at Request.RP$callback [as _callback] (/usr/local/lib/node_modules/homebridge-connexoon/node_modules/request-promise-core/lib/plumbing.js:46:31)
at Request.self.callback (/usr/local/lib/node_modules/homebridge-connexoon/node_modules/request/request.js:185:22)
at Request.emit (events.js:210:5)
at Request.<anonymous> (/usr/local/lib/node_modules/homebridge-connexoon/node_modules/request/request.js:1161:10)
at Request.emit (events.js:210:5)
at IncomingMessage.<anonymous> (/usr/local/lib/node_modules/homebridge-connexoon/node_modules/request/request.js:1083:12)
at Object.onceWrapper (events.js:299:28)
at IncomingMessage.emit (events.js:215:7)
at endReadableNT (_stream_readable.js:1198:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
name: 'StatusCodeError',
statusCode: 400,
message: '400 - {"message":"error.invalid.grant","data":[],"uid":"hex stuff"}',
error: { message: 'error.invalid.grant', data: [], uid: 'hex stuff' },
options: {
url: 'https://accounts.somfy.com/oauth/oauth/v2/token',
form: {
grant_type: 'password',
username: 'user',
password: 'pass',
client_id: 'long numbers',
client_secret: 'long numbers'
},
json: true,
method: 'POST',
callback: [Function: RP$callback],
transform: undefined,
simple: true,
resolveWithFullResponse: false,
transform2xxOnly: false
},
response: <ref *1> IncomingMessage {
_readableState: ReadableState {
objectMode: false,
highWaterMark: 16384,
buffer: BufferList { head: null, tail: null, length: 0 },
length: 0,
pipes: [],
flowing: true,
ended: true,
endEmitted: true,
reading: false,
sync: true,
needReadable: false,
emittedReadable: false,
readableListening: false,
resumeScheduled: false,
paused: false,
errorEmitted: false,
emitClose: true,
autoDestroy: false,
destroyed: false,
defaultEncoding: 'utf8',
awaitDrainWriters: null,
multiAwaitDrain: false,
readingMore: true,
decoder: null,
encoding: null
},
readable: false,
_events: [Object: null prototype] {
end: [Array],
close: [Array],
data: [Function (anonymous)],
error: [Function (anonymous)]
},
_eventsCount: 4,
_maxListeners: undefined,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'accounts.somfy.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'accounts.somfy.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [ClientRequest],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 193,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: {
'cache-control': 'no-cache, private',
'content-type': 'application/json',
date: 'Mon, 28 Oct 2019 14:07:11 GMT',
server: 'openresty',
'content-length': '65',
connection: 'Close'
},
rawHeaders: [
'Cache-Control',
'no-cache, private',
'Content-Type',
'application/json',
'Date',
'Mon, 28 Oct 2019 14:07:11 GMT',
'Server',
'openresty',
'Content-Length',
'65',
'Connection',
'Close'
],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 400,
statusMessage: 'Bad Request',
client: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'accounts.somfy.com',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'accounts.somfy.com',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [ClientRequest],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 193,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_consuming: false,
_dumped: false,
req: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: true,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: null,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
_header: 'POST /oauth/oauth/v2/token HTTP/1.1\r\n' +
'host: accounts.somfy.com\r\n' +
'content-type: application/x-www-form-urlencoded\r\n' +
'accept: application/json\r\n' +
'content-length: 221\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'POST',
path: '/oauth/oauth/v2/token',
_ended: true,
res: [Circular *1],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
[Symbol(kNeedDrain)]: false,
[Symbol(isCorked)]: false,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
request: Request {
_events: [Object: null prototype],
_eventsCount: 5,
_maxListeners: undefined,
method: 'POST',
readable: true,
writable: true,
explicitMethod: true,
_qs: [Querystring],
_auth: [Auth],
_oauth: [OAuth],
_multipart: [Multipart],
_redirect: [Redirect],
_tunnel: [Tunnel],
_rp_resolve: [Function (anonymous)],
_rp_reject: [Function (anonymous)],
_rp_promise: [Promise],
_rp_callbackOrig: undefined,
callback: [Function (anonymous)],
_rp_options: [Object],
headers: [Object],
setHeader: [Function (anonymous)],
hasHeader: [Function (anonymous)],
getHeader: [Function (anonymous)],
removeHeader: [Function (anonymous)],
localAddress: undefined,
pool: {},
dests: [],
__isRequestRequest: true,
_callback: [Function: RP$callback],
uri: [Url],
proxy: null,
tunnel: true,
setHost: true,
originalCookieHeader: undefined,
_disableCookies: true,
_jar: undefined,
port: 443,
host: 'accounts.somfy.com',
body: 'grant_type=password&username=user&password=pass&client_id=long numbers&client_secret=long numbers$
path: '/oauth/oauth/v2/token',
_json: true,
httpModule: [Object],
agentClass: [Function: Agent],
agent: [Agent],
_started: true,
href: 'https://accounts.somfy.com/oauth/oauth/v2/token',
req: [ClientRequest],
ntick: true,
response: [Circular *1],
originalHost: 'accounts.somfy.com',
originalHostHeaderName: 'host',
responseContent: [Circular *1],
_destdata: true,
_ended: true,
_callbackCalled: true
},
toJSON: [Function: responseToJSON],
caseless: Caseless { dict: [Object] },
body: { message: 'error.invalid.grant', data: [], uid: 'hex stuff' }
}
I'll be honest I have no idea what is causing the authentication process to fail.
I'd normally use an Android phone and Android Studio in debug mode to log all network requests sent from the device to find out what the Somfy app (the original one) is sending to the server to login for your account. It's not possible to do the same from iOS unfortunately (not easily at least).
What I would like to know is if the previous login mechanism was working for you. Could you please go to your homebridge setup's package.json
file and change the version of Homebridge Connexoon to 1.0.0
? Then do an npm install and restart the platform.
If that works, I will just put both login mechanisms in place and fallback to the non OAuth one when the first one fails.
I've given 1.0.0 a try, unfortunately also doesn't work... I get:
[30/10/2019, 12:53:04] [My Connexoon Hub] Failed to login { errorCode: 'AUTHENTICATION_ERROR', error: 'Bad credentials' }
[30/10/2019, 12:53:04] [My Connexoon Hub] Failed to get device list { errorCode: 'AUTHENTICATION_ERROR', error: 'Bad credentials' }
[30/10/2019, 12:53:04] [My Connexoon Hub] StatusCodeError: 401 - {"errorCode":"AUTHENTICATION_ERROR","error":"Bad credentials"}
etc. etc.
Have you tried the other services too?
I’m afraid so.
If it makes any difference, the Homebridge-Tahoma plugin works. (Though I’m having other issues with that one!)
Mmmmmh that's interesting. v1.0.0
's login method is entirely based on Homebridge-Tahoma's implementation.
I'll need to go back it and see if there is any difference in the processing that could explain a Bad Credentials error.
Apologies, had a brain blip.
Using version 1.0.0, I managed to get it to work using either "TaHoma" or "Connexoon". "ConnexoonRTS" (the default, I believe?) gives me a bad credentials error.
So now I've got login working, I'm not getting any devices!
I've configured an awning as a "Roller Shutter" in the Connexoon Window app, however nothing's loading in the app. Simply get this:
[10/30/2019, 10:20:21 PM] [My Connexoon Hub] Initializing Connexoon platform...
[10/30/2019, 10:20:21 PM] [My Connexoon Hub] Connexoon Init
This is using a Connexoon RTS box.
If it helps, my config is...
{
"platform": "Connexoon",
"name": "My Connexoon Hub",
"username": "email",
"password": "pass",
"service": "TaHoma",
"devices": {
"Awning": {
"commands": [
{ "command": "open", "position": 0 },
{ "command": "close", "position": 100 }
]
}
}
},
Alright, it's good to know that the previous authentication mechanism is working, I will have to put up a fix for it when possible.
Regarding the next issue, could you please go to your local node_modules
directory and find the following file:
node_modules/homebridge-connexoon/src/api/overkiz-api.js
If you could add some logs at this line: https://github.com/yenoiwesa/homebridge-connexoon/blob/v1.0.0/src/api/overkiz-api.js#L102
Insert:
this.log.info('Device List Response:', jsonDevices);
Restart the platform, and then paste here the result that you get for the added log line (you can redact the device IDs, but I need the device class and type).
The log is as follows:
{
creationTime: 1572191556000,
lastUpdateTime: 1572191556000,
label: 'Box',
deviceURL: 'internal://device pin/pod/0',
shortcut: false,
controllableName: 'internal:PodMiniComponent',
definition: {
commands: [Array],
states: [Array],
dataProperties: [],
widgetName: 'Pod',
uiClass: 'Pod',
qualifiedName: 'internal:PodMiniComponent',
type: 'ACTUATOR'
},
states: [ [Object], [Object] ],
attributes: [],
available: true,
enabled: true,
placeOID: 'long number',
widget: 'Pod',
type: 1,
oid: 'long number',
uiClass: 'Pod'
},
{
creationTime: 1572473791000,
lastUpdateTime: 1572473791000,
label: 'Awning',
deviceURL: 'rts://pin/number',
shortcut: false,
controllableName: 'rts:RollerShutterRTSComponent',
definition: {
commands: [Array],
states: [],
dataProperties: [Array],
widgetName: 'UpDownRollerShutter',
uiClass: 'RollerShutter',
qualifiedName: 'rts:RollerShutterRTSComponent',
type: 'ACTUATOR'
},
attributes: [ [Object] ],
available: true,
enabled: true,
placeOID: 'number',
widget: 'UpDownRollerShutter',
type: 1,
oid: 'long number',
uiClass: 'RollerShutter'
}
Thanks!
Alright we're getting closer! The uiClass
of that device is RollerShutter
, which isn't mapped in my plugin (I only have roller blinds at home hehe).
Could you please go again to your local node_modules
and find the following file: homebridge-connexoon/src/services-mapping.js
And in the file, add a new entry for RollerShutter
as such:
module.exports = {
// maps API device UI Class to a list of services
Screen: [WindowCovering],
RollerShutter: [WindowCovering],
};
Now restart the platform and let me know if the device is properly discovered.
Fantastic, that's done the trick. My awning now shows up and works as it should with the reversed open/close positions.
Thanks for all your help!
That's great!
Alright so there are two actions for me now:
I will be working on that when time allows and then release a new version of the plugin. I'll let you know. In the meantime, you can keep using the modified version of the plugin.
Cheers! Matt
Hey @Cardo1,
I have just released v1.2.0
of the plugin with the fixes discussed above.
Please update to the latest version in your package.json
file and do npm install
, then restart the homebridge platform.
Let me know if everything works fine! :-)
Just tried it out. Looks like it's working fine.
Thanks!
Awesome! I'll close the issue then.
Don't hesitate to open a new one if you have more feedback/issues.
Can anyone explain what is the issue for the below errors??
[2/25/2020, 12:47:03 PM] Registering platform 'homebridge-config-ui-x.config' [2/25/2020, 12:47:03 PM] --- [2/25/2020, 12:47:03 PM] Loading 1 platforms... [2/25/2020, 12:47:03 PM] [My Connexoon Hub] Initializing Connexoon platform... [2/25/2020, 12:47:03 PM] [My Connexoon Hub] Connexoon Init [2/25/2020, 12:47:03 PM] Loading 0 accessories... [2/25/2020, 12:47:04 PM] [My Connexoon Hub] Could not login with any of the authentication methods. [2/25/2020, 12:47:04 PM] [My Connexoon Hub] Failed to get device list undefined [2/25/2020, 12:47:04 PM] [My Connexoon Hub] Could not login with any of the authentication methods. Setup Payload: X-HM://0024YV17WIHO4
@tejakolla Hi 👋 The error indicates that the authentication failed with your credentials on the service you selected. Make sure that you are using the right service
in your homebridge configuration file for the Connexoon platform according to your region and Somfy bridge.
@yenoiwesa Hi.. please go through my config file. Am i doing any wrong or should i enter more details on it ??
@tejakolla nothing is wrong per se with your configuration file. You just happen to not have a Somfy account for that service. Try the different service enums if you don't know which one works for your region.
Also please make sure to entirely redact your credentials next time.
Hi there,
I'm trying to set up this plugin, however I receive a "error.invalid.grant" error when it tries to log in. The user/pass appear to be correct, as if I change these I get a wrong credentials error, instead.
I've tried using all the different service types, but I get the same error with all of them. I can log into the Somfy website using the username/password without issues.
I can post the extensive error log, if necessary.
Thoughts?