Add fixes for linters, add github workflows

This runs eslint --fix as well as manually fixing things that the automatic fixer couldn't handle.
This commit is contained in:
2020-08-21 14:58:11 -05:00
parent cca1e1bee9
commit 2a84b7f4fd
10 changed files with 1382 additions and 429 deletions

19
.eslintrc Normal file
View File

@ -0,0 +1,19 @@
{
"rules": {
"comma-dangle": 0,
"indent": [2, 4],
"max-len": "off",
"radix": [2, "as-needed"],
"no-console": 0,
"linebreak-style": "off",
"prettier/prettier": 0
},
"settings": {
"import/core-modules": [ "node_helper" ]
},
"env": {
"browser": true,
"node": true,
"es6": true
}
}

28
.github/workflows/nodejs.yml vendored Normal file
View File

@ -0,0 +1,28 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run build --if-present

8
.markdownlint.json Normal file
View File

@ -0,0 +1,8 @@
{
"default": true,
"no-duplicate-header": {
"siblings_only": true
},
"line-length": false,
"no-inline-html": false
}

View File

@ -1,32 +1,46 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.1.2] - 2020-04-08
### Fixed
- Fixed which property was being read to determine whether heat mode was enabled or not. Previously the state of the heater itself was being used to display on/off status, now the requested mode is used instead (the heater toggles on/off as part of normal operation even while heating is enabled).
## [1.1.1] - 2020-04-07
### Added
- Ability to specify which heat mode to use when enabling heating for a specific body. Previously mode 1 was always sent which means "solar" while most people probably want mode 3 which is "heat pump".
## [1.1.0] - 2020-04-01
### Added
- Ability to show buttons for controlling pool equipment (with a touch screen, for example). NOTE: running `npm install` again is necessary after upgrading to this version if the heat controls are used.
## [1.0.3] - 2018-04-27
### Changed
- Packaged a newer `node-screenlogic` dependency to fix server broadcast in certain environments.
## [1.0.2] - 2018-04-26
### Added
- New option `updateInterval` to control how often the pool data is updated (default 30 minutes).
## [1.0.1] - 2018-04-25
### Added
- New option `showFreezeMode` shows a banner acrosss the top if the pool is currently in freeze-protection mode.
## [1.0.0] - 2018-04-24
- Initial release.

View File

