homebridge-ariston-heater 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ # Homebridge Ariston Heater
2
+
3
+ Homebridge plugin for Ariston NET Velis/Lydos water heaters. It discovers your plant, reads current/target temperature and toggles power. It auto-selects the correct Velis endpoint variant (se/med/slp/one/evo).
4
+
5
+
6
+ ## Installation
7
+
8
+ 1. From this repo root, `cd homebridge-ariston-heater` and install dependencies.
9
+ 2. Publish or use locally via `npm link`.
10
+ 3. Optional: test the network client without Homebridge using `.env` and the CLI:
11
+
12
+ ```
13
+ # .env
14
+ ARISTON_USER=you@example.com
15
+ ARISTON_PASS=yourpassword
16
+ # optional
17
+
18
+ ariston-test-client
19
+ ```
20
+
21
+ ## Configuration (config.json)
22
+
23
+ Add an accessory like:
24
+
25
+ ```
26
+ {
27
+ "accessories": [
28
+ {
29
+ "accessory": "AristonHeater",
30
+ "name": "Water Heater",
31
+ "username": "<ariston email>",
32
+ "password": "<ariston password>",
33
+ "pollInterval": 30,
34
+ "minTemp": 35,
35
+ "maxTemp": 70,
36
+ "debug": false
37
+ }
38
+ ]
39
+ }
40
+ ```
41
+
42
+ ## Features
43
+
44
+ - Auto discovery (if `gateway` not set)
45
+ - Reads current and target temperature
46
+ - Sets target temperature (35–70°C)
47
+ - Power on/off mapped to Heating/Cooling State (OFF/HEAT)
48
+ - Auto-selects best Velis variant by scoring returned payloads and ignoring zeroed responses
49
+
50
+ ## Project structure
51
+
52
+ - `src/client.ts`: network client (login, discovery, read/write, variant selection)
53
+ - `src/accessory.ts`: Homebridge accessory wiring using the client
54
+ - `src/index.ts`: Homebridge registration entry
55
+ - `src/bin/test-client.ts`: standalone CLI source; published binary is `dist/bin/test-client.js`
56
+
57
+ ## Notes
58
+
59
+ - Requires Ariston NET cloud account credentials (same used in the mobile app).
60
+ - For Lydos devices, `sePlantData` is typically selected; MED can return zeros which are ignored automatically.
61
+ - If behavior seems off, delete the cache file (ariston-cache.json) from the Homebridge storage path to force a re-probe.
62
+
63
+ ## License
64
+
65
+ MIT. Portions inspired by the Home Assistant Ariston integration (MIT). See LICENSE.
66
+
67
+ ## Credits
68
+
69
+ Inspired by:
70
+ - [ariston-remotethermo-home-assistant-v3](https://github.com/fustom/ariston-remotethermo-home-assistant-v3)
71
+ - [homebridge-aristonnet](https://github.com/fhihung/homebridge-aristonnet)
@@ -0,0 +1,27 @@
1
+ import type { API, Logging, PlatformConfig, Service } from 'homebridge';
2
+ export declare class AristonHeaterAccessory {
3
+ private log;
4
+ private api;
5
+ private service;
6
+ private cached;
7
+ private variant;
8
+ private plantId;
9
+ private timer?;
10
+ private pollInterval;
11
+ private debug;
12
+ private client;
13
+ private name;
14
+ private minTemp;
15
+ private maxTemp;
16
+ constructor(log: Logging, config: PlatformConfig & any, api: API);
17
+ getServices(): Service[];
18
+ private initialize;
19
+ private schedule;
20
+ private refresh;
21
+ private pushState;
22
+ private onGetCurrentTemperature;
23
+ private onGetTargetTemperature;
24
+ private onSetTargetTemperature;
25
+ private onGetTargetHeatingCoolingState;
26
+ private onSetTargetHeatingCoolingState;
27
+ }
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AristonHeaterAccessory = void 0;
4
+ const client_1 = require("./client");
5
+ class AristonHeaterAccessory {
6
+ constructor(log, config, api) {
7
+ var _a, _b;
8
+ this.log = log;
9
+ this.api = api;
10
+ this.cached = { currentTemp: null, targetTemp: null, power: null };
11
+ this.variant = null;
12
+ const ServiceCtor = api.hap.Service;
13
+ const CharacteristicCtor = api.hap.Characteristic;
14
+ this.name = config.name || 'Ariston Heater';
15
+ this.plantId = config.gateway || null;
16
+ this.pollInterval = Math.max(15, Number(config.pollInterval) || 30);
17
+ this.debug = !!config.debug;
18
+ this.minTemp = Math.max(1, Number((_a = config.minTemp) !== null && _a !== void 0 ? _a : 35));
19
+ this.maxTemp = Math.max(this.minTemp + 1, Number((_b = config.maxTemp) !== null && _b !== void 0 ? _b : 70));
20
+ const cacheDir = (api && api.user && api.user.storagePath && api.user.storagePath()) || process.cwd();
21
+ this.client = new client_1.AristonClient({
22
+ baseURL: config.baseURL,
23
+ userAgent: config.userAgent,
24
+ username: config.username,
25
+ password: config.password,
26
+ log: console,
27
+ debug: this.debug,
28
+ cacheDir,
29
+ });
30
+ this.service = new ServiceCtor.Thermostat(this.name);
31
+ this.service
32
+ .getCharacteristic(CharacteristicCtor.TemperatureDisplayUnits)
33
+ .onGet(async () => CharacteristicCtor.TemperatureDisplayUnits.CELSIUS);
34
+ this.service
35
+ .getCharacteristic(CharacteristicCtor.TargetTemperature)
36
+ .setProps({ minValue: this.minTemp, maxValue: this.maxTemp, minStep: 1 })
37
+ .onGet(this.onGetTargetTemperature.bind(this))
38
+ .onSet(this.onSetTargetTemperature.bind(this));
39
+ this.service
40
+ .getCharacteristic(CharacteristicCtor.CurrentTemperature)
41
+ .onGet(this.onGetCurrentTemperature.bind(this));
42
+ this.service
43
+ .getCharacteristic(CharacteristicCtor.TargetHeatingCoolingState)
44
+ .setProps({ validValues: [CharacteristicCtor.TargetHeatingCoolingState.OFF, CharacteristicCtor.TargetHeatingCoolingState.HEAT] })
45
+ .onGet(this.onGetTargetHeatingCoolingState.bind(this))
46
+ .onSet(this.onSetTargetHeatingCoolingState.bind(this));
47
+ this.initialize();
48
+ }
49
+ getServices() {
50
+ return [this.service];
51
+ }
52
+ async initialize() {
53
+ var _a, _b, _c;
54
+ try {
55
+ await this.client.login();
56
+ if (!this.plantId) {
57
+ const devices = await this.client.discoverVelis();
58
+ const first = devices[0];
59
+ if (!first)
60
+ throw new Error('No Velis devices found');
61
+ this.plantId = (first.gw || first.gateway || first.id || first.plantId);
62
+ }
63
+ const best = await this.client.getBestVelisPlantData(this.plantId);
64
+ this.variant = best.kind;
65
+ this.cached.currentTemp = (_a = best.fields.currentTemp) !== null && _a !== void 0 ? _a : null;
66
+ this.cached.targetTemp = (_b = best.fields.targetTemp) !== null && _b !== void 0 ? _b : null;
67
+ this.cached.power = (_c = best.fields.powerState) !== null && _c !== void 0 ? _c : null;
68
+ this.pushState();
69
+ this.schedule();
70
+ }
71
+ catch (e) {
72
+ this.log('Initialize error:', (e === null || e === void 0 ? void 0 : e.message) || e);
73
+ }
74
+ }
75
+ schedule() {
76
+ if (this.timer)
77
+ clearInterval(this.timer);
78
+ // Slightly delay first refresh to stagger multiple accessories
79
+ setTimeout(() => this.refresh().catch(() => { }), 2000);
80
+ this.timer = setInterval(() => this.refresh().catch(() => { }), this.pollInterval * 1000);
81
+ }
82
+ async refresh() {
83
+ if (!this.plantId)
84
+ return;
85
+ try {
86
+ const best = await this.client.getBestVelisPlantData(this.plantId);
87
+ this.variant = best.kind;
88
+ const { currentTemp, targetTemp, powerState } = best.fields;
89
+ this.cached.currentTemp = typeof currentTemp === 'number' ? currentTemp : this.cached.currentTemp;
90
+ this.cached.targetTemp = typeof targetTemp === 'number' ? targetTemp : this.cached.targetTemp;
91
+ this.cached.power = typeof powerState === 'boolean' ? powerState : this.cached.power;
92
+ this.pushState();
93
+ }
94
+ catch (e) {
95
+ this.log('Refresh failed:', (e === null || e === void 0 ? void 0 : e.message) || e);
96
+ // Optional: backoff a bit to avoid hammering if errors persist
97
+ try {
98
+ await new Promise((r) => setTimeout(r, 500));
99
+ }
100
+ catch { }
101
+ }
102
+ }
103
+ pushState() {
104
+ const C = this.api.hap.Characteristic;
105
+ if (typeof this.cached.currentTemp === 'number')
106
+ this.service.updateCharacteristic(C.CurrentTemperature, this.cached.currentTemp);
107
+ if (typeof this.cached.targetTemp === 'number')
108
+ this.service.updateCharacteristic(C.TargetTemperature, this.cached.targetTemp);
109
+ if (typeof this.cached.power === 'boolean') {
110
+ this.service.updateCharacteristic(C.TargetHeatingCoolingState, this.cached.power ? C.TargetHeatingCoolingState.HEAT : C.TargetHeatingCoolingState.OFF);
111
+ this.service.updateCharacteristic(C.CurrentHeatingCoolingState, this.cached.power ? C.CurrentHeatingCoolingState.HEAT : C.CurrentHeatingCoolingState.OFF);
112
+ }
113
+ }
114
+ async onGetCurrentTemperature() {
115
+ var _a;
116
+ return (_a = this.cached.currentTemp) !== null && _a !== void 0 ? _a : 0;
117
+ }
118
+ async onGetTargetTemperature() {
119
+ var _a;
120
+ return (_a = this.cached.targetTemp) !== null && _a !== void 0 ? _a : 0;
121
+ }
122
+ async onSetTargetTemperature(value) {
123
+ if (!this.plantId || !this.variant)
124
+ throw new Error('Device not ready');
125
+ const vNum = typeof value === 'number' ? value : Number(value);
126
+ const v = Math.max(this.minTemp, Math.min(this.maxTemp, Math.round(vNum)));
127
+ const oldV = typeof this.cached.targetTemp === 'number' ? this.cached.targetTemp : v;
128
+ try {
129
+ await this.client.setTemperature(this.variant, this.plantId, oldV, v, false);
130
+ this.cached.targetTemp = v;
131
+ this.refresh().catch(() => { });
132
+ }
133
+ catch (e1) {
134
+ this.log('setTargetTemperature failed, re-probing variant:', (e1 === null || e1 === void 0 ? void 0 : e1.message) || e1);
135
+ const best = await this.client.getBestVelisPlantData(this.plantId);
136
+ this.variant = best.kind;
137
+ await this.client.setTemperature(this.variant, this.plantId, oldV, v, false);
138
+ this.cached.targetTemp = v;
139
+ this.refresh().catch(() => { });
140
+ }
141
+ }
142
+ async onGetTargetHeatingCoolingState() {
143
+ const C = this.api.hap.Characteristic;
144
+ return this.cached.power ? C.TargetHeatingCoolingState.HEAT : C.TargetHeatingCoolingState.OFF;
145
+ }
146
+ async onSetTargetHeatingCoolingState(value) {
147
+ if (!this.plantId || !this.variant)
148
+ throw new Error('Device not ready');
149
+ const C = this.api.hap.Characteristic;
150
+ const num = typeof value === 'number' ? value : Number(value);
151
+ const on = num === C.TargetHeatingCoolingState.HEAT;
152
+ try {
153
+ await this.client.setPower(this.variant, this.plantId, on);
154
+ this.cached.power = on;
155
+ this.refresh().catch(() => { });
156
+ }
157
+ catch (e1) {
158
+ this.log('setTargetHeatingCoolingState failed, re-probing variant:', (e1 === null || e1 === void 0 ? void 0 : e1.message) || e1);
159
+ const best = await this.client.getBestVelisPlantData(this.plantId);
160
+ this.variant = best.kind;
161
+ await this.client.setPower(this.variant, this.plantId, on);
162
+ this.cached.power = on;
163
+ this.refresh().catch(() => { });
164
+ }
165
+ }
166
+ }
167
+ exports.AristonHeaterAccessory = AristonHeaterAccessory;
168
+ //# sourceMappingURL=accessory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accessory.js","sourceRoot":"","sources":["../src/accessory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const client_1 = require("../client");
10
+ // Lightweight .env loader
11
+ try {
12
+ const envPath = path_1.default.resolve(process.cwd(), '.env');
13
+ if (fs_1.default.existsSync(envPath)) {
14
+ const lines = fs_1.default.readFileSync(envPath, 'utf8').split(/\r?\n/);
15
+ for (const line of lines) {
16
+ if (!line || line.trim().startsWith('#'))
17
+ continue;
18
+ const m = line.match(/^([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
19
+ if (!m)
20
+ continue;
21
+ const [, k, vRaw] = m;
22
+ let v = vRaw;
23
+ if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith('\'') && v.endsWith('\'')))
24
+ v = v.slice(1, -1);
25
+ if (!(k in process.env))
26
+ process.env[k] = v;
27
+ }
28
+ }
29
+ }
30
+ catch { }
31
+ (async () => {
32
+ try {
33
+ const cacheDir = process.env.ARISTON_CACHE_DIR || process.cwd();
34
+ const client = new client_1.AristonClient({ cacheDir, log: console });
35
+ await client.login();
36
+ const gw = process.env.ARISTON_PLANT;
37
+ if (!gw) {
38
+ const devices = await client.discoverVelis();
39
+ console.log(JSON.stringify(devices, null, 2));
40
+ if (!devices.length)
41
+ return;
42
+ const d = devices[0];
43
+ const first = d.gw || d.gateway || d.id || d.plantId;
44
+ const best = await client.getBestVelisPlantData(first);
45
+ console.log(JSON.stringify({ plant: first, variant: best.kind, fields: best.fields, raw: best.data }, null, 2));
46
+ }
47
+ else {
48
+ const best = await client.getBestVelisPlantData(gw);
49
+ console.log(JSON.stringify({ plant: gw, variant: best.kind, fields: best.fields, raw: best.data }, null, 2));
50
+ }
51
+ }
52
+ catch (e) {
53
+ console.error('Error:', (e === null || e === void 0 ? void 0 : e.message) || e);
54
+ process.exit(1);
55
+ }
56
+ })();
57
+ //# sourceMappingURL=test-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-client.js","sourceRoot":"","sources":["../../src/bin/test-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export interface AristonClientOpts {
2
+ baseURL?: string;
3
+ userAgent?: string;
4
+ username?: string;
5
+ password?: string;
6
+ log?: Console;
7
+ debug?: boolean;
8
+ cacheDir?: string;
9
+ }
10
+ export interface PlantBest {
11
+ kind: string;
12
+ data: any;
13
+ fields: {
14
+ currentTemp?: number;
15
+ targetTemp?: number;
16
+ powerState?: boolean;
17
+ };
18
+ score: number;
19
+ }
20
+ export declare class AristonClient {
21
+ private http;
22
+ private token;
23
+ private storage;
24
+ private baseURL;
25
+ private userAgent;
26
+ private username?;
27
+ private password?;
28
+ private log;
29
+ private debug;
30
+ constructor({ baseURL, userAgent, username, password, log, debug, cacheDir }?: AristonClientOpts);
31
+ login(): Promise<string>;
32
+ discoverVelis(): Promise<any[]>;
33
+ private extractFields;
34
+ getBestVelisPlantData(plantId: string): Promise<PlantBest>;
35
+ setTemperature(variantKind: string, plantId: string, oldTemp: number, newTemp: number, eco?: boolean): Promise<void>;
36
+ setPower(variantKind: string, plantId: string, on: boolean): Promise<void>;
37
+ }
package/dist/client.js ADDED
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AristonClient = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const storage_1 = require("./storage");
9
+ class AristonClient {
10
+ constructor({ baseURL, userAgent, username, password, log = console, debug = false, cacheDir } = {}) {
11
+ this.token = null;
12
+ this.baseURL = baseURL || process.env.ARISTON_API || 'https://www.ariston-net.remotethermo.com/api/v2/';
13
+ this.userAgent = userAgent || process.env.ARISTON_UA || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/142.0';
14
+ this.username = username || process.env.ARISTON_USER;
15
+ this.password = password || process.env.ARISTON_PASS;
16
+ this.log = log;
17
+ this.debug = !!debug || process.env.ARISTON_DEBUG === '1' || process.env.DEBUG === '1';
18
+ this.http = axios_1.default.create({
19
+ baseURL: this.baseURL,
20
+ timeout: 15000,
21
+ headers: { 'User-Agent': this.userAgent, 'Content-Type': 'application/json' },
22
+ // Accept up to 599 so axios doesn’t throw on 5xx; we’ll handle status checks explicitly.
23
+ validateStatus: (s) => s >= 200 && s < 600,
24
+ });
25
+ this.storage = new storage_1.VariantStorage(cacheDir, log);
26
+ }
27
+ async login() {
28
+ const body = {
29
+ usr: this.username,
30
+ pwd: this.password,
31
+ imp: false,
32
+ notTrack: true,
33
+ appInfo: { os: 2, appVer: '5.6.7772.40151', appId: 'com.remotethermo.aristonnet' },
34
+ };
35
+ const res = await this.http.post('accounts/login', body);
36
+ if (this.debug)
37
+ this.log.log(`[login] status=${res.status}`);
38
+ if (res.status !== 200 || !(res.data && res.data.token))
39
+ throw new Error(`Login failed (${res.status})`);
40
+ const token = res.data.token;
41
+ this.token = token;
42
+ return token;
43
+ }
44
+ async discoverVelis() {
45
+ const headers = { 'ar.authToken': this.token };
46
+ const paths = ['velis/medPlants', 'velis/plants'];
47
+ for (const p of paths) {
48
+ const res = await this.http.get(p, { headers });
49
+ if (this.debug)
50
+ this.log.log(`[GET ${p}] status=${res.status}`);
51
+ if (res.status === 200 && Array.isArray(res.data) && res.data.length)
52
+ return res.data;
53
+ }
54
+ return [];
55
+ }
56
+ extractFields(raw) {
57
+ const get = (o, ks) => {
58
+ const k = ks.find((key) => o && Object.prototype.hasOwnProperty.call(o, key) && o[key] != null);
59
+ return k ? o[k] : undefined;
60
+ };
61
+ const currentTemp = get(raw, ['temp', 'wtrTemp', 'currentTemp', 'currTemp', 'tCur']);
62
+ const targetTemp = get(raw, ['procReqTemp', 'reqTemp', 'targetTemp', 'tSet']);
63
+ const powerState = get(raw, ['on', 'power', 'pwr']);
64
+ return { currentTemp, targetTemp, powerState };
65
+ }
66
+ async getBestVelisPlantData(plantId) {
67
+ var _a;
68
+ const headers = { 'ar.authToken': this.token };
69
+ const cached = (_a = this.storage.getVariant(plantId)) === null || _a === void 0 ? void 0 : _a.variant;
70
+ if (cached) {
71
+ try {
72
+ const url = `velis/${cached}/${encodeURIComponent(plantId)}`;
73
+ const res = await this.http.get(url, { headers });
74
+ if (this.debug)
75
+ this.log.log(`[GET ${url}] status=${res.status} (cached)`);
76
+ if (res.status === 200 && res.data && Object.keys(res.data).length) {
77
+ const fields = this.extractFields(res.data);
78
+ return { kind: cached, data: res.data, fields, score: 99 };
79
+ }
80
+ }
81
+ catch { }
82
+ }
83
+ const variants = ['sePlantData', 'medPlantData', 'slpPlantData', 'onePlantData', 'evoPlantData'];
84
+ const isNum = (v) => typeof v === 'number' && Number.isFinite(v);
85
+ const gt0 = (v) => isNum(v) && v > 0 && v < 100;
86
+ const scoreCandidate = (f) => {
87
+ let score = 0;
88
+ if (gt0(f.currentTemp))
89
+ score += 3;
90
+ if (gt0(f.targetTemp))
91
+ score += 2;
92
+ if (typeof f.powerState === 'boolean')
93
+ score += 1;
94
+ const bothZeroOrNull = (!isNum(f.currentTemp) || f.currentTemp === 0) && (!isNum(f.targetTemp) || f.targetTemp === 0);
95
+ if (bothZeroOrNull && f.powerState === false)
96
+ score = 0;
97
+ return score;
98
+ };
99
+ const candidates = [];
100
+ for (const v of variants) {
101
+ const url = `velis/${v}/${encodeURIComponent(plantId)}`;
102
+ try {
103
+ const res = await this.http.get(url, { headers });
104
+ if (this.debug)
105
+ this.log.log(`[GET ${url}] status=${res.status}`);
106
+ if (res.status === 200 && res.data && Object.keys(res.data).length) {
107
+ const fields = this.extractFields(res.data);
108
+ const score = scoreCandidate(fields);
109
+ candidates.push({ kind: v, data: res.data, fields, score });
110
+ }
111
+ }
112
+ catch (e) {
113
+ if (this.debug)
114
+ this.log.error(`[GET ${url}] error: ${(e === null || e === void 0 ? void 0 : e.message) || e}`);
115
+ // continue with next variant
116
+ }
117
+ }
118
+ if (!candidates.length)
119
+ throw new Error('No plant data');
120
+ candidates.sort((a, b) => b.score - a.score || variants.indexOf(a.kind) - variants.indexOf(b.kind));
121
+ const best = candidates[0];
122
+ this.storage.setVariant(plantId, best.kind);
123
+ return best;
124
+ }
125
+ async setTemperature(variantKind, plantId, oldTemp, newTemp, eco = false) {
126
+ const headers = { 'ar.authToken': this.token };
127
+ const url = `velis/${variantKind}/${encodeURIComponent(plantId)}/temperature`;
128
+ const body = { eco: !!eco, old: oldTemp, new: newTemp };
129
+ const res = await this.http.post(url, body, { headers });
130
+ if (this.debug)
131
+ this.log.log(`[POST ${url}] status=${res.status}`);
132
+ if (res.status !== 200)
133
+ throw new Error(`Set temperature failed (${res.status})`);
134
+ }
135
+ async setPower(variantKind, plantId, on) {
136
+ const headers = { 'ar.authToken': this.token };
137
+ const url = `velis/${variantKind}/${encodeURIComponent(plantId)}/switch`;
138
+ const res = await this.http.post(url, !!on, { headers });
139
+ if (this.debug)
140
+ this.log.log(`[POST ${url}] status=${res.status}`);
141
+ if (res.status !== 200)
142
+ throw new Error(`Set power failed (${res.status})`);
143
+ }
144
+ }
145
+ exports.AristonClient = AristonClient;
146
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { API } from 'homebridge';
2
+ declare const _default: (api: API) => void;
3
+ export = _default;
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ const accessory_1 = require("./accessory");
3
+ module.exports = (api) => {
4
+ api.registerAccessory('homebridge-ariston-heater', 'AristonHeater', accessory_1.AristonHeaterAccessory);
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,2CAAqD;AAErD,iBAAS,CAAC,GAAQ,EAAE,EAAE;IACpB,GAAG,CAAC,iBAAiB,CAAC,2BAA2B,EAAE,eAAe,EAAE,kCAAsB,CAAC,CAAC;AAC9F,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface VariantEntry {
2
+ variant: string;
3
+ updatedAt: string;
4
+ }
5
+ export declare class VariantStorage {
6
+ private file;
7
+ private cache;
8
+ private log;
9
+ constructor(baseDir?: string, log?: {
10
+ warn?: (...args: any[]) => void;
11
+ } | Console);
12
+ private load;
13
+ private save;
14
+ getVariant(plantId: string): VariantEntry | null;
15
+ setVariant(plantId: string, variant: string): void;
16
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.VariantStorage = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ class VariantStorage {
10
+ constructor(baseDir, log = console) {
11
+ this.log = log;
12
+ const dir = baseDir || process.cwd();
13
+ this.file = path_1.default.join(dir, 'ariston-cache.json');
14
+ try {
15
+ fs_1.default.mkdirSync(dir, { recursive: true });
16
+ }
17
+ catch { }
18
+ this.cache = this.load();
19
+ }
20
+ load() {
21
+ var _a, _b;
22
+ try {
23
+ if (fs_1.default.existsSync(this.file)) {
24
+ const txt = fs_1.default.readFileSync(this.file, 'utf8');
25
+ return JSON.parse(txt);
26
+ }
27
+ }
28
+ catch (e) {
29
+ (_b = (_a = this.log) === null || _a === void 0 ? void 0 : _a.warn) === null || _b === void 0 ? void 0 : _b.call(_a, 'Failed to load cache:', (e === null || e === void 0 ? void 0 : e.message) || e);
30
+ }
31
+ return { variants: {} };
32
+ }
33
+ save() {
34
+ var _a, _b;
35
+ try {
36
+ fs_1.default.writeFileSync(this.file, JSON.stringify(this.cache, null, 2));
37
+ }
38
+ catch (e) {
39
+ (_b = (_a = this.log) === null || _a === void 0 ? void 0 : _a.warn) === null || _b === void 0 ? void 0 : _b.call(_a, 'Failed to save cache:', (e === null || e === void 0 ? void 0 : e.message) || e);
40
+ }
41
+ }
42
+ getVariant(plantId) {
43
+ var _a;
44
+ return (((_a = this.cache) === null || _a === void 0 ? void 0 : _a.variants) && this.cache.variants[plantId]) || null;
45
+ }
46
+ setVariant(plantId, variant) {
47
+ if (!this.cache.variants)
48
+ this.cache.variants = {};
49
+ this.cache.variants[plantId] = { variant, updatedAt: new Date().toISOString() };
50
+ this.save();
51
+ }
52
+ }
53
+ exports.VariantStorage = VariantStorage;
54
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AACpB,gDAAwB;AAWxB,MAAa,cAAc;IAKzB,YAAY,OAAgB,EAAE,MAAqD,OAAO;QACxF,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,MAAM,GAAG,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,cAAI,CAAC,IAAI,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;QACjD,IAAI,CAAC;YACH,YAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3B,CAAC;IAEO,IAAI;;QACV,IAAI,CAAC;YACH,IAAI,YAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,MAAM,GAAG,GAAG,YAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAe,CAAC;YACvC,CAAC;QACH,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,mDAAG,uBAAuB,EAAE,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,KAAI,CAAC,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAC1B,CAAC;IAEO,IAAI;;QACV,IAAI,CAAC;YACH,YAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,CAAM,EAAE,CAAC;YAChB,MAAA,MAAA,IAAI,CAAC,GAAG,0CAAE,IAAI,mDAAG,uBAAuB,EAAE,CAAA,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,KAAI,CAAC,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,UAAU,CAAC,OAAe;;QACxB,OAAO,CAAC,CAAA,MAAA,IAAI,CAAC,KAAK,0CAAE,QAAQ,KAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,IAAI,CAAC;IACxE,CAAC;IAED,UAAU,CAAC,OAAe,EAAE,OAAe;QACzC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ;YAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAS,CAAC;QAC1D,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAChF,IAAI,CAAC,IAAI,EAAE,CAAC;IACd,CAAC;CACF;AA5CD,wCA4CC"}
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "homebridge-ariston-heater",
3
+ "version": "0.1.0",
4
+ "displayName": "Homebridge Ariston Heater",
5
+ "description": "Homebridge plugin for Ariston Velis/Lydos water heaters (Ariston NET)",
6
+ "license": "MIT",
7
+ "author": "Matteo Crippa",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/matteocrippa/homebridge-ariston-heater.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/matteocrippa/homebridge-ariston-heater/issues"
14
+ },
15
+ "homepage": "https://github.com/matteocrippa/homebridge-ariston-heater#readme",
16
+ "main": "dist/index.js",
17
+ "bin": {
18
+ "ariston-test-client": "dist/bin/test-client.js"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "engines": {
26
+ "node": ">=18.0.0",
27
+ "homebridge": "^1.8.0 || ^2.0.0-beta.0"
28
+ },
29
+ "keywords": [
30
+ "homebridge-plugin",
31
+ "ariston",
32
+ "velis",
33
+ "lydos",
34
+ "water-heater",
35
+ "ariston-lydos"
36
+ ],
37
+ "scripts": {
38
+ "build": "rimraf ./dist && tsc && npm run postbuild",
39
+ "clean": "rimraf dist",
40
+ "lint": "eslint src",
41
+ "prepublishOnly": "npm run lint && npm run build",
42
+ "prepare": "npm run build",
43
+ "watch": "npm run build && npm link && nodemon",
44
+ "postbuild": "chmod +x dist/bin/test-client.js"
45
+ },
46
+ "dependencies": {
47
+ "axios": "^1.11.0"
48
+ },
49
+ "devDependencies": {
50
+ "@eslint/js": "^9.21.0",
51
+ "@types/node": "^20.14.10",
52
+ "eslint": "^9.21.0",
53
+ "homebridge": "^2.0.0-beta.0",
54
+ "nodemon": "^3.1.9",
55
+ "rimraf": "^6.0.1",
56
+ "ts-node": "^10.9.2",
57
+ "typescript": "^5.5.4",
58
+ "typescript-eslint": "^8.24.1"
59
+ },
60
+ "peerDependencies": {
61
+ "homebridge": "^1.8.0 || ^2.0.0-beta.0"
62
+ }
63
+ }