Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ For the first generation, see [node-shellies](https://github.com/alexryd/node-sh
* [Shelly Plus 1 PM](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlus1PM)
* [Shelly Plus 2 PM](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlus2PM)
* [Shelly Plus I4](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlusI4)
* [Shelly Plus Plug IT](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlusPlugIT)
* [Shelly Plus Plug S](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlusPlugS)
* [Shelly Plus Plug UK](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlusPlugUK)
* [Shelly Plus Plug US](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlugUS)
* [Shelly Plus Smoke](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlusSmoke)
* [Shelly Plus H&T](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPlusHT) <sup>1</sup>
* [Shelly Pro 1](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro1)
* [Shelly Pro 1 PM](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro1PM)
* [Shelly Pro 2](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro2)
* [Shelly Pro 2 PM](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro2PM)
* [Shelly Pro 3](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro3)
* [Shelly Pro 4 PM](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro4PM)
* [Shelly Pro 4 PM](https://shelly-api-docs.shelly.cloud/gen2/Devices/ShellyPro4PM) <sup>2</sup>

<sup>1</sup> Support for outbound websockets is a work in progress.
<sup>2</sup> Support for v1 and v2.

## Basic usage example

Expand Down
8,036 changes: 1,646 additions & 6,390 deletions package-lock.json

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,21 @@
"url": "https://ko-fi.com/alexryd"
},
"devDependencies": {
"@types/jest": "^28.1.2",
"@typescript-eslint/eslint-plugin": "^5.28.0",
"@typescript-eslint/parser": "^5.28.0",
"eslint": "^8.18.0",
"jest": "^28.1.1",
"rimraf": "^3.0.2",
"ts-jest": "^28.0.5",
"typescript": "^4.7.4"
"@types/jest": "^29.4.0",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"eslint": "^8.35.0",
"jest": "^29.4.3",
"rimraf": "^4.1.2",
"ts-jest": "^29.0.5",
"typescript": "^4.9.5"
},
"dependencies": {
"@types/multicast-dns": "^7.2.1",
"eventemitter3": "^4.0.7",
"eventemitter3": "^5.0.0",
"fast-deep-equal": "^3.1.3",
"json-rpc-2.0": "^1.3.0",
"json-rpc-2.0": "^1.5.1",
"multicast-dns": "^7.2.5",
"ws": "^8.8.0"
"ws": "^8.12.1"
}
}
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ export * from './light';
export * from './mqtt';
export * from './outbound-websocket';
export * from './script';
export * from './smoke';
export * from './switch';
export * from './system';
export * from './temperature';
export * from './ui';
export * from './wifi';
export * from './plugs-ui';
42 changes: 42 additions & 0 deletions src/components/plugs-ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Component } from './base';
import { Device } from '../devices';

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface PlugsUiAttributes {}

export interface PlugsUiConfig {
leds: {
mode: 'power' | 'switch' | 'off';
colors: {
'switch:0': {
on: {
rgb: number[] | null;
brightness: number;
};
off: {
rgb: number[] | null;
brightness: number;
};
};
power: {
brightness: number;
};
};
night_mode: {
enable: boolean;
brightness: number;
active_between: string[];
};
};
controls: {
'switch:0': {
in_mode: 'momentary' | 'detached';
};
};
}

export class PlugsUi extends Component<PlugsUiAttributes, PlugsUiConfig> implements PlugsUiAttributes {
constructor (readonly name: string, device: Device) {
super(name, device);
}
}
43 changes: 43 additions & 0 deletions src/components/smoke.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { characteristic, ComponentWithId } from './base';
import { Device } from '../devices';

export interface SmokeAttributes {
id: number;
alarm: boolean;
mute: boolean;
}

export interface SmokeConfig {
id: number;
name: string | null;
}

/**
* Represents a switch (relay) of a device.
*/
export class Smoke extends ComponentWithId<SmokeAttributes, SmokeConfig> implements SmokeAttributes {
/**
* Alarm state.
*/
@characteristic
readonly alarm: boolean = false;

/**
* Mute state.
*/
@characteristic
readonly mute: boolean = false;

constructor(device: Device, id = 0) {
super('Smoke', device, id);
}

/**
* Mutes alarm of the associated smoke sensor.
*/
muteAlarm(): PromiseLike<null> {
return this.rpc<null>('Mute', {
id: this.id,
});
}
}
5 changes: 5 additions & 0 deletions src/devices/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,8 @@ export * from './shelly-pro-2';
export * from './shelly-pro-2-pm';
export * from './shelly-pro-3';
export * from './shelly-pro-4-pm';
export * from './shelly-pro-4-pm-v2';
export * from './shelly-plus-plug-it';
export * from './shelly-plus-plug-s';
export * from './shelly-plus-plug-uk';
export * from './shelly-plus-smoke';
9 changes: 9 additions & 0 deletions src/devices/shelly-plus-plug-it.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Device } from './base';
import { ShellyPlusPlugUs } from './shelly-plus-plug-us';

export class ShellyPlusPlugIt extends ShellyPlusPlugUs {
static readonly model: string = 'SNPL-00110IT';
static readonly modelName: string = 'Shelly Plus Plug IT';
}

Device.registerClass(ShellyPlusPlugIt);
42 changes: 42 additions & 0 deletions src/devices/shelly-plus-plug-s.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { component, Device } from './base';
import {
BluetoothLowEnergy,
Cloud,
Mqtt,
OutboundWebSocket,
Script,
Switch,
WiFi,
PlugsUi,
} from '../components';