@ -1,288 +1,288 @@
poolData = {};
var moduleObj;
let poolData = {};
let moduleObj;
Module.register("MMM-ScreenLogic",{
defaults: {
showPoolTemp: true,
showSpaTemp: true,
showPH: true,
showOrp: true,
showSaltLevel: true,
showSaturation: true,
showFreezeMode: true,
showControls: false,
controls: [],
colored: true,
coldTemp: 84,
hotTemp: 90,
columns: 3,
contentClass: "light",
updateInterval: 30 * 60 * 1000
},
defaults: {
showPoolTemp: true,
showSpaTemp: true,
showPH: true,
showOrp: true,
showSaltLevel: true,
showSaturation: true,
showFreezeMode: true,
showControls: false,
controls: [],
colored: true,
coldTemp: 84,
hotTemp: 90,
columns: 3,
contentClass: "light",
updateInterval: 30 * 60 * 1000
},
start: function() {
// this isn't a great solution...is there a better one? needed to do stuff with buttons
moduleObj = this;
if (this.config.showControls && (!this.config.controls || this.config.controls.length == 0)) {
Log.warn('Controls are enabled, but no controls are configured. See README for info on setting up controls.');
this.config.showControls = false;
}
start: function() {
// this isn't a great solution...is there a better one? needed to do stuff with buttons
moduleObj = this;
if (this.config.showControls && (!this.config.controls || this.config.controls.length === 0)) {
Log.warn('Controls are enabled, but no controls are configured. See README for info on setting up controls.');
this.config.showControls = false;
}
this.sendSocketNotification('SCREENLOGIC_CONFIG', this.config);
this.sendSocketNotification('SCREENLOGIC_UPDATE');
},
this.sendSocketNotification('SCREENLOGIC_CONFIG', this.config);
this.sendSocketNotification('SCREENLOGIC_UPDATE');
},
getStyles: function() {
return ["screenlogic.css"];
},
getStyles: function() {
return ["screenlogic.css"];
},
getDom: function() {
if (!poolData.status) {
var wrapper = document.createElement("div");
wrapper.innerHTML = 'Loading...';
wrapper.className += "dimmed light small";
getDom: function() {
if (!poolData.status) {
let wrapper = document.createElement("div");
wrapper.innerHTML = 'Loading...';
wrapper.className += "dimmed light small";
return wrapper;
} else {
var table = document.createElement('table');
table.className = "small";
if (this.config.colored) {
table.className += " colored";
}
return wrapper;
} else {
let table = document.createElement('table');
table.className = "small";
if (this.config.colored) {
table.className += " colored";
}
var contents = [];
let contents = [];
if (this.config.showPoolTemp) {
var className = "";
if (poolData.status.currentTemp[0] <= this.config.coldTemp) {
className += " cold-temp";
} else if (poolData.status.currentTemp[0] >= this.config.hotTemp) {
className += " hot-temp";
}
if (this.config.showPoolTemp) {
let className = "";
if (poolData.status.currentTemp[0] <= this.config.coldTemp) {
className += " cold-temp";
} else if (poolData.status.currentTemp[0] >= this.config.hotTemp) {
className += " hot-temp";
}
contents.push({
header: "Pool temp",
data: poolData.status.currentTemp[0] + "&deg;" + (!isPoolActive(poolData.status) ? " (last)" : ""),
class: this.config.contentClass + className
});
}
if (this.config.showSpaTemp) {
var className = "";
if (poolData.status.currentTemp[1] <= this.config.coldTemp) {
className = " cold-temp";
} else if (poolData.status.currentTemp[1] >= this.config.hotTemp) {
className = " hot-temp";
}
contents.push({
header: "Pool temp",
data: poolData.status.currentTemp[0] + "&deg;" + (!isPoolActive(poolData.status) ? " (last)" : ""),
class: this.config.contentClass + className
});
}
if (this.config.showSpaTemp) {
let className = "";
if (poolData.status.currentTemp[1] <= this.config.coldTemp) {
className = " cold-temp";
} else if (poolData.status.currentTemp[1] >= this.config.hotTemp) {
className = " hot-temp";
}
contents.push({
header: "Spa temp",
data: poolData.status.currentTemp[1] + "&deg;" + (!isSpaActive(poolData.status) ? " (last)" : ""),
class: this.config.contentClass + className
});
}
if (this.config.showPH) {
contents.push({
header: "pH",
data: poolData.status.pH,
class: this.config.contentClass
});
}
if (this.config.showOrp) {
contents.push({
header: "ORP",
data: poolData.status.orp,
class: this.config.contentClass
});
}
if (this.config.showSaltLevel) {
contents.push({
header: "Salt PPM",
data: poolData.status.saltPPM,
class: this.config.contentClass
});
}
if (this.config.showSaturation) {
contents.push({
header: "Saturation",
data: poolData.status.saturation,
class: this.config.contentClass
});
}
if (this.config.showControls) {
for (var control in this.config.controls) {
var controlObj = this.config.controls[control];
contents.push({
header: "Spa temp",
data: poolData.status.currentTemp[1] + "&deg;" + (!isSpaActive(poolData.status) ? " (last)" : ""),
class: this.config.contentClass + className
});
}
if (this.config.showPH) {
contents.push({
header: "pH",
data: poolData.status.pH,
class: this.config.contentClass
});
}
if (this.config.showOrp) {
contents.push({
header: "ORP",
data: poolData.status.orp,
class: this.config.contentClass
});
}
if (this.config.showSaltLevel) {
contents.push({
header: "Salt PPM",
data: poolData.status.saltPPM,
class: this.config.contentClass
});
}
if (this.config.showSaturation) {
contents.push({
header: "Saturation",
data: poolData.status.saturation,
class: this.config.contentClass
});
}
if (this.config.showControls) {
for (let control in this.config.controls) {
let controlObj = this.config.controls[control];
if (controlObj.type === 'circuit') {
var name = controlObj.name;
for (var circuit in poolData.controllerConfig.bodyArray) {
if (poolData.controllerConfig.bodyArray[circuit].circuitId == controlObj.id) {
if (!name) {
name = poolData.controllerConfig.bodyArray[circuit].name;
}
}
}
if (controlObj.type === 'circuit') {
let name = controlObj.name;
for (let circuit in poolData.controllerConfig.bodyArray) {
if (poolData.controllerConfig.bodyArray[circuit].circuitId === controlObj.id) {
if (!name) {
name = poolData.controllerConfig.bodyArray[circuit].name;
}
}
}
var on = false;
for (var circuit in poolData.status.circuitArray) {
if (poolData.status.circuitArray[circuit].id == controlObj.id) {
on = poolData.status.circuitArray[circuit].state !== 0;
}
}
let on = false;
for (let circuit in poolData.status.circuitArray) {
if (poolData.status.circuitArray[circuit].id === controlObj.id) {
on = poolData.status.circuitArray[circuit].state !== 0;
}
}
var cls = '';
if (this.config.colored) {
cls = on ? 'control-on' : 'control-off';
}
let cls = '';
if (this.config.colored) {
cls = on ? 'control-on' : 'control-off';
}
contents.push({
data: '<button id="sl-control-' + controlObj.id + '" class="control ' + cls + '" onclick="setCircuit(this)" data-circuit="' +
contents.push({
data: '<button id="sl-control-' + controlObj.id + '" class="control ' + cls + '" onclick="setCircuit(this)" data-circuit="' +
controlObj.id + '" data-state="' + (on ? '1' : '0') + '"><div class="content">' +
name + '</div></button>',
class: this.config.contentClass
});
} else if (controlObj.type === 'heatpoint') {
if (controlObj.body < 0 || controlObj.body > poolData.status.setPoint.length) {
Log.warn('Invalid body specified for heatpoint');
continue;
}
class: this.config.contentClass
});
} else if (controlObj.type === 'heatpoint') {
if (controlObj.body < 0 || controlObj.body > poolData.status.setPoint.length) {
Log.warn('Invalid body specified for heatpoint');
continue;
}
var temperature = poolData.status.setPoint[controlObj.body];
let temperature = poolData.status.setPoint[controlObj.body];
var dataHtml = '<div class="temperature-container">';
dataHtml += '<button id="sl-temp-up-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, 1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">+</div></button>';
dataHtml += '<div class="temperature-label">'+controlObj.name+': '+temperature+'&deg;</div>';
dataHtml += '<button id="sl-temp-down-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, -1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">-</div></button>';
let dataHtml = '<div class="temperature-container">';
dataHtml += '<button id="sl-temp-up-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, 1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">+</div></button>';
dataHtml += '<div class="temperature-label">'+controlObj.name+': '+temperature+'&deg;</div>';
dataHtml += '<button id="sl-temp-down-'+controlObj.body+'" class="temperature control-off" onclick="setHeatpoint(this, -1)" data-body="'+controlObj.body+'" data-temperature="'+temperature+'"><div class="content">-</div></button>';
contents.push({
data: dataHtml,
class: this.config.contentClass
});
} else if (controlObj.type === 'heatmode') {
if (controlObj.body < 0 || controlObj.body > poolData.status.heatMode.length) {
Log.warn('Invalid body specified for heatmode');
continue;
}
contents.push({
data: dataHtml,
class: this.config.contentClass
});
} else if (controlObj.type === 'heatmode') {
if (controlObj.body < 0 || controlObj.body > poolData.status.heatMode.length) {
Log.warn('Invalid body specified for heatmode');
continue;
}
var on = poolData.status.heatMode[controlObj.body] !== 0;
var mode = typeof controlObj.heatMode === 'number' ? controlObj.heatMode : 3;
let on = poolData.status.heatMode[controlObj.body] !== 0;
let mode = typeof controlObj.heatMode === 'number' ? controlObj.heatMode : 3;
var cls = '';
if (this.config.colored) {
cls = on ? 'control-on' : 'control-off';
}
let cls = '';
if (this.config.colored) {
cls = on ? 'control-on' : 'control-off';
}
contents.push({
data: '<button id="sl-heat-' + controlObj.body + '" class="control ' + cls + '" onclick="setHeatmode(this)" data-body="' +
contents.push({
data: '<button id="sl-heat-' + controlObj.body + '" class="control ' + cls + '" onclick="setHeatmode(this)" data-body="' +
controlObj.body + '" data-state="' + (on ? '1' : '0') + '" data-mode="' + mode.toString() + '"><div class="content">' +
controlObj.name + '</div></button>',
class: this.config.contentClass
});
} else {
Log.warn('circuit with unknown type, unable to display:');
Log.warn(controlObj);
}
}
}
class: this.config.contentClass
});
} else {
Log.warn('circuit with unknown type, unable to display:');
Log.warn(controlObj);
}
}
}
var headerRow = null;
var contentRow = null;
let headerRow = null;
let contentRow = null;
if (this.config.showFreezeMode && poolData.status.freezeMode !== 0) {
var row = document.createElement('tr');
table.appendChild(row);
row.className = 'cold-temp';
var cell = document.createElement('th');
row.appendChild(cell);
cell.colSpan = this.config.columns;
cell.innerHTML = '<center>FREEZE MODE</center>';
}
if (this.config.showFreezeMode && poolData.status.freezeMode !== 0) {
let row = document.createElement('tr');
table.appendChild(row);
row.className = 'cold-temp';
let cell = document.createElement('th');
row.appendChild(cell);
cell.colSpan = this.config.columns;
cell.innerHTML = '<center>FREEZE MODE</center>';
}
var cols = -1;
for (var item in contents) {
cols++;
if (cols % this.config.columns === 0) {
headerRow = document.createElement('tr');
contentRow = document.createElement('tr');
table.appendChild(headerRow);
table.appendChild(contentRow);
}
let cols = -1;
for (let item in contents) {
cols++;
if (cols % this.config.columns === 0) {
headerRow = document.createElement('tr');
contentRow = document.createElement('tr');
table.appendChild(headerRow);
table.appendChild(contentRow);
}
if (contents[item].header) {
var headerCell = document.createElement('th');
headerCell.innerHTML = contents[item].header;
headerRow.appendChild(headerCell);
}
if (contents[item].header) {
let headerCell = document.createElement('th');
headerCell.innerHTML = contents[item].header;
headerRow.appendChild(headerCell);
}
var contentCell = document.createElement('td');
contentCell.innerHTML = contents[item].data;
contentCell.className = contents[item].class;
contentRow.appendChild(contentCell);
}
let contentCell = document.createElement('td');
contentCell.innerHTML = contents[item].data;
contentCell.className = contents[item].class;
contentRow.appendChild(contentCell);
}
return table;
}
},
return table;
}
},
socketNotificationReceived: function(notification, payload) {
if (notification === 'SCREENLOGIC_RESULT') {
poolData = payload;
this.updateDom();
} else if (notification === 'SCREENLOGIC_CIRCUIT_DONE'
socketNotificationReceived: function(notification, payload) {
if (notification === 'SCREENLOGIC_RESULT') {
poolData = payload;
this.updateDom();
} else if (notification === 'SCREENLOGIC_CIRCUIT_DONE'
|| notification === 'SCREENLOGIC_HEATSTATE_DONE'
|| notification === 'SCREENLOGIC_HEATPOINT_DONE') {
poolData.status = payload.status;
this.updateDom();
}
},
poolData.status = payload.status;
this.updateDom();
}
},
});
const SPA_CIRCUIT_ID = 500;
const POOL_CIRCUIT_ID = 505;
function isPoolActive(status) {
for (var i = 0; i < status.circuitArray.length; i++) {
if (status.circuitArray[i].id === POOL_CIRCUIT_ID) {
return status.circuitArray[i].state === 1;
}
}
for (let i = 0; i < status.circuitArray.length; i++) {
if (status.circuitArray[i].id === POOL_CIRCUIT_ID) {
return status.circuitArray[i].state === 1;
}
}
}
function hasSpa(status) {
for (var i = 0; i < status.circuitArray.length; i++) {
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
return true;
}
}
for (let i = 0; i < status.circuitArray.length; i++) {
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
return true;
}
}
return false;
return false;
}
function isSpaActive(status) {
for (var i = 0; i < status.circuitArray.length; i++) {
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
return status.circuitArray[i].state === 1;
}
}
for (let i = 0; i < status.circuitArray.length; i++) {
if (status.circuitArray[i].id === SPA_CIRCUIT_ID) {
return status.circuitArray[i].state === 1;
}
}
}
function setCircuit(e) {
var circuitId = parseInt(e.dataset.circuit);
var on = e.dataset.state !== '0';
moduleObj.sendSocketNotification('SCREENLOGIC_CIRCUIT', {id: circuitId, state: on ? 0 : 1});
e.classList.remove('control-on', 'control-off');
let circuitId = parseInt(e.dataset.circuit);
let on = e.dataset.state !== '0';
moduleObj.sendSocketNotification('SCREENLOGIC_CIRCUIT', {id: circuitId, state: on ? 0 : 1});
e.classList.remove('control-on', 'control-off');
}
function setHeatmode(e) {
var bodyId = parseInt(e.dataset.body);
var on = e.dataset.state !== '0';
var mode = e.dataset.mode;
moduleObj.sendSocketNotification('SCREENLOGIC_HEATSTATE', {body: bodyId, state: on ? 0 : parseInt(mode)});
e.classList.remove('control-on', 'control-off');
let bodyId = parseInt(e.dataset.body);
let on = e.dataset.state !== '0';
let mode = e.dataset.mode;
moduleObj.sendSocketNotification('SCREENLOGIC_HEATSTATE', {body: bodyId, state: on ? 0 : parseInt(mode)});
e.classList.remove('control-on', 'control-off');
}
function setHeatpoint(e, tempChange) {
var bodyId = parseInt(e.dataset.body);
var temp = parseInt(e.dataset.temperature) + tempChange;
moduleObj.sendSocketNotification('SCREENLOGIC_HEATPOINT', {body: bodyId, temperature: temp});
e.classList.remove('control-on', 'control-off');
let bodyId = parseInt(e.dataset.body);
let temp = parseInt(e.dataset.temperature) + tempChange;
moduleObj.sendSocketNotification('SCREENLOGIC_HEATPOINT', {body: bodyId, temperature: temp});
e.classList.remove('control-on', 'control-off');
}

