initial commit

This commit is contained in:
Mathias Scherer 2021-04-04 19:38:03 +02:00
commit 95fd422f78
No known key found for this signature in database
GPG Key ID: 6A618EAA2BC2C1E5
12 changed files with 790 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules/

View File

@ -0,0 +1,25 @@
#MMM-HomeAssistant-Touch {
display: flex;
justify-content: center;
}
#MMM-HomeAssistant-Touch .ha-entity {
border: 0.1rem solid grey;
border-radius: 0.5rem;
padding: 0.5rem;
margin: 0.5rem;
}
#MMM-HomeAssistant-Touch .ha-entity .title,
#MMM-HomeAssistant-Touch .ha-entity .status {
display: block;
}
#MMM-HomeAssistant-Touch .ha-entity.ha-switch.on,
#MMM-HomeAssistant-Touch .ha-entity.ha-light.on {
background-color: #2AF20261;
}
body {
cursor: default;
}

108
MMM-HomeAssistant-Touch.js Normal file
View File

@ -0,0 +1,108 @@
Module.register("MMM-HomeAssistant-Touch", {
defaults: {
host: "http://127.0.0.1",
port: 8123,
token: "NOT_VALID",
ignoreCert: false,
entities: [],
},
// default mm functions
init,
start,
getDom,
socketNotificationReceived,
getStyles: function () {
return [this.file("MMM-HomeAssistant-Touch.css")];
},
getScripts: function () {
return [
this.file("./helpers/UIClassFactory.js"),
this.file("./UIClasses/Base.js"),
this.file("./UIClasses/Light.js"),
this.file("./UIClasses/Switch.js"),
this.file("./UIClasses/Unsupported.js"),
];
},
// custom functions
sendSocketNotificationHelper,
getStates,
getState,
updateState,
loadEntityClasses,
});
// Default MM Functions
function init() {
// rewrite sendSocketNotification function to include the identifier
this._sendSocketNotification = this.sendSocketNotification;
this.sendSocketNotification = this.sendSocketNotificationHelper;
}
function getDom() {
var wrapper = document.createElement("div");
wrapper.id = "MMM-HomeAssistant-Touch";
for (const entity in this.entities) {
wrapper.appendChild(this.entities[entity].getContainer());
}
return wrapper;
}
function start() {
Log.log(this.name + " is started!");
this.loadEntityClasses();
this.sendSocketNotification("CONNECT", {
host: this.config.host,
port: this.config.port,
token: this.config.token,
ignoreCert: this.config.ignoreCert,
});
this.getStates();
}
function socketNotificationReceived(notification, payload) {
if (payload.identifier === this.identifier) {
switch (notification) {
case "GOT_STATE":
case "CHANGED_STATE":
this.updateState(payload.data);
break;
}
}
}
// Custom Functions
function getStates() {
for (const entity of this.config.entities) {
this.getState(entity);
}
}
function getState(entity) {
this.sendSocketNotification("GET_STATE", { entity });
}
function updateState(state) {
if (this.entities.hasOwnProperty(state.entity_id)) {
this.entities[state.entity_id].updateState(state);
}
}
function sendSocketNotificationHelper(notification, payload) {
payload.identifier = this.identifier;
this._sendSocketNotification(notification, payload);
}
// initializes each entity to render it
function loadEntityClasses() {
this.UIClassFactory = new UIClassFactory();
this.entities = {};
// load UI Classes
for (const entity of this.config.entities) {
const entityClass = this.UIClassFactory.getEntityClass(entity);
if (entityClass) {
this.entities[entity] = new entityClass(entity, this);
}
}
}

37
UIClasses/Base.js Normal file
View File

@ -0,0 +1,37 @@
class Base {
constructor(id, mm) {
this.id = id;
this.type = id.split('.')[0]
this.name = id;
this.mm = mm;
}
updateState(state) {
this.name = (state.attributes || {}).friendly_name || this.id;
this.state = state.state;
this.render();
}
getContainer() {
const entity = document.createElement("div");
entity.classList.add("ha-entity");
entity.classList.add(`ha-${this.type}`)
entity.id = this.id;
entity.innerHTML = "Loading...";
return entity;
}
render() {
const container = document.getElementById(this.id);
container.className = ""
container.classList.add("ha-entity");
container.classList.add(`ha-${this.type}`)
const title = document.createElement("span");
title.className = "title";
title.innerHTML = this.name;
container.innerHTML = "";
container.appendChild(title);
}
}