export class ShellyPlusPlugS extends Device {
static readonly model: string = 'SNPL-00112EU';
static readonly modelName: string = 'Shelly Plus Plug S';

@component
readonly wifi = new WiFi(this);

@component
readonly bluetoothLowEnergy = new BluetoothLowEnergy(this);

@component
readonly cloud = new Cloud(this);

@component
readonly mqtt = new Mqtt(this);

@component
readonly outboundWebSocket = new OutboundWebSocket(this);

@component
readonly switch0 = new Switch(this, 0);

@component
readonly script = new Script(this);

@component
readonly plugsUi = new PlugsUi('PLUGS_UI', this);
}

Device.registerClass(ShellyPlusPlugS);
13 changes: 13 additions & 0 deletions src/devices/shelly-plus-plug-uk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { component, Device } from './base';
import { ShellyPlusPlugS } from './shelly-plus-plug-s';
import { PlugsUi } from '../components';

export class ShellyPlusPlugUk extends ShellyPlusPlugS {
static readonly model: string = 'SNPL-00112UK';
static readonly modelName: string = 'Shelly Plus Plug UK';

@component
readonly plugsUi = new PlugsUi('PLUGUK_UI', this);
}

Device.registerClass(ShellyPlusPlugUk);
38 changes: 38 additions & 0 deletions src/devices/shelly-plus-smoke.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { component, Device } from './base';
import {
BluetoothLowEnergy,
Cloud,
DevicePower,
Mqtt,
OutboundWebSocket,
Smoke,
WiFi,
} from '../components';

export class ShellyPlusSmoke extends Device {
static readonly model: string = 'SNSN-0031Z';
static readonly modelName: string = 'Shelly Plus Smoke';

@component
readonly wifi = new WiFi(this);

@component
readonly bluetoothLowEnergy = new BluetoothLowEnergy(this);

@component
readonly cloud = new Cloud(this);

@component
readonly mqtt = new Mqtt(this);

@component
readonly outboundWebSocket = new OutboundWebSocket(this);

@component
readonly devicePower0 = new DevicePower(this, 0);

@component
readonly smoke0 = new Smoke(this, 0);
}

Device.registerClass(ShellyPlusSmoke);
68 changes: 68 additions & 0 deletions src/devices/shelly-pro-4-pm-v2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { component, Device } from './base';
import {
BluetoothLowEnergy,
Cloud,
Ethernet,
Input,
Mqtt,
OutboundWebSocket,
Script,
Switch,
Ui,
WiFi,
} from '../components';

export class ShellyPro4PmV2 extends Device {
static readonly model: string = 'SPSW-104PE16EU';
static readonly modelName: string = 'Shelly Pro 4 PM V2';

@component
readonly wifi = new WiFi(this);

@component
readonly ethernet = new Ethernet(this);

@component
readonly bluetoothLowEnergy = new BluetoothLowEnergy(this);

@component
readonly cloud = new Cloud(this);

@component
readonly mqtt = new Mqtt(this);

@component
readonly outboundWebSocket = new OutboundWebSocket(this);

@component
readonly input0 = new Input(this, 0);

@component
readonly input1 = new Input(this, 1);

@component
readonly input2 = new Input(this, 2);

@component
readonly input3 = new Input(this, 3);

@component
readonly switch0 = new Switch(this, 0);

@component
readonly switch1 = new Switch(this, 1);

@component
readonly switch2 = new Switch(this, 2);

@component
readonly switch3 = new Switch(this, 3);

@component
readonly script = new Script(this);

@component
readonly ui = new Ui(this);
}

Device.registerClass(ShellyPro4PmV2);
2 changes: 2 additions & 0 deletions src/rpc/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export class JSONRPCClientWithAuthentication<ClientParams = void> extends JSONRP
const req: JSONRPCRequestWithAuth = { auth: this.auth, ...request };

// send the request
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const response = await super.requestAdvanced(req, clientParams);

// handle errors
Expand Down
10 changes: 10 additions & 0 deletions src/services/shelly.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import {
MqttConfig,
OutboundWebSocketAttributes,
OutboundWebSocketConfig,
PlugsUiAttributes,
PlugsUiConfig,
SmokeAttributes,
SmokeConfig,
SwitchAttributes,
SwitchConfig,
SystemAttributes,
Expand Down Expand Up @@ -48,6 +52,7 @@ export interface ShellyStatus {
'input:1'?: InputAttributes;
'input:2'?: InputAttributes;
'input:3'?: InputAttributes;
'smoke:0'?: SmokeAttributes;
'switch:0'?: SwitchAttributes;
'switch:1'?: SwitchAttributes;
'switch:2'?: SwitchAttributes;
Expand All @@ -57,6 +62,8 @@ export interface ShellyStatus {
'humidity:0'?: HumidityAttributes;
'temperature:0'?: TemperatureAttributes;
ui?: UiAttributes;
plugs_ui?: PlugsUiAttributes;
pluguk_ui?: PlugsUiAttributes;
}

export interface ShellyConfig {
Expand All @@ -72,6 +79,7 @@ export interface ShellyConfig {
'input:1'?: InputConfig;
'input:2'?: InputConfig;
'input:3'?: InputConfig;
'smoke:0'?: SmokeConfig;
'switch:0'?: SwitchConfig;
'switch:1'?: SwitchConfig;
'switch:2'?: SwitchConfig;
Expand All @@ -81,6 +89,8 @@ export interface ShellyConfig {
'humidity:0'?: HumidityConfig;
'temperature:0'?: TemperatureConfig;
ui?: UiConfig;
plugs_ui?: PlugsUiConfig;
pluguk_ui?: PlugsUiConfig;
}

export interface ShellyMethods {
Expand Down