From 4c80bc793043b0842df1d938a0151675486f8210 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 15 Apr 2018 19:46:04 +0200 Subject: [PATCH 01/28] +Theken-Floalts --- config/rzl.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/config/rzl.js b/config/rzl.js index 2279c8f..4fcf024 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -177,10 +177,16 @@ const config : Config = { values: {} } }, + //Kuechen-Floalts floalt.topics("65537"), floalt.topics("65538"), floalt.topics("65539"), floalt.topics("65540"), + + //Theken-Floalts + floalt.topics("65543"), + floalt.topics("65544"), + esper_topics("afba40", "flyfry"), esper_topics("afba45", "alarm") ], @@ -638,6 +644,57 @@ const config : Config = { delayedApply: true } ] + }, + kitchen_counter_light: { + name: "Deckenlicht Theke", + position: [400, 440], + icon: "ceiling-light", + ui: [ + { + type: "section", + text: "Lampe Eingang" + }, + { + type: "slider", + min: 0, + max: 100, + text: "Helligkeit", + icon: "brightness-7", + topic: floalt.brightness("65544"), + delayedApply: true + }, + { + type: "slider", + min: 0, + max: 100, + text: "Farbtemperatur", + icon: "weather-sunset-down", + topic: floalt.color("65544"), + delayedApply: true + }, + { + type: "section", + text: "Lampe Hauptraum" + }, + { + type: "slider", + min: 0, + max: 100, + text: "Helligkeit", + icon: "brightness-7", + topic: floalt.brightness("65543"), + delayedApply: true + }, + { + type: "slider", + min: 0, + max: 100, + text: "Farbtemperatur", + icon: "weather-sunset-down", + topic: floalt.color("65543"), + delayedApply: true + } + ] } }, layers: [ From 2c8feefb0484a84d749802daced0d39223bd086c Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 15 Apr 2018 20:32:27 +0200 Subject: [PATCH 02/28] =?UTF-8?q?+Batteriest=C3=A4nde=20Fernbedinungen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/rzl.js | 32 ++++++++++++++++++++++++++++++-- config/utils.js | 19 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 4fcf024..60304bd 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -2,7 +2,7 @@ import type { Config } from "config/flowtypes"; import * as types from "config/types"; import { hex, rgb, rgba, rainbow } from "config/colors"; -import { esper_topics, esper_statistics, floalt } from "./utils"; +import { esper_topics, esper_statistics, floalt, remote } from "./utils"; const config : Config = { space: { @@ -182,10 +182,12 @@ const config : Config = { floalt.topics("65538"), floalt.topics("65539"), floalt.topics("65540"), + remote.topics("65536"), //Theken-Floalts floalt.topics("65543"), floalt.topics("65544"), + remote.topics("65542"), esper_topics("afba40", "flyfry"), esper_topics("afba45", "alarm") @@ -695,7 +697,33 @@ const config : Config = { delayedApply: true } ] - } + }, + remotes: { + name: "Fernbedinungen", + position: [400, 348], + icon: "remote", + iconColor: ({remote_65536_low, remote_65542_low}) => + ((remote_65536_low == "true") || (remote_65542_low == "true")) + ? hex("#ff0000") : hex("#000000"), + ui: [ + { + type: "progress", + icon: "battery", + min: 0, + max: 100, + text: "Tisch", + topic: "remote_65536_level" + }, + { + type: "progress", + icon: "battery", + min: 0, + max: 100, + text: "Theke", + topic: "remote_65542_level" + } + ] + }, }, layers: [ { diff --git a/config/utils.js b/config/utils.js index 4e96d9b..bfe593c 100644 --- a/config/utils.js +++ b/config/utils.js @@ -59,6 +59,25 @@ export const floalt = { }) } +export const remote = { + level: (remote_id: string) => `remote_${remote_id}_level`, + low: (remote_id: string) => `remote_${remote_id}_low`, + topics: (remote_id: string) => ({ + [ `remote_${remote_id}_level` ]: { + state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_level/state`, + command: ``, + defaultValue: "0", + values: {} + }, + [ `remote_${remote_id}_low` ]: { + state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_low/state`, + command: ``, + defaultValue: "OFF", + values: { true: "ON", false: "OFF" } + } + }) +} + export const esper_statistics = (name: string, prev_ui: Array = []) => ( prev_ui.concat([ From 5c3b45751153269fabf4e3b3a2ba2d188345616c Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Mon, 16 Apr 2018 00:43:14 +0200 Subject: [PATCH 03/28] Improvements after talking to uwap - rename utils/remote to tradfri_remote because the name was to general - rename internal topics according to previous point - change type of battery remote low from string to boolean - do not use raw topic name in config, we have helper-functions for that - reformat iconColor to be a bit more readable --- config/rzl.js | 15 +++++++-------- config/utils.js | 12 ++++++------ 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 60304bd..7f9e124 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -2,7 +2,7 @@ import type { Config } from "config/flowtypes"; import * as types from "config/types"; import { hex, rgb, rgba, rainbow } from "config/colors"; -import { esper_topics, esper_statistics, floalt, remote } from "./utils"; +import { esper_topics, esper_statistics, floalt, tradfri_remote } from "./utils"; const config : Config = { space: { @@ -182,12 +182,12 @@ const config : Config = { floalt.topics("65538"), floalt.topics("65539"), floalt.topics("65540"), - remote.topics("65536"), + tradfri_remote.topics("65536"), //Theken-Floalts floalt.topics("65543"), floalt.topics("65544"), - remote.topics("65542"), + tradfri_remote.topics("65542"), esper_topics("afba40", "flyfry"), esper_topics("afba45", "alarm") @@ -702,9 +702,8 @@ const config : Config = { name: "Fernbedinungen", position: [400, 348], icon: "remote", - iconColor: ({remote_65536_low, remote_65542_low}) => - ((remote_65536_low == "true") || (remote_65542_low == "true")) - ? hex("#ff0000") : hex("#000000"), + iconColor: (state) => + (state[tradfri_remote.low("65536")] || state[tradfri_remote.low("65542")]) ? hex("#ff0000") : hex("#000000"), ui: [ { type: "progress", @@ -712,7 +711,7 @@ const config : Config = { min: 0, max: 100, text: "Tisch", - topic: "remote_65536_level" + topic: tradfri_remote.level("65536") }, { type: "progress", @@ -720,7 +719,7 @@ const config : Config = { min: 0, max: 100, text: "Theke", - topic: "remote_65542_level" + topic: tradfri_remote.level("65542") } ] }, diff --git a/config/utils.js b/config/utils.js index bfe593c..c19ddb0 100644 --- a/config/utils.js +++ b/config/utils.js @@ -59,21 +59,21 @@ export const floalt = { }) } -export const remote = { - level: (remote_id: string) => `remote_${remote_id}_level`, - low: (remote_id: string) => `remote_${remote_id}_low`, +export const tradfri_remote = { + level: (remote_id: string) => `tradfri_remote_${remote_id}_level`, + low: (remote_id: string) => `tradfri_remote_${remote_id}_low`, topics: (remote_id: string) => ({ - [ `remote_${remote_id}_level` ]: { + [ `tradfri_remote_${remote_id}_level` ]: { state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_level/state`, command: ``, defaultValue: "0", values: {} }, - [ `remote_${remote_id}_low` ]: { + [ `tradfri_remote_${remote_id}_low` ]: { state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_low/state`, command: ``, defaultValue: "OFF", - values: { true: "ON", false: "OFF" } + values: { [true]: "ON", [false]: "OFF" } } }) } From 3a34f345587b0da920008431f9a43fd46f45296d Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sat, 21 Apr 2018 12:40:08 +0200 Subject: [PATCH 04/28] use string instead of boolean Because array-keys are strings and it seems that they can not be booleans --- config/rzl.js | 2 +- config/utils.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 7f9e124..3cec3f3 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -703,7 +703,7 @@ const config : Config = { position: [400, 348], icon: "remote", iconColor: (state) => - (state[tradfri_remote.low("65536")] || state[tradfri_remote.low("65542")]) ? hex("#ff0000") : hex("#000000"), + ((state[tradfri_remote.low("65536")] == "true") || (state[tradfri_remote.low("65542")] == "true")) ? hex("#ff0000") : hex("#000000"), ui: [ { type: "progress", diff --git a/config/utils.js b/config/utils.js index c19ddb0..a4cce98 100644 --- a/config/utils.js +++ b/config/utils.js @@ -73,7 +73,7 @@ export const tradfri_remote = { state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_low/state`, command: ``, defaultValue: "OFF", - values: { [true]: "ON", [false]: "OFF" } + values: { true: "ON", false: "OFF" } } }) } From 1f248a5e9a0c89f13e41b2bd5e19e775c2ab9619 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 29 Apr 2018 18:24:23 +0200 Subject: [PATCH 05/28] +2 neue Fernbedinungen --- config/rzl.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/config/rzl.js b/config/rzl.js index 3cec3f3..3ab9230 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -183,11 +183,13 @@ const config : Config = { floalt.topics("65539"), floalt.topics("65540"), tradfri_remote.topics("65536"), + tradfri_remote.topics("65547"), //Theken-Floalts floalt.topics("65543"), floalt.topics("65544"), tradfri_remote.topics("65542"), + tradfri_remote.topics("65546"), esper_topics("afba40", "flyfry"), esper_topics("afba45", "alarm") @@ -703,7 +705,7 @@ const config : Config = { position: [400, 348], icon: "remote", iconColor: (state) => - ((state[tradfri_remote.low("65536")] == "true") || (state[tradfri_remote.low("65542")] == "true")) ? hex("#ff0000") : hex("#000000"), + ((state[tradfri_remote.low("65536")] == "true") || (state[tradfri_remote.low("65542")] == "true") || (state[tradfri_remote.low("65546")] == "true") || (state[tradfri_remote.low("65547")] == "true")) ? hex("#ff0000") : hex("#000000"), ui: [ { type: "progress", @@ -713,6 +715,14 @@ const config : Config = { text: "Tisch", topic: tradfri_remote.level("65536") }, + { + type: "progress", + icon: "battery", + min: 0, + max: 100, + text: "Tisch 2", + topic: tradfri_remote.level("65547") + }, { type: "progress", icon: "battery", @@ -720,6 +730,14 @@ const config : Config = { max: 100, text: "Theke", topic: tradfri_remote.level("65542") + }, + { + type: "progress", + icon: "battery", + min: 0, + max: 100, + text: "Theke 2", + topic: tradfri_remote.level("65546") } ] }, From 8fa2643eacc5b79c28b4ad79a2700583a5d480f8 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 10 Jun 2018 12:10:59 +0200 Subject: [PATCH 06/28] +Projector --- config/rzl.js | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/config/rzl.js b/config/rzl.js index 2279c8f..7298fba 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -129,6 +129,31 @@ const config : Config = { defaultValue: "OFF", values: { on: "ON", off: "OFF" } }, + projector: { + state: "/service/beamer/state", + command: "/service/beamer/command", + defaultValue: "unavailable", + values: {on: "ON", off: "OFF"}, + type: msg => { + switch (msg.toString()) { + case "START_UP": + case "START_UP_LAMP": + return "transient_on" + case "COOLING": + case "COOLING2": + return "transient_off" + case "POWER_ON": + return "on" + case "STANDBY": + return "off" + case "unknown": + return "unknown" + + default: + return msg.toString() + } + } + }, printer_3d_status: { state: "/service/ultimaker/state", command: "", @@ -295,6 +320,28 @@ const config : Config = { } ]) }, + projector: { + name: "Beamer", + position: [415, 590], + icon: "projector", + iconColor: ({projector}) => + ({ + transient_on: hex("#b3b300"), + transient_off: hex("#b3b300"), + on: hex("#00ff00"), + off: hex("#000000"), + unknown: hex("#888888"), + })[projector], + ui: [ + { + type: "toggle", + text: "Beamer", + topic: "projector", + toggled: val => val == "transient_on" || val == "on", + icon: "power" + } + ] + }, artnet: { name: "Artnet", position: [535,480], From d749e8107ac908dba5b5817df0c92c7c557f42f3 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Thu, 21 Jun 2018 17:02:28 +0000 Subject: [PATCH 07/28] chore(package): update flow-bin to version 0.75.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b269e53..bbfa7f0 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "eslint-plugin-react": "^7.6.1", "file-loader": "^1.1.5", "flow": "^0.2.3", - "flow-bin": "^0.70.0", + "flow-bin": "^0.75.0", "flow-typed": "^2.3.0", "html-webpack-plugin": "^3.1.0", "husky": "^0.14.3", From 75816dc15c35aa46cf941a45e9c88c1a8254afc3 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 13:20:47 +0200 Subject: [PATCH 08/28] Show number of WLAN-devices --- config/rzl.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/config/rzl.js b/config/rzl.js index 304c6e7..5ffa826 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -123,6 +123,12 @@ const config : Config = { values: {}, type: msg => JSON.parse(msg.toString()).join(", ") }, + devices_status: { + state: "/service/status/devices", + command: "", + defaultValue: "", + values: {} + }, infoscreen: { state: "/service/openhab/out/pca301_infoscreen/state", command: "/service/openhab/in/pca301_infoscreen/command", @@ -458,7 +464,14 @@ const config : Config = { text: "Anwesend", topic: "presence_status", icon: "account" + }, + { + type: "text", + text: "Devices", + topic: "devices_status", + icon: "wifi" } + ] }, infoscreen: { From 32fc4d613d81ca91050b2c0a1fd07ce2f4bc0b53 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 13:39:41 +0200 Subject: [PATCH 09/28] Flip projector icon --- config/rzl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rzl.js b/config/rzl.js index 7298fba..d5d29a6 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -323,7 +323,7 @@ const config : Config = { projector: { name: "Beamer", position: [415, 590], - icon: "projector", + icon: "projector flip-v", iconColor: ({projector}) => ({ transient_on: hex("#b3b300"), From 2df52f75be860b299a12331cf5ea872c42a80b26 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 14:24:42 +0200 Subject: [PATCH 10/28] Rechner und Drucker aufgeteilt auf 2 Funkdosen. Fixes #14 --- config/rzl.js | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index b9a8e7b..7736479 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -48,6 +48,12 @@ const config : Config = { defaultValue: "OFF", values: { on: "ON", off: "OFF" } }, + olymp_printer: { + state: "stat/sonoff2/POWER", + command: "cmnd/sonoff2/power", + defaultValue: "OFF", + values: { on: "ON", off: "OFF" } + }, flyfry: { state: "/service/openhab/out/wifi_flyfry/state", command: "/service/openhab/in/wifi_flyfry/command", @@ -274,19 +280,38 @@ const config : Config = { ] }, olymp_pc: { - name: "Rechner und Drucker", + name: "Rechner", position: [297, 90], icon: "desktop-classic", iconColor: ({olymp_pc}) => olymp_pc == "on" ? hex("#00FF00") : hex("#000000"), ui: [ { type: "toggle", - text: "Rechner und Drucker", + text: "Rechner", topic: "olymp_pc", icon: "power" } ] }, + olymp_printer: { + name: "Drucker", + position: [335, 90], + icon: "printer", + iconColor: ({olymp_printer}) => olymp_printer == "on" ? hex("#00FF00") : hex("#000000"), + ui: [ + { + type: "toggle", + text: "Drucker", + topic: "olymp_printer", + icon: "power" + }, + { + type: "link", + link: "http://annette.rzl/", + text: "Open Annette" + } + ] + }, flyfry: { name: "Fliegenbratgerät", position: [450, 590], From f507e388d587d605c8a3d80264ec6f8903d1281c Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 15:46:04 +0200 Subject: [PATCH 11/28] devices_status: +type: types.str --- config/rzl.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/rzl.js b/config/rzl.js index 5ffa826..1f3e24b 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -127,7 +127,8 @@ const config : Config = { state: "/service/status/devices", command: "", defaultValue: "", - values: {} + values: {}, + type: types.str }, infoscreen: { state: "/service/openhab/out/pca301_infoscreen/state", From d93362edcb970b849707c2077f413d2dba87382d Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 16:27:59 +0200 Subject: [PATCH 12/28] Changes from pull request discussion - simplyfy empty tradfri battery detection - change command string format --- config/rzl.js | 5 +++-- config/utils.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 129d4ae..0f2dc2f 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -736,8 +736,9 @@ const config : Config = { name: "Fernbedinungen", position: [400, 348], icon: "remote", - iconColor: (state) => - ((state[tradfri_remote.low("65536")] == "true") || (state[tradfri_remote.low("65542")] == "true") || (state[tradfri_remote.low("65546")] == "true") || (state[tradfri_remote.low("65547")] == "true")) ? hex("#ff0000") : hex("#000000"), + iconColor: (state) => //if any remote is low make icon red + ["65536", "65542", "65546", "65547" + ].some(x => state[tradfri_remote.low(x)] == "true") ? hex("#ff0000") : hex("#000000"), ui: [ { type: "progress", diff --git a/config/utils.js b/config/utils.js index 4f9ad4a..3542ca0 100644 --- a/config/utils.js +++ b/config/utils.js @@ -65,13 +65,13 @@ export const tradfri_remote = { topics: (remote_id: string) => ({ [ `tradfri_remote_${remote_id}_level` ]: { state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_level/state`, - command: ``, + command: "", defaultValue: "0", values: {} }, [ `tradfri_remote_${remote_id}_low` ]: { state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_low/state`, - command: ``, + command: "", defaultValue: "OFF", values: { true: "ON", false: "OFF" } } From ed0f22645e7f939c29318fa05a52e147db470224 Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 16:34:59 +0200 Subject: [PATCH 13/28] Completely rework how icons work in mqtt control map --- config/entropia.js | 7 +- config/rzl.js | 100 ++++++++++++++-------------- config/utils.js | 11 +-- package.json | 4 +- src/components/App.js | 4 +- src/components/ControlMap.js | 6 +- src/components/SideBar.js | 7 +- src/components/UiItemList/UiItem.js | 7 +- src/components/UiItemList/index.js | 6 +- src/config/flowtypes.js | 19 +++--- src/config/icon.js | 59 ++++++++++++++++ src/utils/parseIconName.js | 25 ------- webpack.config.js | 1 - yarn.lock | 71 +++++++++++++++++++- 14 files changed, 216 insertions(+), 111 deletions(-) create mode 100644 src/config/icon.js delete mode 100644 src/utils/parseIconName.js diff --git a/config/entropia.js b/config/entropia.js index 36e25d9..fc2f6ca 100644 --- a/config/entropia.js +++ b/config/entropia.js @@ -1,6 +1,7 @@ // @flow import type { Config } from "config/flowtypes"; import { hex, rgb, rgba, rainbow } from "config/colors"; +import { mdi } from "config/icon"; import { esper_topics, esper_statistics } from "./utils"; const config : Config = { @@ -29,20 +30,20 @@ const config : Config = { hauptraum_table_light: { name: "Hauptraum Tisch", position: [450, 450], - icon: "white-balance-iridescent", + icon: mdi("white-balance-iridescent"), iconColor: () => hex("#000000"), ui: [ { type: "toggle", text: "Licht", topic: "hauptraum_table_light", - icon: "power" + icon: mdi("power") }, { type: "toggle", text: "Licht", topic: "hauptraum_table_light_on_hack", - icon: "power" + icon: mdi("power") } ] } diff --git a/config/rzl.js b/config/rzl.js index 304c6e7..1180912 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -2,6 +2,7 @@ import type { Config } from "config/flowtypes"; import * as types from "config/types"; import { hex, rgb, rgba, rainbow } from "config/colors"; +import { mdi, raw_mdi } from "config/icon"; import { esper_topics, esper_statistics, floalt } from "./utils"; const config : Config = { @@ -194,63 +195,64 @@ const config : Config = { led_stahltrager: { name: "LED Stahlträger", position: [380, 590], - icon: "white-balance-iridescent", + icon: mdi("white-balance-iridescent"), iconColor: ({led_stahltraeger}) => led_stahltraeger == "on" ? rainbow : hex("#000000"), ui: [ { type: "toggle", text: "Stahlträger LED", topic: "led_stahltraeger", - icon: "power" + icon: mdi("power") }, ] }, snackbar: { name: "Snackbar", position: [510, 500], - icon: "fridge", + icon: mdi("fridge"), iconColor: ({snackbar}) => snackbar == "on" ? hex("#E20074") : hex("#000000"), ui: [ { type: "toggle", text: "Snackbar", topic: "snackbar", - icon: "power" + icon: mdi("power") } ] }, twinkle: { name: "Twinkle", position: [530, 560], - icon: ({twinkle}) => twinkle == "on" ? "led-on flip-v" : "led-off flip-v", + icon: ({twinkle}) => + twinkle == "on" ? raw_mdi("led-on flip-v") : raw_mdi("led-off flip-v"), iconColor: ({twinkle}) => twinkle == "on" ? rainbow : hex("#000000"), ui: [ { type: "toggle", text: "Twinkle", topic: "twinkle", - icon: "power" + icon: mdi("power") } ] }, fan: { name: "Ventilator", position: [520, 450], - icon: "fan", + icon: mdi("fan"), iconColor: ({fan}) => fan == "on" ? hex("#00FF00") : hex("#000000"), ui: [ { type: "toggle", text: "Ventilator", topic: "fan", - icon: "power" + icon: mdi("power") } ] }, cashdesk: { name: "Cashdesk", position: [500, 470], - icon: "coin", + icon: mdi("coin"), ui: [ { type: "link", @@ -262,49 +264,49 @@ const config : Config = { videogames: { name: "Videospiele", position: [100, 100], - icon: "gamepad-variant", + icon: mdi("gamepad-variant"), iconColor: ({videogames}) => videogames == "on" ? hex("#00FF00") : hex("#000000"), ui: [ { type: "toggle", text: "Videospiele", topic: "videogames", - icon: "power" + icon: mdi("power") } ] }, olymp_pc: { name: "Rechner und Drucker", position: [297, 90], - icon: "desktop-classic", + icon: mdi("desktop-classic"), iconColor: ({olymp_pc}) => olymp_pc == "on" ? hex("#00FF00") : hex("#000000"), ui: [ { type: "toggle", text: "Rechner und Drucker", topic: "olymp_pc", - icon: "power" + icon: mdi("power") } ] }, flyfry: { name: "Fliegenbratgerät", position: [450, 590], - icon: "fire", + icon: mdi("fire"), iconColor: ({flyfry}) => flyfry == "on" ? hex("#6666FF") : hex("#000000"), ui: esper_statistics("flyfry", [ { type: "toggle", text: "Fliegenbratgerät", topic: "flyfry", - icon: "power" + icon: mdi("power") } ]) }, artnet: { name: "Artnet", position: [535,480], - icon: "spotlight", + icon: mdi("spotlight"), iconColor: ({artnet}) => ({ off: hex("#000000"), @@ -321,7 +323,7 @@ const config : Config = { topic: "artnet", on: "cycle", toggled: val => val != "off", - icon: "power" + icon: mdi("power") }, { type: "dropDown", @@ -335,7 +337,7 @@ const config : Config = { cycle: "Farbwechsel" }, enableCondition: val => val != "off", - icon: "palette" + icon: mdi("palette") } ] }, @@ -344,12 +346,12 @@ const config : Config = { position: [350, 650], iconColor: ({onkyo_connection, onkyo_power}) => onkyo_connection != "connected" ? hex("#888888") : (onkyo_power == "on" ? hex("#00FF00") : hex("#000000")), - icon: "audio-video", + icon: mdi("audio-video"), ui: [ { type: "toggle", text: "Power", - icon: "power", + icon: mdi("power"), topic: "onkyo_power", enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" }, @@ -363,14 +365,14 @@ const config : Config = { topic: "onkyo_volume", min: 0, max: 50, - icon: "volume-high", + icon: mdi("volume-high"), enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" }, { type: "toggle", text: "Mute", topic: "onkyo_mute", - icon: "volume-off", + icon: mdi("volume-off"), enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" }, { @@ -388,7 +390,7 @@ const config : Config = { pult: "Pult", front: "Front HDMI" }, - icon: "usb", + icon: mdi("usb"), enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" }, { @@ -407,7 +409,7 @@ const config : Config = { somafm_beatblender: "Beat Blender (Soma FM)", ponyville: "Ponyville FM" }, - icon: "radio", + icon: mdi("radio"), enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" && state.onkyo_inputs.internal == "netzwerk" }, { @@ -424,28 +426,28 @@ const config : Config = { rundumleuchte: { name: "Rundumleuchte", position: [310,275], - icon: "alarm-light", + icon: mdi("alarm-light"), iconColor: ({rundumleuchte}) => rundumleuchte == "on" ? hex("#F0DF10") : hex("#000000"), ui: [ { type: "toggle", text: "Rundumleuchte", topic: "rundumleuchte", - icon: "power" + icon: mdi("power") } ] }, alarm: { name: "Alarm", position: [340, 250], - icon: "alarm-bell", + icon: mdi("alarm-bell"), iconColor: () => hex("#000000"), ui: esper_statistics("alarm") }, door: { name: "Tür", position: [455,350], - icon: "swap-vertical", + icon: mdi("swap-vertical"), iconColor: ({door_status}) => door_status == "on" ? hex("#00FF00") : hex("#FF0000"), ui: [ { @@ -457,21 +459,21 @@ const config : Config = { type: "text", text: "Anwesend", topic: "presence_status", - icon: "account" + icon: mdi("account") } ] }, infoscreen: { name: "Infoscreen", position: [255, 495], - icon: "television-guide flip-v", + icon: mdi("television-guide flip-v"), iconColor: ({infoscreen}) => infoscreen == "on" ? hex("#4444FF") : hex("#000000"), ui: [ { type: "toggle", text: "Infoscreen", topic: "infoscreen", - icon: "power" + icon: mdi("power") }, { type: "link", @@ -483,7 +485,7 @@ const config : Config = { printer_3d: { name: "Ultimaker 3", position: [754, 560], - icon: "printer-3d", + icon: mdi("printer-3d"), iconColor: ({printer_3d_status}) => ({ awaiting_interaction: hex("#b3b300"), @@ -504,7 +506,7 @@ const config : Config = { }, { type: "progress", - icon: "rotate-right", + icon: mdi("rotate-right"), min: 0, max: 1, text: "Printing Progress", @@ -515,7 +517,7 @@ const config : Config = { partkeepr: { name: "Partkeepr", position: [48, 450], - icon: "chip", + icon: mdi("chip"), ui: [ { type: "link", @@ -527,7 +529,7 @@ const config : Config = { kitchen_light: { name: "Deckenlicht Küche", position: [325, 407], - icon: "ceiling-light", + icon: mdi("ceiling-light"), ui: [ { type: "toggle", @@ -536,14 +538,14 @@ const config : Config = { toggled: n => parseInt(n) > 0, topic: "kitchen_light_brightness", text: "Ein/Ausschalten", - icon: "power" + icon: mdi("power") }, { type: "slider", min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: "kitchen_light_brightness", delayedApply: true }, @@ -552,7 +554,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: "kitchen_light_color", delayedApply: true }, @@ -565,7 +567,7 @@ const config : Config = { min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: floalt.brightness("65537"), delayedApply: true }, @@ -574,7 +576,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: floalt.color("65537"), delayedApply: true }, @@ -587,7 +589,7 @@ const config : Config = { min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: floalt.brightness("65538"), delayedApply: true }, @@ -596,7 +598,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: floalt.color("65538"), delayedApply: true }, @@ -609,7 +611,7 @@ const config : Config = { min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: floalt.brightness("65539"), delayedApply: true }, @@ -618,7 +620,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: floalt.color("65539"), delayedApply: true }, @@ -631,7 +633,7 @@ const config : Config = { min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: floalt.brightness("65540"), delayedApply: true }, @@ -640,7 +642,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: floalt.color("65540"), delayedApply: true } @@ -649,7 +651,7 @@ const config : Config = { kitchen_sink_light: { name: "Licht Spüle", position: [300, 345], - icon: "wall-sconce-flat", + icon: mdi("wall-sconce-flat"), ui: [ { type: "toggle", @@ -658,14 +660,14 @@ const config : Config = { toggled: n => parseInt(n) > 0, topic: "kitchen_sink_light_brightness", text: "Ein/Ausschalten", - icon: "power" + icon: mdi("power") }, { type: "slider", min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: "kitchen_sink_light_brightness", delayedApply: true } diff --git a/config/utils.js b/config/utils.js index 20cc656..1738354 100644 --- a/config/utils.js +++ b/config/utils.js @@ -1,5 +1,6 @@ // @flow import type { ControlUI } from "config/flowtypes"; +import { mdi } from "config/icon"; export const esper_topics = (chip_id: string, name: string) => ({ [ `esper_${name}_version` ]: { @@ -69,31 +70,31 @@ export const esper_statistics = (name: string, { type: "text", text: "Device Variant", - icon: "chart-donut", + icon: mdi("chart-donut"), topic: `esper_${name}_device` }, { type: "text", text: "Version", - icon: "source-branch", + icon: mdi("source-branch"), topic: `esper_${name}_version` }, { type: "text", text: "IP", - icon: "access-point-network", + icon: mdi("access-point-network"), topic: `esper_${name}_ip` }, { type: "text", text: "RSSI", - icon: "wifi", + icon: mdi("wifi"), topic: `esper_${name}_rssi` }, { type: "text", text: "Running since…", - icon: "av-timer", + icon: mdi("av-timer"), topic: `esper_${name}_uptime` } ]) diff --git a/package.json b/package.json index b269e53..ec57d5f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "build": "webpack --bail --config webpack.config.js -p --env", "dev": "webpack --bail --config webpack.config.js --mode development --env", - "watch": "webpack-dev-server --open --config webpack.dev.js --mode development --env", + "watch": "webpack-dev-server --open --config webpack.config.js --mode development --env", "travis": "./travis.sh", "lint": "eslint -- --ext js --ext jsx src/", "precommit": "yarn lint" @@ -30,8 +30,8 @@ "babel-eslint": "^8.0.1", "babel-loader": "^7.1.1", "babel-plugin-transform-class-properties": "^6.24.1", - "babel-preset-react": "^6.24.1", "babel-preset-env": "^1.6.0", + "babel-preset-react": "^6.24.1", "clean-webpack-plugin": "^0.1.18", "css-loader": "^0.28.9", "eslint": "^4.16.0", diff --git a/src/components/App.js b/src/components/App.js index fc5becd..7d6fb2f 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -19,7 +19,7 @@ import TopBar from "components/TopBar"; import UiItemList from "components/UiItemList"; import keyOf from "utils/keyOf"; -import { controlGetIcon } from "utils/parseIconName"; +import { toRawIcon } from "config/icon"; import connectMqtt from "../connectMqtt"; @@ -127,7 +127,7 @@ class App extends React.PureComponent { control={this.state.selectedControl} onCloseRequest={this.closeDrawer.bind(this)} icon={this.state.selectedControl == null ? null : - controlGetIcon(this.state.selectedControl, + toRawIcon(this.state.selectedControl.icon, this.state.mqttState)} > {this.state.selectedControl == null diff --git a/src/components/ControlMap.js b/src/components/ControlMap.js index 7524673..2606561 100644 --- a/src/components/ControlMap.js +++ b/src/components/ControlMap.js @@ -4,7 +4,7 @@ import { Map, ImageOverlay, Marker, LayersControl } from "react-leaflet"; import { CRS, point, divIcon } from "leaflet"; import map from "lodash/map"; import mapValues from "lodash/mapValues"; -import parseIconName, { controlGetIcon } from "utils/parseIconName"; +import { toRawIcon } from "config/icon"; import type { Controls, Control } from "config/flowtypes"; @@ -50,8 +50,8 @@ export default class ControlMap extends React.PureComponent { } createLeafletIcon(control: Control) { - const icon = controlGetIcon(control, this.props.state); - const iconClass = parseIconName(`${icon} 36px`); + const icon = toRawIcon(control.icon, this.props.state); + const iconClass = `${icon} mdi-36px`; return divIcon({ iconSize: point(36, 36), iconAnchor: point(18, 18), diff --git a/src/components/SideBar.js b/src/components/SideBar.js index a94e62e..5015bdc 100644 --- a/src/components/SideBar.js +++ b/src/components/SideBar.js @@ -8,15 +8,16 @@ import IconButton from "@material-ui/core/IconButton"; import AppBar from "@material-ui/core/AppBar"; import Toolbar from "@material-ui/core/Toolbar"; import List from "@material-ui/core/List"; -import { renderIcon } from "utils/parseIconName"; +import { renderRawIcon } from "config/icon"; +import type { RawIcon } from "config/icon"; import type { Control } from "config/flowtypes"; export type SideBarProps = { control: ?Control, open: boolean, onCloseRequest: () => void, - icon?: ?string, + icon?: ?RawIcon, children?: React.Node }; @@ -55,7 +56,7 @@ class SideBar extends React.PureComponent {this.props.icon == null - || renderIcon(this.props.icon, "mdi-36px")} + || renderRawIcon(this.props.icon, "mdi-36px")} {this.props.control == null || this.props.control.name} diff --git a/src/components/UiItemList/UiItem.js b/src/components/UiItemList/UiItem.js index 3821c18..886f47c 100644 --- a/src/components/UiItemList/UiItem.js +++ b/src/components/UiItemList/UiItem.js @@ -185,7 +185,7 @@ export class DropDown extends UiControl { } export class Slider extends UiControl { - runPrimaryAction = (_e: ?any, v: ?number) => { + runPrimaryAction = (e: ?Event, v: ?number) => { if (v != null) { this.changeState(v); } @@ -197,8 +197,9 @@ export class Slider extends UiControl { this.props.item.delayedApply || this.runPrimaryAction()} + step={this.props.item.step || 1} + onChange={(e, v) => + this.props.item.delayedApply || this.runPrimaryAction(e, v)} onDragEnd={this.runPrimaryAction} disabled={!this.isEnabled()} /> ]; diff --git a/src/components/UiItemList/index.js b/src/components/UiItemList/index.js index eef50ec..b23b3cc 100644 --- a/src/components/UiItemList/index.js +++ b/src/components/UiItemList/index.js @@ -2,7 +2,7 @@ import React from "react"; import ListItem from "@material-ui/core/ListItem"; import ListItemIcon from "@material-ui/core/ListItemIcon"; -import { renderIcon } from "utils/parseIconName"; +import { renderIcon } from "config/icon"; import type { ControlUI } from "config/flowtypes"; @@ -33,7 +33,9 @@ export default class UiItemList extends React.PureComponent { return ( {control.icon == null || - {renderIcon(control.icon, "mdi-24px")}} + + {renderIcon(control.icon, this.props.state, "mdi-24px")} + } {this.renderControl(control)} ); diff --git a/src/config/flowtypes.js b/src/config/flowtypes.js index bef0562..6e58f3b 100644 --- a/src/config/flowtypes.js +++ b/src/config/flowtypes.js @@ -1,5 +1,6 @@ // @flow import type { Color } from "config/colors"; +import type { Icon } from "config/icon"; export type TopicType = (msg: Buffer) => any; @@ -33,7 +34,7 @@ export type UIToggle = $ReadOnly<{| type: "toggle", text: string, topic: string, - icon?: string, + icon?: Icon, enableCondition?: TopicDependentOption, on?: Actual, off?: Actual, @@ -44,7 +45,7 @@ export type UIDropDown = $ReadOnly<{| type: "dropDown", text: string, topic: string, - icon?: string, + icon?: Icon, enableCondition?: TopicDependentOption, options: Map, renderValue?: (value: string) => string @@ -54,7 +55,7 @@ export type UISlider = $ReadOnly<{| type: "slider", text: string, topic: string, - icon?: string, + icon?: Icon, enableCondition?: TopicDependentOption, min?: number, max?: number, @@ -74,21 +75,21 @@ export type UILink = $ReadOnly<{| enableCondition?: StateDependentOption, // TODO: check if both the following options are implemented - icon?: string + icon?: Icon |}>; export type UIText = $ReadOnly<{| type: "text", text: string, topic: string, - icon?: string + icon?: Icon |}>; export type UIProgress = $ReadOnly<{| type: "progress", text: string, topic: string, - icon?: string, + icon?: Icon, min?: number, max?: number |}>; @@ -105,11 +106,7 @@ export type ControlUI = export type Control = { name: string, position: [number, number], - icon: string | ( - internals: Map, - actuals: Map, - state: State - ) => string, + icon: Icon, iconColor?: ( internals: Map, actuals: Map, diff --git a/src/config/icon.js b/src/config/icon.js new file mode 100644 index 0000000..524395e --- /dev/null +++ b/src/config/icon.js @@ -0,0 +1,59 @@ +// @flow +import * as React from "react"; +import { getInternals, getActuals } from "utils/state"; + +export opaque type RawIcon: string = string; + +export type Icon = (Map, Map, State) => + RawIcon; + +export const raw_mdi = (name: string): RawIcon => { + return `mdi ${name.split(" ").map((icon) => "mdi-".concat(icon)).join(" ")}`; +}; + +export const mdi = (icon: string) => () => raw_mdi(icon); + +export const mdi_battery = (topic: string) => + (state: Map) => { + const rawval = state[topic]; + const val = parseInt(rawval); + if (isNaN(val)) { + return raw_mdi("battery-unknown"); + } else if (val > 95) { + return raw_mdi("battery"); + } else if (val > 85) { + return raw_mdi("battery-90"); + } else if (val > 75) { + return raw_mdi("battery-80"); + } else if (val > 65) { + return raw_mdi("battery-70"); + } else if (val > 55) { + return raw_mdi("battery-60"); + } else if (val > 45) { + return raw_mdi("battery-50"); + } else if (val > 35) { + return raw_mdi("battery-40"); + } else if (val > 25) { + return raw_mdi("battery-30"); + } else if (val > 15) { + return raw_mdi("battery-20"); + } else { + return raw_mdi("battery-10"); + } + }; + +export const toRawIcon = (icon: Icon, state: State): RawIcon => { + const internals: Map = getInternals(state); + const actuals: Map = getActuals(state); + return icon(internals, actuals, state); +}; + +export const renderRawIcon = + (icon: RawIcon, extraClass?: string): React.Node => { + return ; + }; + +export const renderIcon = + (icon: Icon, state: State, extraClass?: string): React.Node => { + return renderRawIcon(toRawIcon(icon, state), extraClass); + }; diff --git a/src/utils/parseIconName.js b/src/utils/parseIconName.js deleted file mode 100644 index 96d290f..0000000 --- a/src/utils/parseIconName.js +++ /dev/null @@ -1,25 +0,0 @@ -// @flow -import * as React from "react"; -import { getInternals, getActuals } from "utils/state"; - -import type { Control } from "config/flowtypes"; - -export default function parseIconName(name: string): string { - return `mdi ${name.split(" ").map((icon) => "mdi-".concat(icon)).join(" ")}`; -} - -export const renderIcon = (name: string, extraClass?: string): React.Node => { - return ; -}; - -export const controlGetIcon = (control: Control, state: State): string => { - const internals: Map = getInternals(state); - const actuals: Map = getActuals(state); - return typeof control.icon !== "function" ? control.icon - : control.icon(internals, actuals, state); -}; - -export const renderControlIcon = (control: Control, - state: State, extraClass?: string): React.Node => { - return renderIcon(controlGetIcon(control, state), extraClass); -}; diff --git a/webpack.config.js b/webpack.config.js index 71d7f96..0c38752 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,6 @@ const webpack = require('webpack'); const WebpackShellPlugin = require('webpack-shell-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); - const preBuildScripts = process.env.NO_FLOW == undefined ? process.env.FLOW_PATH != undefined ? [process.env.FLOW_PATH] : ['flow'] : []; diff --git a/yarn.lock b/yarn.lock index 592ad3d..935b0e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -175,6 +175,10 @@ acorn@^5.0.0, acorn@^5.5.0: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" +acorn@^5.3.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + ajv-keywords@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" @@ -1026,6 +1030,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bfj-node4@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.3.1.tgz#e23d8b27057f1d0214fc561142ad9db998f26830" + dependencies: + bluebird "^3.5.1" + check-types "^7.3.0" + tryer "^1.0.0" + big-integer@^1.6.17: version "1.6.27" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.27.tgz#8e56c6f8b2dd6c4fe8d32102b83d4f25868e4b3a" @@ -1380,7 +1392,7 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^2.4.1: +chalk@^2.3.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -1404,6 +1416,10 @@ charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" +check-types@^7.3.0: + version "7.4.0" + resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" + chokidar@^1.6.1: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1588,7 +1604,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@2.15.x, commander@^2.11.0, commander@~2.15.0: +commander@2.15.x, commander@^2.11.0, commander@^2.13.0, commander@~2.15.0: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" @@ -2141,6 +2157,10 @@ duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + duplexify@^3.4.2, duplexify@^3.5.1, duplexify@^3.5.3: version "3.5.4" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" @@ -2160,6 +2180,10 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" +ejs@^2.5.7: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" + electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30: version "1.3.42" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.42.tgz#95c33bf01d0cc405556aec899fe61fd4d76ea0f9" @@ -2570,6 +2594,10 @@ filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" +filesize@^3.5.11: + version "3.6.1" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" + fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" @@ -2924,6 +2952,13 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" +gzip-size@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" + dependencies: + duplexer "^0.1.1" + pify "^3.0.0" + handle-thing@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" @@ -4493,6 +4528,10 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +opener@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + opn@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" @@ -6230,6 +6269,10 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" +tryer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" + tslib@^1.9.0: version "1.9.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e" @@ -6540,6 +6583,23 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.0" +webpack-bundle-analyzer@^2.13.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz#07d2176c6e86c3cdce4c23e56fae2a7b6b4ad526" + dependencies: + acorn "^5.3.0" + bfj-node4 "^5.2.0" + chalk "^2.3.0" + commander "^2.13.0" + ejs "^2.5.7" + express "^4.16.2" + filesize "^3.5.11" + gzip-size "^4.1.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + opener "^1.4.3" + ws "^4.0.0" + webpack-cli@^3.0.0: version "3.0.8" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.0.8.tgz#90eddcf04a4bfc31aa8c0edc4c76785bc4f1ccd9" @@ -6734,6 +6794,13 @@ ws@^3.2.0: safe-buffer "~5.1.0" ultron "~1.1.0" +ws@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From 0e1b41f87c21488f86c38a758811ad47921d44bd Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 16:38:04 +0200 Subject: [PATCH 14/28] Update rzl.js --- config/rzl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 0f2dc2f..b00e813 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -737,8 +737,8 @@ const config : Config = { position: [400, 348], icon: "remote", iconColor: (state) => //if any remote is low make icon red - ["65536", "65542", "65546", "65547" - ].some(x => state[tradfri_remote.low(x)] == "true") ? hex("#ff0000") : hex("#000000"), + ["65536", "65542", "65546", "65547"].some( + x => state[tradfri_remote.low(x)] == "true") ? hex("#ff0000") : hex("#000000"), ui: [ { type: "progress", From a34ca7c25c3630a50384e8ebcc017ecfff1a8779 Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 16:42:36 +0200 Subject: [PATCH 15/28] RZL: Use mdi_battery for tradfri remote battery icons --- config/rzl.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index b515f95..eac774d 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -769,7 +769,7 @@ const config : Config = { ui: [ { type: "progress", - icon: "battery", + icon: mdi_battery(tradfri_remote.level("65536")), min: 0, max: 100, text: "Tisch", @@ -777,7 +777,7 @@ const config : Config = { }, { type: "progress", - icon: "battery", + icon: mdi_battery(tradfri_remote.level("65547")), min: 0, max: 100, text: "Tisch 2", @@ -785,7 +785,7 @@ const config : Config = { }, { type: "progress", - icon: "battery", + icon: mdi_battery(tradfri_remote.level("65542")), min: 0, max: 100, text: "Theke", @@ -793,7 +793,7 @@ const config : Config = { }, { type: "progress", - icon: "battery", + icon: mdi_battery(tradfri_remote.level("65546")), min: 0, max: 100, text: "Theke 2", From aad1b59a96efe5b9a3e28d0ca15eef5c6e7f7833 Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 16:46:29 +0200 Subject: [PATCH 16/28] Fix merge conflicts --- config/rzl.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index eac774d..c21dd99 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -308,14 +308,14 @@ const config : Config = { olymp_printer: { name: "Drucker", position: [335, 90], - icon: "printer", + icon: mdi("printer"), iconColor: ({olymp_printer}) => olymp_printer == "on" ? hex("#00FF00") : hex("#000000"), ui: [ { type: "toggle", text: "Drucker", topic: "olymp_printer", - icon: "power" + icon: mdi("power") }, { type: "link", @@ -711,7 +711,7 @@ const config : Config = { kitchen_counter_light: { name: "Deckenlicht Theke", position: [400, 440], - icon: "ceiling-light", + icon: mdi("ceiling-light"), ui: [ { type: "section", @@ -722,7 +722,7 @@ const config : Config = { min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: floalt.brightness("65544"), delayedApply: true }, @@ -731,7 +731,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: floalt.color("65544"), delayedApply: true }, @@ -744,7 +744,7 @@ const config : Config = { min: 0, max: 100, text: "Helligkeit", - icon: "brightness-7", + icon: mdi("brightness-7"), topic: floalt.brightness("65543"), delayedApply: true }, @@ -753,7 +753,7 @@ const config : Config = { min: 0, max: 100, text: "Farbtemperatur", - icon: "weather-sunset-down", + icon: mdi("weather-sunset-down"), topic: floalt.color("65543"), delayedApply: true } From fdce5b96458a643a090cb1ed13016ca84482f727 Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 16:51:09 +0200 Subject: [PATCH 17/28] Add forgotten import --- config/rzl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index c21dd99..0ffaa0e 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -2,7 +2,7 @@ import type { Config } from "config/flowtypes"; import * as types from "config/types"; import { hex, rgb, rgba, rainbow } from "config/colors"; -import { mdi, raw_mdi } from "config/icon"; +import { mdi, raw_mdi, mdi_battery } from "config/icon"; import { esper_topics, esper_statistics, floalt, tradfri_remote } from "./utils"; const config : Config = { @@ -762,7 +762,7 @@ const config : Config = { remotes: { name: "Fernbedinungen", position: [400, 348], - icon: "remote", + icon: mdi("remote"), iconColor: (state) => //if any remote is low make icon red ["65536", "65542", "65546", "65547"].some( x => state[tradfri_remote.low(x)] == "true") ? hex("#ff0000") : hex("#000000"), From 6a5bf85c1eec432b242413553cf2b50bf4fe62fe Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 16:55:44 +0200 Subject: [PATCH 18/28] RZL: Use the light switch icon instead of remote --- config/rzl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rzl.js b/config/rzl.js index 0ffaa0e..81e50c6 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -762,7 +762,7 @@ const config : Config = { remotes: { name: "Fernbedinungen", position: [400, 348], - icon: mdi("remote"), + icon: mdi("light-switch"), iconColor: (state) => //if any remote is low make icon red ["65536", "65542", "65546", "65547"].some( x => state[tradfri_remote.low(x)] == "true") ? hex("#ff0000") : hex("#000000"), From bb2f151e110ab13b0a3d4c276b5fd1e620e9ecc2 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 16:57:45 +0200 Subject: [PATCH 19/28] types.str -> types.string --- config/rzl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rzl.js b/config/rzl.js index 1f3e24b..dc660d5 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -128,7 +128,7 @@ const config : Config = { command: "", defaultValue: "", values: {}, - type: types.str + type: types.string }, infoscreen: { state: "/service/openhab/out/pca301_infoscreen/state", From a8756c2a180254a64b847b35104ff0052f091f1d Mon Sep 17 00:00:00 2001 From: uwap Date: Sun, 24 Jun 2018 17:02:12 +0200 Subject: [PATCH 20/28] RZL: Optimize Tradfri Remote frontend --- config/rzl.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 81e50c6..fee9977 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -761,7 +761,7 @@ const config : Config = { }, remotes: { name: "Fernbedinungen", - position: [400, 348], + position: [400, 344], icon: mdi("light-switch"), iconColor: (state) => //if any remote is low make icon red ["65536", "65542", "65546", "65547"].some( @@ -772,7 +772,7 @@ const config : Config = { icon: mdi_battery(tradfri_remote.level("65536")), min: 0, max: 100, - text: "Tisch", + text: "Licht Tisch 1", topic: tradfri_remote.level("65536") }, { @@ -780,7 +780,7 @@ const config : Config = { icon: mdi_battery(tradfri_remote.level("65547")), min: 0, max: 100, - text: "Tisch 2", + text: "Licht Tisch 2", topic: tradfri_remote.level("65547") }, { @@ -788,7 +788,7 @@ const config : Config = { icon: mdi_battery(tradfri_remote.level("65542")), min: 0, max: 100, - text: "Theke", + text: "Licht Theke 1", topic: tradfri_remote.level("65542") }, { @@ -796,7 +796,7 @@ const config : Config = { icon: mdi_battery(tradfri_remote.level("65546")), min: 0, max: 100, - text: "Theke 2", + text: "Licht Theke 2", topic: tradfri_remote.level("65546") } ] From fe175c9055b2a28638a8f49294dcbd5d5b37dcc8 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 17:32:54 +0200 Subject: [PATCH 21/28] Projector: Handle offline-State --- config/rzl.js | 1 + 1 file changed, 1 insertion(+) diff --git a/config/rzl.js b/config/rzl.js index d5d29a6..61b4ae3 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -147,6 +147,7 @@ const config : Config = { case "STANDBY": return "off" case "unknown": + case "offline": return "unknown" default: From 9db6d1c50a6e417ac32d8a8c8a103d7b02554768 Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Sun, 24 Jun 2018 17:50:41 +0200 Subject: [PATCH 22/28] Projector: use new icon format --- config/rzl.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/rzl.js b/config/rzl.js index 61b4ae3..df62817 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -324,7 +324,7 @@ const config : Config = { projector: { name: "Beamer", position: [415, 590], - icon: "projector flip-v", + icon: mdi("projector flip-v"), iconColor: ({projector}) => ({ transient_on: hex("#b3b300"), @@ -339,7 +339,7 @@ const config : Config = { text: "Beamer", topic: "projector", toggled: val => val == "transient_on" || val == "on", - icon: "power" + icon: mdi("power") } ] }, From fc0a2940604b1400b87343e94627ece0a2ad207e Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Tue, 26 Jun 2018 04:01:52 +0000 Subject: [PATCH 23/28] chore(package): update eslint to version 5.0.1 Closes #38 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec41426..7c1a03d 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "babel-preset-react": "^6.24.1", "clean-webpack-plugin": "^0.1.18", "css-loader": "^0.28.9", - "eslint": "^4.16.0", + "eslint": "^5.0.1", "eslint-plugin-flowtype": "^2.42.0", "eslint-plugin-react": "^7.6.1", "file-loader": "^1.1.5", From 62732acc5076e67c49cc56cf65ba75aabdd6b903 Mon Sep 17 00:00:00 2001 From: uwap Date: Tue, 26 Jun 2018 14:55:20 +0200 Subject: [PATCH 24/28] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c1a03d..4e44247 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "dev": "webpack --bail --config webpack.config.js --mode development --env", "watch": "webpack-dev-server --open --config webpack.config.js --mode development --env", "travis": "./travis.sh", - "lint": "eslint -- --ext js --ext jsx src/", + "lint": "eslint --ext js --ext jsx src/", "precommit": "yarn lint" }, "dependencies": { From 24ab3990adacbe7a4f40d0f866c6ae9137455569 Mon Sep 17 00:00:00 2001 From: uwap Date: Tue, 26 Jun 2018 15:12:38 +0200 Subject: [PATCH 25/28] Fix eslint warnings and errors --- src/components/SideBar.js | 7 +- src/components/TopBar.js | 2 +- src/components/UiItemList/UiItem.js | 2 +- src/components/UiItemList/index.js | 2 +- src/config/types.js | 6 +- src/index.jsx | 6 +- yarn.lock | 284 +++++++++++++--------------- 7 files changed, 141 insertions(+), 168 deletions(-) diff --git a/src/components/SideBar.js b/src/components/SideBar.js index 5015bdc..1f30932 100644 --- a/src/components/SideBar.js +++ b/src/components/SideBar.js @@ -24,9 +24,10 @@ export type SideBarProps = { export type SideBarState = { }; -class SideBar extends React.PureComponent -{ - constructor(props: SideBarProps & Classes) { +type Props = SideBarProps & Classes; + +class SideBar extends React.PureComponent { + constructor(props: Props) { super(props); } diff --git a/src/components/TopBar.js b/src/components/TopBar.js index 56cbe10..0d4953f 100644 --- a/src/components/TopBar.js +++ b/src/components/TopBar.js @@ -16,7 +16,7 @@ export type TopBarState = { }; export default class TopBar - extends React.PureComponent { + extends React.PureComponent { constructor(props: TopBarProps) { super(props); } diff --git a/src/components/UiItemList/UiItem.js b/src/components/UiItemList/UiItem.js index 886f47c..de70edc 100644 --- a/src/components/UiItemList/UiItem.js +++ b/src/components/UiItemList/UiItem.js @@ -31,7 +31,7 @@ type UiItemProps = { // eslint-disable-next-line flowtype/no-weak-types export default class UiItem - extends React.PureComponent> { + extends React.PureComponent> { constructor(props: UiItemProps) { super(props); } diff --git a/src/components/UiItemList/index.js b/src/components/UiItemList/index.js index b23b3cc..b0c3f16 100644 --- a/src/components/UiItemList/index.js +++ b/src/components/UiItemList/index.js @@ -7,7 +7,7 @@ import { renderIcon } from "config/icon"; import type { ControlUI } from "config/flowtypes"; import { Toggle, DropDown, Link, - Section, Text, Progress, Slider } from "./UiItem"; + Section, Text, Progress, Slider } from "./UiItem"; export type UiItemListProps = { controls: Array, diff --git a/src/config/types.js b/src/config/types.js index 0a4961d..8fe7c58 100644 --- a/src/config/types.js +++ b/src/config/types.js @@ -1,8 +1,8 @@ // @flow import type { TopicType } from "config/flowtypes"; -export const string: TopicType = msg => msg.toString(); +export const string: TopicType = (msg) => msg.toString(); export const json = (path: string, innerType?: TopicType): TopicType => { - const parseAgain = innerType == null ? x => x : innerType; - return msg => parseAgain(JSON.parse(msg.toString())[path]); + const parseAgain = innerType == null ? (x) => x : innerType; + return (msg) => parseAgain(JSON.parse(msg.toString())[path]); }; diff --git a/src/index.jsx b/src/index.jsx index 66997e4..9e96856 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -8,11 +8,11 @@ import App from "components/App"; import "../node_modules/@mdi/font/css/materialdesignicons.min.css"; import "../css/styles.css"; -const Config : Config = window.config; +const config : Config = window.config; injectTapEventPlugin(); -document.title = `${Config.space.name} Map`; +document.title = `${config.space.name} Map`; // $FlowFixMe const contentElement: Element = document.getElementById("content"); -ReactDOM.render(, contentElement); +ReactDOM.render(, contentElement); diff --git a/yarn.lock b/yarn.lock index 935b0e1..ecf63c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -161,28 +161,20 @@ acorn-dynamic-import@^3.0.0: dependencies: acorn "^5.0.0" -acorn-jsx@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" +acorn-jsx@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-4.1.1.tgz#e8e41e48ea2fe0c896740610ab6a4ffd8add225e" dependencies: - acorn "^3.0.4" + acorn "^5.0.3" -acorn@^3.0.4: - version "3.3.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" - -acorn@^5.0.0, acorn@^5.5.0: +acorn@^5.0.0: version "5.5.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.5.3.tgz#f473dd47e0277a08e28e9bec5aeeb04751f0b8c9" -acorn@^5.3.0: +acorn@^5.0.3, acorn@^5.6.0: version "5.7.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" -ajv-keywords@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-2.1.1.tgz#617997fc5f60576894c435f940d819e135b80762" - ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.1.0.tgz#ac2b27939c543e95d2c06e7f7f5c27be4aa543be" @@ -194,15 +186,6 @@ ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.2.3, ajv@^5.3.0: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - ajv@^6.0.1, ajv@^6.1.0: version "6.4.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.4.0.tgz#d3aff78e9277549771daf0164cff48482b754fc6" @@ -212,6 +195,15 @@ ajv@^6.0.1, ajv@^6.1.0: json-schema-traverse "^0.3.0" uri-js "^3.0.2" +ajv@^6.5.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.1.tgz#88ebc1263c7133937d108b80c5572e64e1d9322d" + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.1" + alphanum-sort@^1.0.1, alphanum-sort@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -426,7 +418,7 @@ babel-cli@^6.24.1: optionalDependencies: chokidar "^1.6.1" -babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: +babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" dependencies: @@ -1030,14 +1022,6 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bfj-node4@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/bfj-node4/-/bfj-node4-5.3.1.tgz#e23d8b27057f1d0214fc561142ad9db998f26830" - dependencies: - bluebird "^3.5.1" - check-types "^7.3.0" - tryer "^1.0.0" - big-integer@^1.6.17: version "1.6.27" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.27.tgz#8e56c6f8b2dd6c4fe8d32102b83d4f25868e4b3a" @@ -1392,7 +1376,7 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^2.3.0, chalk@^2.4.1: +chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -1416,10 +1400,6 @@ charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" -check-types@^7.3.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" - chokidar@^1.6.1: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" @@ -1604,7 +1584,7 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@2.15.x, commander@^2.11.0, commander@^2.13.0, commander@~2.15.0: +commander@2.15.x, commander@^2.11.0, commander@~2.15.0: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" @@ -1649,7 +1629,7 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concat-stream@^1.5.0, concat-stream@^1.6.0, concat-stream@^1.6.2: +concat-stream@^1.5.0, concat-stream@^1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" dependencies: @@ -1754,7 +1734,7 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: safe-buffer "^5.0.1" sha.js "^2.4.8" -cross-spawn@^5.0.1, cross-spawn@^5.1.0: +cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" dependencies: @@ -2157,10 +2137,6 @@ duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" -duplexer@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" - duplexify@^3.4.2, duplexify@^3.5.1, duplexify@^3.5.3: version "3.5.4" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.5.4.tgz#4bb46c1796eabebeec4ca9a2e66b808cb7a3d8b4" @@ -2180,10 +2156,6 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -ejs@^2.5.7: - version "2.6.1" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" - electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.30: version "1.3.42" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.42.tgz#95c33bf01d0cc405556aec899fe61fd4d76ea0f9" @@ -2244,6 +2216,16 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" +es-abstract@^1.10.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.11.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.11.0.tgz#cce87d518f0496893b1a30cd8461835535480681" @@ -2292,59 +2274,66 @@ eslint-scope@^3.7.1, eslint-scope@~3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" -eslint@^4.16.0: - version "4.19.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.19.1.tgz#32d1d653e1d90408854bfb296f076ec7e186a300" +eslint@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.0.1.tgz#109b90ab7f7a736f54e0f341c8bb9d09777494c3" dependencies: - ajv "^5.3.0" - babel-code-frame "^6.22.0" + ajv "^6.5.0" + babel-code-frame "^6.26.0" chalk "^2.1.0" - concat-stream "^1.6.0" - cross-spawn "^5.1.0" + cross-spawn "^6.0.5" debug "^3.1.0" doctrine "^2.1.0" - eslint-scope "^3.7.1" + eslint-scope "^4.0.0" eslint-visitor-keys "^1.0.0" - espree "^3.5.4" - esquery "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" esutils "^2.0.2" file-entry-cache "^2.0.0" functional-red-black-tree "^1.0.1" glob "^7.1.2" - globals "^11.0.1" + globals "^11.5.0" ignore "^3.3.3" imurmurhash "^0.1.4" - inquirer "^3.0.6" - is-resolvable "^1.0.0" - js-yaml "^3.9.1" + inquirer "^5.2.0" + is-resolvable "^1.1.0" + js-yaml "^3.11.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.3.0" - lodash "^4.17.4" - minimatch "^3.0.2" + lodash "^4.17.5" + minimatch "^3.0.4" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" path-is-inside "^1.0.2" pluralize "^7.0.0" progress "^2.0.0" - regexpp "^1.0.1" + regexpp "^1.1.0" require-uncached "^1.0.3" - semver "^5.3.0" + semver "^5.5.0" + string.prototype.matchall "^2.0.0" strip-ansi "^4.0.0" - strip-json-comments "~2.0.1" - table "4.0.2" - text-table "~0.2.0" + strip-json-comments "^2.0.1" + table "^4.0.3" + text-table "^0.2.0" -espree@^3.5.4: - version "3.5.4" - resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.4.tgz#b0f447187c8a8bed944b815a660bddf5deb5d1a7" +espree@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.0.0.tgz#253998f20a0f82db5d866385799d912a83a36634" dependencies: - acorn "^5.5.0" - acorn-jsx "^3.0.0" + acorn "^5.6.0" + acorn-jsx "^4.1.1" esprima@^2.6.0: version "2.7.3" @@ -2354,7 +2343,7 @@ esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" -esquery@^1.0.0: +esquery@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" dependencies: @@ -2487,7 +2476,7 @@ extend@^3.0.0, extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.0.4: +external-editor@^2.1.0: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" dependencies: @@ -2534,6 +2523,10 @@ fast-deep-equal@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" @@ -2594,10 +2587,6 @@ filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" -filesize@^3.5.11: - version "3.6.1" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" - fill-range@^2.1.0: version "2.2.3" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" @@ -2663,9 +2652,9 @@ flatten@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" -flow-bin@^0.70.0: - version "0.70.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.70.0.tgz#080ae83a997f2b4ddb3dc2649bf13336825292b5" +flow-bin@^0.75.0: + version "0.75.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.75.0.tgz#b96d1ee99d3b446a3226be66b4013224ce9df260" flow-typed@^2.3.0: version "2.4.0" @@ -2900,10 +2889,14 @@ global@~4.3.0: min-document "^2.19.0" process "~0.5.1" -globals@^11.0.1, globals@^11.1.0: +globals@^11.1.0: version "11.4.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.4.0.tgz#b85c793349561c16076a3c13549238a27945f1bc" +globals@^11.5.0: + version "11.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.7.0.tgz#a583faa43055b1aca771914bf68258e2fc125673" + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -2952,13 +2945,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.4, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" -gzip-size@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-4.1.0.tgz#8ae096257eabe7d69c45be2b67c448124ffb517c" - dependencies: - duplexer "^0.1.1" - pify "^3.0.0" - handle-thing@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" @@ -2992,6 +2978,10 @@ has-symbol-support-x@^1.4.1: version "1.4.2" resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + has-to-string-tag-x@^1.2.0: version "1.4.1" resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" @@ -3308,21 +3298,20 @@ ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" -inquirer@^3.0.6: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" +inquirer@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" dependencies: ansi-escapes "^3.0.0" chalk "^2.0.0" cli-cursor "^2.1.0" cli-width "^2.0.0" - external-editor "^2.0.4" + external-editor "^2.1.0" figures "^2.0.0" lodash "^4.3.0" mute-stream "0.0.7" run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" + rxjs "^5.5.2" string-width "^2.1.0" strip-ansi "^4.0.0" through "^2.3.6" @@ -3608,7 +3597,7 @@ is-relative@^1.0.0: dependencies: is-unc-path "^1.0.0" -is-resolvable@^1.0.0: +is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" @@ -3700,9 +3689,9 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.9.1: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" +js-yaml@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -3734,6 +3723,10 @@ json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + json-schema@0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" @@ -4528,10 +4521,6 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" -opener@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" - opn@^5.1.0: version "5.3.0" resolved "https://registry.yarnpkg.com/opn/-/opn-5.3.0.tgz#64871565c863875f052cfdf53d3e3cb5adb53b1c" @@ -5438,7 +5427,13 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" -regexpp@^1.0.1: +regexp.prototype.flags@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz#6b30724e306a27833eeb171b66ac8890ba37e41c" + dependencies: + define-properties "^1.1.2" + +regexpp@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab" @@ -5604,15 +5599,11 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" +rxjs@^5.5.2: + version "5.5.11" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.11.tgz#f733027ca43e3bec6b994473be4ab98ad43ced87" dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + symbol-observable "1.0.1" rxjs@^6.1.0: version "6.2.1" @@ -6009,6 +6000,16 @@ string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string.prototype.matchall@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-2.0.0.tgz#2af8fe3d2d6dc53ca2a59bd376b089c3c152b3c8" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.10.0" + function-bind "^1.1.1" + has-symbols "^1.0.0" + regexp.prototype.flags "^1.2.0" + string_decoder@^1.0.0, string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -6055,7 +6056,7 @@ strip-indent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" -strip-json-comments@~2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -6100,6 +6101,10 @@ svgo@^0.7.0: sax "~1.2.1" whet.extend "~0.9.9" +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + symbol-observable@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.4.tgz#29bf615d4aa7121bdd898b22d4b3f9bc4e2aa03d" @@ -6108,18 +6113,7 @@ symbol-observable@^1.0.3, symbol-observable@^1.0.4, symbol-observable@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" -table@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/table/-/table-4.0.2.tgz#a33447375391e766ad34d3486e6e2aedc84d2e36" - dependencies: - ajv "^5.2.3" - ajv-keywords "^2.1.0" - chalk "^2.1.0" - lodash "^4.17.4" - slice-ansi "1.0.0" - string-width "^2.1.1" - -table@^4.0.2: +table@^4.0.2, table@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" dependencies: @@ -6155,7 +6149,7 @@ tar@^2.2.1: fstream "^1.0.2" inherits "2" -text-table@~0.2.0: +text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -6269,10 +6263,6 @@ trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" -tryer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.0.tgz#027b69fa823225e551cace3ef03b11f6ab37c1d7" - tslib@^1.9.0: version "1.9.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e" @@ -6436,6 +6426,12 @@ uri-js@^3.0.2: dependencies: punycode "^2.1.0" +uri-js@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -6583,23 +6579,6 @@ wbuf@^1.1.0, wbuf@^1.7.2: dependencies: minimalistic-assert "^1.0.0" -webpack-bundle-analyzer@^2.13.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.13.1.tgz#07d2176c6e86c3cdce4c23e56fae2a7b6b4ad526" - dependencies: - acorn "^5.3.0" - bfj-node4 "^5.2.0" - chalk "^2.3.0" - commander "^2.13.0" - ejs "^2.5.7" - express "^4.16.2" - filesize "^3.5.11" - gzip-size "^4.1.0" - lodash "^4.17.4" - mkdirp "^0.5.1" - opener "^1.4.3" - ws "^4.0.0" - webpack-cli@^3.0.0: version "3.0.8" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.0.8.tgz#90eddcf04a4bfc31aa8c0edc4c76785bc4f1ccd9" @@ -6794,13 +6773,6 @@ ws@^3.2.0: safe-buffer "~5.1.0" ultron "~1.1.0" -ws@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From b40f4a774ec7ea16d3b60dd671ee2b72f158c8f3 Mon Sep 17 00:00:00 2001 From: uwap Date: Tue, 26 Jun 2018 15:17:50 +0200 Subject: [PATCH 26/28] Fix flow error --- src/index.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.jsx b/src/index.jsx index 9e96856..c8ab2bd 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -8,6 +8,8 @@ import App from "components/App"; import "../node_modules/@mdi/font/css/materialdesignicons.min.css"; import "../css/styles.css"; +import type { Config } from "config/flowtypes"; + const config : Config = window.config; injectTapEventPlugin(); From a1a3cf0ed85a7033ef7d37bc8c32625d4d7c6baf Mon Sep 17 00:00:00 2001 From: Ranlvor Date: Thu, 28 Jun 2018 18:38:34 +0200 Subject: [PATCH 27/28] Use new map.rzl.so-Domain --- config/rzl.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/rzl.js b/config/rzl.js index aec1a33..0fc4ce4 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -9,7 +9,7 @@ const config : Config = { space: { name: "RZL", color: "orange", - mqtt: "ws://map.rzl:1884" + mqtt: "ws://map.rzl.so:1884" }, topics: [ { From c0117fa7d653dd364c585632a8af5ef7341ce2bb Mon Sep 17 00:00:00 2001 From: uwap Date: Thu, 28 Jun 2018 21:25:06 +0200 Subject: [PATCH 28/28] Do not use internal and actual values anymore (Fixes #42) --- config/entropia.js | 19 +- config/rzl.js | 436 ++++++++++++++++------------ config/utils.js | 95 +++--- src/components/App.js | 45 ++- src/components/ControlMap.js | 8 +- src/components/SideBar.js | 4 +- src/components/UiItemList/UiItem.js | 39 +-- src/components/UiItemList/index.js | 4 +- src/config/flowtypes.js | 46 ++- src/config/icon.js | 70 ++--- src/config/types.js | 19 +- src/utils/state.js | 8 - types/types.js | 21 +- 13 files changed, 421 insertions(+), 393 deletions(-) delete mode 100644 src/utils/state.js diff --git a/config/entropia.js b/config/entropia.js index fc2f6ca..ea6939a 100644 --- a/config/entropia.js +++ b/config/entropia.js @@ -1,6 +1,7 @@ // @flow import type { Config } from "config/flowtypes"; import { hex, rgb, rgba, rainbow } from "config/colors"; +import * as types from "config/types"; import { mdi } from "config/icon"; import { esper_topics, esper_statistics } from "./utils"; @@ -13,16 +14,18 @@ const config : Config = { topics: [ { hauptraum_table_light: { - command: "/public/sensoren/TPH/leinwand/control", - state: "test", - defaultValue: "A1 ON", - values: { on: "A1 ON", off: "A1 OFF" } + command: { + name: "/public/sensoren/TPH/leinwand/control", + type: types.option({ "A1 ON": "on", "A1 OFF": "off" }) + }, + defaultValue: "off" }, hauptraum_table_light_on_hack: { - command: "/public/sensoren/TPH/leinwand/control", - state: "test", - defaultValue: "A1 OFF", - values: { on: "A1 ON", off: "A1 OFF" } + command: { + name: "/public/sensoren/TPH/leinwand/control", + type: types.option({ "A1 ON": "on", "A1 OFF": "off" }) + }, + defaultValue: "on" } } ], diff --git a/config/rzl.js b/config/rzl.js index aec1a33..e606527 100644 --- a/config/rzl.js +++ b/config/rzl.js @@ -14,187 +14,299 @@ const config : Config = { topics: [ { led_stahltraeger: { - state: "/service/openhab/out/pca301_ledstrips/state", - command: "/service/openhab/in/pca301_ledstrips/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_ledstrips/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_ledstrips/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, snackbar: { - state: "/service/openhab/out/pca301_snackbar/state", - command: "/service/openhab/in/pca301_snackbar/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_snackbar/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_snackbar/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off", }, twinkle: { - state: "/service/openhab/out/pca301_twinkle/state", - command: "/service/openhab/in/pca301_twinkle/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_twinkle/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_twinkle/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, fan: { - state: "/service/openhab/out/pca301_fan/state", - command: "/service/openhab/in/pca301_fan/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_fan/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_fan/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, videogames: { - state: "/service/openhab/out/pca301_videogames/state", - command: "/service/openhab/in/pca301_videogames/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_videogames/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_videogames/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, olymp_pc: { - state: "/service/openhab/out/pca301_olymp_pc/state", - command: "/service/openhab/in/pca301_olymp_pc/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_olymp_pc/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_olymp_pc/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, olymp_printer: { - state: "stat/sonoff2/POWER", - command: "cmnd/sonoff2/power", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "stat/sonoff2/POWER", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "cmnd/sonoff2/power", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, flyfry: { - state: "/service/openhab/out/wifi_flyfry/state", - command: "/service/openhab/in/wifi_flyfry/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } - }, - artnet: { - state: "/artnet/state", - command: "/artnet/push", - defaultValue: "blackout", - values: { off: "blackout", yellow: "yellow", purple: "purple", - blue: "blue", green: "green", red: "red", random: "random", - cycle: "cycle-random" } + state: { + name: "/service/openhab/out/wifi_flyfry/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/wifi_flyfry/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, onkyo_connection: { - state: "/service/onkyo/connected", - command: "", - defaultValue: "0", - values: { disconnected: "0", connecting: "1", connected: "2" }, + state: { + name: "/service/onkyo/connected", + type: types.option({ + "0": "disconnected", + "1": "connecting", + "2": "connected" + }) + }, + defaultValue: "disconnected" }, onkyo_power: { - state: "/service/onkyo/status/system-power", - command: "/service/onkyo/command", - defaultValue: "PWR00", - values: { off: "PWR00", on: "PWR01" }, - type: types.json("onkyo_raw") + state: { + name: "/service/onkyo/status/system-power", + type: types.json("onkyo_raw", types.option({ + PWR00: "off", + PWR01: "on" + })) + }, + command: { + name: "/service/onkyo/command", + type: types.option({ off: "PWR00", on: "PWR01" }) + }, + defaultValue: "off" }, onkyo_mute: { - state: "/service/onkyo/status/audio-muting", - command: "/service/onkyo/command", - defaultValue: "AMT00", - values: { off: "AMT00", on: "AMT01" }, - type: types.json("onkyo_raw") + state: { + name: "/service/onkyo/status/audio-muting", + type: types.json("onkyo_raw", types.option({ + AMT00: "off", + AMT01: "on" + })) + }, + command: { + name: "/service/onkyo/command", + type: types.option({ off: "AMT00", on: "AMT01" }) + }, + defaultValue: "off" }, onkyo_volume: { - state: "/service/onkyo/status/volume", - command: "/service/onkyo/set/volume", - defaultValue: 0, - values: {}, - type: types.json("val") + state: { + name: "/service/onkyo/status/volume", + type: types.json("val") + }, + command: { + name: "/service/onkyo/set/volume", + type: types.string + }, + defaultValue: "0" }, onkyo_inputs: { - state: "/service/onkyo/status/input-selector", - command: "/service/onkyo/command", - defaultValue: "SLI00", - values: { tisch: "SLI11", chromecast: "SLI01", pult: "SLI10", netzwerk: "SLI2B", front: "SLI03" }, - type: types.json("onkyo_raw") + state: { + name: "/service/onkyo/status/input-selector", + type: types.json("onkyo_raw", types.option({ + SLI11: "tisch", + SLI01: "chromecast", + SLI10: "pult", + SLI2B: "netzwerk", + SLI03: "front", + otherwise: "unknown" + })) + }, + command: { + name: "/service/onkyo/command", + type: types.option({ + tisch: "SLI11", + chromecast: "SLI01", + pult: "SLI10", + netzwerk: "SLI2B", + front: "SLI03", + unknown: "SLI00" + }) + }, + defaultValue: "unknown", }, onkyo_radios: { - state: "/service/onkyo/status/latest-NPR", - command: "/service/onkyo/command", - defaultValue: "", - values: { mpd: "NPR01", kohina: "NPR02", somafm_dronezone: "NPR03", somafm_thetrip: "NPR04", - querfunk: "NPR05", somafm_defconradio: "NPR06", somafm_secretagent: "NPR07", somafm_lush: "NPR08", - somafm_beatblender: "NPR09", ponyville: "NPR0a"} + state: { + name: "/service/onkyo/status/latest-NPR", + type: types.option({ + NPR01: "mpd", + NPR02: "kohina", + NPR03: "somafm_dronezone", + NPR04: "somafm_thetrip", + NPR05: "querfunk", + NPR06: "somafm_defconradio", + NPR07: "somafm_secretagent", + NPR08: "somafm_lush", + NPR09: "somafm_beatblender", + NPR0a: "ponyville", + otherwise: "unknown" + }) + }, + command: { + name: "/service/onkyo/command", + type: types.option({ + mpd: "NPR01", + kohina: "NPR02", + somafm_dronezone: "NPR03", + somafm_thetrip: "NPR04", + querfunk: "NPR05", + somafm_defconradio: "NPR06", + somafm_secretagent: "NPR07", + somafm_lush: "NPR08", + somafm_beatblender: "NPR09", + ponyville: "NPR0a", + otherwise: "NPR00" + }) + }, + defaultValue: "unknown" }, rundumleuchte: { - state: "/service/openhab/out/pca301_rundumleuchte/state", - command: "/service/openhab/in/pca301_rundumleuchte/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_rundumleuchte/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_rundumleuchte/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, door_status: { - state: "/service/status", - command: "", - defaultValue: "\"closed\"", - values: { on: "\"open\"", off: "\"closed\"" } + state: { + name: "/service/status", + type: types.option({ "\"open\"": "on", "\"closed\"": "off" }) + }, + defaultValue: "off" }, presence_status: { - state: "service/status/presence", - command: "", - defaultValue: "", - values: {}, - type: msg => JSON.parse(msg.toString()).join(", ") + state: { + name: "service/status/presence", + type: types.jsonArray + }, + defaultValue: "" }, devices_status: { - state: "/service/status/devices", - command: "", - defaultValue: "", - values: {}, - type: types.string + state: { + name: "/service/status/devices", + type: types.string + }, + defaultValue: "" }, infoscreen: { - state: "/service/openhab/out/pca301_infoscreen/state", - command: "/service/openhab/in/pca301_infoscreen/command", - defaultValue: "OFF", - values: { on: "ON", off: "OFF" } + state: { + name: "/service/openhab/out/pca301_infoscreen/state", + type: types.option({ ON: "on", OFF: "off" }) + }, + command: { + name: "/service/openhab/in/pca301_infoscreen/command", + type: types.option({ on: "ON", off: "OFF" }) + }, + defaultValue: "off" }, printer_3d_status: { - state: "/service/ultimaker/state", - command: "", + state: { + name: "/service/ultimaker/state", + type: types.option({ + unreachable: "unavailable", + booting: "unavailable", + pre_print: "printing", + post_print: "printing", + printing: "printing", + otherwise: "awaiting_interaction" + }) + }, defaultValue: "unavailable", - values: {}, - type: msg => { - switch (msg.toString()) { - case "unreachable": - case "booting": - return "unavailable" - - case "pausing": - case "paused": - case "resuming": - case "wait_cleanup": - case "maintenance": - return "awaiting_interaction" - - case "pre_print": - case "post_print": - case "printing": - return "printing" - - default: - return msg.toString() - } - } }, printer_3d_progress: { - state: "/service/ultimaker/job", - command: "", - defaultValue: "", - values: {}, - type: msg => JSON.parse(msg.toString()).progress || 0 + state: { + name: "/service/ultimaker/job", + type: msg => JSON.parse(msg.toString()).progress || "0" + }, + defaultValue: "0" }, kitchen_light_color: { - state: "/service/openhab/out/kitchen_light_all_color_temperature/state", - command: "/service/openhab/in/kitchen_light_all_color_temperature/command", - defaultValue: "0", - values: {} + state: { + name: "/service/openhab/out/kitchen_light_all_color_temperature/state", + type: types.string + }, + command: { + name: "/service/openhab/in/kitchen_light_all_color_temperature/command", + type: types.string + }, + defaultValue: "0" }, kitchen_light_brightness: { - state: "/service/openhab/out/kitchen_light_all_brightness/state", - command: "/service/openhab/in/kitchen_light_all_brightness/command", - defaultValue: "0", - values: {} + state: { + name: "/service/openhab/out/kitchen_light_all_brightness/state", + type: types.string + }, + command: { + name: "/service/openhab/in/kitchen_light_all_brightness/command", + type: types.string + }, + defaultValue: "0" }, kitchen_sink_light_brightness: { - state: "/service/openhab/out/tradfri_0100_gwb8d7af2b448f_65545_brightness/state", - command: "/service/openhab/in/tradfri_0100_gwb8d7af2b448f_65545_brightness/command", - defaultValue: "0", - values: {} + state: { + name: "/service/openhab/out/tradfri_0100_gwb8d7af2b448f_65545_brightness/state", + type: types.string + }, + command: { + name: "/service/openhab/in/tradfri_0100_gwb8d7af2b448f_65545_brightness/command", + type: types.string + }, + defaultValue: "0" } }, //Kuechen-Floalts @@ -345,44 +457,6 @@ const config : Config = { } ]) }, - artnet: { - name: "Artnet", - position: [535,480], - icon: mdi("spotlight"), - iconColor: ({artnet}) => - ({ - off: hex("#000000"), - yellow: hex("#F0DF10"), - red: hex("#FF0000"), - purple: hex("#FF00FF"), - green: hex("#00FF00"), - cycle: rainbow - })[artnet], - ui: [ - { - type: "toggle", - text: "An/Aus", - topic: "artnet", - on: "cycle", - toggled: val => val != "off", - icon: mdi("power") - }, - { - type: "dropDown", - text: "Farbe", - topic: "artnet", - options: { - yellow: "Gelb", - red: "Rot", - purple: "Pink", - green: "Grün", - cycle: "Farbwechsel" - }, - enableCondition: val => val != "off", - icon: mdi("palette") - } - ] - }, onkyo: { name: "Onkyo", position: [350, 650], @@ -395,7 +469,7 @@ const config : Config = { text: "Power", icon: mdi("power"), topic: "onkyo_power", - enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" + enableCondition: ({ onkyo_connection }) => onkyo_connection == "connected" }, { type: "section", @@ -408,14 +482,14 @@ const config : Config = { min: 0, max: 50, icon: mdi("volume-high"), - enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" + enableCondition: ({ onkyo_connection }) => onkyo_connection == "connected" }, { type: "toggle", text: "Mute", topic: "onkyo_mute", icon: mdi("volume-off"), - enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" + enableCondition: ({ onkyo_connection }) => onkyo_connection == "connected" }, { type: "section", @@ -433,7 +507,7 @@ const config : Config = { front: "Front HDMI" }, icon: mdi("usb"), - enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" + enableCondition: ({ onkyo_connection }) => onkyo_connection == "connected" }, { type: "dropDown", @@ -452,7 +526,7 @@ const config : Config = { ponyville: "Ponyville FM" }, icon: mdi("radio"), - enableCondition: (a, b, state) => state.onkyo_connection.internal == "connected" && state.onkyo_inputs.internal == "netzwerk" + enableCondition: (state) => state.onkyo_connection == "connected" && state.onkyo_inputs == "netzwerk" }, { type: "section", @@ -582,8 +656,8 @@ const config : Config = { ui: [ { type: "toggle", - on: 50, - off: 0, + on: "50", + off: "0", toggled: n => parseInt(n) > 0, topic: "kitchen_light_brightness", text: "Ein/Ausschalten", @@ -704,8 +778,8 @@ const config : Config = { ui: [ { type: "toggle", - on: 50, - off: 0, + on: "50", + off: "0", toggled: n => parseInt(n) > 0, topic: "kitchen_sink_light_brightness", text: "Ein/Ausschalten", diff --git a/config/utils.js b/config/utils.js index e3d4169..5ebd526 100644 --- a/config/utils.js +++ b/config/utils.js @@ -1,43 +1,44 @@ // @flow import type { ControlUI } from "config/flowtypes"; import { mdi } from "config/icon"; +import * as types from "config/types"; export const esper_topics = (chip_id: string, name: string) => ({ [ `esper_${name}_version` ]: { - state: `/service/esper/${chip_id}/info`, - command: "", - defaultValue: "UNKNOWN", - values: {}, - type: msg => JSON.parse(msg.toString()).version.esper + state: { + name: `/service/esper/${chip_id}/info`, + type: types.json("version.esper") + }, + defaultValue: "UNKNOWN" }, [ `esper_${name}_ip` ]: { - state: `/service/esper/${chip_id}/info`, - command: "", - defaultValue: "UNKNOWN", - values: {}, - type: msg => JSON.parse(msg.toString()).network.ip + state: { + name: `/service/esper/${chip_id}/info`, + type: types.json("network.ip") + }, + defaultValue: "UNKNOWN" }, [ `esper_${name}_rssi` ]: { - state: `/service/esper/${chip_id}/info`, - command: "", - defaultValue: "UNKNOWN", - values: {}, - type: msg => JSON.parse(msg.toString()).wifi.rssi + state: { + name: `/service/esper/${chip_id}/info`, + type: types.json("wifi.rssi") + }, + defaultValue: "UNKNOWN" }, [ `esper_${name}_uptime` ]: { - state: `/service/esper/${chip_id}/info`, - command: "", - defaultValue: "UNKNOWN", - values: {}, - type: msg => new Date(JSON.parse(msg.toString()).time.startup * 1000) + state: { + name: `/service/esper/${chip_id}/info`, + type: msg => new Date(JSON.parse(msg.toString()).time.startup * 1000) .toLocaleString() + }, + defaultValue: "UNKNOWN", }, [ `esper_${name}_device` ]: { - state: `/service/esper/${chip_id}/info`, - command: "", - defaultValue: "UNKNOWN", - values: {}, - type: msg => JSON.parse(msg.toString()).device + state: { + name: `/service/esper/${chip_id}/info`, + type: types.json("device") + }, + defaultValue: "UNKNOWN" } }); @@ -46,16 +47,26 @@ export const floalt = { brightness: (light_id: string) => `floalt_${light_id}_brightness`, topics: (light_id: string) => ({ [ `floalt_${light_id}_color` ]: { - state: `/service/openhab/out/tradfri_0220_gwb8d7af2b448f_${light_id}_color_temperature/state`, - command: `/service/openhab/in/tradfri_0220_gwb8d7af2b448f_${light_id}_color_temperature/command`, - defaultValue: "0", - values: {} + state: { + name: `/service/openhab/out/tradfri_0220_gwb8d7af2b448f_${light_id}_color_temperature/state`, + type: types.string + }, + command: { + name: `/service/openhab/in/tradfri_0220_gwb8d7af2b448f_${light_id}_color_temperature/command`, + type: types.string + }, + defaultValue: "0" }, [ `floalt_${light_id}_brightness` ]: { - state: `/service/openhab/out/tradfri_0220_gwb8d7af2b448f_${light_id}_brightness/state`, - command: `/service/openhab/in/tradfri_0220_gwb8d7af2b448f_${light_id}_brightness/command`, - defaultValue: "0", - values: {} + state: { + name: `/service/openhab/out/tradfri_0220_gwb8d7af2b448f_${light_id}_brightness/state`, + type: types.string + }, + command: { + name: `/service/openhab/in/tradfri_0220_gwb8d7af2b448f_${light_id}_brightness/command`, + type: types.string + }, + defaultValue: "0" } }) } @@ -65,16 +76,18 @@ export const tradfri_remote = { low: (remote_id: string) => `tradfri_remote_${remote_id}_low`, topics: (remote_id: string) => ({ [ `tradfri_remote_${remote_id}_level` ]: { - state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_level/state`, - command: "", - defaultValue: "0", - values: {} + state: { + name: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_level/state`, + type: types.string + }, + defaultValue: "0" }, [ `tradfri_remote_${remote_id}_low` ]: { - state: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_low/state`, - command: "", - defaultValue: "OFF", - values: { true: "ON", false: "OFF" } + state: { + name: `/service/openhab/out/tradfri_0830_gwb8d7af2b448f_${remote_id}_battery_low/state`, + type: types.option({ ON: "true", OFF: "false" }) + }, + defaultValue: "false", } }) } diff --git a/src/components/App.js b/src/components/App.js index 7d6fb2f..d11a56b 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -18,9 +18,6 @@ import ControlMap from "components/ControlMap"; import TopBar from "components/TopBar"; import UiItemList from "components/UiItemList"; -import keyOf from "utils/keyOf"; -import { toRawIcon } from "config/icon"; - import connectMqtt from "../connectMqtt"; export type AppProps = { @@ -31,7 +28,7 @@ export type AppState = { selectedControl: ?Control, drawerOpened: boolean, mqttState: State, - mqttSend: (topic: string, value: Actual) => void, + mqttSend: (topic: string, value: Buffer) => void, mqttConnected: boolean, }; @@ -41,16 +38,15 @@ class App extends React.PureComponent { this.state = { selectedControl: null, drawerOpened: false, - mqttState: mapValues(this.topics, (topic) => ({ - actual: topic.defaultValue, - internal: keyOf(topic.values, topic.defaultValue) - })), + mqttState: mapValues(this.topics, (topic) => topic.defaultValue), mqttSend: connectMqtt(props.config.space.mqtt, { onMessage: this.receiveMessage.bind(this), onConnect: () => this.setState({ mqttConnected: true }), onReconnect: () => this.setState({ mqttConnected: false }), onDisconnect: () => this.setState({ mqttConnected: false }), - subscribe: map(this.topics, (x) => x.state) + subscribe: map( + filter(keys(this.topics), (x) => this.topics[x].state != null), + (x) => this.topics[x].state.name) }), mqttConnected: false }; @@ -77,23 +73,23 @@ class App extends React.PureComponent { }); } - receiveMessage(rawTopic: string, message: Object) { + receiveMessage(rawTopic: string, message: Buffer) { const topics = filter( keys(this.topics), - (k) => this.topics[k].state === rawTopic + (k) => this.topics[k].state != null && + this.topics[k].state.name === rawTopic ); if (topics.length === 0) { return; } for (let i in topics) { + // TODO: Remove FlowFixMe const topic = topics[i]; - const parseValue = this.topics[topic].type; + // $FlowFixMe + const parseValue = this.topics[topic].state.type; const val = parseValue == null ? message.toString() : parseValue(message); this.setState({mqttState: Object.assign({}, merge(this.state.mqttState, - { [topic]: { - actual: val, - internal: keyOf(this.topics[topic].values, val) || val - }}))}); + { [topic]: val}))}); } } @@ -105,15 +101,15 @@ class App extends React.PureComponent { this.setState({drawerOpened: false}); } - changeState(topic: string, value: Actual) { - const rawTopic = this.topics[topic].command; - if (rawTopic == null) { + changeState(topic: string, value: string) { + if (this.topics[topic].command == null) { return; } - this.state.mqttSend( - rawTopic, - String(this.topics[topic].values[value] || value) - ); + const rawTopic = this.topics[topic].command.name; + const transformValue = this.topics[topic].command.type; + const val = + transformValue == null ? value : transformValue(Buffer.from(value)); + this.state.mqttSend(rawTopic, Buffer.from(val)); } render() { @@ -127,8 +123,7 @@ class App extends React.PureComponent { control={this.state.selectedControl} onCloseRequest={this.closeDrawer.bind(this)} icon={this.state.selectedControl == null ? null : - toRawIcon(this.state.selectedControl.icon, - this.state.mqttState)} + this.state.selectedControl.icon(this.state.mqttState)} > {this.state.selectedControl == null || { } createLeafletIcon(control: Control) { - const icon = toRawIcon(control.icon, this.props.state); + const icon = control.icon(this.props.state); const iconClass = `${icon} mdi-36px`; return divIcon({ iconSize: point(36, 36), @@ -61,10 +59,8 @@ export default class ControlMap extends React.PureComponent { } iconColor(control: Control): string { - const ints = mapValues(this.props.state, (x) => x.internal || x.actual); - const acts = mapValues(this.props.state, (x) => x.actual); if (control.iconColor != null) { - return control.iconColor(ints, acts, this.props.state); + return control.iconColor(this.props.state); } return "#000"; } diff --git a/src/components/SideBar.js b/src/components/SideBar.js index 1f30932..eff2c34 100644 --- a/src/components/SideBar.js +++ b/src/components/SideBar.js @@ -8,7 +8,7 @@ import IconButton from "@material-ui/core/IconButton"; import AppBar from "@material-ui/core/AppBar"; import Toolbar from "@material-ui/core/Toolbar"; import List from "@material-ui/core/List"; -import { renderRawIcon } from "config/icon"; +import { renderIcon } from "config/icon"; import type { RawIcon } from "config/icon"; import type { Control } from "config/flowtypes"; @@ -57,7 +57,7 @@ class SideBar extends React.PureComponent { {this.props.icon == null - || renderRawIcon(this.props.icon, "mdi-36px")} + || renderIcon(this.props.icon, "mdi-36px")} {this.props.control == null || this.props.control.name} diff --git a/src/components/UiItemList/UiItem.js b/src/components/UiItemList/UiItem.js index de70edc..aadfd83 100644 --- a/src/components/UiItemList/UiItem.js +++ b/src/components/UiItemList/UiItem.js @@ -21,12 +21,11 @@ import type { } from "config/flowtypes"; import keyOf from "utils/keyOf"; -import { getInternals, getActuals } from "utils/state"; type UiItemProps = { item: I, state: State, - onChangeState: (topic: string, nextState: Actual) => void + onChangeState: (topic: string, nextState: string) => void }; // eslint-disable-next-line flowtype/no-weak-types @@ -54,9 +53,7 @@ export default class UiItem typeof this.props.item.enableCondition == "function") { const enableCondition = this.props.item.enableCondition; const state = this.props.state; - const internals = getInternals(state); - const actuals = getActuals(state); - return enableCondition(internals, actuals, state); + return enableCondition(state); } else { return true; } @@ -68,7 +65,7 @@ export class UiControl extends UiItem { super(props); } - changeState(next: Actual) { + changeState(next: string) { if (this.props.item.topic == null) { throw new Error( `Missing topic in ${this.props.item.type} "${this.props.item.text}"` @@ -93,19 +90,6 @@ export class UiControl extends UiItem { } return value; } - - isEnabled() { - if (Object.keys(this.props.item).includes("enableCondition") && - // $FlowFixMe - typeof this.props.item.enableCondition == "function") { - const enableCondition = this.props.item.enableCondition; - const value = this.getValue(); - return enableCondition( - value.internal || value.actual, value.actual, this.props.state); - } else { - return true; - } - } } export class Toggle extends UiControl { @@ -113,9 +97,8 @@ export class Toggle extends UiControl { const value = this.getValue(); const control = this.props.item; const isChecked = control.toggled || - ((i, _a, _s) => i === (control.on || "on")); - const checked = isChecked( - value.internal || value.actual, value.actual, this.props.state); + ((i, _s) => i === (control.on || "on")); + const checked = isChecked(value, this.props.state); return checked; } @@ -145,7 +128,7 @@ export class Toggle extends UiControl { } export class DropDown extends UiControl { - runPrimaryAction = (next?: Actual) => { + runPrimaryAction = (next?: string) => { if (this.isEnabled()) { const control = this.props.item; const optionKeys = keys(control.options); @@ -172,7 +155,7 @@ export class DropDown extends UiControl { return ( {control.text} - } @@ -187,7 +170,7 @@ export class DropDown extends UiControl { export class Slider extends UiControl { runPrimaryAction = (e: ?Event, v: ?number) => { if (v != null) { - this.changeState(v); + this.changeState(v.toString()); } } @@ -195,7 +178,7 @@ export class Slider extends UiControl { return [ , @@ -245,7 +228,7 @@ export class Text extends UiControl { render() { return [ , - + ]; } } @@ -254,7 +237,7 @@ export class Progress extends UiControl { render() { const min = this.props.item.min || 0; const max = this.props.item.max || 100; - const val = parseFloat(this.getValue().internal || this.getValue().actual); + const val = parseFloat(this.getValue()); const value = val * 100 / max - min; return [ , diff --git a/src/components/UiItemList/index.js b/src/components/UiItemList/index.js index b0c3f16..a627377 100644 --- a/src/components/UiItemList/index.js +++ b/src/components/UiItemList/index.js @@ -12,7 +12,7 @@ import { Toggle, DropDown, Link, export type UiItemListProps = { controls: Array, state: State, - onChangeState: (topic: string, nextState: Actual) => void + onChangeState: (topic: string, nextState: string) => void }; export default class UiItemList extends React.PureComponent { @@ -34,7 +34,7 @@ export default class UiItemList extends React.PureComponent { {control.icon == null || - {renderIcon(control.icon, this.props.state, "mdi-24px")} + {renderIcon(control.icon(this.props.state), "mdi-24px")} } {this.renderControl(control)} diff --git a/src/config/flowtypes.js b/src/config/flowtypes.js index 6e58f3b..6cccf3f 100644 --- a/src/config/flowtypes.js +++ b/src/config/flowtypes.js @@ -2,24 +2,20 @@ import type { Color } from "config/colors"; import type { Icon } from "config/icon"; -export type TopicType = (msg: Buffer) => any; +export type TopicType = (msg: Buffer) => string; + +export type StateCommand = { + name: string, + type: TopicType +} export type Topic = { - state: string, - command: string, - defaultValue: Actual, - values: Map, - type?: TopicType + state?: StateCommand, + command?: StateCommand, + defaultValue: string }; export type Topics = Map; -export type TopicDependentOption = ( - internal: Internal, actual: Actual, state: State - ) => T; -export type StateDependentOption = ( - internals: Map, actuals: Map, state: State - ) => T; - export interface UIControl { +type: string, +text: string, @@ -27,7 +23,7 @@ export interface UIControl { } export interface Enableable { - enableCondition?: TopicDependentOption + enableCondition?: (s: State) => boolean } export type UIToggle = $ReadOnly<{| @@ -35,10 +31,10 @@ export type UIToggle = $ReadOnly<{| text: string, topic: string, icon?: Icon, - enableCondition?: TopicDependentOption, - on?: Actual, - off?: Actual, - toggled?: TopicDependentOption + enableCondition?: (s: State) => boolean, + on?: string, + off?: string, + toggled?: (v: string, s: State) => boolean |}>; export type UIDropDown = $ReadOnly<{| @@ -46,8 +42,8 @@ export type UIDropDown = $ReadOnly<{| text: string, topic: string, icon?: Icon, - enableCondition?: TopicDependentOption, - options: Map, + enableCondition?: (s: State) => boolean, + options: Map, renderValue?: (value: string) => string |}>; @@ -56,7 +52,7 @@ export type UISlider = $ReadOnly<{| text: string, topic: string, icon?: Icon, - enableCondition?: TopicDependentOption, + enableCondition?: (s: State) => boolean, min?: number, max?: number, step?: number, @@ -72,7 +68,7 @@ export type UILink = $ReadOnly<{| type: "link", text: string, link: string, - enableCondition?: StateDependentOption, + enableCondition?: (s: State) => boolean, // TODO: check if both the following options are implemented icon?: Icon @@ -107,11 +103,7 @@ export type Control = { name: string, position: [number, number], icon: Icon, - iconColor?: ( - internals: Map, - actuals: Map, - state: State - ) => Color, + iconColor?: (state: State) => Color, ui: Array }; export type Controls = Map; diff --git a/src/config/icon.js b/src/config/icon.js index 524395e..e1ae9f8 100644 --- a/src/config/icon.js +++ b/src/config/icon.js @@ -1,11 +1,9 @@ // @flow import * as React from "react"; -import { getInternals, getActuals } from "utils/state"; export opaque type RawIcon: string = string; -export type Icon = (Map, Map, State) => - RawIcon; +export type Icon = (State) => RawIcon; export const raw_mdi = (name: string): RawIcon => { return `mdi ${name.split(" ").map((icon) => "mdi-".concat(icon)).join(" ")}`; @@ -13,47 +11,35 @@ export const raw_mdi = (name: string): RawIcon => { export const mdi = (icon: string) => () => raw_mdi(icon); -export const mdi_battery = (topic: string) => - (state: Map) => { - const rawval = state[topic]; - const val = parseInt(rawval); - if (isNaN(val)) { - return raw_mdi("battery-unknown"); - } else if (val > 95) { - return raw_mdi("battery"); - } else if (val > 85) { - return raw_mdi("battery-90"); - } else if (val > 75) { - return raw_mdi("battery-80"); - } else if (val > 65) { - return raw_mdi("battery-70"); - } else if (val > 55) { - return raw_mdi("battery-60"); - } else if (val > 45) { - return raw_mdi("battery-50"); - } else if (val > 35) { - return raw_mdi("battery-40"); - } else if (val > 25) { - return raw_mdi("battery-30"); - } else if (val > 15) { - return raw_mdi("battery-20"); - } else { - return raw_mdi("battery-10"); - } - }; - -export const toRawIcon = (icon: Icon, state: State): RawIcon => { - const internals: Map = getInternals(state); - const actuals: Map = getActuals(state); - return icon(internals, actuals, state); +export const mdi_battery = (topic: string) => (state: State) => { + const rawval = state[topic]; + const val = parseInt(rawval); + if (isNaN(val)) { + return raw_mdi("battery-unknown"); + } else if (val > 95) { + return raw_mdi("battery"); + } else if (val > 85) { + return raw_mdi("battery-90"); + } else if (val > 75) { + return raw_mdi("battery-80"); + } else if (val > 65) { + return raw_mdi("battery-70"); + } else if (val > 55) { + return raw_mdi("battery-60"); + } else if (val > 45) { + return raw_mdi("battery-50"); + } else if (val > 35) { + return raw_mdi("battery-40"); + } else if (val > 25) { + return raw_mdi("battery-30"); + } else if (val > 15) { + return raw_mdi("battery-20"); + } else { + return raw_mdi("battery-10"); + } }; -export const renderRawIcon = +export const renderIcon = (icon: RawIcon, extraClass?: string): React.Node => { return ; }; - -export const renderIcon = - (icon: Icon, state: State, extraClass?: string): React.Node => { - return renderRawIcon(toRawIcon(icon, state), extraClass); - }; diff --git a/src/config/types.js b/src/config/types.js index 8fe7c58..91bb28b 100644 --- a/src/config/types.js +++ b/src/config/types.js @@ -1,8 +1,21 @@ // @flow import type { TopicType } from "config/flowtypes"; +import at from "lodash/at"; + +export const string: TopicType = (msg: Buffer) => msg.toString(); -export const string: TopicType = (msg) => msg.toString(); export const json = (path: string, innerType?: TopicType): TopicType => { - const parseAgain = innerType == null ? (x) => x : innerType; - return (msg) => parseAgain(JSON.parse(msg.toString())[path]); + const parseAgain = innerType == null ? (x) => x.toString() : innerType; + return (msg) => parseAgain(Buffer.from( + at(JSON.parse(msg.toString()), path)[0].toString())); }; + +export type TypeOptionParam = { otherwise?: string, [string]: string }; +export const option = (values: TypeOptionParam): TopicType => { + // TODO: error + const defaultValue = values.otherwise != null ? values.otherwise : ""; + const mapVal = (x) => (values[x] != null ? values[x] : defaultValue); + return (x) => mapVal(x.toString()); +}; + +export const jsonArray = (msg: Buffer) => JSON.parse(msg.toString()).join(", "); diff --git a/src/utils/state.js b/src/utils/state.js deleted file mode 100644 index c68269c..0000000 --- a/src/utils/state.js +++ /dev/null @@ -1,8 +0,0 @@ -// @flow -import mapValues from "lodash/mapValues"; - -export const getInternals = (state: State): Map => - mapValues(state, (x) => x.internal || x.actual); - -export const getActuals = (state: State): Map => - mapValues(state, (x) => x.actual); diff --git a/types/types.js b/types/types.js index d0f09ba..5503e1a 100644 --- a/types/types.js +++ b/types/types.js @@ -7,26 +7,7 @@ declare type Classes = { classes: Map }; -declare type Internal = string; -declare type Actual = any; -declare type StateValue = { - internal: string, - actual: any -}; -declare type State = Map; - -//declare type State = { -// mqtt: ?any, -// uiOpened: ?string, - // A map of the actual state values for each topic. - // internal is the internal term for the value, - // that is equal to the key in the values section of that - // topic, for example given by: - // values: { off: "OFF", on: "ON" } - // and actual is the value of that or whatever is given by mqtt. -// values: Map, -// visibleLayers: Array -//}; +declare type State = Map; declare type Point = [number, number];