21
UIClasses/Light.js Normal file
View File

@ -0,0 +1,21 @@
class Light extends Base {
getContainer() {
const entity = super.getContainer();
entity.onclick = () => {
this.mm.sendSocketNotification("TOGGLE_STATE", { entity: this.id });
};
entity.ontouchend = () => {
this.mm.sendSocketNotification("TOGGLE_STATE", { entity: this.id });
};
return entity;
}
render() {
super.render();
const container = document.getElementById(this.id);
container.classList.add(this.state);
container.appendChild(statusCheckbox);
}
}

21
UIClasses/Switch.js Normal file
View File

@ -0,0 +1,21 @@
class Switch extends Base {
getContainer() {
const entity = super.getContainer();
entity.onclick = () => {
this.mm.sendSocketNotification("TOGGLE_STATE", { entity: this.id });
};
entity.ontouchend = () => {
this.mm.sendSocketNotification("TOGGLE_STATE", { entity: this.id });
}
return entity;
}
render() {
super.render();
const container = document.getElementById(this.id);
container.classList.add(this.state)
container.appendChild(statusCheckbox);
}
}

17
UIClasses/Unsupported.js Normal file
View File

@ -0,0 +1,17 @@
class Unsupported extends Base {
render() {
const container = document.getElementById(this.id);
const title = document.createElement("span");
title.className = "title";
title.innerHTML = `${this.name} (Unsupported)`;
const status = document.createElement("span");
status.className = "status";
status.innerHTML = this.state;
container.innerHTML = "";
container.appendChild(title);
container.appendChild(status);
}
}

19
helpers/Logger.js Normal file
View File

@ -0,0 +1,19 @@
class Logger {
constructor(name) {
this.name = name
}
info(...message) {
console.info(`[${this.name}]`, message)
}
error(...message) {
console.error(`[${this.name}]`, message)
}
debug(...message) {
console.debug(`[${this.name}]`, message)
}
}
module.exports = Logger

14
helpers/UIClassFactory.js Normal file
View File

@ -0,0 +1,14 @@
class UIClassFactory {
getEntityClass = function (entity_id) {
const [domain] = entity_id.split(".");
switch (domain) {
case "light":
return Light;
case "switch":
return Switch;
default:
return Unsupported;
}
};
}

110
node_helper.js Normal file
View File

@ -0,0 +1,110 @@
const NodeHelper = require("node_helper");
const HomeAssistant = require("homeassistant");
const HomeAssistantWS = require("homeassistant-ws");
const Logger = require("./helpers/Logger");
const connections = {};
module.exports = NodeHelper.create({
start,
socketNotificationReceived,
connect,
getState,
toggleState,
onStateChangedEvent,
});
function start() {
this.logger = new Logger(this.name);
}
function socketNotificationReceived(notification, payload) {
this.logger.debug(`Recieved notification ${notification}`, payload);
if (notification !== 'CONNECT' && (!payload.identifier || !connections[payload.identifier])) {
this.logger.error(`No connection for ${payload.identifier} found`);
return;
}
switch (notification) {
case "CONNECT":
this.connect(payload);
break;
case "GET_STATE":
this.getState(payload);
break;
case "TOGGLE_STATE":
this.toggleState(payload);
break;
}
}
async function connect(payload) {
const connectionConfig = {
host: payload.host,
port: payload.port,
token: payload.token,
ignoreCert: payload.ignoreCert,
};
const hass = new HomeAssistant(connectionConfig);
this.logger.info(`HomeAssistant connected for ${payload.identifier}`);
connections[payload.identifier] = {
hass,
entities: [],
};
const self = this;
HomeAssistantWS.default({
...connectionConfig,
host: new URL(connectionConfig.host).host,
})
.then((hassWs) => {
connections[payload.identifier].websocket = hassWs;
hassWs.onStateChanged(onStateChangedEvent.bind(self));
})
.catch((err) => {
this.logger.error(
`WS connection for ${payload.identifier} failed with`,
err
);
});
}
async function getState(payload) {
this.logger.debug(`Getting state for ${payload.entity}`);
const hass = connections[payload.identifier].hass;
const [domain, entity] = payload.entity.split(".");
const response = await hass.states.get(domain, entity);
this.logger.debug(`Got state for ${payload.entity}`);
this.sendSocketNotification("GOT_STATE", {
identifier: payload.identifier,
data: response,
});
if (!connections[payload.identifier].entities.includes(payload.entity)) {
connections[payload.identifier].entities.push(payload.entity);
}
}
async function toggleState(payload) {
this.logger.debug(`Toggling state for ${payload.entity}`);
const hass = connections[payload.identifier].hass;
const [domain, entity] = payload.entity.split(".");
const response = await hass.services.call('toggle', domain, entity)
this.logger.debug(`Response for toggling state of ${payload.entity}`, response)
this.getState(payload)
}
function onStateChangedEvent(event) {
//this.logger.debug(`Got state change for ${event.data.entity_id}`);
for (const connection in connections) {
if (connections[connection].entities.includes(event.data.entity_id)) {
this.logger.debug(
`Found listening connection (${connection}) for entity ${event.data.entity_id}`
);
this.sendSocketNotification("CHANGED_STATE", {
identifier: connection,
data: event.data.new_state,
});
}
}
}

