From b69f8dd2d4b96f154edaca431737cd221dee1961 Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Mon, 10 Sep 2018 08:24:01 +0200 Subject: [PATCH] Added the Casek Floor Heating prototype --- casek-floor-heating/casek-backend/main.js | 175 +++++++++++++ casek-floor-heating/casek-frontend/README.md | 4 + casek-floor-heating/casek-frontend/att.svg | 51 ++++ casek-floor-heating/casek-frontend/bat000.svg | 6 + casek-floor-heating/casek-frontend/bat020.svg | 9 + casek-floor-heating/casek-frontend/bat040.svg | 10 + casek-floor-heating/casek-frontend/bat060.svg | 13 + casek-floor-heating/casek-frontend/bat080.svg | 14 + casek-floor-heating/casek-frontend/bat100.svg | 15 ++ .../casek-frontend/casek_logo.png | Bin 0 -> 7312 bytes .../casek-frontend/ciss_logo.png | Bin 0 -> 4777 bytes casek-floor-heating/casek-frontend/clock.svg | 118 +++++++++ casek-floor-heating/casek-frontend/flame.svg | 175 +++++++++++++ casek-floor-heating/casek-frontend/index.html | 246 ++++++++++++++++++ casek-floor-heating/casek-frontend/script.js | 173 ++++++++++++ .../casek-frontend/seluxit_logo.png | Bin 0 -> 56199 bytes casek-floor-heating/casek-frontend/style.css | 210 +++++++++++++++ 17 files changed, 1219 insertions(+) create mode 100755 casek-floor-heating/casek-backend/main.js create mode 100644 casek-floor-heating/casek-frontend/README.md create mode 100755 casek-floor-heating/casek-frontend/att.svg create mode 100755 casek-floor-heating/casek-frontend/bat000.svg create mode 100755 casek-floor-heating/casek-frontend/bat020.svg create mode 100755 casek-floor-heating/casek-frontend/bat040.svg create mode 100755 casek-floor-heating/casek-frontend/bat060.svg create mode 100755 casek-floor-heating/casek-frontend/bat080.svg create mode 100755 casek-floor-heating/casek-frontend/bat100.svg create mode 100755 casek-floor-heating/casek-frontend/casek_logo.png create mode 100755 casek-floor-heating/casek-frontend/ciss_logo.png create mode 100755 casek-floor-heating/casek-frontend/clock.svg create mode 100755 casek-floor-heating/casek-frontend/flame.svg create mode 100755 casek-floor-heating/casek-frontend/index.html create mode 100755 casek-floor-heating/casek-frontend/script.js create mode 100755 casek-floor-heating/casek-frontend/seluxit_logo.png create mode 100755 casek-floor-heating/casek-frontend/style.css diff --git a/casek-floor-heating/casek-backend/main.js b/casek-floor-heating/casek-backend/main.js new file mode 100755 index 0000000..524139f --- /dev/null +++ b/casek-floor-heating/casek-backend/main.js @@ -0,0 +1,175 @@ +load("jquery.js") + +/* + * Mappings between Wappsto names and Uppaal Stratego ids + */ + +const d2s_temperature = { + "TEMP AND HUMIDITY 1": 3, + "TEMP AND HUMIDITY 2": 10, + "TEMP AND HUMIDITY 3": 1, + "TEMP AND HUMIDITY 4": 9, + "TEMP AND HUMIDITY 5": 2, + "TEMP AND HUMIDITY 6": 4, + "TEMP AND HUMIDITY 7": 8, + "TEMP AND HUMIDITY 8": 5, + "TEMP AND HUMIDITY 9": 6, + "TEMP AND HUMIDITY10": 7, + "TEMP AND HUMIDITY11": 11, + "TEMP AND HUMIDITY12": 0, +}; + +const d2s_target = { + "SETPOINT1": 3, + "SETPOINT2": 10, + "SETPOINT3": 11, + "SETPOINT4": 1, + "SETPOINT5": 9, + "SETPOINT6": 6, + "SETPOINT7": 5, + "SETPOINT8": 2, + "SETPOINT9": 4, + "SETPOINT10": 8, +}; + +const d2s_valves = { + "RL 1": 3, + "RL 2": 10, + "RL 3": 11, + "RL 4": 1, + "RL 5": 9, + "RL 6": 6, + "RL 7": 5, + "RL 8": 2, + "RL 9": 4, + "RL 10": 8, +}; + +/* + * Get Wappsto devices and data + */ + +const dev_sensors = getDevice({name: "TEMP AND HUMIDITY"}, {quantity: 12}); +const dev_target = getDevice({name: "Relay Box Set Points"}, {quantity: 1})[0]; +const dev_valves = getDevice({name: "Relay Box"}, {quantity: 2})[1]; +let data = getData()[0]; + +function run_stratego() { + // Initial values + let t = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let tg = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let te = [0, 0, 0, 0]; + let v = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let cap = [9, 11, 13, 12, 11, 13, 9, 7, 14, 19, 31]; + let max = 80; + + // Get data from temperature device + for (let i in dev_sensors) { + // Get objects from Wappsto + let sensor = dev_sensors[i]; + let name = sensor.get("name").toUpperCase(); + + // Get values from Wappsto + let temperature = Number( + sensor.get("value") + .findWhere({type: "Temperature"}).get("state") + .findWhere({type: "Report"}).get("data") + ); + + // Update arrays + if (d2s_temperature[name] === 0) { + te[0] = temperature; + } else { + t[d2s_temperature[name] - 1] = temperature; + } + } + + // Get data from target relays + dev_target.get("value").each(function (value) { + // Get objects from Wappsto + let name = value.get("name").toUpperCase(); + + // Get values from Wappsto + let target = Number( + value.get("state").findWhere({type: "Report"}).get("data") + ); + + // Update arrays + tg[d2s_target[name] - 1] = target; + }); + + // Get data from valve relays + dev_valves.get("value").each(function (value) { + // Get objects from Wappsto + let name = value.get("name").toUpperCase(); + + // Filter values we don't need + if (name.startsWith("RL")) { + // Get values from Wappsto + let valve = Number( + value.get("state").findWhere({type: "Report"}).get("data") + ); + + // Update arrays + v[d2s_valves[name] - 1] = valve; + } + }); + + // Update weather forecast array (just use current temperature for now) + te[1] = te[0]; + te[2] = te[0]; + te[3] = te[0]; + + // Print values + console.log("t: [ " + t.map(x => (x<10?" ":"") + x.toFixed(1)).join(', ') + " ]"); + console.log("tg: [ " + tg.map(x => (x<10?" ":"") + x.toFixed(1)).join(', ') + " ]"); + console.log("te: [ " + te.map(x => (x<10?" ":"") + x.toFixed(1)).join(', ') + " ]"); + console.log("v: [ " + v.map(x => (x<10?" ":"") + x.toFixed(0)).join(', ') + " ]"); + console.log("cap: [ " + cap.map(x => (x<10?" ":"") + x.toFixed(0)).join(', ') + " ]"); + console.log("max: " + max); + + // Build URL + let url = "/"; + t.forEach(function (x) { + url += x + "_" + }); + tg.forEach(function (x) { + url += x + "_" + }); + te.forEach(function (x) { + url += x + "_" + }); + v.forEach(function (x) { + url += x + "_" + }); + cap.forEach(function (x) { + url += x + "_" + }); + url += max; + + // Call Uppaal Stratego webservice + $.ajax({ + method: "GET", + url: "/external/casek-uppaal" + url + "?proto=http", + headers: { + "x-session": sessionID + } + }).done(function (strategy) { + console.log("s: [ " + strategy.slice(1, -1).split(" ").map( + x => (Number(x)<10?" ":"") + Number(x).toFixed(0)).join(', ') + " ]" + ); + data.save({ + ":id": data.get(":id"), + ":type": data.get(":type"), + "strategy": strategy, + "timestamp": Date.now(), + }, { + wait: true, + patch: true + }); + }).fail(function (error) {}); +} + +// Run Uppaal Stratego now and in regular intervals +run_stratego(); +setInterval(function() { run_stratego(); }, (15*60)*1000); diff --git a/casek-floor-heating/casek-frontend/README.md b/casek-floor-heating/casek-frontend/README.md new file mode 100644 index 0000000..9157368 --- /dev/null +++ b/casek-floor-heating/casek-frontend/README.md @@ -0,0 +1,4 @@ +The files 'att.svg', 'bat000.svg', 'bat020.svg', 'bat040.svg', +'bat060.svg', 'bat080.svg', 'bat100.svg', 'clock.svg', and 'flame.svg' +were acquired from [openclipart.org](), thus are released under the +[Creative Commons Zero 1.0 Public Domain License](http://creativecommons.org/publicdomain/zero/1.0/). diff --git a/casek-floor-heating/casek-frontend/att.svg b/casek-floor-heating/casek-frontend/att.svg new file mode 100755 index 0000000..4b5c8a3 --- /dev/null +++ b/casek-floor-heating/casek-frontend/att.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + attention + 2008-02-04T19:22:40 + + https://openclipart.org/detail/12607/attention-by-anonymous-12607 + + + Anonymous + + + + + attention + icon + warning + + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/bat000.svg b/casek-floor-heating/casek-frontend/bat000.svg new file mode 100755 index 0000000..a66d932 --- /dev/null +++ b/casek-floor-heating/casek-frontend/bat000.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/casek-floor-heating/casek-frontend/bat020.svg b/casek-floor-heating/casek-frontend/bat020.svg new file mode 100755 index 0000000..de7cf94 --- /dev/null +++ b/casek-floor-heating/casek-frontend/bat020.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/bat040.svg b/casek-floor-heating/casek-frontend/bat040.svg new file mode 100755 index 0000000..109b66a --- /dev/null +++ b/casek-floor-heating/casek-frontend/bat040.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/bat060.svg b/casek-floor-heating/casek-frontend/bat060.svg new file mode 100755 index 0000000..1e8e67b --- /dev/null +++ b/casek-floor-heating/casek-frontend/bat060.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/bat080.svg b/casek-floor-heating/casek-frontend/bat080.svg new file mode 100755 index 0000000..b9ae591 --- /dev/null +++ b/casek-floor-heating/casek-frontend/bat080.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/bat100.svg b/casek-floor-heating/casek-frontend/bat100.svg new file mode 100755 index 0000000..1d93511 --- /dev/null +++ b/casek-floor-heating/casek-frontend/bat100.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/casek_logo.png b/casek-floor-heating/casek-frontend/casek_logo.png new file mode 100755 index 0000000000000000000000000000000000000000..4d13282b7c5659c8dc21cf95c18bacd456f48ac9 GIT binary patch literal 7312 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
^Wya_b<;Nac7s*OUN%@};?R-isST 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 Irhhx^e=F18uK)l5 literal 0 HcmV?d00001 diff --git a/casek-floor-heating/casek-frontend/clock.svg b/casek-floor-heating/casek-frontend/clock.svg new file mode 100755 index 0000000..ecbb5e4 --- /dev/null +++ b/casek-floor-heating/casek-frontend/clock.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + Openclipart + + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/flame.svg b/casek-floor-heating/casek-frontend/flame.svg new file mode 100755 index 0000000..5b8db3f --- /dev/null +++ b/casek-floor-heating/casek-frontend/flame.svg @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/casek-floor-heating/casek-frontend/index.html b/casek-floor-heating/casek-frontend/index.html new file mode 100755 index 0000000..fe2a9a5 --- /dev/null +++ b/casek-floor-heating/casek-frontend/index.html @@ -0,0 +1,246 @@ + + + + + + + Casek: Floor Heating Prototype + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Bathroom 1

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Room 3

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Kitchen

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Utility

