Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make devices not static #76

Draft
wants to merge 19 commits into
base: itemname-rework
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
{
"env": {
"es6": true,
"es2020": true,
"jest": true,
"node": true
},
"extends": [
"eslint:recommended",
"prettier"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2019,
"sourceType": "module"
},
"plugins": [
"prettier"
],
Expand Down
14 changes: 11 additions & 3 deletions functions/apihandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
* @author Michael Krug - Rework
*
*/
/// <reference path="../typedefs.js" />
const http = require('http');
const https = require('https');

class ApiHandler {
/**
* @param {object} config
* @param {Object} config
*/
constructor(config = { host: '', path: '/rest/items/', port: 80 }) {
if (!config.path.startsWith('/')) {
Expand All @@ -46,7 +47,7 @@ class ApiHandler {
}

/**
* @param {object} data
* @param {Object} data
*/
updateCache(data) {
if (data.name) {
Expand All @@ -56,6 +57,7 @@ class ApiHandler {

/**
* @param {string} itemName
* @returns {Item[]}
*/
getFromCache(itemName) {
if (itemName) {
Expand All @@ -67,9 +69,10 @@ class ApiHandler {
}

/**
* @param {string} method
* @param {'GET'|'POST'} method
* @param {string} itemName
* @param {number} length
* @returns {Object}
*/
getOptions(method = 'GET', itemName = '', length = 0) {
const queryString =
Expand Down Expand Up @@ -102,6 +105,7 @@ class ApiHandler {

/**
* @param {string} itemName
* @returns {Promise<Item[]>}
*/
getItem(itemName = '') {
const cached = this.getFromCache(itemName);
Expand Down Expand Up @@ -143,6 +147,9 @@ class ApiHandler {
});
}

/**
* @returns {Promise<Item[]>}
*/
getItems() {
return this.getItem();
}
Expand All @@ -151,6 +158,7 @@ class ApiHandler {
* @param {string} itemName
* @param {string} payload
* @param {string} deviceId
* @returns {Promise}
*/
sendCommand(itemName, payload, deviceId) {
const options = this.getOptions('POST', itemName, payload.length);
Expand Down
14 changes: 8 additions & 6 deletions functions/commands/activatescene.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
const DefaultCommand = require('./default.js');

class ActivateScene extends DefaultCommand {
static get type() {
get type() {
return 'action.devices.commands.ActivateScene';
}

static validateParams(params) {
return ('deactivate' in params && typeof params.deactivate === 'boolean') || !('deactivate' in params);
get hasValidParams() {
return (
('deactivate' in this.params && typeof this.params.deactivate === 'boolean') || !('deactivate' in this.params)
);
}

static convertParamsToValue(params, _, device) {
let deactivate = params.deactivate;
if (this.isInverted(device)) {
convertParamsToValue() {
let deactivate = this.params.deactivate;
if (this.isInverted) {
deactivate = !deactivate;
}
return !deactivate ? 'ON' : 'OFF';
Expand Down
31 changes: 15 additions & 16 deletions functions/commands/appselect.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,34 @@ const DefaultCommand = require('./default.js');
const TV = require('../devices/tv.js');

class AppSelect extends DefaultCommand {
static get type() {
get type() {
return 'action.devices.commands.appSelect';
}

static validateParams(params) {
get hasValidParams() {
return (
('newApplication' in params && typeof params.newApplication === 'string') ||
('newApplicationName' in params && typeof params.newApplicationName === 'string')
('newApplication' in this.params && typeof this.params.newApplication === 'string') ||
('newApplicationName' in this.params && typeof this.params.newApplicationName === 'string')
);
}

static requiresItem() {
get requiresItem() {
return true;
}

static getItemName(device) {
const members = this.getMembers(device);
if ('tvApplication' in members) {
return members.tvApplication;
get itemName() {
if ('tvApplication' in this.members) {
return this.members.tvApplication;
}
throw { statusCode: 400 };
}

static convertParamsToValue(params, item) {
const applicationMap = TV.getApplicationMap(item);
if (params.newApplication && params.newApplication in applicationMap) {
return params.newApplication;
convertParamsToValue(item) {
const applicationMap = new TV(item).applicationMap;
if (this.params.newApplication && this.params.newApplication in applicationMap) {
return this.params.newApplication;
}
const search = params.newApplicationName;
const search = this.params.newApplicationName;
for (const key in applicationMap) {
if (applicationMap[key].includes(search)) {
return key;
Expand All @@ -39,9 +38,9 @@ class AppSelect extends DefaultCommand {
throw { errorCode: 'noAvailableApp' };
}

static getResponseStates(params, item) {
getResponseStates(item) {
return {
currentApplication: this.convertParamsToValue(params, item)
currentApplication: this.convertParamsToValue(item)
};
}
}
Expand Down
87 changes: 44 additions & 43 deletions functions/commands/armdisarm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,29 @@ const DefaultCommand = require('./default.js');
const SecuritySystem = require('../devices/securitysystem.js');

class ArmDisarm extends DefaultCommand {
static get type() {
get type() {
return 'action.devices.commands.ArmDisarm';
}

static validateParams(params) {
return 'arm' in params && typeof params.arm === 'boolean';
get hasValidParams() {
return 'arm' in this.params && typeof this.params.arm === 'boolean';
}

static convertParamsToValue(params, _, device) {
if (params.armLevel && this.getDeviceType(device) === 'SecuritySystem') {
return params.armLevel;
convertParamsToValue() {
if (this.params.armLevel && this.deviceType === 'SecuritySystem') {
return this.params.armLevel;
}
let arm = params.arm;
if (this.isInverted(device)) {
let arm = this.params.arm;
if (this.isInverted) {
arm = !arm;
}
return arm ? 'ON' : 'OFF';
}

static getItemName(device, params) {
if (this.getDeviceType(device) === 'SecuritySystem') {
const members = this.getMembers(device);
if (params.armLevel) {
get itemName() {
if (this.deviceType === 'SecuritySystem') {
const members = this.members;
if (this.params.armLevel) {
if (SecuritySystem.armLevelMemberName in members) {
return members[SecuritySystem.armLevelMemberName];
}
Expand All @@ -35,91 +35,92 @@ class ArmDisarm extends DefaultCommand {
}
throw { statusCode: 400 };
}
return device.id;
return this.device.id;
}

static requiresItem() {
get requiresItem() {
return true;
}

static bypassPin(device, params) {
return !!(device.customData && device.customData.pinOnDisarmOnly && (params.armLevel || params.arm));
get bypassPin() {
return !!(this.customData.pinOnDisarmOnly && (this.params.armLevel || this.params.arm));
}

static getResponseStates(params) {
getResponseStates() {
const response = {
isArmed: params.arm
isArmed: this.params.arm
};
if (params.armLevel) {
response.currentArmLevel = params.armLevel;
if (this.params.armLevel) {
response.currentArmLevel = this.params.armLevel;
}
return response;
}

static get requiresUpdateValidation() {
get requiresUpdateValidation() {
return true;
}

static validateStateChange(params, item, device) {
validateStateChange(item) {
let isCurrentlyArmed;
let currentLevel;

if (this.getDeviceType(device) === 'SecuritySystem') {
const members = SecuritySystem.getMembers(item);
if (this.deviceType === 'SecuritySystem') {
const members = new SecuritySystem(item).members;
isCurrentlyArmed =
(SecuritySystem.armedMemberName in members && members[SecuritySystem.armedMemberName].state) ===
(this.isInverted(device) ? 'OFF' : 'ON');
(this.isInverted ? 'OFF' : 'ON');
currentLevel =
(SecuritySystem.armLevelMemberName in members && members[SecuritySystem.armLevelMemberName].state) || undefined;
} else {
isCurrentlyArmed = item.state === (this.isInverted(device) ? 'OFF' : 'ON');
isCurrentlyArmed = item.state === (this.isInverted ? 'OFF' : 'ON');
}

if (params.armLevel && this.getDeviceType(device) === 'SecuritySystem') {
if (params.arm && isCurrentlyArmed && params.armLevel === currentLevel) {
if (this.params.armLevel && this.deviceType === 'SecuritySystem') {
if (this.params.arm && isCurrentlyArmed && this.params.armLevel === currentLevel) {
throw { errorCode: 'alreadyInState' };
}
return true;
}

if (params.arm && isCurrentlyArmed) {
if (this.params.arm && isCurrentlyArmed) {
throw { errorCode: 'alreadyArmed' };
}

if (!params.arm && !isCurrentlyArmed) {
if (!this.params.arm && !isCurrentlyArmed) {
throw { errorCode: 'alreadyDisarmed' };
}

return true;
}

static validateUpdate(params, item, device) {
if (this.getDeviceType(device) === 'SecuritySystem') {
const members = SecuritySystem.getMembers(item);
const isCurrentlyArmed =
members[SecuritySystem.armedMemberName].state === (this.isInverted(device) ? 'OFF' : 'ON');
// @ts-ignore
validateUpdate(item) {
if (this.deviceType === 'SecuritySystem') {
const securitySystem = new SecuritySystem(item);
const members = securitySystem.members;
const isCurrentlyArmed = members[SecuritySystem.armedMemberName].state === (this.isInverted ? 'OFF' : 'ON');
const currentLevel =
SecuritySystem.armLevelMemberName in members ? members[SecuritySystem.armLevelMemberName].state : '';
const armStatusSuccessful = params.arm === isCurrentlyArmed;
const armLevelSuccessful = params.armLevel ? params.armLevel === currentLevel : true;
const armStatusSuccessful = this.params.arm === isCurrentlyArmed;
const armLevelSuccessful = this.params.armLevel ? this.params.armLevel === currentLevel : true;
if (!armStatusSuccessful || !armLevelSuccessful) {
if (!params.arm) {
if (!this.params.arm) {
throw { errorCode: 'disarmFailure' };
} else {
const report = SecuritySystem.getStatusReport(item, members);
const report = securitySystem.getStatusReport();
if (report.length) {
return {
ids: [device.id],
ids: [this.device.id],
status: 'EXCEPTIONS',
states: Object.assign({ online: true, currentStatusReport: report }, SecuritySystem.getState(item))
states: Object.assign({ online: true, currentStatusReport: report }, securitySystem.state)
};
}
throw { errorCode: 'armFailure' };
}
}
} else {
if (params.arm !== (item.state === (this.isInverted(device) ? 'OFF' : 'ON'))) {
throw { errorCode: params.arm ? 'armFailure' : 'disarmFailure' };
if (this.params.arm !== (item.state === (this.isInverted ? 'OFF' : 'ON'))) {
throw { errorCode: this.params.arm ? 'armFailure' : 'disarmFailure' };
}
}
}
Expand Down
26 changes: 15 additions & 11 deletions functions/commands/brightnessabsolute.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
const DefaultCommand = require('./default.js');

class BrightnessAbsolute extends DefaultCommand {
static get type() {
get type() {
return 'action.devices.commands.BrightnessAbsolute';
}

static validateParams(params) {
return 'brightness' in params && typeof params.brightness === 'number';
get hasValidParams() {
return 'brightness' in this.params && typeof this.params.brightness === 'number';
}

static getItemName(device) {
if (this.getDeviceType(device) === 'SpecialColorLight') {
const members = this.getMembers(device);
get requiresItem() {
return this.deviceType === 'SpecialColorLight' && !this.hasMembers;
}

get itemName() {
if (this.deviceType === 'SpecialColorLight') {
const members = this.members;
if ('lightBrightness' in members) {
return members.lightBrightness;
}
throw { statusCode: 400 };
}
return device.id;
return this.device.id;
}

static convertParamsToValue(params) {
return params.brightness.toString();
convertParamsToValue() {
return this.params.brightness.toString();
}

static getResponseStates(params) {
getResponseStates() {
return {
brightness: params.brightness
brightness: this.params.brightness
};
}
}
Expand Down
Loading