402
package-lock.json generated Normal file
View File

@ -0,0 +1,402 @@
{
"name": "mmm-homeassistant-touch",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"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"
}
},
"asn1": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"aws-sign2": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"optional": true
},
"bcrypt-pbkdf": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"requires": {
"tweetnacl": "^0.14.3"
}
},
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"optional": true,
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"dashdash": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
},
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"optional": true
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
},
"extsprintf": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"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=="
},
"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=="
},
"forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
},
"form-data": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
"assert-plus": "^1.0.0"
}
},
"har-schema": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
},
"har-validator": {
"version": "5.1.5",
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
"integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
"requires": {
"ajv": "^6.12.3",
"har-schema": "^2.0.0"
}
},
"homeassistant": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/homeassistant/-/homeassistant-0.2.0.tgz",
"integrity": "sha512-kOH9PXLNOXgxcB4N3bhiO2wsgFBTVynNn3jLknnmYN4nwMTfAWrh8B4rnUFEm9dlWrnEA5XXlBCxtBiBApYGgg==",
"requires": {
"moment": "^2.24.0",
"request": "^2.88.0"
}
},
"homeassistant-ws": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/homeassistant-ws/-/homeassistant-ws-0.1.3.tgz",
"integrity": "sha512-VnT1HVmmyEF0FI3uY5W8rXLI3hc6F1zf0qbIZlCCICPgx8y9FiIpoDBmI4TcE4SSsGCYE7YBIsXMR7hah23YJw==",
"requires": {
"buffer": "^5.6.0",
"events": "^3.1.0",
"isomorphic-ws": "^4.0.1",
"ws": "^7.2.5"
}
},
"http-signature": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"optional": true
},
"is-typedarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"isomorphic-ws": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz",
"integrity": "sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w=="
},
"isstream": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
},
"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=="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
"requires": {
"assert-plus": "1.0.0",
"extsprintf": "1.3.0",
"json-schema": "0.2.3",
"verror": "1.10.0"
}
},
"mime-db": {
"version": "1.47.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz",
"integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw=="
},
"mime-types": {
"version": "2.1.30",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz",
"integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==",
"requires": {
"mime-db": "1.47.0"
}
},
"moment": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
},
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"qs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"request": {
"version": "2.88.2",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
"integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
"requires": {
"aws-sign2": "~0.7.0",
"aws4": "^1.8.0",
"caseless": "~0.12.0",
"combined-stream": "~1.0.6",
"extend": "~3.0.2",
"forever-agent": "~0.6.1",
"form-data": "~2.3.2",
"har-validator": "~5.1.3",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.19",
"oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
"qs": "~6.5.2",
"safe-buffer": "^5.1.2",
"tough-cookie": "~2.5.0",
"tunnel-agent": "^0.6.0",
"uuid": "^3.3.2"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"sshpk": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
"bcrypt-pbkdf": "^1.0.0",
"dashdash": "^1.12.0",
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
"integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
"requires": {
"psl": "^1.1.28",
"punycode": "^2.1.1"
}
},
"tunnel-agent": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"requires": {
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
"assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
"extsprintf": "^1.2.0"
}
},
"ws": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
"integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw=="
}
}
}

15
package.json Normal file
View File

@ -0,0 +1,15 @@
{
"name": "mmm-homeassistant-touch",
"version": "1.0.0",
"description": "",
"main": "MMM-HomeAssistant-Touch.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Mathias Scherer <scherer.mat@gmail.com>",
"license": "ISC",
"dependencies": {
"homeassistant": "^0.2.0",
"homeassistant-ws": "^0.1.3"
}
}