edilkamin 1.7.4 → 1.9.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/.github/dependabot.yml +5 -1
- package/README.md +92 -4
- package/dist/cjs/package.json +16 -5
- package/dist/cjs/src/bluetooth-utils.d.ts +13 -0
- package/dist/cjs/src/bluetooth-utils.js +28 -0
- package/dist/cjs/src/bluetooth-utils.test.d.ts +1 -0
- package/dist/cjs/src/bluetooth-utils.test.js +35 -0
- package/dist/cjs/src/bluetooth.d.ts +40 -0
- package/dist/cjs/src/bluetooth.js +107 -0
- package/dist/cjs/src/cli.js +130 -0
- package/dist/cjs/src/index.d.ts +2 -1
- package/dist/cjs/src/index.js +3 -1
- package/dist/cjs/src/library.d.ts +26 -0
- package/dist/cjs/src/library.js +361 -0
- package/dist/cjs/src/library.test.js +266 -0
- package/dist/cjs/src/types.d.ts +30 -1
- package/dist/esm/package.json +16 -5
- package/dist/esm/src/bluetooth-utils.d.ts +13 -0
- package/dist/esm/src/bluetooth-utils.js +25 -0
- package/dist/esm/src/bluetooth-utils.test.d.ts +1 -0
- package/dist/esm/src/bluetooth-utils.test.js +33 -0
- package/dist/esm/src/bluetooth.d.ts +40 -0
- package/dist/esm/src/bluetooth.js +100 -0
- package/dist/esm/src/cli.js +130 -0
- package/dist/esm/src/index.d.ts +2 -1
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/library.d.ts +26 -0
- package/dist/esm/src/library.js +361 -0
- package/dist/esm/src/library.test.js +266 -0
- package/dist/esm/src/types.d.ts +30 -1
- package/package.json +16 -5
- package/src/bluetooth-utils.test.ts +46 -0
- package/src/bluetooth-utils.ts +29 -0
- package/src/bluetooth.ts +115 -0
- package/src/cli.ts +249 -0
- package/src/index.ts +2 -0
- package/src/library.test.ts +372 -0
- package/src/library.ts +426 -0
- package/src/types.ts +35 -0
- package/tsconfig.json +1 -0
package/.github/dependabot.yml
CHANGED
|
@@ -11,7 +11,11 @@ updates:
|
|
|
11
11
|
open-pull-requests-limit: 5
|
|
12
12
|
commit-message:
|
|
13
13
|
prefix: ":arrow_up:"
|
|
14
|
-
|
|
14
|
+
# Ignore non-LTS Node.js versions for @types/node
|
|
15
|
+
# Update this when bumping to the next LTS (e.g., 26.x -> ignore 27.x)
|
|
16
|
+
ignore:
|
|
17
|
+
- dependency-name: "@types/node"
|
|
18
|
+
versions: ["25.x"]
|
|
15
19
|
# GitHub Actions dependencies
|
|
16
20
|
- package-ecosystem: "github-actions"
|
|
17
21
|
directory: "/"
|
package/README.md
CHANGED
|
@@ -115,12 +115,96 @@ const legacyApi = configure(OLD_API_URL);
|
|
|
115
115
|
|
|
116
116
|
> **Note**: The legacy API uses AWS API Gateway and may be deprecated in the future.
|
|
117
117
|
|
|
118
|
+
## Bluetooth Device Discovery
|
|
119
|
+
|
|
120
|
+
For automatic device discovery in web browsers, use the `edilkamin/bluetooth` subpath export.
|
|
121
|
+
|
|
122
|
+
### Quick Example (Web)
|
|
123
|
+
|
|
124
|
+
```javascript
|
|
125
|
+
import { scanForDevices } from "edilkamin/bluetooth";
|
|
126
|
+
import { deviceInfo, signIn } from "edilkamin";
|
|
127
|
+
|
|
128
|
+
// Scan for nearby stoves (requires user gesture)
|
|
129
|
+
const devices = await scanForDevices();
|
|
130
|
+
const { wifiMac } = devices[0];
|
|
131
|
+
|
|
132
|
+
// Use discovered MAC for API calls
|
|
133
|
+
const token = await signIn(username, password);
|
|
134
|
+
const info = await deviceInfo(token, wifiMac);
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### MAC Address Helper
|
|
138
|
+
|
|
139
|
+
The core library includes a helper to convert BLE MAC to WiFi MAC:
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
import { bleToWifiMac } from "edilkamin";
|
|
143
|
+
|
|
144
|
+
// BLE MAC from Bluetooth scan
|
|
145
|
+
const bleMac = "A8:03:2A:FE:D5:0A";
|
|
146
|
+
|
|
147
|
+
// WiFi MAC for API calls (BLE - 2)
|
|
148
|
+
const wifiMac = bleToWifiMac(bleMac); // "a8032afed508"
|
|
149
|
+
```
|
|
150
|
+
|
|
118
151
|
## Motivations
|
|
119
152
|
|
|
120
153
|
- providing an open source web alternative
|
|
121
154
|
to the [proprietary mobile app](https://play.google.com/store/apps/details?id=com.edilkamin.stufe)
|
|
122
155
|
- improving the interoperability (Nest, HomeAssistant...)
|
|
123
156
|
|
|
157
|
+
## Device Control Methods
|
|
158
|
+
|
|
159
|
+
The library provides comprehensive control over Edilkamin stoves:
|
|
160
|
+
|
|
161
|
+
### Power Control
|
|
162
|
+
|
|
163
|
+
```js
|
|
164
|
+
setPowerOn(token, mac); // Turn on
|
|
165
|
+
setPowerOff(token, mac); // Turn off
|
|
166
|
+
setPower(token, mac, 1); // 1=on, 0=off
|
|
167
|
+
getPower(token, mac); // Returns boolean
|
|
168
|
+
setPowerLevel(token, mac, 3); // Set power level (1-5)
|
|
169
|
+
getPowerLevel(token, mac); // Returns 1-5
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Fan Speed
|
|
173
|
+
|
|
174
|
+
```js
|
|
175
|
+
setFan1Speed(token, mac, 3); // Set fan 1 speed (0-5)
|
|
176
|
+
setFan2Speed(token, mac, 3); // Set fan 2 speed (0-5)
|
|
177
|
+
setFan3Speed(token, mac, 3); // Set fan 3 speed (0-5)
|
|
178
|
+
getFan1Speed(token, mac); // Get fan 1 speed
|
|
179
|
+
getFan2Speed(token, mac); // Get fan 2 speed
|
|
180
|
+
getFan3Speed(token, mac); // Get fan 3 speed
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Operating Modes
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
setAirkare(token, mac, true); // Enable/disable air quality mode
|
|
187
|
+
setRelax(token, mac, true); // Enable/disable comfort mode
|
|
188
|
+
setStandby(token, mac, true); // Enable/disable standby mode
|
|
189
|
+
getStandby(token, mac); // Get standby status
|
|
190
|
+
setStandbyTime(token, mac, 30); // Set standby timer (minutes)
|
|
191
|
+
getStandbyTime(token, mac); // Get standby timer
|
|
192
|
+
setAuto(token, mac, true); // Enable/disable auto mode
|
|
193
|
+
getAuto(token, mac); // Get auto mode status
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Temperature Control
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
setTargetTemperature(token, mac, 22); // Set zone 1 temperature
|
|
200
|
+
getTargetTemperature(token, mac); // Get zone 1 target
|
|
201
|
+
getEnvironmentTemperature(token, mac); // Get ambient temperature
|
|
202
|
+
setEnvironment2Temperature(token, mac, 20); // Set zone 2 temperature
|
|
203
|
+
getEnvironment2Temperature(token, mac); // Get zone 2 target
|
|
204
|
+
setEnvironment3Temperature(token, mac, 18); // Set zone 3 temperature
|
|
205
|
+
getEnvironment3Temperature(token, mac); // Get zone 3 target
|
|
206
|
+
```
|
|
207
|
+
|
|
124
208
|
## Roadmap
|
|
125
209
|
|
|
126
210
|
- [x] AWS Amplify/ Cognito authentication
|
|
@@ -128,10 +212,14 @@ const legacyApi = configure(OLD_API_URL);
|
|
|
128
212
|
- [x] authenticated endpoint call
|
|
129
213
|
- [ ] ~list stoves~
|
|
130
214
|
- [x] turn stove on/off
|
|
131
|
-
- [
|
|
215
|
+
- [x] set temperature
|
|
216
|
+
- [x] power level control
|
|
217
|
+
- [x] fan speed control
|
|
218
|
+
- [x] operating modes (Airkare, Relax, Standby, Auto)
|
|
219
|
+
- [x] multi-zone temperature control
|
|
132
220
|
|
|
133
221
|
## Limitations
|
|
134
222
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
223
|
+
- **No server-side device listing**: The API doesn't provide an endpoint to list stoves associated to a user.
|
|
224
|
+
- **Bluetooth discovery available**: Use `edilkamin/bluetooth` for web browser device discovery, similar to the official app.
|
|
225
|
+
- **Manual MAC entry fallback**: For unsupported browsers or CLI, users can find the BLE MAC with different means and use `bleToWifiMac()` to calculate the WiFi MAC for API calls.
|
package/dist/cjs/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edilkamin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/cjs/src/index.js",
|
|
6
6
|
"module": "dist/esm/src/index.js",
|
|
@@ -15,6 +15,16 @@
|
|
|
15
15
|
"types": "./dist/cjs/src/index.d.ts",
|
|
16
16
|
"default": "./dist/cjs/src/index.js"
|
|
17
17
|
}
|
|
18
|
+
},
|
|
19
|
+
"./bluetooth": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/esm/src/bluetooth.d.ts",
|
|
22
|
+
"default": "./dist/esm/src/bluetooth.js"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/cjs/src/bluetooth.d.ts",
|
|
26
|
+
"default": "./dist/cjs/src/bluetooth.js"
|
|
27
|
+
}
|
|
18
28
|
}
|
|
19
29
|
},
|
|
20
30
|
"scripts": {
|
|
@@ -60,9 +70,10 @@
|
|
|
60
70
|
"@eslint/eslintrc": "^3.2.0",
|
|
61
71
|
"@eslint/js": "^9.16.0",
|
|
62
72
|
"@types/mocha": "^10.0.10",
|
|
63
|
-
"@types/node": "^
|
|
73
|
+
"@types/node": "^24",
|
|
64
74
|
"@types/pako": "^2.0.4",
|
|
65
|
-
"@types/sinon": "^
|
|
75
|
+
"@types/sinon": "^21.0.0",
|
|
76
|
+
"@types/web-bluetooth": "^0.0.21",
|
|
66
77
|
"@typescript-eslint/eslint-plugin": "^8.17.0",
|
|
67
78
|
"@typescript-eslint/parser": "^8.17.0",
|
|
68
79
|
"esbuild": "^0.27.1",
|
|
@@ -73,12 +84,12 @@
|
|
|
73
84
|
"mocha": "^11.7.5",
|
|
74
85
|
"nyc": "^17.1.0",
|
|
75
86
|
"prettier": "^3.7.4",
|
|
76
|
-
"sinon": "^
|
|
87
|
+
"sinon": "^21.0.1",
|
|
77
88
|
"ts-node": "^10.9.1",
|
|
78
89
|
"typedoc": "^0.28.15",
|
|
79
90
|
"typescript": "^5.7.2"
|
|
80
91
|
},
|
|
81
92
|
"optionalDependencies": {
|
|
82
|
-
"commander": "^
|
|
93
|
+
"commander": "^14.0.2"
|
|
83
94
|
}
|
|
84
95
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a BLE MAC address to WiFi MAC address.
|
|
3
|
+
* The WiFi MAC is the BLE MAC minus 2 in hexadecimal.
|
|
4
|
+
*
|
|
5
|
+
* @param bleMac - BLE MAC address (with or without colons/dashes)
|
|
6
|
+
* @returns WiFi MAC address in lowercase without separators
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* bleToWifiMac("A8:03:2A:FE:D5:0A") // returns "a8032afed508"
|
|
10
|
+
* bleToWifiMac("a8032afed50a") // returns "a8032afed508"
|
|
11
|
+
*/
|
|
12
|
+
declare const bleToWifiMac: (bleMac: string) => string;
|
|
13
|
+
export { bleToWifiMac };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bleToWifiMac = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Converts a BLE MAC address to WiFi MAC address.
|
|
6
|
+
* The WiFi MAC is the BLE MAC minus 2 in hexadecimal.
|
|
7
|
+
*
|
|
8
|
+
* @param bleMac - BLE MAC address (with or without colons/dashes)
|
|
9
|
+
* @returns WiFi MAC address in lowercase without separators
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* bleToWifiMac("A8:03:2A:FE:D5:0A") // returns "a8032afed508"
|
|
13
|
+
* bleToWifiMac("a8032afed50a") // returns "a8032afed508"
|
|
14
|
+
*/
|
|
15
|
+
const bleToWifiMac = (bleMac) => {
|
|
16
|
+
// Remove colons, dashes, and convert to lowercase
|
|
17
|
+
const normalized = bleMac.replace(/[:-]/g, "").toLowerCase();
|
|
18
|
+
// Validate MAC address format (12 hex characters)
|
|
19
|
+
if (!/^[0-9a-f]{12}$/.test(normalized)) {
|
|
20
|
+
throw new Error(`Invalid MAC address format: ${bleMac}`);
|
|
21
|
+
}
|
|
22
|
+
// Convert to number, subtract 2, convert back to hex
|
|
23
|
+
const bleValue = BigInt(`0x${normalized}`);
|
|
24
|
+
const wifiValue = bleValue - BigInt(2);
|
|
25
|
+
// Pad to 12 characters and return lowercase
|
|
26
|
+
return wifiValue.toString(16).padStart(12, "0");
|
|
27
|
+
};
|
|
28
|
+
exports.bleToWifiMac = bleToWifiMac;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const assert_1 = require("assert");
|
|
4
|
+
const bluetooth_utils_1 = require("./bluetooth-utils");
|
|
5
|
+
describe("bleToWifiMac", () => {
|
|
6
|
+
it("converts BLE MAC with colons to WiFi MAC", () => {
|
|
7
|
+
assert_1.strict.equal((0, bluetooth_utils_1.bleToWifiMac)("A8:03:2A:FE:D5:0A"), "a8032afed508");
|
|
8
|
+
});
|
|
9
|
+
it("converts BLE MAC without separators", () => {
|
|
10
|
+
assert_1.strict.equal((0, bluetooth_utils_1.bleToWifiMac)("a8032afed50a"), "a8032afed508");
|
|
11
|
+
});
|
|
12
|
+
it("converts BLE MAC with dashes", () => {
|
|
13
|
+
assert_1.strict.equal((0, bluetooth_utils_1.bleToWifiMac)("A8-03-2A-FE-D5-0A"), "a8032afed508");
|
|
14
|
+
});
|
|
15
|
+
it("handles lowercase input", () => {
|
|
16
|
+
assert_1.strict.equal((0, bluetooth_utils_1.bleToWifiMac)("a8:03:2a:fe:d5:0a"), "a8032afed508");
|
|
17
|
+
});
|
|
18
|
+
it("handles edge case where subtraction crosses byte boundary", () => {
|
|
19
|
+
// FF:FF:FF:FF:FF:01 - 2 = FF:FF:FF:FF:FE:FF
|
|
20
|
+
assert_1.strict.equal((0, bluetooth_utils_1.bleToWifiMac)("FF:FF:FF:FF:FF:01"), "fffffffffeff");
|
|
21
|
+
});
|
|
22
|
+
it("handles minimum value edge case", () => {
|
|
23
|
+
// 00:00:00:00:00:02 - 2 = 00:00:00:00:00:00
|
|
24
|
+
assert_1.strict.equal((0, bluetooth_utils_1.bleToWifiMac)("00:00:00:00:00:02"), "000000000000");
|
|
25
|
+
});
|
|
26
|
+
it("throws on invalid MAC format - too short", () => {
|
|
27
|
+
assert_1.strict.throws(() => (0, bluetooth_utils_1.bleToWifiMac)("A8:03:2A"), /Invalid MAC address format/);
|
|
28
|
+
});
|
|
29
|
+
it("throws on invalid MAC format - invalid characters", () => {
|
|
30
|
+
assert_1.strict.throws(() => (0, bluetooth_utils_1.bleToWifiMac)("G8:03:2A:FE:D5:0A"), /Invalid MAC address format/);
|
|
31
|
+
});
|
|
32
|
+
it("throws on empty string", () => {
|
|
33
|
+
assert_1.strict.throws(() => (0, bluetooth_utils_1.bleToWifiMac)(""), /Invalid MAC address format/);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DiscoveredDevice } from "./types";
|
|
2
|
+
/** Device name broadcast by Edilkamin stoves */
|
|
3
|
+
declare const EDILKAMIN_DEVICE_NAME = "EDILKAMIN_EP";
|
|
4
|
+
/** GATT Service UUID for Edilkamin devices (0xABF0) */
|
|
5
|
+
declare const EDILKAMIN_SERVICE_UUID = 44016;
|
|
6
|
+
/**
|
|
7
|
+
* Check if Web Bluetooth API is available in the current browser.
|
|
8
|
+
*
|
|
9
|
+
* @returns true if Web Bluetooth is supported
|
|
10
|
+
*/
|
|
11
|
+
declare const isWebBluetoothSupported: () => boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Scan for nearby Edilkamin stoves using the Web Bluetooth API.
|
|
14
|
+
*
|
|
15
|
+
* This function triggers the browser's Bluetooth device picker dialog,
|
|
16
|
+
* filtered to show only devices named "EDILKAMIN_EP".
|
|
17
|
+
*
|
|
18
|
+
* Note: Web Bluetooth requires:
|
|
19
|
+
* - HTTPS or localhost
|
|
20
|
+
* - User gesture (button click)
|
|
21
|
+
* - Chrome/Edge/Opera (not Firefox/Safari)
|
|
22
|
+
*
|
|
23
|
+
* @returns Promise resolving to array of discovered devices
|
|
24
|
+
* @throws Error if Web Bluetooth is not supported or user cancels
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* const devices = await scanForDevices();
|
|
28
|
+
* console.log(devices[0].wifiMac); // Use this for API calls
|
|
29
|
+
*/
|
|
30
|
+
declare const scanForDevices: () => Promise<DiscoveredDevice[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Scan for devices with a custom filter.
|
|
33
|
+
* Advanced function for users who need more control over device selection.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Web Bluetooth requestDevice options
|
|
36
|
+
* @returns Promise resolving to the selected BluetoothDevice
|
|
37
|
+
*/
|
|
38
|
+
declare const scanWithOptions: (options: RequestDeviceOptions) => Promise<BluetoothDevice>;
|
|
39
|
+
export { EDILKAMIN_DEVICE_NAME, EDILKAMIN_SERVICE_UUID, isWebBluetoothSupported, scanForDevices, scanWithOptions, };
|
|
40
|
+
export type { DiscoveredDevice } from "./types";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.scanWithOptions = exports.scanForDevices = exports.isWebBluetoothSupported = exports.EDILKAMIN_SERVICE_UUID = exports.EDILKAMIN_DEVICE_NAME = void 0;
|
|
13
|
+
const bluetooth_utils_1 = require("./bluetooth-utils");
|
|
14
|
+
/** Device name broadcast by Edilkamin stoves */
|
|
15
|
+
const EDILKAMIN_DEVICE_NAME = "EDILKAMIN_EP";
|
|
16
|
+
exports.EDILKAMIN_DEVICE_NAME = EDILKAMIN_DEVICE_NAME;
|
|
17
|
+
/** GATT Service UUID for Edilkamin devices (0xABF0) */
|
|
18
|
+
const EDILKAMIN_SERVICE_UUID = 0xabf0;
|
|
19
|
+
exports.EDILKAMIN_SERVICE_UUID = EDILKAMIN_SERVICE_UUID;
|
|
20
|
+
/**
|
|
21
|
+
* Check if Web Bluetooth API is available in the current browser.
|
|
22
|
+
*
|
|
23
|
+
* @returns true if Web Bluetooth is supported
|
|
24
|
+
*/
|
|
25
|
+
const isWebBluetoothSupported = () => {
|
|
26
|
+
return typeof navigator !== "undefined" && "bluetooth" in navigator;
|
|
27
|
+
};
|
|
28
|
+
exports.isWebBluetoothSupported = isWebBluetoothSupported;
|
|
29
|
+
/**
|
|
30
|
+
* Scan for nearby Edilkamin stoves using the Web Bluetooth API.
|
|
31
|
+
*
|
|
32
|
+
* This function triggers the browser's Bluetooth device picker dialog,
|
|
33
|
+
* filtered to show only devices named "EDILKAMIN_EP".
|
|
34
|
+
*
|
|
35
|
+
* Note: Web Bluetooth requires:
|
|
36
|
+
* - HTTPS or localhost
|
|
37
|
+
* - User gesture (button click)
|
|
38
|
+
* - Chrome/Edge/Opera (not Firefox/Safari)
|
|
39
|
+
*
|
|
40
|
+
* @returns Promise resolving to array of discovered devices
|
|
41
|
+
* @throws Error if Web Bluetooth is not supported or user cancels
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const devices = await scanForDevices();
|
|
45
|
+
* console.log(devices[0].wifiMac); // Use this for API calls
|
|
46
|
+
*/
|
|
47
|
+
const scanForDevices = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
+
if (!isWebBluetoothSupported()) {
|
|
49
|
+
throw new Error("Web Bluetooth API is not supported in this browser. " +
|
|
50
|
+
"Use Chrome, Edge, or Opera on desktop/Android. " +
|
|
51
|
+
"On iOS, use the Bluefy browser app.");
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
// Request device - this opens the browser's device picker
|
|
55
|
+
const device = yield navigator.bluetooth.requestDevice({
|
|
56
|
+
filters: [{ name: EDILKAMIN_DEVICE_NAME }],
|
|
57
|
+
optionalServices: [EDILKAMIN_SERVICE_UUID],
|
|
58
|
+
});
|
|
59
|
+
// Extract BLE MAC from device ID if available
|
|
60
|
+
// Note: device.id format varies by platform, may need adjustment
|
|
61
|
+
const bleMac = device.id || "";
|
|
62
|
+
const name = device.name || EDILKAMIN_DEVICE_NAME;
|
|
63
|
+
// Calculate WiFi MAC for API calls
|
|
64
|
+
let wifiMac = "";
|
|
65
|
+
if (bleMac && /^[0-9a-f:-]{12,17}$/i.test(bleMac)) {
|
|
66
|
+
try {
|
|
67
|
+
wifiMac = (0, bluetooth_utils_1.bleToWifiMac)(bleMac);
|
|
68
|
+
}
|
|
69
|
+
catch (_a) {
|
|
70
|
+
// device.id may not be a valid MAC format on all platforms
|
|
71
|
+
wifiMac = "";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const discoveredDevice = {
|
|
75
|
+
bleMac,
|
|
76
|
+
wifiMac,
|
|
77
|
+
name,
|
|
78
|
+
// RSSI not directly available from requestDevice
|
|
79
|
+
};
|
|
80
|
+
return [discoveredDevice];
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof Error) {
|
|
84
|
+
if (error.name === "NotFoundError") {
|
|
85
|
+
// User cancelled the device picker
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
throw new Error("Unknown error during Bluetooth scan");
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
exports.scanForDevices = scanForDevices;
|
|
94
|
+
/**
|
|
95
|
+
* Scan for devices with a custom filter.
|
|
96
|
+
* Advanced function for users who need more control over device selection.
|
|
97
|
+
*
|
|
98
|
+
* @param options - Web Bluetooth requestDevice options
|
|
99
|
+
* @returns Promise resolving to the selected BluetoothDevice
|
|
100
|
+
*/
|
|
101
|
+
const scanWithOptions = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
+
if (!isWebBluetoothSupported()) {
|
|
103
|
+
throw new Error("Web Bluetooth API is not supported in this browser.");
|
|
104
|
+
}
|
|
105
|
+
return navigator.bluetooth.requestDevice(options);
|
|
106
|
+
});
|
|
107
|
+
exports.scanWithOptions = scanWithOptions;
|
package/dist/cjs/src/cli.js
CHANGED
|
@@ -153,6 +153,11 @@ const createProgram = () => {
|
|
|
153
153
|
description: "Retrieve device power status",
|
|
154
154
|
getter: (api, jwtToken, mac) => api.getPower(jwtToken, mac),
|
|
155
155
|
},
|
|
156
|
+
{
|
|
157
|
+
commandName: "getPowerLevel",
|
|
158
|
+
description: "Retrieve manual power level (1-5)",
|
|
159
|
+
getter: (api, jwtToken, mac) => api.getPowerLevel(jwtToken, mac),
|
|
160
|
+
},
|
|
156
161
|
{
|
|
157
162
|
commandName: "getEnvironmentTemperature",
|
|
158
163
|
description: "Retrieve environment temperature",
|
|
@@ -163,6 +168,66 @@ const createProgram = () => {
|
|
|
163
168
|
description: "Retrieve target temperature",
|
|
164
169
|
getter: (api, jwtToken, mac) => api.getTargetTemperature(jwtToken, mac),
|
|
165
170
|
},
|
|
171
|
+
{
|
|
172
|
+
commandName: "getFan1Speed",
|
|
173
|
+
description: "Retrieve fan 1 speed",
|
|
174
|
+
getter: (api, jwtToken, mac) => api.getFan1Speed(jwtToken, mac),
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
commandName: "getFan2Speed",
|
|
178
|
+
description: "Retrieve fan 2 speed",
|
|
179
|
+
getter: (api, jwtToken, mac) => api.getFan2Speed(jwtToken, mac),
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
commandName: "getFan3Speed",
|
|
183
|
+
description: "Retrieve fan 3 speed",
|
|
184
|
+
getter: (api, jwtToken, mac) => api.getFan3Speed(jwtToken, mac),
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
commandName: "getStandby",
|
|
188
|
+
description: "Retrieve Standby mode status",
|
|
189
|
+
getter: (api, jwtToken, mac) => api.getStandby(jwtToken, mac),
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
commandName: "getStandbyTime",
|
|
193
|
+
description: "Retrieve standby waiting time in minutes",
|
|
194
|
+
getter: (api, jwtToken, mac) => api.getStandbyTime(jwtToken, mac),
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
commandName: "getAuto",
|
|
198
|
+
description: "Retrieve Auto mode status",
|
|
199
|
+
getter: (api, jwtToken, mac) => api.getAuto(jwtToken, mac),
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
commandName: "getEnvironment2Temperature",
|
|
203
|
+
description: "Retrieve Environment 2 target temperature",
|
|
204
|
+
getter: (api, jwtToken, mac) => api.getEnvironment2Temperature(jwtToken, mac),
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
commandName: "getEnvironment3Temperature",
|
|
208
|
+
description: "Retrieve Environment 3 target temperature",
|
|
209
|
+
getter: (api, jwtToken, mac) => api.getEnvironment3Temperature(jwtToken, mac),
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
commandName: "getMeasureUnit",
|
|
213
|
+
description: "Retrieve temperature unit (true=Fahrenheit, false=Celsius)",
|
|
214
|
+
getter: (api, jwtToken, mac) => api.getMeasureUnit(jwtToken, mac),
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
commandName: "getLanguage",
|
|
218
|
+
description: "Retrieve display language code (0-9)",
|
|
219
|
+
getter: (api, jwtToken, mac) => api.getLanguage(jwtToken, mac),
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
commandName: "getPelletInReserve",
|
|
223
|
+
description: "Retrieve pellet reserve status (true=low/reserve, false=ok)",
|
|
224
|
+
getter: (api, jwtToken, mac) => api.getPelletInReserve(jwtToken, mac),
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
commandName: "getPelletAutonomyTime",
|
|
228
|
+
description: "Retrieve estimated pellet autonomy time",
|
|
229
|
+
getter: (api, jwtToken, mac) => api.getPelletAutonomyTime(jwtToken, mac),
|
|
230
|
+
},
|
|
166
231
|
].forEach(({ commandName, description, getter }) => {
|
|
167
232
|
addLegacyOption(addMacOption(addAuthOptions(program.command(commandName).description(description)))).action((options) => executeGetter(options, getter));
|
|
168
233
|
});
|
|
@@ -173,11 +238,76 @@ const createProgram = () => {
|
|
|
173
238
|
description: "Set the power state of the device (1 for ON, 0 for OFF)",
|
|
174
239
|
setter: (api, jwtToken, mac, value) => api.setPower(jwtToken, mac, value),
|
|
175
240
|
},
|
|
241
|
+
{
|
|
242
|
+
commandName: "setPowerLevel",
|
|
243
|
+
description: "Set manual power level (1-5)",
|
|
244
|
+
setter: (api, jwtToken, mac, value) => api.setPowerLevel(jwtToken, mac, value),
|
|
245
|
+
},
|
|
176
246
|
{
|
|
177
247
|
commandName: "setTargetTemperature",
|
|
178
248
|
description: "Set the target temperature (degree celsius) for a device",
|
|
179
249
|
setter: (api, jwtToken, mac, value) => api.setTargetTemperature(jwtToken, mac, value),
|
|
180
250
|
},
|
|
251
|
+
{
|
|
252
|
+
commandName: "setFan1Speed",
|
|
253
|
+
description: "Set fan 1 speed (0-5)",
|
|
254
|
+
setter: (api, jwtToken, mac, value) => api.setFan1Speed(jwtToken, mac, value),
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
commandName: "setFan2Speed",
|
|
258
|
+
description: "Set fan 2 speed (0-5)",
|
|
259
|
+
setter: (api, jwtToken, mac, value) => api.setFan2Speed(jwtToken, mac, value),
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
commandName: "setFan3Speed",
|
|
263
|
+
description: "Set fan 3 speed (0-5)",
|
|
264
|
+
setter: (api, jwtToken, mac, value) => api.setFan3Speed(jwtToken, mac, value),
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
commandName: "setAirkare",
|
|
268
|
+
description: "Enable/disable Airkare mode (1=on, 0=off)",
|
|
269
|
+
setter: (api, jwtToken, mac, value) => api.setAirkare(jwtToken, mac, value === 1),
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
commandName: "setRelax",
|
|
273
|
+
description: "Enable/disable Relax mode (1=on, 0=off)",
|
|
274
|
+
setter: (api, jwtToken, mac, value) => api.setRelax(jwtToken, mac, value === 1),
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
commandName: "setStandby",
|
|
278
|
+
description: "Enable/disable Standby mode (1=on, 0=off)",
|
|
279
|
+
setter: (api, jwtToken, mac, value) => api.setStandby(jwtToken, mac, value === 1),
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
commandName: "setStandbyTime",
|
|
283
|
+
description: "Set standby waiting time in minutes",
|
|
284
|
+
setter: (api, jwtToken, mac, value) => api.setStandbyTime(jwtToken, mac, value),
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
commandName: "setAuto",
|
|
288
|
+
description: "Enable/disable Auto mode (1=on, 0=off)",
|
|
289
|
+
setter: (api, jwtToken, mac, value) => api.setAuto(jwtToken, mac, value === 1),
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
commandName: "setEnvironment2Temperature",
|
|
293
|
+
description: "Set Environment 2 target temperature (degrees Celsius)",
|
|
294
|
+
setter: (api, jwtToken, mac, value) => api.setEnvironment2Temperature(jwtToken, mac, value),
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
commandName: "setEnvironment3Temperature",
|
|
298
|
+
description: "Set Environment 3 target temperature (degrees Celsius)",
|
|
299
|
+
setter: (api, jwtToken, mac, value) => api.setEnvironment3Temperature(jwtToken, mac, value),
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
commandName: "setMeasureUnit",
|
|
303
|
+
description: "Set temperature unit (1=Fahrenheit, 0=Celsius)",
|
|
304
|
+
setter: (api, jwtToken, mac, value) => api.setMeasureUnit(jwtToken, mac, value === 1),
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
commandName: "setLanguage",
|
|
308
|
+
description: "Set display language (0=IT,1=FR,2=EN,3=ES,4=PT,5=DA,6=NL,7=DE,8=HU,9=PL)",
|
|
309
|
+
setter: (api, jwtToken, mac, value) => api.setLanguage(jwtToken, mac, value),
|
|
310
|
+
},
|
|
181
311
|
].forEach(({ commandName, description, setter }) => {
|
|
182
312
|
addLegacyOption(addMacOption(addAuthOptions(program.command(commandName).description(description)).requiredOption("-v, --value <number>", "Value to set", parseFloat))).action((options) => executeSetter(options, setter));
|
|
183
313
|
});
|
package/dist/cjs/src/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export { bleToWifiMac } from "./bluetooth-utils";
|
|
1
2
|
export { decompressBuffer, isBuffer, processResponse } from "./buffer-utils";
|
|
2
3
|
export { API_URL, NEW_API_URL, OLD_API_URL } from "./constants";
|
|
3
4
|
export { configure, getSession, signIn } from "./library";
|
|
4
5
|
export { serialNumberDisplay, serialNumberFromHex, serialNumberToHex, } from "./serial-utils";
|
|
5
|
-
export { BufferEncodedType, CommandsType, DeviceAssociationBody, DeviceAssociationResponse, DeviceInfoRawType, DeviceInfoType, EditDeviceAssociationBody, StatusType, TemperaturesType, UserParametersType, } from "./types";
|
|
6
|
+
export { BufferEncodedType, CommandsType, DeviceAssociationBody, DeviceAssociationResponse, DeviceInfoRawType, DeviceInfoType, DiscoveredDevice, EditDeviceAssociationBody, StatusType, TemperaturesType, UserParametersType, } from "./types";
|
|
6
7
|
export declare const deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("./types").DeviceInfoType>, registerDevice: (jwtToken: string, macAddress: string, serialNumber: string, deviceName?: string, deviceRoom?: string) => Promise<import("./types").DeviceAssociationResponse>, editDevice: (jwtToken: string, macAddress: string, deviceName?: string, deviceRoom?: string) => Promise<import("./types").DeviceAssociationResponse>, setPower: (jwtToken: string, macAddress: string, value: number) => Promise<unknown>, setPowerOff: (jwtToken: string, macAddress: string) => Promise<unknown>, setPowerOn: (jwtToken: string, macAddress: string) => Promise<unknown>, getPower: (jwtToken: string, macAddress: string) => Promise<boolean>, getEnvironmentTemperature: (jwtToken: string, macAddress: string) => Promise<number>, getTargetTemperature: (jwtToken: string, macAddress: string) => Promise<number>, setTargetTemperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<unknown>;
|
package/dist/cjs/src/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var _a;
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.setTargetTemperature = exports.getTargetTemperature = exports.getEnvironmentTemperature = exports.getPower = exports.setPowerOn = exports.setPowerOff = exports.setPower = exports.editDevice = exports.registerDevice = exports.deviceInfo = exports.serialNumberToHex = exports.serialNumberFromHex = exports.serialNumberDisplay = exports.signIn = exports.getSession = exports.configure = exports.OLD_API_URL = exports.NEW_API_URL = exports.API_URL = exports.processResponse = exports.isBuffer = exports.decompressBuffer = void 0;
|
|
4
|
+
exports.setTargetTemperature = exports.getTargetTemperature = exports.getEnvironmentTemperature = exports.getPower = exports.setPowerOn = exports.setPowerOff = exports.setPower = exports.editDevice = exports.registerDevice = exports.deviceInfo = exports.serialNumberToHex = exports.serialNumberFromHex = exports.serialNumberDisplay = exports.signIn = exports.getSession = exports.configure = exports.OLD_API_URL = exports.NEW_API_URL = exports.API_URL = exports.processResponse = exports.isBuffer = exports.decompressBuffer = exports.bleToWifiMac = void 0;
|
|
5
5
|
const library_1 = require("./library");
|
|
6
|
+
var bluetooth_utils_1 = require("./bluetooth-utils");
|
|
7
|
+
Object.defineProperty(exports, "bleToWifiMac", { enumerable: true, get: function () { return bluetooth_utils_1.bleToWifiMac; } });
|
|
6
8
|
var buffer_utils_1 = require("./buffer-utils");
|
|
7
9
|
Object.defineProperty(exports, "decompressBuffer", { enumerable: true, get: function () { return buffer_utils_1.decompressBuffer; } });
|
|
8
10
|
Object.defineProperty(exports, "isBuffer", { enumerable: true, get: function () { return buffer_utils_1.isBuffer; } });
|
|
@@ -48,8 +48,34 @@ declare const configure: (baseURL?: string) => {
|
|
|
48
48
|
setPowerOff: (jwtToken: string, macAddress: string) => Promise<unknown>;
|
|
49
49
|
setPowerOn: (jwtToken: string, macAddress: string) => Promise<unknown>;
|
|
50
50
|
getPower: (jwtToken: string, macAddress: string) => Promise<boolean>;
|
|
51
|
+
setPowerLevel: (jwtToken: string, macAddress: string, level: number) => Promise<unknown>;
|
|
52
|
+
getPowerLevel: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
53
|
+
setFan1Speed: (jwtToken: string, macAddress: string, speed: number) => Promise<unknown>;
|
|
54
|
+
setFan2Speed: (jwtToken: string, macAddress: string, speed: number) => Promise<unknown>;
|
|
55
|
+
setFan3Speed: (jwtToken: string, macAddress: string, speed: number) => Promise<unknown>;
|
|
56
|
+
getFan1Speed: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
57
|
+
getFan2Speed: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
58
|
+
getFan3Speed: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
59
|
+
setAirkare: (jwtToken: string, macAddress: string, enabled: boolean) => Promise<unknown>;
|
|
60
|
+
setRelax: (jwtToken: string, macAddress: string, enabled: boolean) => Promise<unknown>;
|
|
61
|
+
setStandby: (jwtToken: string, macAddress: string, enabled: boolean) => Promise<unknown>;
|
|
62
|
+
getStandby: (jwtToken: string, macAddress: string) => Promise<boolean>;
|
|
63
|
+
setStandbyTime: (jwtToken: string, macAddress: string, minutes: number) => Promise<unknown>;
|
|
64
|
+
getStandbyTime: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
65
|
+
setAuto: (jwtToken: string, macAddress: string, enabled: boolean) => Promise<unknown>;
|
|
66
|
+
getAuto: (jwtToken: string, macAddress: string) => Promise<boolean>;
|
|
51
67
|
getEnvironmentTemperature: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
52
68
|
getTargetTemperature: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
53
69
|
setTargetTemperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<unknown>;
|
|
70
|
+
setEnvironment2Temperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<unknown>;
|
|
71
|
+
getEnvironment2Temperature: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
72
|
+
setEnvironment3Temperature: (jwtToken: string, macAddress: string, temperature: number) => Promise<unknown>;
|
|
73
|
+
getEnvironment3Temperature: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
74
|
+
setMeasureUnit: (jwtToken: string, macAddress: string, isFahrenheit: boolean) => Promise<unknown>;
|
|
75
|
+
getMeasureUnit: (jwtToken: string, macAddress: string) => Promise<boolean>;
|
|
76
|
+
setLanguage: (jwtToken: string, macAddress: string, languageCode: number) => Promise<unknown>;
|
|
77
|
+
getLanguage: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
78
|
+
getPelletInReserve: (jwtToken: string, macAddress: string) => Promise<boolean>;
|
|
79
|
+
getPelletAutonomyTime: (jwtToken: string, macAddress: string) => Promise<number>;
|
|
54
80
|
};
|
|
55
81
|
export { configure, configureAmplify, createAuthService, getSession, headers, signIn, };
|