View File

@ -1,13 +1,16 @@
# MMM-ScreenLogic
A <a href="https://github.com/MichMich/MagicMirror">MagicMirror²</a> module used to connect to a local Pentair ScreenLogic pool controller system.
[MagicMirror²](https://github.com/MichMich/MagicMirror) module used to connect to a local Pentair ScreenLogic pool controller system.
## Installation
1. Navigate into your MagicMirror's `modules` folder and execute `git clone https://github.com/parnic/MMM-ScreenLogic.git`.
2. `cd MMM-ScreenLogic`
3. Execute `npm install` to install the node dependencies.
3. Execute `npm install --production` to install the node dependencies.
4. Add the module inside `config.js` placing it where you prefer.
## Config
|Option|Type|Description|Default|
|---|---|---|---|
|`coldTemp`|Integer|Show the temperature colored blue if it's at or below this level for pool/spa (requires option `colored`). This is in whatever scale your system is set to (Fahrenheit/Celsius).|`84`|
@ -29,32 +32,36 @@ A <a href="https://github.com/MichMich/MagicMirror">MagicMirror²</a> module use
|`updateInterval`|Integer|How frequently, in milliseconds, to update pool data.|`30 * 60 * 1000` (every 30 minutes)|
Here is an example of an entry in config.js
```
```js
{
module: 'MMM-ScreenLogic',
header: 'Pool info',
position: 'top_left',
config: {
showSpaTemp: false,
columns: 2,
contentClass: 'thin',
showControls: true,
controls: [
{type: 'circuit', id: 500},
{type: 'circuit', id: 505, name: 'Pool'},
{type: 'heatmode', body: 0, name: 'Pool heater'},
{type: 'heatpoint', body: 0, name: 'Pool'},
{type: 'heatmode', body: 1, heatMode: 2, name: 'Spa heater'},
]
}
module: 'MMM-ScreenLogic',
header: 'Pool info',
position: 'top_left',
config: {
showSpaTemp: false,
columns: 2,
contentClass: 'thin',
showControls: true,
controls: [
{type: 'circuit', id: 500},
{type: 'circuit', id: 505, name: 'Pool'},
{type: 'heatmode', body: 0, name: 'Pool heater'},
{type: 'heatpoint', body: 0, name: 'Pool'},
{type: 'heatmode', body: 1, heatMode: 2, name: 'Spa heater'},
]
}
},
```
## Screenshot
#### With color
### With color
![Screenshot with color](/screenshot.png?raw=true "colored: true")
## Notes
Pull requests are very welcome! If you'd like to see any additional functionality, don't hesitate to let me know.
This module only works with ScreenLogic controllers on the local network via either a UDP broadcast on 255.255.255.255 or a direct connection if you've specified an address and port in the configuration.
@ -64,4 +71,5 @@ The data is updated every 30 minutes by default (configurable with `updateInterv
When toggling a circuit or changing heat mode, sometimes other circuits are affected. For example, some pools share the same pump for the pool and spa, so when the pool is toggled on the spa must be toggled off. Unfortunately the ScreenLogic system doesn't update its internal status at any predictable rate, so the data on the screen can be wrong immediately after toggling a circuit until the next periodic update runs. If you know of a reliable way around this, please open a pull request!
## Libraries
This uses a Node.JS library I created for interfacing with ScreenLogic controllers over the network: [node-screenlogic](https://github.com/parnic/node-screenlogic), so feel free to check that out for more information.

View File

@ -1,210 +1,210 @@
var NodeHelper = require('node_helper');
module.exports = NodeHelper.create({
start: function() {
this.setTimer(30 * 60 * 1000);
},
start: function() {
this.setTimer(30 * 60 * 1000);
},
doUpdate: function() {
var self = this;
getPoolData(this.config, function(poolData) {
self.sendSocketNotification('SCREENLOGIC_RESULT', poolData);
});
},
doUpdate: function() {
var self = this;
getPoolData(this.config, function(poolData) {
self.sendSocketNotification('SCREENLOGIC_RESULT', poolData);
});
},
setCircuit: function(circuitState) {
var self = this;
setCircuitState(circuitState, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_CIRCUIT_DONE', {circuitState: circuitState, status: poolStatus});
});
},
setCircuit: function(circuitState) {
var self = this;
setCircuitState(circuitState, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_CIRCUIT_DONE', {circuitState: circuitState, status: poolStatus});
});
},
setHeatpoint: function(heatpoint) {
var self = this;
setHeatpointState(heatpoint, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_HEATPOINT_DONE', {heatpoint: heatpoint, status: poolStatus});
});
},
setHeatpoint: function(heatpoint) {
var self = this;
setHeatpointState(heatpoint, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_HEATPOINT_DONE', {heatpoint: heatpoint, status: poolStatus});
});
},
setHeatstate: function(heatstate) {
var self = this;
setHeatstateState(heatstate, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_HEATSTATE_DONE', {heatstate: heatstate, status: poolStatus});
});
},
setHeatstate: function(heatstate) {
var self = this;
setHeatstateState(heatstate, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_HEATSTATE_DONE', {heatstate: heatstate, status: poolStatus});
});
},
setLightcmd: function(lightCmd) {
var self = this;
setLights(lightCmd, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_LIGHTCMD_DONE', {lightCmd: lightCmd, status: poolStatus});
});
},
setLightcmd: function(lightCmd) {
var self = this;
setLights(lightCmd, function(poolStatus) {
self.sendSocketNotification('SCREENLOGIC_LIGHTCMD_DONE', {lightCmd: lightCmd, status: poolStatus});
});
},
restartTimer: function() {
var interval = this.updateInterval;
this.updateInterval = undefined;
this.setTimer(interval);
},
restartTimer: function() {
var interval = this.updateInterval;
this.updateInterval = undefined;
this.setTimer(interval);
},
setTimer: function(updateInterval) {
var update = true;
update = typeof this.updateInterval === 'undefined' || this.updateInterval != updateInterval;
this.updateInterval = updateInterval;
setTimer: function(updateInterval) {
var update = true;
update = typeof this.updateInterval === 'undefined' || this.updateInterval !== updateInterval;
this.updateInterval = updateInterval;
if (update) {
if (typeof this.timer !== 'undefined') {
clearInterval(this.timer);
}
if (update) {
if (typeof this.timer !== 'undefined') {
clearInterval(this.timer);
}
var self = this;
self.timer = setInterval(function() {
self.doUpdate()
}, self.updateInterval);
}
},
var self = this;
self.timer = setInterval(function() {
self.doUpdate()
}, self.updateInterval);
}
},
socketNotificationReceived: function(notification, payload) {
if (notification === 'SCREENLOGIC_CONFIG') {
this.config = payload;
this.setTimer(this.config.updateInterval);
}
if (notification === 'SCREENLOGIC_UPDATE') {
this.doUpdate();
}
if (notification === 'SCREENLOGIC_CIRCUIT') {
this.setCircuit(payload);
}
if (notification === 'SCREENLOGIC_HEATPOINT') {
this.setHeatpoint(payload);
}
if (notification === 'SCREENLOGIC_HEATSTATE') {
this.setHeatstate(payload);
}
if (notification === 'SCREENLOGIC_LIGHTCMD') {
this.setLightcmd(payload);
}
}
socketNotificationReceived: function(notification, payload) {
if (notification === 'SCREENLOGIC_CONFIG') {
this.config = payload;
this.setTimer(this.config.updateInterval);
}
if (notification === 'SCREENLOGIC_UPDATE') {
this.doUpdate();
}
if (notification === 'SCREENLOGIC_CIRCUIT') {
this.setCircuit(payload);
}
if (notification === 'SCREENLOGIC_HEATPOINT') {
this.setHeatpoint(payload);
}
if (notification === 'SCREENLOGIC_HEATSTATE') {
this.setHeatstate(payload);
}
if (notification === 'SCREENLOGIC_LIGHTCMD') {
this.setLightcmd(payload);
}
}
});
const ScreenLogic = require('node-screenlogic');
var foundUnit;
function getPoolData(config, cb) {
if (!foundUnit && typeof config !== 'undefined' && config.serverAddress && config.serverPort) {
foundUnit = new ScreenLogic.UnitConnection(config.serverPort, config.serverAddress);
}
if (!foundUnit && typeof config !== 'undefined' && config.serverAddress && config.serverPort) {
foundUnit = new ScreenLogic.UnitConnection(config.serverPort, config.serverAddress);
}
if (foundUnit) {
populateSystemData(cb);
} else {
findServer(cb);
}
if (foundUnit) {
populateSystemData(cb);
} else {
findServer(cb);
}
}
function findServer(cb) {
var finder = new ScreenLogic.FindUnits();
finder.on('serverFound', function(server) {
finder.close();
var finder = new ScreenLogic.FindUnits();
finder.on('serverFound', function(server) {
finder.close();
foundUnit = new ScreenLogic.UnitConnection(server);
populateSystemData(cb);
});
foundUnit = new ScreenLogic.UnitConnection(server);
populateSystemData(cb);
});
finder.search();
finder.search();
}
function populateSystemData(cb) {
var poolData = {};
var poolData = {};
if (!foundUnit) {
cb(poolData);
return;
}
if (!foundUnit) {
cb(poolData);
return;
}
foundUnit.once('loggedIn', function() {
foundUnit.getControllerConfig();
}).once('controllerConfig', function(config) {
poolData.controllerConfig = config;
poolData.degStr = config.degC ? 'C' : 'F';
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
poolData.status = status;
foundUnit.once('loggedIn', function() {
foundUnit.getControllerConfig();
}).once('controllerConfig', function(config) {
poolData.controllerConfig = config;
poolData.degStr = config.degC ? 'C' : 'F';
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
poolData.status = status;
foundUnit.close();
cb(poolData);
});
foundUnit.close();
cb(poolData);
});
foundUnit.connect();
foundUnit.connect();
}
function setCircuitState(circuitState, cb) {
if (!foundUnit) {
cb();
return;
}
if (!foundUnit) {
cb();
return;
}
foundUnit.once('loggedIn', function() {
foundUnit.setCircuitState(0, circuitState.id, circuitState.state);
}).once('circuitStateChanged', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.once('loggedIn', function() {
foundUnit.setCircuitState(0, circuitState.id, circuitState.state);
}).once('circuitStateChanged', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.connect();
foundUnit.connect();
}
function setHeatpointState(heatpoint, cb) {
if (!foundUnit) {
cb();
return;
}
if (!foundUnit) {
cb();
return;
}
foundUnit.once('loggedIn', function() {
foundUnit.setSetPoint(0, heatpoint.body, heatpoint.temperature);
}).once('setPointChanged', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.once('loggedIn', function() {
foundUnit.setSetPoint(0, heatpoint.body, heatpoint.temperature);
}).once('setPointChanged', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.connect();
foundUnit.connect();
}
function setHeatstateState(heatstate, cb) {
if (!foundUnit) {
cb();
return;
}
if (!foundUnit) {
cb();
return;
}
foundUnit.once('loggedIn', function() {
foundUnit.setHeatMode(0, heatstate.body, heatstate.state);
}).once('heatModeChanged', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.once('loggedIn', function() {
foundUnit.setHeatMode(0, heatstate.body, heatstate.state);
}).once('heatModeChanged', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.connect();
foundUnit.connect();
}
function setLights(lightCmd, cb) {
if (!foundUnit) {
cb();
return;
}
if (!foundUnit) {
cb();
return;
}
foundUnit.once('loggedIn', function() {
foundUnit.sendLightCommand(0, lightCmd);
}).once('sentLightCommand', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.once('loggedIn', function() {
foundUnit.sendLightCommand(0, lightCmd);
}).once('sentLightCommand', function() {
foundUnit.getPoolStatus();
}).once('poolStatus', function(status) {
foundUnit.close();
cb(status);
});
foundUnit.connect();
foundUnit.connect();
}

872
package-lock.json generated
View File

@ -1,9 +1,628 @@
{
"name": "magic-mirror-module-screenlogic",
"version": "1.0.3",
"version": "1.1.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
"integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==",
"dev": true,
"requires": {
"@babel/highlight": "^7.10.4"
}
},
"@babel/helper-validator-identifier": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz",
"integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==",
"dev": true
},
"@babel/highlight": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
"integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.10.4",
"chalk": "^2.0.0",
"js-tokens": "^4.0.0"
},
"dependencies": {
"chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
}
}
},
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
"dev": true
},
"acorn": {
"version": "7.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.0.tgz",
"integrity": "sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w==",
"dev": true
},
"acorn-jsx": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
"integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==",
"dev": true
},
"ajv": {
"version": "6.12.4",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz",
"integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ansi-colors": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
"dev": true
},
"ansi-regex": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
"integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
"dev": true
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
},
"astral-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
"dev": true
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
"dev": true,
"requires": {
"@types/color-name": "^1.1.1",
"color-convert": "^2.0.1"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
"dev": true
},
"doctrine": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
"integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
"dev": true,
"requires": {
"esutils": "^2.0.2"
}
},
"emoji-regex": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
"integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
"dev": true,
"requires": {
"ansi-colors": "^4.1.1"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
"dev": true
},
"eslint": {
"version": "7.7.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.7.0.tgz",
"integrity": "sha512-1KUxLzos0ZVsyL81PnRN335nDtQ8/vZUD6uMtWbF+5zDtjKcsklIi78XoE0MVL93QvWTu+E5y44VyyCsOMBrIg==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"enquirer": "^2.3.5",
"eslint-scope": "^5.1.0",
"eslint-utils": "^2.1.0",
"eslint-visitor-keys": "^1.3.0",
"espree": "^7.2.0",
"esquery": "^1.2.0",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^5.0.0",
"globals": "^12.1.0",
"ignore": "^4.0.6",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"js-yaml": "^3.13.1",
"json-stable-stringify-without-jsonify": "^1.0.1",
"levn": "^0.4.1",
"lodash": "^4.17.19",
"minimatch": "^3.0.4",
"natural-compare": "^1.4.0",
"optionator": "^0.9.1",
"progress": "^2.0.0",
"regexpp": "^3.1.0",
"semver": "^7.2.1",
"strip-ansi": "^6.0.0",
"strip-json-comments": "^3.1.0",
"table": "^5.2.3",
"text-table": "^0.2.0",
"v8-compile-cache": "^2.0.3"
}
},
"eslint-scope": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz",
"integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==",
"dev": true,
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"eslint-utils": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.1.0"
}
},
"eslint-visitor-keys": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
"integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
"dev": true
},
"espree": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-7.2.0.tgz",
"integrity": "sha512-H+cQ3+3JYRMEIOl87e7QdHX70ocly5iW4+dttuR8iYSPr/hXKFb+7dBsZ7+u1adC4VrnPlTkv0+OwuPnDop19g==",
"dev": true,
"requires": {
"acorn": "^7.3.1",
"acorn-jsx": "^5.2.0",
"eslint-visitor-keys": "^1.3.0"
}
},
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
},
"esquery": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
"dev": true,
"requires": {
"estraverse": "^5.1.0"
},
"dependencies": {
"estraverse": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
"dev": true
}
}
},
"esrecurse": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
"integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
"dev": true,
"requires": {
"estraverse": "^4.1.0"
}
},
"estraverse": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"dev": true
},
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
"dev": true
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"file-entry-cache": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
"integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
"dev": true,
"requires": {
"flat-cache": "^2.0.1"
}
},
"flat-cache": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
"integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
"dev": true,
"requires": {
"flatted": "^2.0.0",
"rimraf": "2.6.3",
"write": "1.0.3"
}
},
"flatted": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
"dev": true
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"functional-red-black-tree": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
"dev": true
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
},
"globals": {
"version": "12.4.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
"dev": true,
"requires": {
"type-fest": "^0.8.1"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
"dev": true
},
"import-fresh": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
"dev": true,
"requires": {
"parent-module": "^1.0.0",
"resolve-from": "^4.0.0"
}
},
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"is-glob": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
"integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
"dev": true
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"js-yaml": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz",
"integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1",
"type-check": "~0.4.0"
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"node-screenlogic": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-screenlogic/-/node-screenlogic-1.3.1.tgz",
@ -12,10 +631,261 @@
"smart-buffer": "~4.0.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
"dev": true,
"requires": {
"deep-is": "^0.1.3",
"fast-levenshtein": "^2.0.6",
"levn": "^0.4.1",
"prelude-ls": "^1.2.1",
"type-check": "^0.4.0",
"word-wrap": "^1.2.3"
}
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"dev": true,
"requires": {
"callsites": "^3.0.0"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
"dev": true
},
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
"dev": true
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"dev": true
},
"regexpp": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
"dev": true
},
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"semver": {
"version": "7.3.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
"integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
"dev": true
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"slice-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
"integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.0",
"astral-regex": "^1.0.0",
"is-fullwidth-code-point": "^2.0.0"
}
},
"smart-buffer": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz",
"integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw=="
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"strip-ansi": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
"integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.0"
}
},
"strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
},
"table": {
"version": "5.4.6",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
"integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
"lodash": "^4.17.14",
"slice-ansi": "^2.1.0",
"string-width": "^3.0.0"
}
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
"dev": true,
"requires": {
"prelude-ls": "^1.2.1"
}
},
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
"integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
"dev": true
},
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
},
"v8-compile-cache": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz",
"integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==",
"dev": true
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
"dev": true
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"write": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
"integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
"dev": true,
"requires": {
"mkdirp": "^0.5.1"
}
}
}
}

