edilkamin 1.0.1 → 1.2.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/README.md +56 -0
- package/dist/package.json +48 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.js +85 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +11 -0
- package/dist/src/library.d.ts +12 -0
- package/dist/src/library.js +57 -0
- package/dist/src/library.test.d.ts +1 -0
- package/dist/src/library.test.js +97 -0
- package/package.json +17 -5
- package/dist/axios.d.ts +0 -2
- package/dist/axios.js +0 -8
- package/dist/index.d.ts +0 -2
- package/dist/index.js +0 -9
- package/dist/library.d.ts +0 -11
- package/dist/library.js +0 -53
- /package/dist/{constants.d.ts → src/constants.d.ts} +0 -0
- /package/dist/{constants.js → src/constants.js} +0 -0
- /package/dist/{types.d.ts → src/types.d.ts} +0 -0
- /package/dist/{types.js → src/types.js} +0 -0
package/README.md
CHANGED
|
@@ -1,18 +1,73 @@
|
|
|
1
1
|
# Edilkamin.js
|
|
2
2
|
|
|
3
3
|
[](https://github.com/AndreMiras/edilkamin.js/actions/workflows/tests.yml)
|
|
4
|
+
[](https://github.com/AndreMiras/edilkamin.js/actions/workflows/cli-tests.yml)
|
|
4
5
|
[](https://github.com/AndreMiras/edilkamin.js/actions/workflows/documentation.yml)
|
|
5
6
|
[](https://badge.fury.io/js/edilkamin)
|
|
6
7
|
|
|
7
8
|
This is a library for the [Reverse Engineered](docs/ReverseEngineering.md) "The Mind" Edilkamin API.
|
|
8
9
|
The Mind offers an app/API to remote control the Edilkamin pellet stoves.
|
|
9
10
|
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
Using npm:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
npm install edilkamin
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Using yarn:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
yarn add edilkamin
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage
|
|
26
|
+
|
|
27
|
+
Basic usage:
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { signIn, deviceInfo, setPowerOff } from "edilkamin";
|
|
31
|
+
|
|
32
|
+
const macAddress = "aabbccddeeff";
|
|
33
|
+
const token = signIn(username, password);
|
|
34
|
+
deviceInfo(token, macAddress).then(console.log);
|
|
35
|
+
setPowerOff(token, macAddress).then(console.log);
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
It's also possible to change the default backend URL:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
import { signIn, configure } from "edilkamin";
|
|
42
|
+
|
|
43
|
+
const baseUrl = "https://my-proxy.com/";
|
|
44
|
+
const { deviceInfo, setPower } = configure(baseUrl);
|
|
45
|
+
deviceInfo(token, macAddress).then(console.log);
|
|
46
|
+
setPower(token, macAddress, 0).then(console.log);
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## CLI
|
|
50
|
+
|
|
51
|
+
The library includes a CLI tool that is useful for debugging.
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
yarn cli deviceInfo --mac $MAC --username $USERNAME --password $PASSWORD
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or with `npx` once the library is installed:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
npx edilkamin deviceInfo --mac $MAC --username $USERNAME --password $PASSWORD
|
|
61
|
+
```
|
|
62
|
+
|
|
10
63
|
## Motivations
|
|
64
|
+
|
|
11
65
|
- providing an open source web alternative
|
|
12
66
|
to the [proprietary mobile app](https://play.google.com/store/apps/details?id=com.edilkamin.stufe)
|
|
13
67
|
- improving the interoperability (Nest, HomeAssistant...)
|
|
14
68
|
|
|
15
69
|
## Roadmap
|
|
70
|
+
|
|
16
71
|
- [x] AWS Amplify/ Cognito authentication
|
|
17
72
|
- [x] unauthenticated endpoint call
|
|
18
73
|
- [x] authenticated endpoint call
|
|
@@ -21,6 +76,7 @@ The Mind offers an app/API to remote control the Edilkamin pellet stoves.
|
|
|
21
76
|
- [ ] set temperature
|
|
22
77
|
|
|
23
78
|
## Limitations
|
|
79
|
+
|
|
24
80
|
It seems like there's no endpoint to list stoves associated to a user.
|
|
25
81
|
The way the official app seem to work is by probing the stove via bluetooth.
|
|
26
82
|
Then cache the stove MAC address to a local database for later use.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "edilkamin",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"cli": "ts-node src/cli.ts",
|
|
9
|
+
"test": "mocha --require ts-node/register src/*.test.ts",
|
|
10
|
+
"lint": "prettier --check src docs .github *.md",
|
|
11
|
+
"format": "prettier --write src docs .github *.md",
|
|
12
|
+
"build": "tsc"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"/dist"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/AndreMiras/edilkamin.js.git"
|
|
20
|
+
},
|
|
21
|
+
"author": "Andre Miras",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/AndreMiras/edilkamin.js/issues"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/AndreMiras/edilkamin.js#readme",
|
|
27
|
+
"bin": {
|
|
28
|
+
"edilkamin": "dist/cli.js"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@aws-amplify/core": "^4.3.14",
|
|
32
|
+
"aws-amplify": "^4.3.14",
|
|
33
|
+
"aws-crt": "^1.14.5"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@aws-amplify/cli": "^7.6.21",
|
|
37
|
+
"@types/mocha": "^10.0.10",
|
|
38
|
+
"@types/sinon": "^17.0.3",
|
|
39
|
+
"mocha": "^10.8.2",
|
|
40
|
+
"prettier": "^2.5.1",
|
|
41
|
+
"sinon": "^19.0.2",
|
|
42
|
+
"ts-node": "^10.9.1",
|
|
43
|
+
"typedoc": "^0.22.12"
|
|
44
|
+
},
|
|
45
|
+
"optionalDependencies": {
|
|
46
|
+
"commander": "^12.1.0"
|
|
47
|
+
}
|
|
48
|
+
}
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
4
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
5
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
6
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
7
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
8
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
9
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
13
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.main = void 0;
|
|
17
|
+
const library_1 = require("./library");
|
|
18
|
+
const commander_1 = require("commander");
|
|
19
|
+
const readline_1 = __importDefault(require("readline"));
|
|
20
|
+
const package_json_1 = require("../package.json");
|
|
21
|
+
const promptPassword = () => {
|
|
22
|
+
const rl = readline_1.default.createInterface({
|
|
23
|
+
input: process.stdin,
|
|
24
|
+
output: process.stdout,
|
|
25
|
+
terminal: true,
|
|
26
|
+
});
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
rl.question("Enter password: ", (password) => {
|
|
29
|
+
// Hide the password input
|
|
30
|
+
readline_1.default.moveCursor(process.stdout, 0, -1);
|
|
31
|
+
readline_1.default.clearLine(process.stdout, 0);
|
|
32
|
+
rl.close();
|
|
33
|
+
resolve(password);
|
|
34
|
+
});
|
|
35
|
+
// Disable input echoing for password
|
|
36
|
+
process.stdin.on("data", (char) => {
|
|
37
|
+
if (char.toString("hex") === "0d0a")
|
|
38
|
+
return; // Enter key
|
|
39
|
+
process.stdout.write("*");
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Adds common options (username and password) to a command.
|
|
45
|
+
* @param command The command to which options should be added.
|
|
46
|
+
* @returns The command with options added.
|
|
47
|
+
*/
|
|
48
|
+
const addCommonOptions = (command) => command
|
|
49
|
+
.requiredOption("-u, --username <username>", "Username")
|
|
50
|
+
.option("-p, --password <password>", "Password");
|
|
51
|
+
const createProgram = () => {
|
|
52
|
+
const program = new commander_1.Command();
|
|
53
|
+
program
|
|
54
|
+
.name("edilkamin-cli")
|
|
55
|
+
.description("CLI tool for interacting with the Edilkamin API")
|
|
56
|
+
.version(package_json_1.version);
|
|
57
|
+
// Command: signIn
|
|
58
|
+
addCommonOptions(program.command("signIn").description("Sign in and retrieve a JWT token")).action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
59
|
+
const { username, password } = options;
|
|
60
|
+
const pwd = password || (yield promptPassword());
|
|
61
|
+
const jwtToken = yield library_1.signIn(username, pwd);
|
|
62
|
+
console.log("JWT Token:", jwtToken);
|
|
63
|
+
}));
|
|
64
|
+
// Command: deviceInfo
|
|
65
|
+
addCommonOptions(program
|
|
66
|
+
.command("deviceInfo")
|
|
67
|
+
.description("Retrieve device info for a specific MAC address")
|
|
68
|
+
.requiredOption("-m, --mac <macAddress>", "MAC address of the device")).action((options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
69
|
+
const { username, password, mac } = options;
|
|
70
|
+
const pwd = password || (yield promptPassword());
|
|
71
|
+
const jwtToken = yield library_1.signIn(username, pwd);
|
|
72
|
+
const api = library_1.configure(); // Use the default API configuration
|
|
73
|
+
const deviceInfo = yield api.deviceInfo(jwtToken, mac);
|
|
74
|
+
console.log("Device Info:", deviceInfo.data);
|
|
75
|
+
}));
|
|
76
|
+
return program;
|
|
77
|
+
};
|
|
78
|
+
const main = () => {
|
|
79
|
+
const program = createProgram();
|
|
80
|
+
program.parse(process.argv);
|
|
81
|
+
};
|
|
82
|
+
exports.main = main;
|
|
83
|
+
if (require.main === module) {
|
|
84
|
+
main();
|
|
85
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { API_URL } from "./constants";
|
|
2
|
+
export { CommandsType, DeviceInfoType, StatusType, TemperaturesType, UserParametersType, } from "./types";
|
|
3
|
+
export { signIn, configure } from "./library";
|
|
4
|
+
export declare const deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<import("./types").DeviceInfoType, any>>, setPower: (jwtToken: string, macAddress: string, value: number) => Promise<import("axios").AxiosResponse<any, any>>, setPowerOff: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>, setPowerOn: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.setPowerOn = exports.setPowerOff = exports.setPower = exports.deviceInfo = void 0;
|
|
5
|
+
const library_1 = require("./library");
|
|
6
|
+
var constants_1 = require("./constants");
|
|
7
|
+
Object.defineProperty(exports, "API_URL", { enumerable: true, get: function () { return constants_1.API_URL; } });
|
|
8
|
+
var library_2 = require("./library");
|
|
9
|
+
Object.defineProperty(exports, "signIn", { enumerable: true, get: function () { return library_2.signIn; } });
|
|
10
|
+
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return library_2.configure; } });
|
|
11
|
+
_a = library_1.configure(), exports.deviceInfo = _a.deviceInfo, exports.setPower = _a.setPower, exports.setPowerOff = _a.setPowerOff, exports.setPowerOn = _a.setPowerOn;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DeviceInfoType } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Sign in to return the JWT token.
|
|
4
|
+
*/
|
|
5
|
+
declare const signIn: (username: string, password: string) => Promise<string>;
|
|
6
|
+
declare const configure: (baseURL?: string) => {
|
|
7
|
+
deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<DeviceInfoType, any>>;
|
|
8
|
+
setPower: (jwtToken: string, macAddress: string, value: number) => Promise<import("axios").AxiosResponse<any, any>>;
|
|
9
|
+
setPowerOff: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>;
|
|
10
|
+
setPowerOn: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any, any>>;
|
|
11
|
+
};
|
|
12
|
+
export { signIn, configure };
|
|
@@ -0,0 +1,57 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.configure = exports.signIn = void 0;
|
|
16
|
+
const aws_amplify_1 = require("aws-amplify");
|
|
17
|
+
const axios_1 = __importDefault(require("axios"));
|
|
18
|
+
const constants_1 = require("./constants");
|
|
19
|
+
const amplifyconfiguration = {
|
|
20
|
+
Auth: {
|
|
21
|
+
region: "eu-central-1",
|
|
22
|
+
userPoolId: "eu-central-1_BYmQ2VBlo",
|
|
23
|
+
userPoolWebClientId: "7sc1qltkqobo3ddqsk4542dg2h",
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
aws_amplify_1.Amplify.configure(amplifyconfiguration);
|
|
27
|
+
const headers = (jwtToken) => ({ Authorization: `Bearer ${jwtToken}` });
|
|
28
|
+
/**
|
|
29
|
+
* Sign in to return the JWT token.
|
|
30
|
+
*/
|
|
31
|
+
const signIn = (username, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
const user = yield aws_amplify_1.Auth.signIn(username, password);
|
|
33
|
+
return user.getSignInUserSession().getAccessToken().jwtToken;
|
|
34
|
+
});
|
|
35
|
+
exports.signIn = signIn;
|
|
36
|
+
const deviceInfo = (axiosInstance) => (jwtToken, macAddress) => axiosInstance.get(`device/${macAddress}/info`, {
|
|
37
|
+
headers: headers(jwtToken),
|
|
38
|
+
});
|
|
39
|
+
const mqttCommand = (axiosInstance) => (jwtToken, macAddress, payload) => axiosInstance.put("mqtt/command", Object.assign({ mac_address: macAddress }, payload), { headers: headers(jwtToken) });
|
|
40
|
+
const setPower = (axiosInstance) => (jwtToken, macAddress, value) => mqttCommand(axiosInstance)(jwtToken, macAddress, { name: "power", value });
|
|
41
|
+
const setPowerOn = (axiosInstance) => (jwtToken, macAddress) => setPower(axiosInstance)(jwtToken, macAddress, 1);
|
|
42
|
+
const setPowerOff = (axiosInstance) => (jwtToken, macAddress) => setPower(axiosInstance)(jwtToken, macAddress, 0);
|
|
43
|
+
const configure = (baseURL = constants_1.API_URL) => {
|
|
44
|
+
const axiosInstance = axios_1.default.create({ baseURL });
|
|
45
|
+
const deviceInfoInstance = deviceInfo(axiosInstance);
|
|
46
|
+
const setPowerInstance = setPower(axiosInstance);
|
|
47
|
+
const setPowerOffInstance = setPowerOff(axiosInstance);
|
|
48
|
+
const setPowerOnInstance = setPowerOn(axiosInstance);
|
|
49
|
+
return {
|
|
50
|
+
deviceInfo: deviceInfoInstance,
|
|
51
|
+
setPower: setPowerInstance,
|
|
52
|
+
setPowerOff: setPowerOffInstance,
|
|
53
|
+
setPowerOn: setPowerOnInstance,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
exports.configure = configure;
|
|
57
|
+
const defaultApi = configure();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const assert_1 = require("assert");
|
|
16
|
+
const sinon_1 = __importDefault(require("sinon"));
|
|
17
|
+
const aws_amplify_1 = require("aws-amplify");
|
|
18
|
+
const axios_1 = __importDefault(require("axios"));
|
|
19
|
+
const library_1 = require("../src/library");
|
|
20
|
+
describe("library", () => {
|
|
21
|
+
let axiosStub;
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
axiosStub = sinon_1.default.stub(axios_1.default, "create").returns({
|
|
24
|
+
get: sinon_1.default.stub(),
|
|
25
|
+
put: sinon_1.default.stub(),
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
afterEach(() => {
|
|
29
|
+
sinon_1.default.restore();
|
|
30
|
+
});
|
|
31
|
+
describe("signIn", () => {
|
|
32
|
+
it("should return a JWT token on successful login", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
33
|
+
const expectedJwtToken = "mockToken123";
|
|
34
|
+
const mockUserSession = {
|
|
35
|
+
getAccessToken: () => ({ jwtToken: expectedJwtToken }),
|
|
36
|
+
};
|
|
37
|
+
const mockUser = {
|
|
38
|
+
getSignInUserSession: () => mockUserSession,
|
|
39
|
+
};
|
|
40
|
+
const signInStub = sinon_1.default.stub(aws_amplify_1.Auth, "signIn").resolves(mockUser);
|
|
41
|
+
const jwtToken = yield library_1.signIn("mockUser", "mockPassword");
|
|
42
|
+
assert_1.strict.ok(signInStub.calledOnce);
|
|
43
|
+
assert_1.strict.equal(jwtToken, expectedJwtToken);
|
|
44
|
+
}));
|
|
45
|
+
});
|
|
46
|
+
describe("configure", () => {
|
|
47
|
+
it("should create API methods with the correct baseURL", () => {
|
|
48
|
+
const baseURL = "https://example.com/api";
|
|
49
|
+
const api = library_1.configure(baseURL);
|
|
50
|
+
assert_1.strict.ok(axiosStub.calledOnce);
|
|
51
|
+
assert_1.strict.deepEqual(axiosStub.firstCall.args[0], { baseURL });
|
|
52
|
+
assert_1.strict.deepEqual(Object.keys(api), [
|
|
53
|
+
"deviceInfo",
|
|
54
|
+
"setPower",
|
|
55
|
+
"setPowerOff",
|
|
56
|
+
"setPowerOn",
|
|
57
|
+
]);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
describe("API Methods", () => {
|
|
61
|
+
it("should call axios for deviceInfo", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
62
|
+
const mockAxios = {
|
|
63
|
+
get: sinon_1.default
|
|
64
|
+
.stub()
|
|
65
|
+
.resolves({ data: { id: "123", name: "Mock Device" } }),
|
|
66
|
+
};
|
|
67
|
+
axiosStub.returns(mockAxios);
|
|
68
|
+
const api = library_1.configure("https://example.com/api");
|
|
69
|
+
const result = yield api.deviceInfo("mockToken", "mockMacAddress");
|
|
70
|
+
assert_1.strict.ok(mockAxios.get.calledOnce);
|
|
71
|
+
assert_1.strict.equal(mockAxios.get.firstCall.args[0], "device/mockMacAddress/info");
|
|
72
|
+
assert_1.strict.deepEqual(mockAxios.get.firstCall.args[1], {
|
|
73
|
+
headers: { Authorization: "Bearer mockToken" },
|
|
74
|
+
});
|
|
75
|
+
assert_1.strict.deepEqual(result.data, { id: "123", name: "Mock Device" });
|
|
76
|
+
}));
|
|
77
|
+
it("should call axios for setPowerOn", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
78
|
+
const mockAxios = {
|
|
79
|
+
put: sinon_1.default.stub().resolves({ status: 200 }),
|
|
80
|
+
};
|
|
81
|
+
axiosStub.returns(mockAxios);
|
|
82
|
+
const api = library_1.configure("https://example.com/api");
|
|
83
|
+
const result = yield api.setPowerOn("mockToken", "mockMacAddress");
|
|
84
|
+
assert_1.strict.ok(mockAxios.put.calledOnce);
|
|
85
|
+
assert_1.strict.equal(mockAxios.put.firstCall.args[0], "mqtt/command");
|
|
86
|
+
assert_1.strict.deepEqual(mockAxios.put.firstCall.args[1], {
|
|
87
|
+
mac_address: "mockMacAddress",
|
|
88
|
+
name: "power",
|
|
89
|
+
value: 1,
|
|
90
|
+
});
|
|
91
|
+
assert_1.strict.deepEqual(mockAxios.put.firstCall.args[2], {
|
|
92
|
+
headers: { Authorization: "Bearer mockToken" },
|
|
93
|
+
});
|
|
94
|
+
assert_1.strict.equal(result.status, 200);
|
|
95
|
+
}));
|
|
96
|
+
});
|
|
97
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "edilkamin",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"
|
|
8
|
+
"cli": "ts-node src/cli.ts",
|
|
9
|
+
"test": "mocha --require ts-node/register src/*.test.ts",
|
|
10
|
+
"lint": "prettier --check src docs .github *.md",
|
|
11
|
+
"format": "prettier --write src docs .github *.md",
|
|
11
12
|
"build": "tsc"
|
|
12
13
|
},
|
|
13
14
|
"files": [
|
|
@@ -23,14 +24,25 @@
|
|
|
23
24
|
"url": "https://github.com/AndreMiras/edilkamin.js/issues"
|
|
24
25
|
},
|
|
25
26
|
"homepage": "https://github.com/AndreMiras/edilkamin.js#readme",
|
|
27
|
+
"bin": {
|
|
28
|
+
"edilkamin": "dist/cli.js"
|
|
29
|
+
},
|
|
26
30
|
"dependencies": {
|
|
27
31
|
"@aws-amplify/core": "^4.3.14",
|
|
28
|
-
"aws-amplify": "^4.3.14"
|
|
32
|
+
"aws-amplify": "^4.3.14",
|
|
33
|
+
"aws-crt": "^1.14.5"
|
|
29
34
|
},
|
|
30
35
|
"devDependencies": {
|
|
31
36
|
"@aws-amplify/cli": "^7.6.21",
|
|
37
|
+
"@types/mocha": "^10.0.10",
|
|
38
|
+
"@types/sinon": "^17.0.3",
|
|
39
|
+
"mocha": "^10.8.2",
|
|
32
40
|
"prettier": "^2.5.1",
|
|
41
|
+
"sinon": "^19.0.2",
|
|
33
42
|
"ts-node": "^10.9.1",
|
|
34
43
|
"typedoc": "^0.22.12"
|
|
44
|
+
},
|
|
45
|
+
"optionalDependencies": {
|
|
46
|
+
"commander": "^12.1.0"
|
|
35
47
|
}
|
|
36
48
|
}
|
package/dist/axios.d.ts
DELETED
package/dist/axios.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const axios_1 = require("axios");
|
|
4
|
-
const constants_1 = require("./constants");
|
|
5
|
-
const axiosInstance = axios_1.default.create({
|
|
6
|
-
baseURL: constants_1.API_URL,
|
|
7
|
-
});
|
|
8
|
-
exports.default = axiosInstance;
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
var library_1 = require("./library");
|
|
4
|
-
Object.defineProperty(exports, "signIn", { enumerable: true, get: function () { return library_1.signIn; } });
|
|
5
|
-
Object.defineProperty(exports, "main", { enumerable: true, get: function () { return library_1.main; } });
|
|
6
|
-
Object.defineProperty(exports, "deviceInfo", { enumerable: true, get: function () { return library_1.deviceInfo; } });
|
|
7
|
-
Object.defineProperty(exports, "setPower", { enumerable: true, get: function () { return library_1.setPower; } });
|
|
8
|
-
Object.defineProperty(exports, "setPowerOff", { enumerable: true, get: function () { return library_1.setPowerOff; } });
|
|
9
|
-
Object.defineProperty(exports, "setPowerOn", { enumerable: true, get: function () { return library_1.setPowerOn; } });
|
package/dist/library.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { DeviceInfoType } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Sign in to return the JWT token.
|
|
4
|
-
*/
|
|
5
|
-
declare const signIn: (username: string, password: string) => Promise<string>;
|
|
6
|
-
declare const deviceInfo: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<DeviceInfoType>>;
|
|
7
|
-
declare const setPower: (jwtToken: string, macAddress: string, value: number) => Promise<import("axios").AxiosResponse<any>>;
|
|
8
|
-
declare const setPowerOn: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any>>;
|
|
9
|
-
declare const setPowerOff: (jwtToken: string, macAddress: string) => Promise<import("axios").AxiosResponse<any>>;
|
|
10
|
-
declare const main: () => Promise<void>;
|
|
11
|
-
export { signIn, main, deviceInfo, setPower, setPowerOff, setPowerOn };
|
package/dist/library.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
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.setPowerOn = exports.setPowerOff = exports.setPower = exports.deviceInfo = exports.main = exports.signIn = void 0;
|
|
13
|
-
const assert_1 = require("assert");
|
|
14
|
-
const aws_amplify_1 = require("aws-amplify");
|
|
15
|
-
const axios_1 = require("./axios");
|
|
16
|
-
const amplifyconfiguration = {
|
|
17
|
-
Auth: {
|
|
18
|
-
region: "eu-central-1",
|
|
19
|
-
userPoolId: "eu-central-1_BYmQ2VBlo",
|
|
20
|
-
userPoolWebClientId: "7sc1qltkqobo3ddqsk4542dg2h",
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
aws_amplify_1.Amplify.configure(amplifyconfiguration);
|
|
24
|
-
const headers = (jwtToken) => ({ Authorization: `Bearer ${jwtToken}` });
|
|
25
|
-
/**
|
|
26
|
-
* Sign in to return the JWT token.
|
|
27
|
-
*/
|
|
28
|
-
const signIn = (username, password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
-
const user = yield aws_amplify_1.Auth.signIn(username, password);
|
|
30
|
-
return user.getSignInUserSession().getAccessToken().jwtToken;
|
|
31
|
-
});
|
|
32
|
-
exports.signIn = signIn;
|
|
33
|
-
const deviceInfo = (jwtToken, macAddress) => axios_1.default.get(`device/${macAddress}/info`, {
|
|
34
|
-
headers: headers(jwtToken),
|
|
35
|
-
});
|
|
36
|
-
exports.deviceInfo = deviceInfo;
|
|
37
|
-
const mqttCommand = (jwtToken, macAddress, payload) => axios_1.default.put(`mqtt/command`, Object.assign({ mac_address: macAddress }, payload), { headers: headers(jwtToken) });
|
|
38
|
-
const setPower = (jwtToken, macAddress, value) => mqttCommand(jwtToken, macAddress, { name: "power", value });
|
|
39
|
-
exports.setPower = setPower;
|
|
40
|
-
const setPowerOn = (jwtToken, macAddress) => setPower(jwtToken, macAddress, 1);
|
|
41
|
-
exports.setPowerOn = setPowerOn;
|
|
42
|
-
const setPowerOff = (jwtToken, macAddress) => setPower(jwtToken, macAddress, 0);
|
|
43
|
-
exports.setPowerOff = setPowerOff;
|
|
44
|
-
const main = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
45
|
-
const { USERNAME, PASSWORD, MAC_ADDRESS } = process.env;
|
|
46
|
-
assert_1.ok(USERNAME);
|
|
47
|
-
assert_1.ok(PASSWORD);
|
|
48
|
-
assert_1.ok(MAC_ADDRESS);
|
|
49
|
-
const jwtToken = yield signIn(USERNAME, PASSWORD);
|
|
50
|
-
const info = yield deviceInfo(jwtToken, MAC_ADDRESS);
|
|
51
|
-
console.log({ info });
|
|
52
|
-
});
|
|
53
|
-
exports.main = main;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|