dparnell / homebridge-chuango-h4

Homebridge plugin for the Chuango H4 home security system
Apache License 2.0
1 stars 0 forks source link

Chuango H4 support #2

Open halk1982 opened 3 years ago

halk1982 commented 3 years ago

Allow me to start by thanking you for making an effort to create a homebridge plugin for Chuango. I tried to use it with my Chuango H4 alarm (not H4 plus) and it doesn't work. Any chance to include H4 alarm as well ? If I can contribute in any way to this, please let me know, I would e more than happy to help. Thank you!!

dparnell commented 3 years ago

Hi, did it do anything at all? Do you have the homebridge logs? There may also be an issue with the SSL version in newer versions of node. I get a warning under node 14.15.3

halk1982 commented 3 years ago

It didn't appear as an accessory to Homekit.

First these successful 2 lines :

[3/14/2021, 10:30:40 PM] [ChuangoH4HomebridgePlugin] Initializing ChuangoH4HomebridgePlugin platform... [3/14/2021, 10:30:40 PM] [ChuangoH4HomebridgePlugin] Logging in...

And then this to homebridge error log(marked as red) :

[3/14/2021, 10:30:46 PM] [ChuangoH4HomebridgePlugin] Error: Request failed with status code 466 at createError (/usr/lib/node_modules/homebridge-chuango-h4/node_modules/axios/lib/core/createError.js:16:15) at settle (/usr/lib/node_modules/homebridge-chuango-h4/node_modules/axios/lib/core/settle.js:17:12) at IncomingMessage.handleStreamEnd (/usr/lib/node_modules/homebridge-chuango-h4/node_modules/axios/lib/adapters/http.js:260:11) at IncomingMessage.emit (events.js:327:22) at endReadableNT (internal/streams/readable.js:1327:12) at processTicksAndRejections (internal/process/task_queues.js:80:21) { config: { url: '/uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus', method: 'get', headers: { Accept: 'application/json, text/plain, /', dcsn: 'test123456789', 'User-Agent': 'axios/0.21.1' }, baseURL: 'https://52.59.107.21', transformRequest: [ [Function: transformRequest] ], transformResponse: [ [Function: transformResponse] ], timeout: 0, adapter: [Function: httpAdapter], xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, httpsAgent: Agent { _events: [Object: null prototype], _eventsCount: 2, _maxListeners: undefined, defaultPort: 443, protocol: 'https:', options: [Object], requests: {}, sockets: {}, freeSockets: [Object], keepAliveMsecs: 1000, keepAlive: true, maxSockets: Infinity, maxFreeSockets: 256, scheduling: 'fifo', maxTotalSockets: Infinity, totalSocketCount: 0, maxCachedSessions: 100, _sessionCache: [Object],

},
validateStatus: [Function: validateStatus],
data: undefined

}, request: <ref *1> ClientRequest { _events: [Object: null prototype] { socket: [Function (anonymous)], abort: [Function (anonymous)], aborted: [Function (anonymous)], connect: [Function (anonymous)], error: [Function (anonymous)], timeout: [Function (anonymous)], prefinish: [Function: requestOnPrefinish] }, _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: true, chunkedEncoding: false, shouldKeepAlive: true, _defaultKeepAlive: true, useChunkedEncodingByDefault: false, sendDate: false, _removedConnection: false, _removedContLen: false, _removedTE: false, _contentLength: 0, _hasBody: true, _trailer: '', finished: true, _headerSent: true, socket: TLSSocket { _tlsOptions: [Object], _secureEstablished: true, _securePending: false, _newSessionPending: false, _controlReleased: true, secureConnecting: false, _SNICallback: null, servername: false, alpnProtocol: false, authorized: false, authorizationError: 'ERR_TLS_CERT_ALTNAME_INVALID', encrypted: true, _events: [Object: null prototype], _eventsCount: 9, connecting: false, _hadError: false, _parent: null, _host: null, _readableState: [ReadableState], _maxListeners: undefined, _writableState: [WritableState], allowHalfOpen: false, _sockname: null, _pendingData: null, _pendingEncoding: '', server: undefined, _server: null, ssl: [TLSWrap], _requestCert: true, _rejectUnauthorized: false, parser: null, _httpMessage: null, timeout: 0,

  [Symbol(verified)]: true,
  [Symbol(pendingSession)]: null,
  [Symbol(async_id_symbol)]: -1,
  [Symbol(kHandle)]: [TLSWrap],
  [Symbol(kSetNoDelay)]: false,
  [Symbol(lastWriteQueueSize)]: 0,
  [Symbol(timeout)]: null,
  [Symbol(kBuffer)]: null,
  [Symbol(kBufferCb)]: null,
  [Symbol(kBufferGen)]: null,
  [Symbol(kCapture)]: false,
  [Symbol(kBytesRead)]: 0,
  [Symbol(kBytesWritten)]: 0,
  [Symbol(connect-options)]: [Object],
  [Symbol(RequestTimeout)]: undefined
},
_header: 'GET /uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus HTTP/1.1\r\n' +
  'Accept: application/json, text/plain, */*\r\n' +
  'dcsn: test123456789\r\n' +
  'User-Agent: axios/0.21.1\r\n' +
  'Host: 52.59.107.21\r\n' +
  'Connection: keep-alive\r\n' +
  '\r\n',
_keepAliveTimeout: 0,
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
  _events: [Object: null prototype],
  _eventsCount: 2,
  _maxListeners: undefined,
  defaultPort: 443,
  protocol: 'https:',
  options: [Object],
  requests: {},
  sockets: {},
  freeSockets: [Object],
  keepAliveMsecs: 1000,
  keepAlive: true,
  maxSockets: Infinity,
  maxFreeSockets: 256,
  scheduling: 'fifo',
  maxTotalSockets: Infinity,
  totalSocketCount: 0,
  maxCachedSessions: 100,
  _sessionCache: [Object],
  [Symbol(kCapture)]: false
},
socketPath: undefined,
method: 'GET',
maxHeaderSize: undefined,
insecureHTTPParser: undefined,
path: '/uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus',
_ended: true,
res: IncomingMessage {
  _readableState: [ReadableState],
  _events: [Object: null prototype],
  _eventsCount: 3,
  _maxListeners: undefined,
  socket: null,
  httpVersionMajor: 1,
  httpVersionMinor: 1,
  httpVersion: '1.1',
  complete: true,
  headers: [Object],
  rawHeaders: [Array],
  trailers: {},
  rawTrailers: [],
  aborted: false,
  upgrade: false,
  url: '',
  method: null,
  statusCode: 466,
  statusMessage: 'unknown',
  client: [TLSSocket],
  _consuming: true,
  _dumped: false,
  req: [Circular *1],
  responseUrl: 'https://52.59.107.21/uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus',
  redirects: [],
  [Symbol(kCapture)]: false,
  [Symbol(RequestTimeout)]: undefined
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
reusedSocket: false,
host: '52.59.107.21',
protocol: 'https:',
_redirectable: Writable {
  _writableState: [WritableState],
  _events: [Object: null prototype],
  _eventsCount: 2,
  _maxListeners: undefined,
  _options: [Object],
  _ended: true,
  _ending: true,
  _redirectCount: 0,
  _redirects: [],
  _requestBodyLength: 0,
  _requestBodyBuffers: [],
  _onNativeResponse: [Function (anonymous)],
  _currentRequest: [Circular *1],
  _currentUrl: 'https://52.59.107.21/uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus',
  [Symbol(kCapture)]: false
},
[Symbol(kCapture)]: false,
[Symbol(kNeedDrain)]: false,
[Symbol(corked)]: 0,
[Symbol(kOutHeaders)]: [Object: null prototype] {
  accept: [Array],
  dcsn: [Array],
  'user-agent': [Array],
  host: [Array]
}

}, response: { status: 466, statusText: 'unknown', headers: { 'x-powered-by': 'Express', 'content-type': 'application/json; charset=utf-8', 'content-length': '59', etag: 'W/"3b-XqSSKJNIR1NWL7P+IFkqZVTIrjI"', date: 'Sun, 14 Mar 2021 20:30:46 GMT', connection: 'keep-alive' }, config: { url: '/uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus', method: 'get', headers: [Object], baseURL: 'https://52.59.107.21', transformRequest: [Array], transformResponse: [Array], timeout: 0, adapter: [Function: httpAdapter], xsrfCookieName: 'XSRF-TOKEN', xsrfHeaderName: 'X-XSRF-TOKEN', maxContentLength: -1, maxBodyLength: -1, httpsAgent: [Agent], validateStatus: [Function: validateStatus], data: undefined }, request: <ref 1> ClientRequest { _events: [Object: null prototype], _eventsCount: 7, _maxListeners: undefined, outputData: [], outputSize: 0, writable: true, destroyed: true, _last: true, chunkedEncoding: false, shouldKeepAlive: true, _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 /uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus HTTP/1.1\r\n' + 'Accept: application/json, text/plain, /*\r\n' + 'dcsn: test123456789\r\n' + 'User-Agent: axios/0.21.1\r\n' + 'Host: 52.59.107.21\r\n' + 'Connection: keep-alive\r\n' + '\r\n', _keepAliveTimeout: 0, _onPendingData: [Function: noopPendingOutput], agent: [Agent], socketPath: undefined, method: 'GET', maxHeaderSize: undefined, insecureHTTPParser: undefined, path: '/uac/SET/userLogin/00s/01/com.dreamcatcher.smanos/halk1982//1.8.2/b4752710-2b50-45fb-a8af-5b755b33ea9a-com.chuango.h4plus/dc01gmfy27a3b-SaM2w8GKZRcQ==/1615753846395/dc/en/h4_plus', _ended: true, res: [IncomingMessage], aborted: false, timeoutCb: null, upgradeOrConnect: false, parser: null, maxHeadersCount: null, reusedSocket: false, host: '52.59.107.21', protocol: 'https:', _redirectable: [Writable],

  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype]
},
data: { status: '466', message: 'User is not exist' }

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

I believe the issue is that the network server for this alarm is not the same like H4 plus which is:

com.dreamcatcher.smanos

When logging in the IP of H4 via my browser I go to network settings and I see the below:

Screen Shot 2021-03-14 at 22 31 23

Does this help you somehow ? Even the username for H4 is not an email, but just a normal username and password.

The android app for H4 is this one:

https://play.google.com/store/apps/details?id=cn.chuango.chuangoh4&hl=el&gl=US

I'm under Node.js Version | v14.16.0

dparnell commented 3 years ago

Yeah, it looks like the H4 is different to the H4 Plus so it is probably not going to work. The way I decoded the H4 Plus protocol was a combination of packet sniffing and reverse engineering the android app.

To sniff the packets I used PCAP Remote and Wireshark on my desktop.

halk1982 commented 3 years ago

Do you believe if I do the same thing and send you the .pcap file, you 'll be able to add support for H4 as well ?

dparnell commented 3 years ago

It is possible, however it will be tricky to test without access to the device