View File

@ -8,5 +8,11 @@
"license": "MIT",
"dependencies": {
"node-screenlogic": "1.x"
},
"devDependencies": {
"eslint": "^7.7.0"
},
"scripts": {
"lint": "./node_modules/.bin/eslint ."
}
}

View File

@ -1,13 +1,13 @@
.MMM-ScreenLogic table.colored .cold-temp {
color: #BCDDFF;
color: #BCDDFF;
}
.MMM-ScreenLogic table.colored .hot-temp {
color: #FF8E99;
color: #FF8E99;
}
.MMM-ScreenLogic td {
width: 33%;
width: 33%;
}
.MMM-ScreenLogic .control {
@ -19,11 +19,11 @@
text-align: center;
line-height: 1.5;
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
box-sizing: border-box;
position: relative;
width: 80%;
height: 5rem;
margin: auto;
box-sizing: border-box;
position: relative;
width: 80%;
height: 5rem;
margin: auto;
font-weight: bold;
-webkit-user-select: none;
-moz-user-select: none;
@ -34,13 +34,13 @@
}
.MMM-ScreenLogic .control:after {
padding-bottom: 100%;
content: "";
display: block;
padding-bottom: 100%;
content: "";
display: block;
}
.MMM-ScreenLogic .content {
position: absolute;
position: absolute;
width: 90%;
height: 90%;
left: 0px;
@ -52,13 +52,13 @@
}
.MMM-ScreenLogic .control-on {
background: #28a745 !important;
border-color: #28a745 !important;
background: #28a745 !important;
border-color: #28a745 !important;
}
.MMM-ScreenLogic .control-off {
background: transparent !important;
border-color: #6c757d !important;
background: transparent !important;
border-color: #6c757d !important;
}
.MMM-ScreenLogic .temperature-container {
@ -81,10 +81,10 @@
background: #000;
border: 0px solid #6c757d;
color: #fff;
position: relative;
width: 80%;
height: 2.45rem;
margin: auto;
position: relative;
width: 80%;
height: 2.45rem;
margin: auto;
font-weight: bold;
-webkit-user-select: none;
-moz-user-select: none;