Skip to content

I made some small upgrades to the amazing library you built#1

Open
nitaybz wants to merge 63 commits into
johnathanvidu:masterfrom
nitaybz:master
Open

I made some small upgrades to the amazing library you built#1
nitaybz wants to merge 63 commits into
johnathanvidu:masterfrom
nitaybz:master

Conversation

@nitaybz

@nitaybz nitaybz commented Sep 24, 2020

Copy link
Copy Markdown
  • Removed unnecessary spaces after switcher name
  • Included SWITCHER_PORT in the constructor to support earlier versions of node
  • Extract default_shutdown_seconds
  • Extract power_consumption
  • Hard code phone_id + device_pass (like all new firmwares support)
  • Smarter discovery (optionally) - can detect specific device by name, IP or ID.
  • Added optional timeout for discovery + function to close the socket
  • Adjusted README

Hope you'll merge :)

@johnathanvidu

johnathanvidu commented Sep 29, 2020

Copy link
Copy Markdown
Owner

Thank you for taking the time to contribute to switcher-js. I'll take a look at your changes in the coming days

@johnathanvidu johnathanvidu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks again for contributing! please refer to my comments

Comment thread README.md
- **Switcher V3** (Switcher touch) - FW **V1.51**
- **Switcher V3**: (Switcher touch) - Firmware **V1.51**
- **Switcher V2**: Firmware **3.21** (Based on ESP chipset)
- **Switcher V2**: Firmware**72.32** (Qualcomm chipset)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested all three devices?

Comment thread src/switcher.js Outdated
class ConnectionError extends Error {
constructor(ip, port) {
super('connection error: failed to connect to switcher on ip: ${ip}:${port}. please make sure it is turned on and available.');
super(`connection error: failed to connect to switcher on ip: ${ip}:${port}. please make sure it is turned on and available.`);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it necessary?

Comment thread src/switcher.js Outdated
SWITCHER_PORT = 9957;

constructor(device_id, switcher_ip, phone_id, device_pass, log) {
constructor(device_id, switcher_ip, log, listen) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure phone_id and device_pass aren't required for older firmware? cause as far as I understand they are

Comment thread src/switcher.js Outdated
this.p_session = null;
this.socket = null;
this.status_socket = this._hijack_status_report();
if (listen)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to always listen to status messages. I want the user to always be able to rely on proxy.on('status') to work, no matter how to switcher class was configured

Comment thread src/switcher.js Outdated
var device_id = udp_message.extract_device_id();
proxy.emit(READY_EVENT, new Switcher(device_id, ipaddr, phone_id, device_pass, log));
var device_name = udp_message.extract_device_name();
if (identifier && identifier !== device_id && identifier !== device_name && identifier !== ipaddr) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the discovery timeout, but can you elaborate on the identifier? I don't really understand why we need it. Are you assuming a house with multiple switchers?

Comment thread src/switcher.js Outdated
return proxy;
}

static listen(log, identifier) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you please elaborate why this listen method is needed?

Comment thread src/switcher.js Outdated
name: device_name,
state: state,
device_id: this.device_id,
power: state,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you remove name? and state can be changed to power, though I prefer something like power_state, but it is a breaking change, so maybe we can change it in a different commit, and increase the minor/major version

Comment thread src/switcher.js Outdated
var socket = await this._connect(this.SWITCHER_PORT, this.switcher_ip);
socket.on('error', (error) => {
this.log.debug('gloabal error event:', error);
this.log('gloabal error event:', error);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the log function is basically a logger (I used the one I receive from homebridge) so your changes will break the homebridge plugin.

Comment thread src/switcher.js Outdated
var device_id = udp_message.extract_device_id()
if (device_id === this.device_id)
this.emit(STATUS_EVENT, {
device_id: device_id,

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double device_id

Comment thread src/switcher.js Outdated
ConnectionError: ConnectionError,
ON: ON,
OFF, OFF
ConnectionError: ConnectionError

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove the ON and OFF?

nitaybz added 30 commits July 10, 2022 18:12
- fix this.log → log in static discover() / listen() (this.log is undefined
  in static method context; use the log parameter instead)
- fix accidental semicolon on `if (discovery_timeout);` so the discovery
  timeout actually respects the parameter instead of always firing
- correct close log message in listen() (was 'closing discover socket')
- bump runtime deps: adm-zip ^0.5.17, python-struct ^1.1.3
- bump devDep eslint to ^9.39.4 and declare engines.node >=18

Closes #2 #3

Credit to @mbravorus for the static method fix (#3) and @LeonFedotov
for spotting the semicolon (#2).
The OnWall sends device-type byte 0321 in its UDP broadcast, which had
no entry in the types map and showed up as UNKNOWN_0321. It's an
old-protocol boiler with the same state shape as v3/v4/mini, so:

- udp.js: map 0321 → 'on_wall'
- switcher.js: include 'on_wall' in OLD_TCP_GROUP and in the boiler
  state-emit branch of listen()

Closes nitaybz/homebridge-switcher-platform#67 nitaybz/homebridge-switcher-platform#73
- move on_wall out of OLD_TCP_GROUP so it tries the new TCP port (10000)
  instead of 9957, which an OnWall device reported as ECONNREFUSED. We
  do not actually have an OnWall device to verify but this is the next
  reasonable port to try.
- wrap _run_power_command, _run_general_command, and set_default_shutdown
  in try/catch that emits ERROR_EVENT instead of letting connection
  errors propagate as unhandled rejections. Previously a single device's
  TCP failure could crash the entire Homebridge child bridge.
…ures

After a long idle period (overnight, WiFi reassoc, device firmware
hiccups), the cached TCP socket to a Switcher device could go stale
without Node noticing. The next command would then fail with ECONNRESET
on login and the user had to restart Homebridge to recover. Three
changes to fix that:

- _getsocket: when the cached socket emits error or close, null out
  this.socket and this.p_session immediately so the next command opens
  a fresh connection instead of writing to a dead one.
- _connect: setKeepAlive(true, 30000) so dead idle connections are
  detected within ~30s instead of the OS default ~2 hours.
- _run_power_command and _run_general_command: wrap the body in an
  inner attempt() and retry once on failure after _reset_connection_state.
  This handles the very first command after idle without bothering the
  user.

Closes nitaybz/homebridge-switcher-platform#55
- log device_type, newType flag, and resolved TCP port at construction
  so we can see at startup whether the protocol path is correct
- log opening connection and ready event with ip:port instead of a
  generic 'successful connection' message, so we can confirm whether
  the right port is being used
- tag each login flow distinctly (_login old-TCP / _login2 new-TCP /
  _login3 token-auth) instead of three identical 'login...' lines
- log 'waiting for response' after every login and command write so
  silent device timeouts are visible in the log instead of just
  trailing off into nothing

No behavior change, debug output only.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants