From a7d8bf9ac5dd999e49efcaf0076561ab08fb4648 Mon Sep 17 00:00:00 2001 From: git Date: Tue, 23 Mar 2021 10:41:41 +0100 Subject: [PATCH] Set new Base version --- .gitignore | 2 + README.md | 50 ++++++ docker-compose.yml | 30 ++++ site.conf | 11 ++ src/assets/css/style.css | 250 ++++++++++++++++++++++++++ src/assets/img/background.svg | 44 +++++ src/assets/img/power-button-black.svg | 8 + src/assets/img/power-button-blue.svg | 8 + src/assets/img/power-button-gold.svg | 8 + src/assets/img/power-button-green.svg | 10 ++ src/assets/img/power-button-grey.svg | 8 + src/assets/img/power-button-red.svg | 13 ++ src/assets/js/forms.js | 19 ++ src/assets/js/locationpicker.js | 38 ++++ src/assets/js/pagefunctions.js | 159 ++++++++++++++++ src/index.html | 93 ++++++++++ 16 files changed, 751 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 site.conf create mode 100644 src/assets/css/style.css create mode 100644 src/assets/img/background.svg create mode 100755 src/assets/img/power-button-black.svg create mode 100755 src/assets/img/power-button-blue.svg create mode 100755 src/assets/img/power-button-gold.svg create mode 100755 src/assets/img/power-button-green.svg create mode 100755 src/assets/img/power-button-grey.svg create mode 100755 src/assets/img/power-button-red.svg create mode 100644 src/assets/js/forms.js create mode 100644 src/assets/js/locationpicker.js create mode 100644 src/assets/js/pagefunctions.js create mode 100644 src/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..26b6b1a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Created by .ignore support plugin (hsz.mobi) +/.idea/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..c45bd02 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# PiSwitch_frontend +A Frontend for the [PiSwitch](https://git.dennisvandermeulen.nl/dennis/PiSwitch) and [PiSwitch_Reporting](https://git.dennisvandermeulen.nl/dennis/PiSwitch_reporting) + +## Installation Process + +Clone the repository +```shell +git clone https://git.dennisvandermeulen.nl/dennis/PiSwitch_frontend.git +``` + +## Setup +Go to the js asset file folder +````shell +cd PiSwitch_frontend/assets/js/ +```` +Set the values in pagefunctions.js +```shell +nano pagefunctions.js +``` +Set the key and the url of the [PiSwitch reporting server](https://git.dennisvandermeulen.nl/dennis/PiSwitch_reporting) +````javascript +var apiurl = '' +var srvkey = '' +```` +Set the key and the url of the [PiSwitch](https://git.dennisvandermeulen.nl/dennis/PiSwitch) for this dashboard instance +```javascript +var deviceurl = '' +var deviceid = +``` +Set de mapquest api key in locationpicker.js +```shell +nano locationpicker.js +``` +Set your mapquest key +```javascript +L.mapquest.key = ''; +``` + +## Docker +Ensure you built the [PiSwitch reporting server](https://git.dennisvandermeulen.nl/dennis/PiSwitch_reporting) dockerfile + +Use the included Docker-Compose files to start the nginx server +````shell +docker-compose . -up -d +```` + +Visit your dashboard at: +````shell +http://your-ip-or-hostname:81/index.html +```` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..1ff15b2 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +version: "3.7" +services: + + web: + container_name: nginx + restart: unless-stopped + image: nginx:alpine + ports: + - 81:80 + depends_on: + - api + volumes: + - ./src:/usr/share/nginx/html + networks: + - piswitch-network + + api: + container_name: raspapi + image: appserver/raspapi + restart: unless-stopped + ports: + - 5000:5000 + tty: true + working_dir: /code/src/ + networks: + - piswitch-network + +networks: + piswitch-network: + driver: bridge diff --git a/site.conf b/site.conf new file mode 100644 index 0000000..d2073d5 --- /dev/null +++ b/site.conf @@ -0,0 +1,11 @@ +server { + listen 80; + index index.html; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /var/www/; + location / { + try_files $uri $uri/ /index.php?$query_string; + gzip_static on; + } +} \ No newline at end of file diff --git a/src/assets/css/style.css b/src/assets/css/style.css new file mode 100644 index 0000000..036c329 --- /dev/null +++ b/src/assets/css/style.css @@ -0,0 +1,250 @@ +body { + margin: 0; + background-color: black; +} + +a { + text-decoration: none; +} + +h1 { + font-family: 'Roboto', 'sans-serif'; + color: white; +} + +h2 { + font-family: 'Roboto', 'sans-serif'; + color: white; +} + +h6 { + font-family: 'Roboto', 'sans-serif'; + color: white; + margin-top: 10px; + z-index: 2; +} + +.onethird { + width: 34%; + margin: auto; +} + +.twothird { + width: 66%; + +} + +.fullwide { + width: 100%; + height: 100%; + position: relative; + display: flex; +} + +.leftaligned { + float: left; + position: relative; +} + +.rightaligned { + float: right; + position: relative; +} + +.clear { + clear: both; +} + +#background { + background-image: url("../img/background.svg"); + background-size: 100%, 100%; + background-repeat: no-repeat; + width: 100vw; + height: 100vh; + z-index: -99; + position: fixed; + top: 0; + left: 0; +} + +.flexparent_row { + display: flex; + flex-direction: row; + flex-wrap: wrap; + width: 100vw; + position: relative; +} + +.flexparent_column { + display: flex; + flex-direction: column; + flex-wrap: nowrap; + width: 100vw; + position: relative; +} + +.flex_center_top { + justify-content: center; + align-items: flex-start; + align-content: flex-start; +} + +.flex_center { + justify-content: center; + align-items: center; + align-content: flex-start; +} + +.flex_center_left { + justify-content: flex-start; + align-items: flex-start; + align-content: flex-start; +} + +.flexitem { + +} + +.flexbtn { + position: relative; + background-color: #333333; + margin: 15px; + border-radius: 25px; + text-align: center; + overflow: hidden; + min-width: 300px; + min-height: 300px; + display:flex; + justify-content:center; + align-items:center; + z-index: 0; +} + +.onewide { + min-width: 1130px; + max-width: 1130px; + height: 350px; +} + +.twowide { + min-width: 545px; + max-width: 545px; + height: 350px; +} + +.threewide { + width: 350px; + height: 350px; +} + +#container{ + max-width: 1200px; + position: relative; + background-color: #222222; + margin: 25px; + border-radius: 25px; + text-align: center; + overflow: hidden; +} + +.flexbtn:hover { + background-color: #222222; +} + +.centeredtext { + text-align: center; + width: 100%; + position: relative; +} + +#content { + position: relative; + width: 100%; +} + +.spanfull { + position: fixed; + left: 0; + top: 0; + height: 100%; + width: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +/** edge colors for buttons **/ + +.goldedgecolor { + border: 5px solid #ffd700; +} + +.blueedgecolor { + border: 5px solid blue; +} + +.blackedgecolor { + border: 5px solid black; +} + +.whiteedgecolor { + border: 5px solid white; +} + +.greyedgecolor { + border: 5px solid #444444; +} + +.greenedgecolor { + border: 5px solid green; +} + +.rededgecolor { + border: 5px solid red; +} + +/** form **/ +input[type=time].form, input[type=text].form, select.form { + width: 90%; + padding: 12px 20px; + margin: 8px 0; + display: inline-block; + border-radius: 4px; + box-sizing: border-box; +} + +input[type=submit].form { + padding: 14px 20px; + margin: 8px 10%; + border-radius: 2px; + cursor: pointer; + font-family: 'Roboto', 'sans-serif'; + color: white; + background-color: blue; +} + +input[type=submit]:hover.form { + background-color: #001f3f; + color: white; +} + +label.form { + font-family: 'Roboto', 'sans-serif'; + text-align: center; + color: white; + vertical-align: top; +} + +#map { + width: 100%; + height: 350px; + position: absolute; + overflow: hidden; +} + +.tg {border-collapse:collapse;border-spacing:0;} +.tg td{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px; + overflow:hidden;padding:10px 5px;word-break:normal;} +.tg th{border-color:black;border-style:solid;border-width:1px;font-family:Arial, sans-serif;font-size:14px; + font-weight:normal;overflow:hidden;padding:10px 5px;word-break:normal;} +.tg .tg-mk6l{background-color:#000000;border-color:#000000;color:#ffffff;text-align:left;vertical-align:top} \ No newline at end of file diff --git a/src/assets/img/background.svg b/src/assets/img/background.svg new file mode 100644 index 0000000..869a83b --- /dev/null +++ b/src/assets/img/background.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/img/power-button-black.svg b/src/assets/img/power-button-black.svg new file mode 100755 index 0000000..d93944f --- /dev/null +++ b/src/assets/img/power-button-black.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/img/power-button-blue.svg b/src/assets/img/power-button-blue.svg new file mode 100755 index 0000000..5374600 --- /dev/null +++ b/src/assets/img/power-button-blue.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/img/power-button-gold.svg b/src/assets/img/power-button-gold.svg new file mode 100755 index 0000000..a1926b3 --- /dev/null +++ b/src/assets/img/power-button-gold.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/img/power-button-green.svg b/src/assets/img/power-button-green.svg new file mode 100755 index 0000000..e28a888 --- /dev/null +++ b/src/assets/img/power-button-green.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/img/power-button-grey.svg b/src/assets/img/power-button-grey.svg new file mode 100755 index 0000000..696ee3a --- /dev/null +++ b/src/assets/img/power-button-grey.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/img/power-button-red.svg b/src/assets/img/power-button-red.svg new file mode 100755 index 0000000..868f754 --- /dev/null +++ b/src/assets/img/power-button-red.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/assets/js/forms.js b/src/assets/js/forms.js new file mode 100644 index 0000000..aaadde5 --- /dev/null +++ b/src/assets/js/forms.js @@ -0,0 +1,19 @@ +$(document).ready(function () { + $('form').submit(function (e) { + e.preventDefault(); + var form = $(this); + $.ajax({ + type: form.attr('method'), + url: form.attr('action'), + data: form.serialize(), + success: function (data) { + console.log('Submission was successful.'); + console.log(form.data()); + }, + error: function (data) { + console.log('An error occurred.'); + console.log(form.data()); + }, + }); + }); +}); \ No newline at end of file diff --git a/src/assets/js/locationpicker.js b/src/assets/js/locationpicker.js new file mode 100644 index 0000000..938e347 --- /dev/null +++ b/src/assets/js/locationpicker.js @@ -0,0 +1,38 @@ +function createmap(lat, lon) { + if (switchstatus == 0) { + color = '#333333' + } else if (switchstatus == 1) { + color = '#ffd700' + } + + L.mapquest.key = ''; + + var map = L.mapquest.map('map', { + center: [lat, lon], + layers: L.mapquest.tileLayer('dark'), + zoom: 14 + }).on('click', function (e) { + addMarker(e); + }); + var locmarker = L.mapquest.textMarker([lat, lon], { + + type: 'marker', + icon: { + primaryColor: '#333333', + secondaryColor: color, + size: 'sm' + } + }).addTo(map); + + function addMarker(e) { + updatelocform(e.latlng.wrap()) + locmarker.setLatLng(e.latlng) + } + + function updatelocform(ll) { + document.getElementById('loc_lat').setAttribute('value', ll.lat) + document.getElementById('loc_lon').setAttribute('value', ll.lng) + } + +} + diff --git a/src/assets/js/pagefunctions.js b/src/assets/js/pagefunctions.js new file mode 100644 index 0000000..95f3a2e --- /dev/null +++ b/src/assets/js/pagefunctions.js @@ -0,0 +1,159 @@ +// Filled in by database +var switchstatus = 0 +var astralstatus = 0 +var connstatus = 0 +var lastupdate = 0 +var devicekey = 0 + +// Fill in manually +var apiurl = '' +var srvkey = '' +var deviceurl = '' +var deviceid = + + + setInterval(getstatus, 1000); + +function getstatus_init() { + var request = new XMLHttpRequest(); + request.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + var response = JSON.parse(request.responseText) + setswitchstatus(response) + setastralstatus(response) + setconnstatus(response) + setpagevars(response) + createmap(response.loc_lat, response.loc_lon); + retrievelogs() + } + } + request.open('POST', apiurl+'/fullstatus?id=1&apikey='+srvkey, true); + request.send(); +} + +function getstatus() { + var request = new XMLHttpRequest(); + request.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + var response = JSON.parse(request.responseText) + setswitchstatus(response) + setastralstatus(response) + setconnstatus(response) + } + } + request.open('POST', apiurl+'/fullstatus?id=1&apikey='+srvkey, true); + request.send(); +} + +function updatelocation() { + var request = new XMLHttpRequest(); + request.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + var response = JSON.parse(request.responseText) + setpagevars(response) + } + } + request.open('POST', apiurl+'/fullstatus?id=1&apikey=apikey='+srvkey, true); + request.send(); +} + +function setswitchstatus(response) { + var elements = document.getElementsByClassName('switchedgecolor') + var button = document.getElementById('switchbtn') + if (response.switch_status == 1) { + changeedgecolor('gold', button, elements) + switchstatus = 1 + } else if (response.switch_status == 0) { + changeedgecolor('grey', button, elements) + switchstatus = 0 + } +} + +function setastralstatus(response) { + var elements = document.getElementsByClassName('astraledgecolor') + var button = document.getElementById('astralbtn') + if (response.astral_status == 1) { + changeedgecolor('blue', button, elements) + astralstatus = 1 + } else if (response.astral_status == 0) { + changeedgecolor('grey', button, elements) + astralstatus = 0 + } +} + +function setconnstatus(response) { + var elements = document.getElementsByClassName('connedgecolor') + var button = document.getElementById('connbtn') + if (response.conn_status == 1) { + changeedgecolor('green', button, elements) + connstatus = 1 + } else if (response.conn_status == 0) { + changeedgecolor('red', button, elements) + connstatus = 0 + } +} + +function setpagevars(response) { + document.getElementById('subtitle').innerHTML = "Last update: " + response.last_updated + document.getElementById('pagetitle').innerHTML = "PiSwitch Dashboard " + response.switch_name + document.getElementById('turnontime').setAttribute('value', response.on_time) + document.getElementById('turnofftime').setAttribute('value', response.off_time) + document.getElementById('loc_name').setAttribute('value', response.loc_name) + document.getElementById('loc_region').setAttribute('value', response.loc_region) + document.getElementById('loc_lat').setAttribute('value', response.loc_lat) + document.getElementById('loc_lon').setAttribute('value', response.loc_lon) + devicekey = response.apikey + + var elements = document.getElementsByClassName('srvkey') + for (var i = 0, len = elements.length; i < len; i++) { + elements[i].setAttribute('value', srvkey) + } +} + +function toggleswitch() { + var request = new XMLHttpRequest(); + request.open('POST', deviceurl+deviceid+'/override?apikey='+devicekey, true); + request.send(); +} + +function retrievelogs() { + var request = new XMLHttpRequest(); + request.onreadystatechange = function () { + if (this.readyState == 4 && this.status == 200) { + var response = JSON.parse(request.responseText) + logtable(response) + } + } + request.open('GET', apiurl+'/cmd?id=1&apikey='+srvkey, true); + request.send(); + +} + +function toggleastral() { + if (astralstatus == 0) { + var request = new XMLHttpRequest(); + request.open('POST', deviceurl+deviceid+'/toggleastral?command=1&apikey='+devicekey, true); + request.send(); + } else if (astralstatus == 1) { + var request = new XMLHttpRequest(); + request.open('POST', deviceurl+deviceid+'/toggleastral?command=0&apikey='+devicekey, true); + request.send(); + } +} + +function changeedgecolor(color, button, elements) { + for (var i = 0, len = elements.length; i < len; i++) { + elements[i].classList.add('class', color + 'edgecolor') + if (color != 'grey') { + elements[i].classList.remove('class', 'greyedgecolor') + } + button.src = 'assets/img/power-button-' + color + '.svg' + } +} + +// function logtable(response) { +// for (i = 0; i < Object.keys(response).length; i++) { +// var tablecontent = tablecontent + '' + response[i]['date'] + '' + response[i]['command'] + ''; +// } +// document.getElementById('log').innerHTML = tablecontent; +// } diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..3523aba --- /dev/null +++ b/src/index.html @@ -0,0 +1,93 @@ + + + + + PiSwitch Dashboard + + + + + + + + + +
+
+
+

+

+ +
+ powerbtn +
+ +
+ astralbtn +
+ +
+ connbtn +
+ +
+
+
+
+ + + + + + + +
+
+
+
+
+
+ +
+
+ +
+
+ + + + + +
+
+ +
+
+ + + + + +
+
+
+
+ + + + \ No newline at end of file