Skip to content

Commit

Permalink
✨ Set target temperature
Browse files Browse the repository at this point in the history
Support setting the target temperature (degree celsius) of a device.
Also add setTargetTemperature and setPower commands to the CLI.
  • Loading branch information
AndreMiras committed Dec 6, 2024
1 parent a6b7f65 commit 8b5299d
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 1 deletion.
52 changes: 52 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,29 @@ const executeGetter = async (
console.log(result);
};

/**
* Executes a setter command by handling common steps (authentication, API initialization).
* @param options The options passed from the CLI command.
* @param setter A function to call on the configured API object.
*/
const executeSetter = async (
options: { username: string; password?: string; mac: string; value: number },
setter: (
api: ReturnType<typeof configure>,
jwtToken: string,
mac: string,
value: number
) => Promise<unknown>
): Promise<void> => {
const { username, password, mac, value } = options;
const normalizedMac = mac.replace(/:/g, "");
const pwd = password || (await promptPassword());
const jwtToken = await signIn(username, pwd);
const api = configure();
const result = await setter(api, jwtToken, normalizedMac, value);
console.log(result);
};

const createProgram = (): Command => {
const program = new Command();
program
Expand Down Expand Up @@ -125,6 +148,35 @@ const createProgram = (): Command => {
addAuthOptions(program.command(commandName).description(description))
).action((options) => executeGetter(options, getter));
});
// Generic setter commands
[
{
commandName: "setPower",
description: "Set the power state of the device (1 for ON, 0 for OFF)",
setter: (
api: ReturnType<typeof configure>,
jwtToken: string,
mac: string,
value: number
) => api.setPower(jwtToken, mac, value),
},
{
commandName: "setTargetTemperature",
description: "Set the target temperature (degree celsius) for a device",
setter: (
api: ReturnType<typeof configure>,
jwtToken: string,
mac: string,
value: number
) => api.setTargetTemperature(jwtToken, mac, value),
},
].forEach(({ commandName, description, setter }) => {
addMacOption(
addAuthOptions(
program.command(commandName).description(description)
).requiredOption("-v, --value <number>", "Value to set", parseFloat)
).action((options) => executeSetter(options, setter));
});

return program;
};
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export const {
getPower,
getEnvironmentTemperature,
getTargetTemperature,
setTargetTemperature,
} = configure();
47 changes: 47 additions & 0 deletions src/library.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ describe("library", () => {
"getPower",
"getEnvironmentTemperature",
"getTargetTemperature",
"setTargetTemperature",
];
it("should create API methods with the correct baseURL", () => {
const baseURL = "https://example.com/api";
Expand Down Expand Up @@ -225,5 +226,51 @@ describe("library", () => {
assert.equal(result, expectedResult);
});
});
// Setter tests
const setterTests = [
{
method: "setTargetTemperature",
call: (
api: ReturnType<typeof configure>,
token: string,
mac: string,
value: number
) => api.setTargetTemperature(token, mac, value),
payload: {
name: "enviroment_1_temperature",
value: 20,
},
},
];
setterTests.forEach(({ method, call, payload }) => {
it(`should call axios and send the correct payload for ${method}`, async () => {
const mockAxios = {
put: sinon.stub().resolves({ status: 200 }),
};
axiosStub.returns(mockAxios);
const api = configure("https://example.com/api");

const result = await call(
api,
expectedToken,
"mockMacAddress",
payload.value
);

assert.deepEqual(mockAxios.put.args, [
[
"mqtt/command",
{
mac_address: "mockMacAddress",
...payload,
},
{
headers: { Authorization: `Bearer ${expectedToken}` },
},
],
]);
assert.equal(result.status, 200);
});
});
});
});
20 changes: 19 additions & 1 deletion src/library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,13 +169,29 @@ const getTargetTemperature =
*
* @param {string} jwtToken - The JWT token for authentication.
* @param {string} macAddress - The MAC address of the device.
* @returns {Promise<number>} - A promise that resolves to the target temperature.
* @returns {Promise<number>} - A promise that resolves to the target temperature (degree celsius).
*/
async (jwtToken: string, macAddress: string): Promise<number> => {
const info = await deviceInfo(axiosInstance)(jwtToken, macAddress);
return info.nvm.user_parameters.enviroment_1_temperature;
};

const setTargetTemperature =
(axiosInstance: AxiosInstance) =>
/**
* Sends a command to set the target temperature (degree celsius) of a device.
*
* @param {string} jwtToken - The JWT token for authentication.
* @param {string} macAddress - The MAC address of the device.
* @param {number} temperature - The desired target temperature (degree celsius).
* @returns {Promise<string>} - A promise that resolves to the command response.
*/
(jwtToken: string, macAddress: string, temperature: number) =>
mqttCommand(axiosInstance)(jwtToken, macAddress, {
name: "enviroment_1_temperature",
value: temperature,
});

/**
* Configures the library for API interactions.
* Initializes API methods with a specified base URL.
Expand All @@ -197,6 +213,7 @@ const configure = (baseURL: string = API_URL) => {
const getEnvironmentTemperatureInstance =
getEnvironmentTemperature(axiosInstance);
const getTargetTemperatureInstance = getTargetTemperature(axiosInstance);
const setTargetTemperatureInstance = setTargetTemperature(axiosInstance);
return {
deviceInfo: deviceInfoInstance,
setPower: setPowerInstance,
Expand All @@ -205,6 +222,7 @@ const configure = (baseURL: string = API_URL) => {
getPower: getPowerInstance,
getEnvironmentTemperature: getEnvironmentTemperatureInstance,
getTargetTemperature: getTargetTemperatureInstance,
setTargetTemperature: setTargetTemperatureInstance,
};
};

Expand Down

0 comments on commit 8b5299d

Please sign in to comment.