+ +
+ 00 + °C +
+ + +
+

Bathroom 2

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Bedroom

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Hall

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Dining Room

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Living Room

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Room 1

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Room 2

+ +
+ 00 + °C +
+
+ + 00°C + +
+ + +
+

Patio

+ +
+ 00 + °C +
+ +
+
+ +
+ Room selected for heating by Uppaal Stratego + (last updated: ). +
+
+
+ +
+

Prototype produced by

+ + +
+ +
+ + + + + + + + +
+ + + + \ No newline at end of file diff --git a/casek-floor-heating/casek-frontend/script.js b/casek-floor-heating/casek-frontend/script.js new file mode 100755 index 0000000..6b62c80 --- /dev/null +++ b/casek-floor-heating/casek-frontend/script.js @@ -0,0 +1,173 @@ +/* + * Mappings between Wappsto names and HTML ids + */ + +const d2i_temperature = { + "TEMP AND HUMIDITY 1": "t3", + "TEMP AND HUMIDITY 2": "t10", + "TEMP AND HUMIDITY 3": "t1", + "TEMP AND HUMIDITY 4": "t9", + "TEMP AND HUMIDITY 5": "t2", + "TEMP AND HUMIDITY 6": "t4", + "TEMP AND HUMIDITY 7": "t8", + "TEMP AND HUMIDITY 8": "t5", + "TEMP AND HUMIDITY 9": "t6", + "TEMP AND HUMIDITY10": "t7", + "TEMP AND HUMIDITY11": "t11", + "TEMP AND HUMIDITY12": "t0", +}; + +const d2i_clock = { + "TEMP AND HUMIDITY 1": "c3", + "TEMP AND HUMIDITY 2": "c10", + "TEMP AND HUMIDITY 3": "c1", + "TEMP AND HUMIDITY 4": "c9", + "TEMP AND HUMIDITY 5": "c2", + "TEMP AND HUMIDITY 6": "c4", + "TEMP AND HUMIDITY 7": "c8", + "TEMP AND HUMIDITY 8": "c5", + "TEMP AND HUMIDITY 9": "c6", + "TEMP AND HUMIDITY10": "c7", + "TEMP AND HUMIDITY11": "c11", + "TEMP AND HUMIDITY12": "c0", +}; + +const d2i_battery = { + "TEMP AND HUMIDITY 1": "b3", + "TEMP AND HUMIDITY 2": "b10", + "TEMP AND HUMIDITY 3": "b1", + "TEMP AND HUMIDITY 4": "b9", + "TEMP AND HUMIDITY 5": "b2", + "TEMP AND HUMIDITY 6": "b4", + "TEMP AND HUMIDITY 7": "b8", + "TEMP AND HUMIDITY 8": "b5", + "TEMP AND HUMIDITY 9": "b6", + "TEMP AND HUMIDITY10": "b7", + "TEMP AND HUMIDITY11": "b11", + "TEMP AND HUMIDITY12": "b0", +}; + +const d2i_target = { + "SETPOINT1": "tg3", + "SETPOINT2": "tg10", + "SETPOINT3": "tg11", + "SETPOINT4": "tg1", + "SETPOINT5": "tg9", + "SETPOINT6": "tg6", + "SETPOINT7": "tg5", + "SETPOINT8": "tg2", + "SETPOINT9": "tg4", + "SETPOINT10": "tg8", +}; + +/* + * Get Wappsto devices and data + */ + +const dev_sensors = getDevice({name: "TEMP AND HUMIDITY"}, {quantity: 12}); +const dev_target = getDevice({name: "Relay Box Set Points"}, {quantity: 1})[0]; +let data = getData()[0]; + +/** + * Function for updating the display with the strategy from Uppaal Stratego + */ +function update_strategy() { + let strategy = data.get("strategy"); + let timestamp = new Date(data.get("timestamp")); + let valves = strategy.slice(1, -1).split(" "); + for (let i in valves) { + let element = document.getElementById("v" + (Number(i)+1)); + if (Number(valves[i]) > 0) { + element.style.display = "block"; + } else { + element.style.display = "none"; + } + } + document.getElementById("c_strategy").innerHTML = timestamp.toUTCString(); +} + +/** + * Function for updating the display with data from Wappsto + */ +function update_display() { + // Update with info from sensors + for (let i in dev_sensors) { + // Get objects from Wappsto + let sensor = dev_sensors[i]; + let values = sensor.get("value"); + let report = values + .findWhere({type: "Temperature"}).get("state") + .findWhere({type: "Report"}); + let name = sensor.get("name").toUpperCase(); + + // Get values from Wappsto + let temperature = Number( + report.get("data") + ); + let timestamp = new Date( + report.get("timestamp") + ); + let battery = Number( + values + .findWhere({type: "Battery"}).get("state") + .findWhere({type: "Report"}).get("data") + ); + + // Get HTML elements + let t_span = document.getElementById(d2i_temperature[name]); + let b_img = document.getElementById(d2i_battery[name]); + let c_img = document.getElementById(d2i_clock[name]); + + // Update display + t_span.innerHTML = temperature.toFixed(1); + b_img.title = "Battery Level: " + battery.toFixed(0) + "%"; + if (battery > 96) { + b_img.src = document.getElementById("bat100").src; + } else if (battery > 88) { + b_img.src = document.getElementById("bat080").src; + } else if (battery > 80) { + b_img.src = document.getElementById("bat060").src; + } else if (battery > 70) { + b_img.src = document.getElementById("bat040").src; + } else if (battery > 50) { + b_img.src = document.getElementById("bat020").src; + } else { + b_img.src = document.getElementById("bat000").src; + } + c_img.title = ""; + if ((Date.now() - timestamp.getTime()) / 1000 > 3600) { + c_img.src = document.getElementById("attention").src; + c_img.title = "Data is more than an hour old!\n"; + } else { + c_img.src = document.getElementById("clock").src; + } + c_img.title += "Last updated: " + timestamp.toUTCString(); + } + + // Update set points + dev_target.get("value").each(function (value) { + let target = Math.round( + value.get("state").findWhere({type: "Report"}).get("data") + ); + let name = value.get("name").toUpperCase(); + let tg_span = document.getElementById(d2i_target[name]); + tg_span.innerHTML = target.toFixed(0); + }); +} + +/** + * Function that will be called on load of HTML body + */ +function on_load() { + // Register callback for backend changes and update it once + data.on("change", function () { + update_strategy(); + }); + update_strategy(); + + // Add regular updates of display + setInterval(function () { + update_display(); + }, 2000); + update_display(); +} diff --git a/casek-floor-heating/casek-frontend/seluxit_logo.png b/casek-floor-heating/casek-frontend/seluxit_logo.png new file mode 100755 index 0000000000000000000000000000000000000000..eacded67188e25a92e4a74d6560f170a06a6468f GIT binary patch literal 56199 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

vCS@AcxU(RxFiX-^!=@up`~WG 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 literal 0 HcmV?d00001 diff --git a/casek-floor-heating/casek-frontend/style.css b/casek-floor-heating/casek-frontend/style.css new file mode 100755 index 0000000..c1bb0ac --- /dev/null +++ b/casek-floor-heating/casek-frontend/style.css @@ -0,0 +1,210 @@ + +/* Reset */ + +* { + border-spacing: 0; + font-family: Tahoma, Geneva, sans-serif; + margin: 0; + padding: 0; +} + +/* Global */ + +body { + background-color: #00b0f2; + height: 100%; + margin: 3.6vh 2vw; + overflow: hidden; +} + +h1 { + font-family: Verdana, Geneva, sans-serif; +} + +.sm_caps { + font-variant: small-caps; +} + +/* Page Header */ + +#page_header { + margin-bottom: 3.6vh; + position: relative; + height: 9vh; +} + +#page_header img { + max-width: 14vw; + max-height: 9vh; + margin-right: 2vw; +} + +#page_header .box { + background-color: white; + border-radius: 25px; + height: 100%; + margin: auto; + position: absolute; + right: 0; + text-align: center; + top: 0; + width: 80vw; +} + +#page_header h1 { + font-size: 5vh; + font-weight: normal; + max-height: 6vh; + overflow: hidden; +} + +#page_header h2 { + font-size: 1.5vh; + font-style: italic; + font-weight: normal; + max-height: 2vh; + overflow: hidden; +} + +/* House Table */ + +#house { + background-color: white; + border-radius: 25px; + padding: 2vw 2vw 0; +} + +#house table { + border-collapse: collapse; + height: 42vw; + margin: auto; + width: 90vw; +} + +#house td { + border: 2.8pt solid #666666; + color: #007099; + position: relative; + text-align: center; + vertical-align: middle; +} + +#house td.no_border { + border: 0 none black; +} + +#house h1 { + color: #007099; + font-size: 1.2vw; + font-weight: normal; + left: 0; + margin: 0.2vw; + position: absolute; + top: 0; +} + +#house #r0 { + border-bottom-style: none; +} + +/* House displays */ + +#house .t_current { + font-size: 3.4vw; + } + +#house .t_current .t_current_unit { + font-size: 1.7vw; +} + +#house .battery { + bottom: 0; + margin: 0.2vw; + position: absolute; + left: 0; + width: 0.8vw; +} + +#house .clock { + margin: 0.2vw; + position: absolute; + right: 0; + top: 0; + width: 1.2vw; +} + +#house .target { + font-size: 1.6vw; +} + +#house .target .t_current_unit { + font-size: 0.8vw; +} + +#house .target button{ + background-color: white; + border: #007099 solid 1pt; + color: #007099; + font-family: "Arial Black", Gadget, sans-serif; + font-size: 1.4vw; + font-weight: bold; + height: 2vw; + width: 2vw; +} + +#house .flame { + bottom: 0; + /*display: none;*/ + left: 1vw; + margin: 0.2vw; + position: absolute; + width: 1vw; +} + +/* Legend */ + +#legend { + height: 2vw; +} + +#legend div { + padding-top: 0.5vw; + font-size: 1vw; +} + +#legend .flame_legend { + float: left; + margin: 0.4vw; + width: 1vw; +} + +/* Credits */ + +#credits { + background-color: white; + border-left: black solid 1pt; + border-radius: 25px 0 0 0; + border-top: black solid 1pt; + bottom: 0; + padding-left: 0.8vw; + padding-top: 0.8vw; + position: absolute; + right: 0; +} + +#credits h1 { + font-size: 0.8vw; + font-weight: normal; + margin-left: 0.6vw; +} + +#credits img { + height: 4vh; + margin: 0.5vw; +} + +/* Secret stuff */ + +#hidden { + display: none; +}