History Clean Up

This commit is contained in:
JonatanRek 2019-08-23 13:39:42 +02:00
commit 8cf912993d
112 changed files with 11395 additions and 0 deletions

31
.editorconfig Normal file
View File

@ -0,0 +1,31 @@
# https://editorconfig.org/
root = true
[*]
tab_width = 4
[*.{php,phpt,inc}]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = tab
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
charset = utf-8
end_of_line = lf
indent_style = tab
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 80
[COMMIT_EDITMSG]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = tab
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 80

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
.ftpconfig
config.php
_nemazat/index.html
_nemazat/css/main.css.map
_nemazat/css/main.css
_nemazat/css/font-awesome.min.css

12
.htaccess Normal file
View File

@ -0,0 +1,12 @@
RewriteEngine On
RewriteBase /vasek/home/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !.css
RewriteCond %{REQUEST_FILENAME} !.js
RewriteRule (.*) index.php?url=$1 [QSA,L]
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_FILENAME} !api.php
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2019 JonatanRek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

67
README.md Normal file
View File

@ -0,0 +1,67 @@
<img src="./templates/images/icon-512x512.png" height="20" width="20">
# Smart_Home
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Discord](https://img.shields.io/discord/601817042475286540.svg?color=Blue&label=Discord&logo=Discord)](https://discord.gg/nMe5evu)
PHP, JS, HTML - Supports PWA
# Installation
default user is Admin and his password id ESP
# Discord
https://discord.gg/nMe5evu
## Browser (Desktop PWA)
<img src="./_README_IMG/1.png" height="500" width="1000">
<img src="./_README_IMG/2.png" height="500" width="1000">
<img src="./_README_IMG/3.png" height="500" width="1000">
<img src="./_README_IMG/4.png" height="500" width="1000">
<img src="./_README_IMG/5.png" height="500" width="1000">
## Mobile (PWA)
<img src="./_README_IMG/6.png" height="500" width="250">
<img src="./_README_IMG/7.png" height="500" width="250">
<img src="./_README_IMG/8.png" height="500" width="250">
<img src="./_README_IMG/9.png" height="500" width="250">
<img src="./_README_IMG/10.png" height="500" width="250">
API
POST Message (Spínač)
```
{
"token":"2"
}
```
Answer (Spínač)
```
{
"device":{
"hostname":"2",
"sleepTime":0
},
"state":"succes",
"value":"0"
}
}
```
POST Message (Sensor)
```
{
"token":"4",
"values":{
"door":{
"value":1
}
}
}
```
Answer (Sensor)
```
{
}
```

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,213 @@
; CH341SER.INF
; Driver for CH341 (USB=>SERIAL chip) V3.4
; WDM&VXD for Windows 98/Me/2000/XP/Server2003/Vista/64bit Vista/Server2008/Win7/64bit Win7
; Copyright (C) W.ch 2001-2014
;
[Version]
Signature = "$Chicago$"
Class = Ports
ClassGuid = {4D36E978-E325-11CE-BFC1-08002BE10318}
Provider = %WinChipHead%
DriverVer = 08/08/2014, 3.4.2014.08
CatalogFile = CH341SER.CAT
[ControlFlags]
ExcludeFromSelect = USB\VID_1A86&PID_7523
ExcludeFromSelect = USB\VID_1A86&PID_5523
ExcludeFromSelect = USB\VID_4348&PID_5523
ExcludeFromSelect = USB\VID_4348&PID_5523&REV_0250
ExcludeFromSelect = USBSERPORT\SER5523
ExcludeFromSelect = CH341PORT\SER5523
[Manufacturer]
%WinChipHead% = WinChipHead,NT,NTamd64,NTia64
[WinChipHead]
%CH340SER.DeviceDesc% = CH341SER_Install, USB\VID_1A86&PID_7523
%CH341ASER.DeviceDesc% = CH341SER_Install, USB\VID_1A86&PID_5523
%CH341SER.DeviceDesc% = CH341SER_Install, USB\VID_4348&PID_5523
%CH340SER.DeviceDesc% = CH341SER_Install, USB\VID_4348&PID_5523&REV_0250
%CH341S98.DeviceDesc% = CH341S98_Install, USBSERPORT\SER5523
%CH341S98.DeviceDesc% = CH341S98_Install, CH341PORT\SER5523
[WinChipHead.NT]
%CH340SER.DeviceDesc% = CH341SER_Install.NT, USB\VID_1A86&PID_7523
%CH341ASER.DeviceDesc% = CH341SER_Install.NT, USB\VID_1A86&PID_5523
%CH341SER.DeviceDesc% = CH341SER_Install.NT, USB\VID_4348&PID_5523
%CH340SER.DeviceDesc% = CH341SER_Install.NT, USB\VID_4348&PID_5523&REV_0250
[WinChipHead.NTamd64]
%CH340SER.DeviceDesc% = CH341SER_Inst.NTamd64, USB\VID_1A86&PID_7523
%CH341ASER.DeviceDesc% = CH341SER_Inst.NTamd64, USB\VID_1A86&PID_5523
%CH341SER.DeviceDesc% = CH341SER_Inst.NTamd64, USB\VID_4348&PID_5523
%CH340SER.DeviceDesc% = CH341SER_Inst.NTamd64, USB\VID_4348&PID_5523&REV_0250
[WinChipHead.NTia64]
%CH340SER.DeviceDesc% = CH341SER_Inst.NTia64, USB\VID_1A86&PID_7523
%CH341ASER.DeviceDesc% = CH341SER_Inst.NTia64, USB\VID_1A86&PID_5523
%CH341SER.DeviceDesc% = CH341SER_Inst.NTia64, USB\VID_4348&PID_5523
%CH340SER.DeviceDesc% = CH341SER_Inst.NTia64, USB\VID_4348&PID_5523&REV_0250
[CH341SER_Install]
DelFiles = CH341S98.DelFiles.SYS
CopyFiles = CH341SER.CopyFiles.SYS, CH341SER.CopyFiles.DLL
AddReg = CH341SER.9X.AddReg, CH341SER.AddReg
[CH341SER_Install.NT]
CopyFiles = CH341SER.NT.CopyFiles.SYS, CH341SER.CopyFiles.DLL
AddReg = CH341SER.NT.AddReg, CH341SER.AddReg
[CH341SER_Install.NT.HW]
AddReg = CH341SER.NT.HW.AddReg
[CH341SER_Inst.NTamd64]
CopyFiles = CH341SER.NT.CopyFiles.SYSA64
AddReg = CH341SER.NT.AddReg, CH341SER.AddReg
[CH341SER_Inst.NTamd64.HW]
AddReg = CH341SER.NT.HW.AddReg
[CH341SER_Inst.NTia64]
CopyFiles = CH341SER.NT.CopyFiles.SYSI64
AddReg = CH341SER.NT.AddReg, CH341SER.AddReg
[CH341SER_Inst.NTia64.HW]
AddReg = CH341SER.NT.HW.AddReg
[CH341S98_Install]
DelFiles = CH341S98.DelFiles.SYS
CopyFiles = CH341S98.CopyFiles.VXD, CH341SER.CopyFiles.SYS
AddReg = CH341S98.9X.AddReg, CH341S98.AddReg
;[CH341S98_Install.NT]
[CH341S98.DelFiles.SYS]
CH341S98.SYS, , , 1
[CH341SER.CopyFiles.SYS]
CH341S98.SYS, , , 2
[CH341SER.NT.CopyFiles.SYS]
CH341SER.SYS, , , 2
[CH341SER.NT.CopyFiles.SYSA64]
CH341S64.SYS, , , 2
[CH341SER.NT.CopyFiles.SYSI64]
;CH341I64.SYS, , , 2
[CH341S98.CopyFiles.VXD]
CH341SER.VXD, , , 2
[CH341SER.CopyFiles.DLL]
CH341PT.DLL, , , 2
;安装DLL是可选的,DLL可以用于识别CH341端口和监视CH341端口的插拔事件
[CH341SER.9X.AddReg]
HKR, , DevLoader, , *NTKERN
HKR, , NTMPDriver, , CH341S98.SYS
[CH341SER.NT.AddReg]
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[CH341SER.NT.HW.AddReg]
HKR,,"UpperFilters",0x00010000,"serenum"
;上面这行用于枚举接在串口的即插即用设备,启动时将产生DTR和RTS信号,如果需要枚举,请将上面这行的分号去掉
[CH341S98.9X.AddReg]
HKR, , DevLoader, , *vcomm
HKR, , PortDriver, , CH341SER.VXD
HKR, , Contention, , *vcd
HKR, , ConfigDialog, , serialui.dll
HKR, , DCB, 3, 1C,00,00,00, 80,25,00,00, 11,00,00,00, 00,00,0A,00, 0A,00,08,00, 00,11,13,00, 00,00,00,00
HKR, , PortSubClass, 1, 01
HKR, , EnumPropPages, , "serialui.dll,EnumPropPages"
HKR, , Enumerator, , serenum.vxd
;上面这行用于枚举接在串口的即插即用设备,启动时将产生DTR和RTS信号,如果需要枚举,请将上面这行的分号去掉
[CH341SER.AddReg]
HKLM, SOFTWARE\WinChipHead\IC\CH341SER, WDM, 0x00010001, 0x00000034
HKLM, SOFTWARE\WinChipHead\IC\CH341PORT, DLL, 0x00010001, 0x00000010
HKLM, SOFTWARE\WinChipHead\IC\CH341SER, Function, , "USB=>Serial"
;HKLM, SYSTEM\CurrentControlSet\Services\CH341SER, UserRemoval, 0x00010001, 0x00000001
;上面这行用于在系统托盘中显示“安全删除USB转SERIAL硬件设备”便于用户手工删除硬件
[CH341S98.AddReg]
HKLM, SOFTWARE\WinChipHead\IC\CH341SER, VXD, 0x00010001, 0x00000023
[CH341SER_Install.NT.Services]
AddService = CH341SER, 2, CH341SER.Service
AddService = Serenum, , Serenum_Service_Inst
[CH341SER_Inst.NTamd64.Services]
AddService = CH341SER_A64, 2, CH341SER.ServiceA64
AddService = Serenum, , Serenum_Service_Inst
[CH341SER_Inst.NTia64.Services]
AddService = CH341SER_I64, 2, CH341SER.ServiceI64
AddService = Serenum, , Serenum_Service_Inst
[CH341SER.Service]
DisplayName = "CH341SER"
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %10%\System32\Drivers\CH341SER.SYS
[CH341SER.ServiceA64]
DisplayName = "CH341SER_A64"
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %10%\System32\Drivers\CH341S64.SYS
[CH341SER.ServiceI64]
DisplayName = "CH341SER_I64"
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %10%\System32\Drivers\CH341I64.SYS
[Serenum_Service_Inst]
DisplayName = "SerEnum"
ServiceType = 1
StartType = 3
ErrorControl = 1
ServiceBinary = %12%\serenum.sys
LoadOrderGroup = PNP Filter
[DestinationDirs]
DefaultDestDir = 10, System32\Drivers
CH341S98.DelFiles.SYS = 11
CH341SER.CopyFiles.SYS = 10, System32\Drivers
CH341SER.NT.CopyFiles.SYS = 10, System32\Drivers
CH341S98.CopyFiles.VXD = 11
CH341SER.CopyFiles.DLL = 11
CH341SER.NT.CopyFiles.SYSA64 = 10, System32\Drivers
;CH341SER.NT.CopyFiles.SYSI64 = 10, System32\Drivers
[SourceDisksFiles]
CH341SER.SYS = 1
CH341S98.SYS = 1
CH341SER.VXD = 1
CH341PT.DLL = 1
CH341S64.SYS = 1
;CH341I64.SYS = 1
[SourceDisksNames]
1 = %DISK_NAME%, , ,
[SourceDisksNames.amd64]
1 = %DISK_NAME%, , ,
[SourceDisksNames.ia64]
1 = %DISK_NAME%, , ,
[Strings]
WinChipHead = "wch.cn"
CH341SER.DeviceDesc = "USB-SERIAL CH341"
CH341S98.DeviceDesc = "USB-SERIAL CH341"
CH340SER.DeviceDesc = "USB-SERIAL CH340"
CH341ASER.DeviceDesc = "USB-SERIAL CH341A"
DISK_NAME = "CH341 Serial Installation Disk"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,346 @@
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
#include "DHT.h"
String ssid = "";
String pasw = "";
String hwId = "";
String url = "";
//Pins
#define LIGHTPIN 13
#define DHTPIN 4
#define DHTTYPE DHT11
#define LED_BUILTIN 16
//Settings
bool deepSleepOn = true;
long sleepTime = 4; //in minutes
bool lightSensor = true;
bool humiditySensor = true;
bool temperatureSensor = true;
ESP8266WebServer server(80);
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
Serial.setDebugOutput(true);
EEPROM.begin(512);
Serial.println("");
}
void loop() {
restorSetting();
if (!checkConnection()) {
settingMode();
while (true){
Serial.println("CONECTION SETTING LOOP");
server.handleClient();
}
} else {
httpRequest();
sleep();
}
}
//webpages
void handleRoot() {
String s = "<!DOCTYPE html><html><head>";
s += "<meta name=\"viewport\" content=\"width=device-width,user-scalable=0\">";
s += "<title>";
s += "Main";
s += "</title>";
s += "</head>";
s += "<body>";
s += "<a href=\"/restart\"><p>Restartovat</p><a/>";
s += "<a href=\"/setting\"><p>Refrest WIFI Networks</p><a/>";
s += "</body>";
s += "</html>";
server.send(200, "text/html", s);
}
void handleSetting() {
String wifiList = "";
int n = WiFi.scanNetworks();
Serial.println("scan done");
if (n == 0) {
Serial.println("no networks found");
} else {
for (int i = 0; i < n; ++i) {
//Serial.println("SSID: " + WiFi.SSID(i));
wifiList = wifiList + String("<option value=\"");
wifiList = wifiList + String(WiFi.SSID(i));
wifiList = wifiList + String("\">");
wifiList = wifiList + String(WiFi.SSID(i) + "(" + WiFi.RSSI() + ")");
wifiList = wifiList + String("</option>");
}
}
String s = "<!DOCTYPE html><html><head>";
s += "<meta name=\"viewport\" content=\"width=device-width,user-scalable=0\">";
s += "<title>";
s += "Main";
s += "</title>";
s += "</head>";
s += "<body>";
s += "<form method=\"get\" action=\"set\">";
s += "<br>SSID: <select name=\"ssid\">";
s += wifiList;
s += "</select>";
s += "<br>Password: <input name=\"pasw\" length=64 type=\"password\">";
s += "<br>Token: <input name=\"token\" length=64 type=\"text\">";
s += "<br>Api Url: <input name=\"url\" length=64 type=\"url\">";
s += "<input type=\"submit\">";
s += "</form>";
s += "</body>";
s += "</html>";
server.send(200, "text/html", s);
}
//functions
bool restorSetting() {
Serial.println("Reading EEPROM");
ssid = "";
pasw = "";
hwId = "";
url = "";
if (EEPROM.read(0) != 0) {
Serial.println("Reading EEPROM");
for (int i = 0; i < 64; ++i) {
ssid += char(EEPROM.read(i));
}
Serial.println("SSID: " + String(ssid));
for (int i = 64; i < 128; ++i) {
pasw += char(EEPROM.read(i));
}
Serial.println("PASS: " + String(pasw));
for (int i = 128; i < 192; ++i) {
hwId += char(EEPROM.read(i));
}
Serial.println("TOKEN: " + String(hwId));
for (int i = 192; i < 256; ++i) {
url += char(EEPROM.read(i));
}
Serial.println("URL: " + String(url));
return true;
} else {
return false;
}
}
String urlDecode(String input) {
String s = input;
s.replace("%20", " ");
s.replace("+", " ");
s.replace("%21", "!");
s.replace("%22", "\"");
s.replace("%23", "#");
s.replace("%24", "$");
s.replace("%25", "%");
s.replace("%26", "&");
s.replace("%27", "\'");
s.replace("%28", "(");
s.replace("%29", ")");
s.replace("%30", "*");
s.replace("%31", "+");
s.replace("%2C", ",");
s.replace("%2E", ".");
s.replace("%2F", "/");
s.replace("%2C", ",");
s.replace("%3A", ":");
s.replace("%3A", ";");
s.replace("%3C", "<");
s.replace("%3D", "=");
s.replace("%3E", ">");
s.replace("%3F", "?");
s.replace("%40", "@");
s.replace("%5B", "[");
s.replace("%5C", "\\");
s.replace("%5D", "]");
s.replace("%5E", "^");
s.replace("%5F", "-");
s.replace("%60", "`");
return s;
}
bool checkConnection() {
int count = 0;
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.forceSleepWake();
WiFi.begin(ssid, pasw);
Serial.print("Waiting for Wi-Fi connection");
while ( count < 30 ) {
if (WiFi.status() == WL_CONNECTED) {
Serial.println();
Serial.println("Connected!");
return (true);
}
delay(500);
Serial.print(".");
count++;
}
Serial.println("Timed out.");
return false;
}
void settingMode(){
WiFi.mode(WIFI_AP);
WiFi.softAP("NodeMeter");
IPAddress myIP = WiFi.softAPIP();
Serial.print("HotSpt IP:");
Serial.println(myIP);
server.on("/", handleRoot);
server.on("/restart", []() {
ESP.restart();
});
server.on("/setting", handleSetting);
server.on("/set", []() {
for (int i = 0; i < 96; ++i) {
EEPROM.write(i, 'e');
}
EEPROM.commit();
ssid = server.arg("ssid");
pasw = server.arg("pasw");
hwId = server.arg("token");
url = server.arg("url");
for (int i = 0; i < 256; ++i) {
EEPROM.write(i, 0);
}
Serial.println("Writing EEPROM...");
Serial.println("SSID:" + ssid);
for (int i = 0; i < ssid.length(); ++i) {
EEPROM.write(i,ssid[i]);
}
Serial.println("PASW:" + pasw);
for (int i = 0; i < pasw.length(); ++i) {
EEPROM.write(64 + i, pasw[i]);
}
Serial.println("TOKEN:" + hwId);
for (int i = 0; i < hwId.length(); ++i) {
EEPROM.write(128 + i, hwId[i]);
}
Serial.println("URL:" + url);
for (int i = 0; i < url.length(); ++i) {
EEPROM.write(192 + i, url[i]);
}
EEPROM.commit();
Serial.println("Write EEPROM done!");
String s = "<h1>Setup complete.</h1><p>device will be connected to \"";
s += ssid;
s += "\" after the restart.";
server.send(200, "text/html", s);
ESP.restart();
});
server.begin();
Serial.println("HTTP server started");
}
bool httpRequest(){
StaticJsonDocument<1024> sendContent;
sendContent["token"] = hwId;
if (temperatureSensor){
sendContent["values"]["temp"]["value"] = String(getTemperature());
sendContent["values"]["temp"]["unit"] = "C";
}
if (humiditySensor){
sendContent["values"]["humi"]["value"] = String(getHumidity());
sendContent["values"]["humi"]["unit"] = "%";
}
if (lightSensor){
sendContent["values"]["light"]["value"] = String(getLight());
sendContent["values"]["light"]["unit"] = "";
}
String requestJson = "";
serializeJson(sendContent, requestJson);
Serial.println("JSON: " + requestJson);
HTTPClient http;
http.begin(String(url));
http.addHeader("Content-Type", "application/json"); //Specify content-type header
int httpCode = http.POST(requestJson);
String payload = http.getString(); //Get the response payload
http.end();
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
String hostname = doc["device"]["hostname"];
sleepTime = doc["device"]["sleepTime"];
WiFi.hostname(hostname);
Serial.println("HTTP CODE: " + String(httpCode) + ""); //Print HTTP return code
Serial.println("HTTP BODY: " + String(payload) + ""); //Print request response payload
http.end(); //Close connection
}
void sleep(){
Serial.println("DISCONECTED FROM WIFI");
WiFi.disconnect();
if (deepSleepOn) {
Serial.println("GOING TO SLEEP FOR " + String(sleepTime));
ESP.deepSleep((sleepTime * 60) * 1000000, RF_DEFAULT); // 20e6 is 20 microseconds
delay(1000);
} else {
delay(1000);
delay(sleepTime);
}
}
//ReadTemperatures
float getTemperature() {
float t = dht.readTemperature();
//Serial.print(dht.readTemperature());
//Serial.println(t);
if (isnan(t)) {
Serial.println( "Failed to read temperature from sensor!") ;
return 999;
}
return t;
}
float getHumidity() {
float h = dht.readHumidity();
//Serial.println(h);
if (isnan(h)) {
Serial.println("Failed to read humidity from sensor!");
return 999;
}
return h;
}
int getLight() {
int l = analogRead(LIGHTPIN);
if (l > 1000) {
return 1;
} else {
return 0;
}
Serial.println("Failed to read light from sensor!");
return 999;
}

View File

@ -0,0 +1,92 @@
//Includes
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
//Variables
const char* ssid = "";
const char* pasw = "";
const char* server = "http://ESP:ESP@dev.steelants.cz/projekty/rest_vasek/api/out.php";
const char* hwId = "";
int lastState = 0;
//Constant
#define SONOFF 12
#define SONOFF_LED 13
#define SONOFF_BUT 0
void setup() {
Serial.begin(9600);
Serial.println("HW: " + String(hwId));
pinMode(SONOFF, OUTPUT);
pinMode(SONOFF_LED, OUTPUT);
pinMode(SONOFF_BUT, OUTPUT);
pinMode(SONOFF_BUT, INPUT);
// WI-FI CONECTING
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pasw);
}
void loop() {
if(WiFi.status() != WL_CONNECTED){
WiFi.begin(ssid, pasw);
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
digitalWrite(SONOFF_LED, LOW); // LOW will turn on the LED
delay(1000);
digitalWrite(SONOFF_LED, HIGH); // HIGH will turn off the LED
delay(1000);
}
Serial.println("\nCONECTED TO WIFI");
Serial.println("IP: " + String(WiFi.localIP()));
}
bool buttonState = digitalRead(SONOFF_BUT);
HTTPClient http;
http.begin(server);
http.addHeader("Content-Type", "text/plain"); //Specify content-type header
String requestJson = "{";
requestJson += "\"tocken\":\"" + String(hwId) + "\"";
if (buttonState == true) {
requestJson += ",";
requestJson += "\"on/off\":{";
requestJson += "\"value\":\"" + String(~lastState) + "\",";
requestJson += "\"unit\":\"\"";
requestJson += "}";
}
while(buttonState == true) {
delay(50); // keeps a small delay
}
requestJson += "}";
Serial.println("JSON: " + requestJson);
int httpCode = http.POST(requestJson);
String payload = http.getString(); //Get the response payload
Serial.println("HTTP CODE: " + String(httpCode) + ""); //Print HTTP return code
Serial.println("HTTP BODY: " + String(payload) + ""); //Print request response payload
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
string hostname = doc["hostname"];
WiFi.hostname(hostname);
int state = doc["state"];
if (state == 1 && lastState == 0) {
Serial.println("ON");
digitalWrite(SONOFF, HIGH); // Turn the LED on by making the voltage LOW
digitalWrite(SONOFF_LED, LOW); // Turn the LED on by making the voltage LOW
} else {
Serial.println("OFF");
digitalWrite(SONOFF, LOW); // Turn the LED on by making the voltage LOW
digitalWrite(SONOFF_LED, HIGH); // Turn the LED on by making the voltage LOW
}
lastState = state;
delay(1000);
}

View File

@ -0,0 +1,94 @@
//Includes
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
//Variables
const char* ssid = "";
const char* pasw = "";
const char* server = "http://ESP:ESP@dev.steelants.cz/projekty/rest_vasek/api/out.php";
const char* hwId = "";
int lastState = 0;
//Constant
#define SONOFF 12
#define SONOFF_LED 13
#define SONOFF_BUT 0
void setup() {
Serial.begin(9600);
Serial.println("HW: " + String(hwId));
pinMode(SONOFF, OUTPUT);
pinMode(SONOFF_LED, OUTPUT);
pinMode(SONOFF_BUT, OUTPUT);
pinMode(SONOFF_BUT, INPUT);
// WI-FI CONECTING
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, pasw);
}
void loop() {
if(WiFi.status() != WL_CONNECTED){
WiFi.begin(ssid, pasw);
while (WiFi.status() != WL_CONNECTED) { // Wait for the Wi-Fi to connect
digitalWrite(SONOFF_LED, LOW); // LOW will turn on the LED
delay(1000);
digitalWrite(SONOFF_LED, HIGH); // HIGH will turn off the LED
delay(1000);
}
Serial.println("\nCONECTED TO WIFI");
Serial.println("IP: " + String(WiFi.localIP()));
}
bool buttonState = digitalRead(SONOFF_BUT);
HTTPClient http;
http.begin(server);
http.addHeader("Content-Type", "text/plain"); //Specify content-type header
String requestJson = "{";
requestJson += "\"tocken\":\"" + String(hwId) + "\"";
if (buttonState == true) {
requestJson += ",";
requestJson += "\"on/off\":{";
requestJson += "\"value\":\"" + String(~lastState) + "\",";
requestJson += "\"unit\":\"\"";
requestJson += "}";
}
while(buttonState == true) {
delay(50); // keeps a small delay
}
requestJson += "}";
Serial.println("JSON: " + requestJson);
int httpCode = http.POST(requestJson);
String payload = http.getString(); //Get the response payload
Serial.println("HTTP CODE: " + String(httpCode) + ""); //Print HTTP return code
Serial.println("HTTP BODY: " + String(payload) + ""); //Print request response payload
DynamicJsonDocument doc(1024);
deserializeJson(doc, payload);
string hostname = doc["device"]["hostname"];
sleepTime = doc["device"]["sleepTime"];
WiFi.hostname(hostname);
int state = doc["state"];
if (state == 1 && lastState == 0) {
Serial.println("ON");
digitalWrite(SONOFF, HIGH); // Turn the LED on by making the voltage LOW
digitalWrite(SONOFF_LED, LOW); // Turn the LED on by making the voltage LOW
} else {
Serial.println("OFF");
digitalWrite(SONOFF, LOW); // Turn the LED on by making the voltage LOW
digitalWrite(SONOFF_LED, HIGH); // Turn the LED on by making the voltage LOW
}
lastState = state;
delay(1000);
}

View File

@ -0,0 +1,94 @@
//Includes
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
//Variables
const char* ssid = "";
const char* pasw = "";
const char* server = "httpa://dev.steelants.cz/vasek/home/api.php";
const char* hwId = "";
int lastState = 0;
int reconectAtemptsMax = 10; //time to wait before restart
//Constant
#define SONOFF 12
#define SONOFF_LED 13
#define SONOFF_BUT 0
HTTPClient http;
void setup() {
Serial.begin(9600);
Serial.println("HW: " + String(hwId));
pinMode(SONOFF, OUTPUT);
pinMode(SONOFF_LED, OUTPUT);
pinMode(SONOFF_BUT, OUTPUT);
pinMode(SONOFF_BUT, INPUT);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.setAutoConnect (true);
WiFi.setAutoReconnect (true);
WiFi.begin(ssid, pasw);
http.begin(server);
}
void loop() {
int reconectAtempts = 0;
while(WiFi.status() != WL_CONNECTED){
if (reconectAtemptsMax == reconectAtempts) {
ESP.restart();
}
WiFi.begin(ssid, pasw);
delay(1000);
}
bool buttonState = digitalRead(SONOFF_BUT);
http.addHeader("Content-Type", "text/plain"); //Specify content-type header
StaticJsonBuffer<1024> jsonContent;
jsonContent["token"] = hwId;
if (buttonState){
jsonContent["values"]["on/off"]["value"] = lastState;
jsonContent["values"]["on/off"]["unit"] = '';
while(buttonState) {
delay(100);
}
}
String requestJson = "";
serializeJson(jsonContent, requestJson);
jsonContent.clean();
Serial.println("JSON: " + requestJson);
int httpCode = http.POST(jsonContent);
String payload = http.getString(); //Get the response payload
Serial.println("HTTP CODE: " + String(httpCode) + ""); //Print HTTP return code
Serial.println("HTTP BODY: " + String(payload) + ""); //Print request response payload
deserializeJson(doc, payload);
string hostname = doc["device"]["hostname"];
WiFi.hostname(hostname);
int state = doc["state"];
if (state == 1 && lastState == 0) {
Serial.println("ON");
digitalWrite(SONOFF, HIGH); // Turn the LED on by making the voltage LOW
digitalWrite(SONOFF_LED, LOW); // Turn the LED on by making the voltage LOW
} else {
Serial.println("OFF");
digitalWrite(SONOFF, LOW); // Turn the LED on by making the voltage LOW
digitalWrite(SONOFF_LED, HIGH); // Turn the LED on by making the voltage LOW
}
lastState = state;
delay(1000);
}

Binary file not shown.

View File

@ -0,0 +1,268 @@
-- phpMyAdmin SQL Dump
-- version 4.6.6deb4
-- https://www.phpmyadmin.net/
--
-- Počítač: localhost:3306
-- Vytvořeno: Pát 28. čen 2019, 10:05
-- Verze serveru: 10.1.38-MariaDB-0+deb9u1
-- Verze PHP: 7.0.33-0+deb9u3
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Databáze: `smart-home`
--
-- --------------------------------------------------------
--
-- Struktura tabulky `automation`
--
CREATE TABLE `automation` (
`automation_id` int(11) NOT NULL,
`name` int(11) NOT NULL,
`on_days` varchar(255) NOT NULL,
`if_something` varchar(255) NOT NULL,
`do_something` varchar(255) NOT NULL,
`executed` tinyint(4) NOT NULL,
`active` tinyint(4) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `dashboard`
--
CREATE TABLE `dashboard` (
`dashboard_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`subdevice_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `devices`
--
CREATE TABLE `devices` (
`device_id` int(11) NOT NULL,
`room_id` int(11) DEFAULT NULL,
`name` varchar(255) NOT NULL,
`token` varchar(255) NOT NULL,
`approved` int(11) NOT NULL,
`icon` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `records`
--
CREATE TABLE `records` (
`record_id` int(11) NOT NULL,
`subdevice_id` int(11) NOT NULL,
`value` varchar(255) NOT NULL,
`time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `rooms`
--
CREATE TABLE `rooms` (
`room_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `scenes`
--
CREATE TABLE `scenes` (
`scene_id` int(11) NOT NULL,
`icon` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`do_something` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `subdevices`
--
CREATE TABLE `subdevices` (
`subdevice_id` int(11) NOT NULL,
`device_id` int(11) NOT NULL,
`type` varchar(255) NOT NULL,
`unit` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- --------------------------------------------------------
--
-- Struktura tabulky `users`
--
CREATE TABLE `users` (
`user_id` int(11) NOT NULL,
`username` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`startPage` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Vypisuji data pro tabulku `users`
--
INSERT INTO `users` (`user_id`, `username`, `password`, `startPage`) VALUES
(2, 'Admin', '08abb3ff83dfae60fb4591125fc49dc80cf7ef28224c2d5df86e2d0d037c553bc7f30e859348fd745c9c07a4edde4863e866a7d45356cf08a22e5e1eafa13406', 1);
--
-- Klíče pro exportované tabulky
--
--
-- Klíče pro tabulku `automation`
--
ALTER TABLE `automation`
ADD PRIMARY KEY (`automation_id`);
--
-- Klíče pro tabulku `dashboard`
--
ALTER TABLE `dashboard`
ADD PRIMARY KEY (`dashboard_id`),
ADD KEY `user_id` (`user_id`),
ADD KEY `subdevice_id` (`subdevice_id`);
--
-- Klíče pro tabulku `devices`
--
ALTER TABLE `devices`
ADD PRIMARY KEY (`device_id`),
ADD KEY `room_id` (`room_id`);
--
-- Klíče pro tabulku `records`
--
ALTER TABLE `records`
ADD PRIMARY KEY (`record_id`),
ADD KEY `device_id` (`subdevice_id`);
--
-- Klíče pro tabulku `rooms`
--
ALTER TABLE `rooms`
ADD PRIMARY KEY (`room_id`);
--
-- Klíče pro tabulku `scenes`
--
ALTER TABLE `scenes`
ADD PRIMARY KEY (`scene_id`);
--
-- Klíče pro tabulku `subdevices`
--
ALTER TABLE `subdevices`
ADD PRIMARY KEY (`subdevice_id`),
ADD KEY `device_id` (`device_id`);
--
-- Klíče pro tabulku `users`
--
ALTER TABLE `users`
ADD PRIMARY KEY (`user_id`);
--
-- AUTO_INCREMENT pro tabulky
--
--
-- AUTO_INCREMENT pro tabulku `automation`
--
ALTER TABLE `automation`
MODIFY `automation_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=10;
--
-- AUTO_INCREMENT pro tabulku `dashboard`
--
ALTER TABLE `dashboard`
MODIFY `dashboard_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=10;
--
-- AUTO_INCREMENT pro tabulku `devices`
--
ALTER TABLE `devices`
MODIFY `device_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=8;
--
-- AUTO_INCREMENT pro tabulku `records`
--
ALTER TABLE `records`
MODIFY `record_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=26310;
--
-- AUTO_INCREMENT pro tabulku `rooms`
--
ALTER TABLE `rooms`
MODIFY `room_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=22;
--
-- AUTO_INCREMENT pro tabulku `scenes`
--
ALTER TABLE `scenes`
MODIFY `scene_id` int(11) NOT NULL AUTO_INCREMENT;
--
-- AUTO_INCREMENT pro tabulku `subdevices`
--
ALTER TABLE `subdevices`
MODIFY `subdevice_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11;
--
-- AUTO_INCREMENT pro tabulku `users`
--
ALTER TABLE `users`
MODIFY `user_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
--
-- Omezení pro exportované tabulky
--
--
-- Omezení pro tabulku `dashboard`
--
ALTER TABLE `dashboard`
ADD CONSTRAINT `dashboard_ibfk_2` FOREIGN KEY (`subdevice_id`) REFERENCES `subdevices` (`subdevice_id`) ON DELETE CASCADE ON UPDATE NO ACTION,
ADD CONSTRAINT `dashboard_ibfk_3` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON DELETE CASCADE ON UPDATE NO ACTION;
--
-- Omezení pro tabulku `devices`
--
ALTER TABLE `devices`
ADD CONSTRAINT `devices_ibfk_1` FOREIGN KEY (`room_id`) REFERENCES `rooms` (`room_id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Omezení pro tabulku `records`
--
ALTER TABLE `records`
ADD CONSTRAINT `records_ibfk_1` FOREIGN KEY (`subdevice_id`) REFERENCES `subdevices` (`subdevice_id`) ON DELETE CASCADE ON UPDATE CASCADE;
--
-- Omezení pro tabulku `subdevices`
--
ALTER TABLE `subdevices`
ADD CONSTRAINT `subdevices_ibfk_1` FOREIGN KEY (`device_id`) REFERENCES `devices` (`device_id`);
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

BIN
_README_IMG/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

BIN
_README_IMG/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
_README_IMG/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
_README_IMG/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

BIN
_README_IMG/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
_README_IMG/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
_README_IMG/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
_README_IMG/7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
_README_IMG/8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
_README_IMG/9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

149
api.php Normal file
View File

@ -0,0 +1,149 @@
<?php
/** Includes **/
include_once('./config.php');
//Autoloader
foreach (["class", "views"] as $dir) {
$files = scandir('./'.$dir.'/');
$files = array_diff($files, array('.', '..'));
foreach ($files as $file) {
include_once './'.$dir.'/'. $file;
}
}
//DB Conector
Db::connect (DBHOST, DBUSER, DBPASS, DBNAME);
//Filtrování IP adress
if (DEBUGMOD != 1) {
if (!in_array($_SERVER['REMOTE_ADDR'], HOMEIP)) {
echo json_encode(array(
'state' => 'unsuccess',
'errorMSG' => "Using API from your IP insn´t alowed!",
));
header("HTTP/1.1 401 Unauthorized");
exit();
}
}
//Read API data
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
if (isset($obj['user']) && $obj['user'] != ''){
//user at home
$user = UserManager::getUser($obj['user']);
$userId = $user['user_id'];
UserManager::atHome($userId, $obj['location']);
die();
}
//automationExecution
AutomationManager::executeAll();
//Record Cleaning
RecordManager::clean(RECORDTIMOUT);
//Variables
$token = $obj['token'];
$values = null;
if (isset($obj['values'])) {
$values = $obj['values'];
}
//Checks
if ($token == null || $token == "") {
echo json_encode(array(
'state' => 'unsuccess',
'errorMSG' => "Missing Value Token in JSON payload",
));
header("HTTP/1.1 401 Unauthorized");
die();
}
//Vstupní Checky
if (!DeviceManager::registeret($token)) {
DeviceManager::create($token, $token);
header("HTTP/1.1 401 Unauthorized");
echo json_encode(array(
'state' => 'unsuccess',
'errorMSG' => "Device not registeret",
));
exit();
}
if (!DeviceManager::approved($token)) {
header("HTTP/1.1 401 Unauthorized");
echo json_encode(array(
'state' => 'unsuccess',
'errorMSG' => "Unaproved Device",
));
exit();
}
if (!DeviceManager::approved($token)) {
header("HTTP/1.1 401 Unauthorized");
echo json_encode(array(
'state' => 'unsuccess',
'errorMSG' => "Unaproved Device",
));
exit();
}
// Subdevices first data!
if ($values != null || $values != "") {
//ZAPIS
$device = DeviceManager::getDeviceByToken($token);
$deviceId = $device['device_id'];
foreach ($values as $key => $value) {
if (!SubDeviceManager::getSubDeviceByMaster($deviceId, $key)) {
SubDeviceManager::create($deviceId, $key, UNITS[$key]);
}
RecordManager::create($deviceId, $key, round($value['value'],2));
}
$hostname = strtolower($device['name']);
$hostname = str_replace(' ', '_', $hostname);
echo json_encode(array(
'device' => [
'hostname' => $hostname,
'sleepTime' => $device['sleep_time'],
],
'state' => 'succes',
));
header("HTTP/1.1 200 OK");
die();
} else {
//Vypis
//TODO: doděla uložení výpisu jinými slovy zda li byl comman vykonán
$device = DeviceManager::getDeviceByToken($token);
$deviceId = $device['device_id'];
if (count(SubDeviceManager::getAllSubDevices($deviceId)) == 0) {
SubDeviceManager::create($deviceId, 'on/off', UNITS[$key]);
RecordManager::create($deviceId, 'on/off', 0);
}
$subDeviceId = SubDeviceManager::getAllSubDevices($deviceId)[0]['subdevice_id'];
$subDeviceLastReord = RecordManager::getLastRecord($subDeviceId);
$subDeviceLastReordValue = $subDeviceLastReord['value'];
RecordManager::setExecuted($subDeviceLastReord['record_id']);
echo json_encode(array(
'device' => [
'hostname' => $device['name'],
'sleepTime' => $device['sleep_time'],
],
'state' => 'succes',
'value' => $subDeviceLastReordValue
));
header("HTTP/1.1 200 OK");
die();
}

View File

@ -0,0 +1,79 @@
<?php
class AutomationManager{
public static $automation;
public function remove($automationId) {
return Db::command ('DELETE FROM automation WHERE automation_id=?', array ($automationId));
}
public function deactive($automationId) {
$automation = Db::loadOne ("SELECT * FROM automation WHERE automation_id=?" , array ($automationId));
$flipedValue = ($automation['active'] == 1 ? 0 : 1);
return Db::command ('UPDATE automation SET active = ? WHERE automation_id=?', array ($flipedValue,$automationId));
}
public function create ($name, $onDays, $doCode, $ifCode) {
$scene = array (
'name' => $name,
'on_days' => $onDays,
'if_something' => $doCode,
'do_something' => $ifCode,
);
try {
Db::add ('automation', $scene);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function getAll(){
return Db::loadAll ("SELECT * FROM automation");
}
public function executeAll(){
global $dateTimeOffset;
$automations = Db::loadAll ("SELECT * FROM automation");
$dayNameNow = strtolower (date('D', time()));
foreach ($automations as $automation) {
$onValue = $automation['if_something'];
$sceneDoJson = $automation['do_something'];
$actionDays = json_decode($automation['on_days'], true);
$value = time();
if ($automation['active'] != 0){
if (in_array($dayNameNow, $actionDays)){
switch ($onValue) {
case 'sunSet':
$value = date_sunset($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90, $dateTimeOffset);
break;
case 'sunRise':
$value = date_sunrise($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90, $dateTimeOffset);
break;
case 'time':
$onValue = explode(':',$onValue);
$today = date_create('now');
$onValue = $today->setTime($onValue[0], $onValue[1]);
$value = $today->getTimestamp();
break;
default:
break;
}
if (time() > $value){
if ($automation['executed'] == 0){
$sceneDoArray = json_decode($sceneDoJson);
foreach ($sceneDoArray as $deviceId => $deviceState) {
RecordManager::create($deviceId, 'on/off', $deviceState);
}
Db::edit('automation', array('executed' => 1), 'WHERE automation_id = ?', array($automation['automation_id']));
}
} elseif (time() < $value && $automation['executed'] = 1) { //recovery realowing of automation
Db::edit('automation', array('executed' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
}
}
}
}
}
}

194
class/ChartJS.php Normal file
View File

@ -0,0 +1,194 @@
<?php
abstract class ChartJS
{
/**
* @var array chart data
*/
protected $_datasets = array();
/**
* @var array chart labels
*/
protected $_labels = array();
/**
* The chart type
* @var string
*/
protected $_type = '';
/**
* @var array Specific options for chart
*/
protected $_options = array();
/**
* @var string Chartjs canvas' ID
*/
protected $_id;
/**
* @var string Canvas width
*/
protected $_width;
/**
* @var string Canvas height
*/
protected $_height;
/**
* @var array Canvas attributes (class,
*/
protected $_attributes = array();
/**
* @var array Default colors
*/
protected static $_defaultColors = array('fill' => 'rgba(220,220,220,0.2)', 'stroke' => 'rgba(220,220,220,1)', 'point' => 'rgba(220,220,220,1)', 'pointStroke' => '#fff');
/**
* Add label(s)
* @param array $labels
* @param bool $reset
*/
public function addLabels(array $labels, $reset = false)
{
if ($reset) {
$this->_labels = array();
}
$this->_labels = $this->_labels + $labels;
}
/**
* Add dataset
* @param $dataset
* @param $reset
*/
public function addDataset($dataset, $reset)
{
if ($reset) {
$this->_datasets = array();
}
$this->_datasets += $dataset;
}
public function __construct($id = null, $width = '', $height = '', $otherAttributes = array())
{
if (!$id) {
$id = uniqid('chartjs_', true);
}
$this->_id = $id;
$this->_width = $width;
$this->_height = $height;
// Always save otherAttributes as array
if ($otherAttributes && !is_array($otherAttributes)) {
$otherAttributes = array($otherAttributes);
}
$this->_attributes = $otherAttributes;
}
/**
* This method allows to echo ChartJS object and directly renders canvas (instead of using ChartJS->render())
*/
public function __toString()
{
return $this->renderCanvas();
}
public function renderCanvas()
{
$data = $this->_renderData();
$options = $this->_renderOptions();
$height = $this->_renderHeight();
$width = $this->_renderWidth();
$attributes = $this->_renderAttributes();
$canvas = '<canvas id="' . $this->_id . '" data-chartjs="' . $this->_type . '"' . $height . $width . $attributes . $data . $options . '></canvas>';
return $canvas;
}
/**
* Prepare canvas' attributes
* @return string
*/
protected function _renderAttributes()
{
$attributes = '';
foreach ($this->_attributes as $attribute => $value) {
$attributes .= ' ' . $attribute . '="' . $value . '"';
}
return $attributes;
}
/**
* Prepare width attribute for canvas
* @return string
*/
protected function _renderWidth()
{
$width = '';
if ($this->_width) {
$width = ' width="' . $this->_width . '"';
}
return $width;
}
/**
* Prepare height attribute for canvas
* @return string
*/
protected function _renderHeight()
{
$height = '';
if ($this->_height) {
$height = ' height="' . $this->_height . '"';
}
return $height;
}
/**
* Render custom options for the chart
* @return string
*/
protected function _renderOptions()
{
if (empty($this->_options)) {
return '';
}
return ' data-options=\'' . json_encode($this->_options) . '\'';
}
/**
* Prepare data (labels and dataset) for the chart
* @return string
*/
protected function _renderData()
{
$array_data = array('labels' => array(), 'datasets' => array());
$i = 0;
foreach ($this->_datasets as $line) {
$this->_completeColors($line['options'], $i);
$array_data['datasets'][] = $line['options'] + array('data' => $line['data']);
$i++;
}
$array_data['labels'] = $this->_labels;
return ' data-data=\'' . json_encode($array_data) . '\'';
}
/**
* Set default colors
* @param array $defaultColors
*/
public static function setDefaultColors(array $defaultColors)
{
self::$_defaultColors = $defaultColors;
}
/**
* @param array $color
*/
public static function addDefaultColor(array $color)
{
if (!empty($color['fill']) && !empty($color['stroke']) && !empty($color['point']) && !empty($color['pointStroke'])) {
self::$_defaultColors[] = $color;
} else {
trigger_error('Color is missing to add this theme (need fill, stroke, point and pointStroke) : color not added', E_USER_WARNING);
}
}
protected function _completeColors(&$options, &$i)
{
if (empty(static::$_defaultColors[$i])) {
$i = 0;
}
$colors = static::$_defaultColors[$i];
foreach (static::$_colorsRequired as $name) {
if (empty($options[$name])) {
$shortName = str_replace('Color', '', $name);
if (empty($colors[$shortName])) {
$shortName = static::$_colorsReplacement[$shortName];
}
$options[$name] = $colors[$shortName];
}
}
}
}

21
class/ChartJS_Line.php Normal file
View File

@ -0,0 +1,21 @@
<?php
class ChartJS_Line extends ChartJS
{
protected $_type = 'Line';
protected static $_colorsRequired = array('fillColor', 'strokeColor', 'pointColor', 'pointStrokeColor', 'pointHighlightFill', 'pointHighlightStroke');
protected static $_colorsReplacement = array('pointHighlightFill' => 'point', 'pointHighlightStroke' => 'pointStroke');
/**
* Add a set of data
* @param array $data
* @param array $options
* @param null $name Name cas be use to change data / options later
*/
public function addLine($data = array(), $options = array(), $name = null)
{
if (!$name) {
$name = count($this->_datasets) + 1;
}
$this->_datasets[$name]['data'] = $data;
$this->_datasets[$name]['options'] = $options;
}
}

86
class/ChartManager.php Normal file
View File

@ -0,0 +1,86 @@
<?php
class ChartManager{
function generateChart($data, $min = 0, $max = 100)
{
echo '<br>Aktuální Hodnota: '.$data[0]['value'];
echo "<style>
.sloupec {
border-top: solid 2px red;
}
</style>";
echo '<div class=graph>';
echo '<div class="posuv " graf-max="'.$max.'" graf-min='.$min.'>';
for ($valuesRow = 0; $valuesRow < count($data); $valuesRow++) {
$row = $data[$valuesRow];
echo '<div class="sloupec " name="sloupec" value="' . $row['value'] . '" data-toggle="tooltip" title=""></div>';
}
echo '</div>';
echo '</div>';
echo '<script src="./include/js/chartDrwer.js"></script>';
echo 'Poslední Update: ';
echo '<style>
.graph {
width: 100%;
overflow: hidden;
margin-top: auto;
}
.posuv {
display: flex;
height: 200px;
background-image: url(./img/graph.png);
padding: 20px;
background-repeat: repeat;
border-bottom: 1px solid black;
}
.sloupec {
border-top: solid 2px blue;
background-color: grey;
float: left;
margin: auto 0 0;
display: inline-block;
width: 1%;
}
</style>
<script>
var posuvList = document.getElementsByClassName("posuv");
var maxHeight = posuvList[0].clientHeight;
for (i = 0; i < posuvList.length; i++) {
var maxPx = 0;
var grafMax = Number(posuvList[i].getAttribute("graf-max")); //100%
var grafMin = Number(posuvList[i].getAttribute("graf-min")); //0%
if (grafMin == 0 && grafMax == 100) {
var onePercent = 1;
} else {
var stepsBetWene = grafMax;
if (grafMin !== 0) {
if (grafMin < 0) {
stepsBetWene = grafMax + Math.abs(grafMin);
}
if (grafMin > 0) {
stepsBetWene = grafMax - grafMin;
}
}
var onePercent = stepsBetWene / 100;
}
var sloupceList = posuvList[i].querySelectorAll(".sloupec");
for (ai = 0; ai < sloupceList.length; ai++) {
var onePxPercent = maxHeight / 100;
var heightInPercent =
Math.abs(sloupceList[ai].getAttribute("value")) / onePercent;
var outputPx = onePxPercent * heightInPercent;
sloupceList[ai].style.height = outputPx + "px";
}
}
</script>';
}
}
?>

96
class/DB.php Normal file
View File

@ -0,0 +1,96 @@
<?php
class Db{
private static $join;
private static $commandDatabase = array (
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
PDO::ATTR_EMULATE_PREPARES => false
);
public static function connect ($host, $user, $password, $database) {
if (!isset (self::$join)) {
self::$join = @new PDO(
"mysql:host=$host;dbname=$database;charset=utf8",
$user,
$password,
self::$commandDatabase
);
self::$join->exec ("set names utf8");
}
}
public static function loadOne ($sql, $values = array (), $numberKey = false) {
$answer = self::$join->prepare ($sql);
$answer->execute ($values);
if (!$numberKey) {
return $answer->fetch (PDO::FETCH_ASSOC);
} else {
return $answer->fetch (PDO::FETCH_NUM);
}
}
public static function command ($sql, $values = array()) {
$answer = self::$join->prepare ($sql);
return $answer->execute ($values);
}
public static function loadAll ($sql, $values = array(), $numberKey = false) {
$answer = self::$join->prepare ($sql);
$answer->execute ($values);
if (!$numberKey) {
return $answer->fetchALL (PDO::FETCH_ASSOC);
} else {
return $answer->fetchALL (PDO::FETCH_NUM);
}
}
public static function loadAlone ($sql, $values = array()) {
$answer = self::$join->prepare ($sql);
$answer->execute ($values);
return $answer->fetch (PDO::FETCH_NUM)[0];
}
public static function add ($table, $values = array()) {
return self::command (
"INSERT INTO `$table` (`" .
implode('`, `', array_keys($values)) .
"`) VALUES (" .
str_repeat('?,', (count($values) > 0 ? count($values)-1 : 0)) .
"?)"
, array_values ($values));
}
// TODO: pokud vlozim prazdne pole tak chyba ??
public static function addAll ($table, $values = array ()) {
try {
foreach ($values as $value) {
self::add ($table, $value);
}
} catch (PDOException $ex) {
throw new PDOException ($ex->getMessage());
}
}
public static function edit (
$table,
$values = array(),
$conditions,
$values2 = array()
) {
return self::command (
"UPDATE `$table` SET `" .
implode('` =?, `', array_keys($values)) .
"` =? " .
$conditions
, array_merge (array_values ($values), $values2));
}
public static function insertId () {
return self::$join->lastInsertId ();
}
public static function addId ($lastTable, $lastIdName) {
$answer = self::$join->prepare ("SELECT `$lastIdName` FROM `$lastTable` ORDER BY `$lastIdName` DESC");
$answer->execute ();
return $answer->fetch (PDO::FETCH_NUM)[0];
}
}

View File

@ -0,0 +1,41 @@
<?php
class DashboardManager{
public static $devices;
function getAllDashboards ($userId) {
return Db::loadAll ("SELECT * FROM dashboard WHERE user_id=?", array($userId));
}
function getAllSubDevices ($userId) {
return Db::loadAll ("SELECT * FROM subdevices WHERE subdevice_id IN (SELECT subdevice_id FROM dashboard WHERE user_id=?)", array($userId));
}
function getSubDevice ($userId, $subDeviceId) {
return Db::loadOne ("SELECT * FROM subdevices WHERE subdevice_id = (SELECT subdevice_id FROM dashboard WHERE user_id=? AND subdevice_id = ? )", array($userId, $subDeviceId));
}
function Add ($subDeviceId) {
if (self::getSubDevice(UserManager::getUserData('user_id'), $subDeviceId) == null){
// to do: pokud existuje nepridej
//
//
$dashboardItem = array (
'user_id' => UserManager::getUserData('user_id'),
'subdevice_id' => $subDeviceId,
);
try {
Db::add ('dashboard', $dashboardItem);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
}
function Remove ($subDeviceId){
$userId = UserManager::getUserData('user_id');
Db::command ('DELETE FROM dashboard WHERE subdevice_id=? AND user_id = ?', array ($subDeviceId, $userId));
}
}

80
class/DeviceManager.php Normal file
View File

@ -0,0 +1,80 @@
<?php
class DeviceManager{
public static $devices;
function getAllDevices () {
return Db::loadAll ("SELECT * FROM devices");
}
function getAllDevicesInRoom ($roomId = "") {
return Db::loadAll ("SELECT * FROM devices WHERE room_id = ?", Array($roomId));
}
function getOtherDevices(){
return Db::loadAll ("SELECT * FROM devices WHERE room_id IS NULL ");
}
function getDeviceByToken($deviceToken) {
return Db::loadOne("SELECT * FROM devices WHERE token = ?", array($deviceToken));
}
function getDeviceById($deviceId) {
return Db::loadOne("SELECT * FROM devices WHERE device_id = ?", array($deviceId));
}
public function create ($name, $token) {
$device = array (
'name' => $name,
'token' => $token,
);
try {
Db::add ('devices', $device);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function edit ($deviceId, $values = []) {
try {
Db::edit ('devices', $values, 'WHERE device_id = ?', array($deviceId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
/**
* [assignRoom Přiřazení zařízení do třídy]
* @param [type] $roomId [číslo místnosti do kter se zařízení přiřadit]
* @param [type] $deviceId [Číslo zařízení které chcete přiřadit do místnosti]
*/
public function assignRoom ($roomId, $deviceId) {
$device = array (
'room_id' => $roomId,
);
try {
Db::edit ('devices', $device, 'WHERE device_id = ?', array($deviceId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
/**
* [delete Smazání zařízení]
* @param [type] $deviceId [Id zařízení ke smazání]
*/
public function delete ($deviceId) {
Db::command ('DELETE FROM devices WHERE device_id=?', array ($deviceId));
}
public function registeret ($deviceToken) {
return (count(Db::loadAll ("SELECT * FROM devices WHERE token=?", array($deviceToken))) == 1 ? true : false);
}
public function approved ($deviceToken) {
return (count(Db::loadAll ("SELECT * FROM devices WHERE token=? AND approved = ?", array($deviceToken, 1))) == 1 ? true : false);
}
}
?>

1
class/Form.php Symbolic link
View File

@ -0,0 +1 @@
C:/Users/spaninger/Documents/git/PHP_FORM_GENERATOR/Form.php

34
class/Partial.php Normal file
View File

@ -0,0 +1,34 @@
<?php
class Partial{
var $assignedValues = [];
var $partBuffer;
var $path;
var $debug;
function __construct($path = "", $debug = false) {
$this->debug = $debug;
if (!empty('templates/part/' . $path . '.phtml') && file_exists('templates/part/' . $path . '.phtml')) {
$this->path = $path;
} else {
echo '<pre>';
echo 'PHTML: Parial File ' . $path . ' not found';
echo '</pre>';
die();
}
}
function prepare($searchS, $repleaceS) {
if (!empty($searchS)) {
$this->assignedValues[strtoupper($searchS)] = $repleaceS;
}
echo ($this->debug == true ? var_dump($this->assignedValues) : '');
}
function render() {
if (!empty($this->assignedValues)){
extract($this->assignedValues);
}
require('templates/part/' . $this->path . '.phtml');
}
}

74
class/RecordManager.php Normal file
View File

@ -0,0 +1,74 @@
<?php
class RecordManager{
public static $records;
public function create ($deviceId, $type, $value) {
$subDeviceId = Db::loadOne('SELECT * FROM subdevices WHERE device_id = ? AND type = ?;', array($deviceId, $type))['subdevice_id'];
if ($subDeviceId == '') {
return false;
};
$record = array (
'subdevice_id' => $subDeviceId,
'value' => $value,
);
try {
return Db::add ('records', $record);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function setExecuted($recordId) {
try {
Db::edit ('records', ['execuded' => 1], 'WHERE record_id = ?', array($recordId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getRecordById($recordId) {
return Db::loadOne('SELECT * FROM records WHERE record_id = ?;', array($recordId));
}
public static function getLastInsertedRecordId() {
return Db::insertId();
}
public static function getLastRecord($subDeviceId, $num = 1) {
if ($num == 1)
return Db::loadOne('SELECT * FROM records WHERE subdevice_id = ? AND value != ? ORDER BY time DESC;', array($subDeviceId, 999));
return Db::loadAll('SELECT * FROM records WHERE subdevice_id = ? AND value != ? ORDER BY time DESC LIMIT ?;', array($subDeviceId, 999, $num));
}
public static function getAllRecord($subDeviceId, $timeFrom, $timeTo) {
return Db::loadAll('SELECT * FROM records WHERE subdevice_id = ? AND time >= ? AND time <= ? AND value != ? ORDER BY time;', array($subDeviceId, $timeFrom, $timeTo, 999));
}
public static function getAllRecordForGraph($subDeviceId, $period = "day", $groupBy = "hour") {
$periodLocal = '- 1 ' . strtoupper($period);
$dateTime = new DateTime();
$dateTime = $dateTime->modify($periodLocal);
$dateTime = $dateTime->format('Y-m-d');
$groupBy = strtoupper($groupBy).'(time)';
$sql = 'SELECT value, time FROM records
WHERE
subdevice_id = ?
AND
value != 999
AND
time > ?
GROUP BY '.$groupBy.'
ORDER BY time ASC';
//TODO: Prasárna Opravit
return Db::loadAll($sql, array($subDeviceId, $dateTime));
}
public static function clean ($day) {
if (isset($day)) {
Db::command ('DELETE FROM records WHERE time < ADDDATE(NOW(), INTERVAL -? DAY);', array($day));
}
}
}
?>

26
class/RoomManager.php Normal file
View File

@ -0,0 +1,26 @@
<?php
class RoomManager{
public static $rooms;
function getAllRooms () {
$allRoom = Db::loadAll ("SELECT rooms.*, COUNT(devices.device_id) as device_count FROM rooms LEFT JOIN devices ON (devices.room_id=rooms.room_id) GROUP BY rooms.room_id");
return $allRoom;
}
public function create ($name) {
$room = array (
'name' => $name,
);
try {
Db::add ('rooms', $room);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function delete ($roomId) {
Db::command ('DELETE FROM rooms WHERE room_id=?', array ($roomId));
}
}
?>

26
class/Route.php Normal file
View File

@ -0,0 +1,26 @@
<?php
class Route{
private $urls = [];
private $views = [];
function __construct() {
// code...
}
function add($url, $view = "", $conrol = "") {
$this->urls[] = '/'.trim($url, '/');
if (!empty($view)) {
$this->views[] = $view;
}
}
function submit(){
$urlGetParam = isset($_GET['url']) ? '/' . $_GET['url'] : '/';
foreach ($this->urls as $urlKey => $urlValue) {
if ($urlValue === $urlGetParam) {
$useView = $this->views[$urlKey];
new $useView();
}
}
}
}

41
class/SceneManager.php Normal file
View File

@ -0,0 +1,41 @@
<?php
class SceneManager{
public static $scenes;
public function create ($icon, $name, $doCode) {
$scene = array (
'icon' => $icon,
'name' => $name,
'do_something' => $doCode,
);
try {
Db::add ('scenes', $scene);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function getAllScenes () {
return Db::loadAll ("SELECT * FROM scenes");
}
public function getScene ($sceneId) {
return Db::loadOne("SELECT * FROM scenes WHERE scene_id = ?", array($sceneId));
}
public function execScene ($sceneId) {
$sceneData = SceneManager::getScene($sceneId);
$sceneDoJson = $sceneData['do_something'];
$sceneDoArray = json_decode($sceneDoJson);
foreach ($sceneDoArray as $deviceId => $deviceState) {
RecordManager::create($deviceId, 'on/off', $deviceState);
}
return true;
}
public function delete($sceneId){
Db::command ('DELETE FROM scenes WHERE scene_id=?', array ($sceneId));
}
}
?>

View File

@ -0,0 +1,55 @@
<?php
class SubDeviceManager
{
public static $devices;
public function getAllSubDevices($deviceId)
{
return Db::loadAll("SELECT * FROM subdevices WHERE device_id = ?", array($deviceId));
}
public function getSubDeviceMaster($subDeviceId)
{
return Db::loadOne("SELECT * FROM devices WHERE device_id = (SELECT device_id FROM subdevices WHERE subdevice_id = ?)", array($subDeviceId));
}
public function getSubDeviceByMaster($deviceId, $subDeviceType = null)
{
if ($subDeviceType == null) {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ?;", array($deviceId));
} else {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ? AND type = ?;", array($deviceId, $subDeviceType));
}
}
public function getSubDeviceByMasterAndType($deviceId, $subDeviceType = null)
{
if (!empty($subDeviceType)) {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ?;", array($deviceId));
} else {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ? AND type = ?;", array($deviceId, $subDeviceType));
}
}
public function getSubDevice($subDeviceId)
{
return Db::loadOne("SELECT * FROM subdevices WHERE subdevice_id = ?;", array($subDeviceId));
}
//check if dubdevice exist
public function create($deviceId, $type, $unit)
{
$record = array(
'device_id' => $deviceId,
'type' => $type,
'unit' => $unit,
);
try {
Db::add('subdevices', $record);
} catch (PDOException $error) {
echo $error->getMessage();
die();
}
}
}

34
class/Template.php Normal file
View File

@ -0,0 +1,34 @@
<?php
class Template extends Partial{
var $assignedValues = [];
var $partBuffer;
var $path;
var $debug;
function __construct($path = "", $debug = false) {
$this->debug = $debug;
if (!empty('templates/' . $path . '.phtml') && file_exists('templates/' . $path . '.phtml')) {
$this->path = $path;
} else {
echo '<pre>';
echo 'PHTML: Template File ' . $path . ' not found';
echo '</pre>';
die();
}
}
function prepare($searchS, $repleaceS) {
if (!empty($searchS)) {
$this->assignedValues[strtoupper($searchS)] = $repleaceS;
}
echo ($this->debug == true ? var_dump($this->assignedValues) : '');
}
function render() {
extract($this->assignedValues);
if (!empty('controls/' . $this->path . '.php') && file_exists('controls/' . $this->path . '.php')) {
require_once('controls/' . $this->path . '.php');
}
require_once('templates/' . $this->path . '.phtml');
}
}

180
class/UserManager.php Normal file
View File

@ -0,0 +1,180 @@
<?php
class UserManager
{
public function getUsers () {
try {
$allRoom = Db::loadAll ("SELECT * FROM users");
return $allRoom;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function getUser ($userName) {
try {
$user = Db::loadOne ("SELECT * FROM users WHERE username = ?", [$userName]);
return $user;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function login ($username, $password, $rememberMe) {
try {
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) {
if ($user['password'] == UserManager::getHashPassword($password)) {
if (isset($rememberMe) && $rememberMe == 'true') {
setcookie ("rememberMe", $this->setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), "/");
}
$_SESSION['user']['id'] = $user['user_id'];
$page = "./index.php";
if ($user["startPage"] == 1) {
$page = "./dashboard.php";
}
unset($_POST['login']);
return $page;
} else {
throw new PDOException("Heslo není správné!");
}
} else {
throw new PDOException("Uživatel s tím to jménem neexistuje!");
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public function isLogin () {
if (isset ($_SESSION['user']) && isset($_SESSION['user']['id'])) {
return true;
} else {
if (isset ($_COOKIE['rememberMe'])){
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($this->getDecryptedCookie($_COOKIE['rememberMe'])))) {
$_SESSION['user']['id'] = $user['user_id'];
return true;
}
}
}
return false;
}
public function logout () {
setcookie ("rememberMe","", time() - (30 * 24 * 60 * 60 * 1000), "/");
unset($_SESSION['user']);
session_destroy();
}
public function setEncryptedCookie($value){
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$method = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivlen);
$newvalue_raw = openssl_encrypt($value, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $newvalue_raw, $second_key, TRUE);
$newvalue = base64_encode ($iv.$hmac.$newvalue_raw);
return $newvalue;
}
public function getDecryptedCookie($value){
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$c = base64_decode($value);
$method = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($method);
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, 32);
$newValue_raw = substr($c, $ivlen+32);
$newValue = openssl_decrypt($newValue_raw, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $newValue_raw, $second_key, TRUE);
if (hash_equals ($hmac, $calcmac)) {
return $newValue;
}
return false;
}
public static function getUserData ($type) {
if (isset($_SESSION['user']['id'])) {
$user = Db::loadOne ('SELECT ' . $type . ' FROM users WHERE user_id=?', array ($_SESSION['user']['id']));
return $user[$type];
}
return "";
}
public function setUserData ($type, $value) {
if (isset ($_SESSION['user']['id'])) {
Db::command ('UPDATE users SET ' . $type . '=? WHERE user_id=?', array ($value, $_SESSION['user']['id']));
}
}
public function getHashPassword ($password) {
$salt = "s0mRIdlKvI";
$hashPassword = hash('sha512', ($password . $salt));
return $hashPassword;
}
public function ulozitObrazek ($file, $path = "", $name = "") {
if (!@is_array (getimagesize($file['tmp_name']))) {
throw new ChybaUzivatele("Formát obrázku ". $file['name'] ." není podporován!");
} else {
$extension = strtolower(strrchr($file['name'], '.'));
switch ($extension) {
case '.jpg':
case '.jpeg':
$img = @imagecreatefromjpeg($file['tmp_name']);
break;
case '.gif':
$img = @imagecreatefromgif($file['tmp_name']);
break;
case '.png':
$img2 = @imagecreatefrompng($file['tmp_name']);
break;
case '.ico':
$img3 = @$file['tmp_name'];
break;
default:
$img = false;
break;
}
if($name == ""){
$nazev = substr($file['name'], 0, strpos($file['name'], ".")) ."_". round(microtime(true) * 1000);
}else{
$nazev = $name;
}
if(!file_exists($path)){
mkdir($path, 0777, true);
}
if (@$img) {
if (!imagejpeg ($img, $path . $nazev .".jpg", 95)) {
throw new ChybaUzivatele ("Obrázek neuložen!");
}
imagedestroy ($img);
} else if (@$img2) {
if (!imagepng ($img2, $path . $nazev .".jpg")) {
throw new ChybaUzivatele ("Obrázek neuložen!");
}
imagedestroy ($img2);
} else if (@$img3) {
if (!copy($img3, $path . $nazev .'.ico')) {
throw new ChybaUzivatele ("Obrázek neuložen!");
}
}
return array('success' => true, 'url' => $path . $nazev .".jpg");
}
}
public function atHome($userId, $atHome){
try {
Db::edit ('users', ['at_home' => $atHome], 'WHERE user_id = ?', array($userId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
}
?>

38
class/Utilities.php Normal file
View File

@ -0,0 +1,38 @@
<?php
/**
*
*/
class Utilities
{
function cleanString($text) {
$utf8 = array(
'/[áàâãªä]/u' => 'a',
'/[ÁÀÂÃÄ]/u' => 'A',
'/[ÍÌÎÏ]/u' => 'I',
'/[íìîï]/u' => 'i',
'/[ěéèêë]/u' => 'e',
'/[ĚÉÈÊË]/u' => 'E',
'/[óòôõºö]/u' => 'o',
'/[ÓÒÔÕÖ]/u' => 'O',
'/[úùûü]/u' => 'u',
'/[ÚÙÛÜ]/u' => 'U',
'/Š/' => 'S',
'/š/' => 's',
'/Č/' => 'C',
'/č/' => 'c',
'/ř/' => 'r',
'/Ř/' => 'R',
'/Ý/' => 'Y',
'/ý/' => 'y',
'/ç/' => 'c',
'/Ç/' => 'C',
'/ñ/' => 'n',
'/Ñ/' => 'N',
'//' => '-', // UTF-8 hyphen to "normal" hyphen
'/[]/u' => ' ', // Literally a single quote
'/[“”«»„]/u' => ' ', // Double quote
'/ /' => ' ', // nonbreaking space (equiv. to 0x160)
);
return preg_replace(array_keys($utf8), array_values($utf8), $text);
}
}

59
config_sample.php Normal file
View File

@ -0,0 +1,59 @@
<?php
define('DBHOST','');
define('DBNAME','');
define('DBUSER','');
define('DBPASS','');
define('BASEDIR','');
//Leade record newer than XX days
define('RECORDTIMOUT', 90);
//HOME IP ADRESS
//Restrict acess to API
define('HOMEIP', '');
//Randomizet Security Keys
define('FIRSTKEY','');
define('SECONDKEY','');
//show debug codes
define('DEBUGMOD',0);
/** Unit Definition **/
const UNITS = [
''=> '',
'temp' => "°C",
'humi' => "%",
'light' => "",
'on/off' => ""
];
//Graph Setting
const RANGES = [
'' => [
'min' => 0,
'max' => 100,
'scale' =>20,
],
'temp' => [
'min' => 10,
'max' => 45,
'scale' =>20,
],
'humi' => [
'min' => 0,
'max' => 100,
'scale' =>20,
],
'light' => [
'min' => 0,
'max' => 1,
'scale' =>1,
],
'on/off' => [
'min' => 0,
'max' => 1,
'scale' =>1,
],
];
?>

14
controls/automation.php Normal file
View File

@ -0,0 +1,14 @@
<?php
if (isset($_POST) && !empty($_POST)){
if (isset($_POST['modalFinal']) && $_POST['modalFinal'] == "Next") {
$ifCode = json_encode($_POST['device'], JSON_PRETTY_PRINT);
$doCode = $_POST['atSelector'];
$onDays = $_POST['atDays'];
AutomationManager::create('name', $onDays, $doCode, $ifCode);
}
header('Location: /vasek/home/' . strtolower(basename(__FILE__, '.php')), TRUE);
die();
}
?>

14
controls/dashboard.php Normal file
View File

@ -0,0 +1,14 @@
<?php
if (isset($_POST) && !empty($_POST)){
if (isset($_POST['modalFinal']) && $_POST['modalFinal'] == "Next") {
$subDeviceIds = $_POST['devices'];
foreach ($subDeviceIds as $subDeviceId) {
DashboardManager::Add($subDeviceId);
}
}
header('Location: /vasek/home/' . strtolower(basename(__FILE__, '.php')), TRUE);
die();
}
?>

67
controls/home.php Normal file
View File

@ -0,0 +1,67 @@
<?php
if (isset($_POST) && !empty($_POST)){
if (isset($_POST['saveDevice']) && $_POST['saveDevice'] != "") {
$deviceId = $_POST['deviceId'];
$deviceName = $_POST['deviceName'];
$deviceIcon = $_POST['deviceIcon'];
$sleepTime = $_POST['sleepTime'];
//TODO: if device isnt on off
$permissionsInJson = json_encode([
(int) $_POST['permissionOwner'],
(int) $_POST['permissionOther'],
]);
$deviceOwnerUserId = $_POST['deviceOwnerUserId'];
try {
$args = array(
'owner' => $deviceOwnerUserId,
'name' => $deviceName,
'icon' => $deviceIcon,
'permission' => $permissionsInJson,
'sleep_time' => $sleepTime
);
DeviceManager::edit($deviceId, $args);
} catch (\Exception $e) {
echo $e->message();
}
//Debug
if (DEBUGMOD == 1) {
echo '<pre>';
echo $permissionsInJson;
echo $deviceId;
var_dump(json_decode ($permissionsInJson));
echo '</pre>';
echo '<a href="/vasek/home/">CONTINUE</a>';
die();
}
} else if (isset($_POST['approveDevice'])) {
$deviceId = $_POST['deviceId'];
$args = array(
'approved' => 1,
);
DeviceManager::edit($deviceId, $args);
} else if (isset($_POST['disableDevice'])) {
$deviceId = $_POST['deviceId'];
$args = array(
'approved' => 2,
);
DeviceManager::edit($deviceId, $args);
}
//Debug
if (DEBUGMOD == 1) {
echo '<pre>';
var_dump($POST);
echo '</pre>';
echo '<a href="/vasek/home/">CONTINUE</a>';
die();
}
header('Location: /vasek/home/', TRUE);
die();
}
?>

18
controls/scene.php Normal file
View File

@ -0,0 +1,18 @@
<?php
if (isset($_POST) && !empty($_POST)){
SceneManager::create($_POST['sceneIcon'], $_POST['sceneName'], json_encode($_POST['devices']));
//Debug
if (DEBUGMOD == 1) {
echo '<pre>';
var_dump($_POST);
echo '</pre>';
echo '<a href="/vasek/home/' . strtolower(basename(__FILE__, '.php')).'">CONTINUE</a>';
die();
}
header('Location: /vasek/home/' . strtolower(basename(__FILE__, '.php')), TRUE);
die();
}

75
index.php Normal file
View File

@ -0,0 +1,75 @@
<?php
//Config
include_once './config.php';
//setup
ini_set ('session.cookie_httponly', 1);
session_start ();
mb_internal_encoding ("UTF-8");
//Autoloader
foreach (["class", "views"] as $dir) {
$files = scandir('./'.$dir.'/');
$files = array_diff($files, array('.', '..'));
foreach($files as $file) {
include_once './'.$dir.'/'. $file;
}
}
/** Language **/
$langTag = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if (DEBUGMOD == 1) {
/*echo '<div class="col-md-9 main-body">';
echo '<pre>';
echo 'Language SLUG: ' . $langTag;
echo '</pre>';
echo '<pre>';
print_r(get_defined_constants());
echo '</pre>';
echo '<pre>';
print_r(get_defined_vars());
echo '</pre>';
echo '</dev>';*/
}
require_once './lang/' . $langTag . '.php';
//DB Conector
Db::connect (DBHOST, DBUSER, DBPASS, DBNAME);
//TODO: Přesunout do Login Pohledu
$userManager = new UserManager();
if (isset($_POST['username']) && isset($_POST['password']) ) {
$userManager->login($_POST['username'], $_POST['password'], $_POST['remember']);
}
/*
$form = new Form('name','1','POST','');
$form->addInput(InputTypes::TEXT,'nadpis','','Label','');
$form->addInput(InputTypes::BUTTON,'nadpis','','Label','test');
$form->addInput(InputTypes::TEXT,'nadpis','','Label','');
$form->addInput(InputTypes::TEXT,'nadpis','','Label','', false);
$form->addInput(InputTypes::TEXT,'nadpis','','Label','');
$form->addInput(InputTypes::CHECK,'nadpis','','Label','');
$form->addInput(InputTypes::TEXT,'nadpis','','Label','');
$arg = array(
'test_v' => 'test',
'test_v2' => 'test',
);
$form->addSelect('1', '1', '1', $arg, false);
$form->render();
die();
*/
$route = new Route();
$route->add('/', 'Home');
$route->add('/login', 'Login');
$route->add('/logout', 'Logout');
$route->add('/automation', 'Automation');
$route->add('/dashboard', 'Dashboard');
$route->add('/setting', 'Setting');
$route->add('/scene', 'Scene');
$route->add('/ajax', 'Ajax');
$route->add('/rooms', 'Rooms');
$route->submit();

71
lang/cs.php Normal file
View File

@ -0,0 +1,71 @@
<?php
$lang = [
//Menu
'm_home' => 'Domů',
'm_dashboard' => 'Nástěnka',
'm_settings' => 'Nastavení',
'm_automatization' => 'Automatizace',
'm_scenes' => 'Scény',
//Buttons
'b_year' => 'Rok',
'b_month' => 'Měsíc',
'b_week' => 'Týden',
'b_day' => 'Den',
'b_hour' => 'Hodina',
'b_next' => 'Další',
'b_create' => 'Vytvořit',
'b_edit' => 'Upravit',
'b_remove' => 'Smazat',
'b_approve' => 'Povolit',
'b_disable' => 'Zakázat',
'b_save' => 'Uložit',
//labels
'l_choseDevice' => 'Zvolte zařízení:',
'l_inHome' => 'Při příchodu',
'l_outHome' => 'Pri odchodu',
'l_sunSet' => 'Východ Slunce',
'l_sunRice' => 'Západ Slunce',
'l_time' => 'Čase',
'l_deviceValue' => 'Hodnotě zařízení',
'l_runAt' => 'Spustit při',
'l_resetAt' => 'Restartovat při',
'l_affectedDevices' => 'Ovlivněná zařízení',
'l_atDays' => 'Ve dny',
'l_read' => 'Číst',
'l_use' => 'Použít',
'l_edit' => 'Upravit',
'l_owner' => 'Vlastník',
'l_member' => 'Člen Domácnosti',
'l_permission' => 'Oprávmnění',
'l_inMinutes' => 'v minutách',
'l_sleepTime' => 'Doba spánku zařízení',
//Title
't_createScene' => 'Vytvořit scénu',
't_editScene' => 'Upravit scénu',
't_createAutomation' => 'Vytvořit Automatizaci',
't_editDevice' => 'Upravit Zařízení',
//constants
'temp' => 'Teplota',
'humi' => 'Vlhkost',
'light' => 'Světlo',
'battery' => 'Baterie',
'on/off' => 'Vypínač',
//words
'w_title' => 'Název',
'w_icon' => 'Ikona',
'w_no' => 'žádná',
'w_noOne' => 'Nikdo',
'w_room' => 'Místnost',
'w_moduls' => 'Moduly',
//example
'' => '',
];

71
lang/en.php Normal file
View File

@ -0,0 +1,71 @@
<?php
$lang = [
//Menu
'm_home' => 'Home',
'm_dashboard' => 'Dashboard',
'm_settings' => 'Setting',
'm_automatization' => 'Automatization',
'm_scenes' => 'Scenes',
//Buttons
'b_year' => 'Year',
'b_month' => 'Month',
'b_week' => 'Week',
'b_day' => 'Day',
'b_hour' => 'Hour',
'b_next' => 'Next',
'b_create' => 'Create',
'b_edit' => 'Edit',
'b_remove' => 'Remove',
'b_approve' => 'Approve',
'b_disable' => 'Disable',
'b_save' => 'Save',
//labels
'l_choseDevice' => 'Chose device:',
'l_inHome' => 'When entering',
'l_outHome' => 'When exiting',
'l_sunSet' => 'Sun Rise',
'l_sunRice' => 'Sun Set',
'l_time' => 'Time',
'l_deviceValue' => 'Device Valalue',
'l_runAt' => 'Run at',
'l_resetAt' => 'Reset at',
'l_affectedDevices' => 'Affected devices',
'l_atDays' => 'At days',
'l_read' => 'Read',
'l_use' => 'Use',
'l_edit' => 'Edit',
'l_owner' => 'Owner',
'l_member' => 'Home Member',
'l_permission' => 'Permission',
'l_inMinutes' => 'in minutes',
'l_sleepTime' => 'Device sleep Time',
//Title
't_createScene' => 'Create Scene',
't_editScene' => 'Edit scénu',
't_createAutomation' => 'Create Automation',
't_editDevice' => 'Edit Device',
//constants
'humi' => 'Humidity',
'temp' => 'Temperature',
'light' => 'Light',
'battery' => 'Batteri',
'on/off' => 'Switch',
//words
'w_title' => 'Name',
'w_icon' => 'Icon',
'w_no' => 'no',
'w_noOne' => 'noone',
'w_room' => 'Room',
'w_moduls' => 'Moduls',
//example
'' => '',
];

22
manifest.json Normal file
View File

@ -0,0 +1,22 @@
{
"name": "Home",
"short_name": "Home",
"description": "Smart Home interface in PWA",
"lang": "cs-CZ",
"start_url": "/vasek/home/",
"scope": "/vasek/home/",
"display": "fullscreen",
"orientation": "portrait",
"theme_color": "#182239",
"icons": [
{
"src": "/vasek/home/templates/images/icon-192x192.png",
"sizes": "192x192"
},
{
"src": "/vasek/home/templates/images/icon-512x512.png",
"sizes": "512x512"
}
],
"background_color": "#182239"
}

78
serviceWorker.js Normal file
View File

@ -0,0 +1,78 @@
/**
* Cache version, change name to force reload
*/
var CACHE_VERSION = 'v1';
/**
* Stuff to put in the cache at install
*/
var CACHE_FILES = [
'templates/automatio.phtml',
'templates/dashboard.phtml',
'templates/home.phtml',
'templates/login.phtml',
'templates/scene.phtml',
'templates/setting.phtml',
'views/Automation.phtml',
'views/Dashboard.phtml',
'views/Home.phtml',
'views/Login.phtml',
'views/Scene.phtml',
'views/Setting.phtml',
'assets/logo.svg'
];
/**
* Service worker 'install' event.
* If all the files are successfully cached, then the service worker will be installed.
* If any of the files fail to download, then the install step will fail.
*/
this.addEventListener('install', function(event) {
console.log('Install');
});
/**
* After a service worker is installed and the user navigates to a different page or refreshes,
* the service worker will begin to receive fetch events.
*
* Network-first approach: if online, request is fetched from network and not from cache
*/
self.addEventListener('push', function(event) {
console.log('Received a push message', event);
var title = 'Notification';
var body = 'There is newly updated content available on the site. Click to see more.';
var icon = 'https://raw.githubusercontent.com/deanhume/typography/gh-pages/icons/typography.png';
var tag = 'simple-push-demo-notification-tag';
event.waitUntil(
self.registration.showNotification(title, {
body: body,
icon: icon,
tag: tag
})
);
});
self.addEventListener('sync', function(event) {
console.info('Event: Sync');
});
self.addEventListener('fetch', function (event) {
});
self.addEventListener("online", function (event) {
});
self.addEventListener("offline", function (event) {
});
self.addEventListener('notificationclick', function(e) {
});

View File

@ -0,0 +1,69 @@
.button{
background-color: $secondary-color;
border: 0;
border-radius: $control-border-radius;
color: $base-font-color;
padding: $control-padding-y $control-padding-x;
transition: background-color .15s;
height: 2.5rem;
display: inline-block;
line-height: 1.5;
font-size: 1rem;
font-weight: 500;
cursor: pointer;
text-decoration: none;
&:hover{
color: $base-font-color;
background-color: $secondary-color-dark;
}
&:active{
background-color: $secondary-color-dark;
}
&:focus{
box-shadow: 0 0 3px $control-focus-color;
}
}
.button.is-small{
padding: $control-padding-y $control-padding-x/1.5;
height: 2rem;
font-size: .875rem;
}
.button.is-large{
height: 3rem;
font-size: 1.25rem;
}
.buttons .button{
margin-right: .25rem;
margin-bottom: .25rem;
}
.button.is-primary{
background-color: $primary-color;
color: white;
&:hover{
color: white;
background-color: $primary-color-dark;
}
&:active{
background-color: $primary-color-dark;
}
}
.button.is-danger{
background-color: map-get($red-colors , '100');
color: map-get($red-colors , '500');
&:hover{
background-color: map-get($red-colors , '200');
color: map-get($red-colors , '600');
}
&:active{
background-color: map-get($red-colors , '200');
color: map-get($red-colors , '600');
}
}

185
templates/automation.phtml Normal file
View File

@ -0,0 +1,185 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="row no-gutters main">
<div class="col-md-3 d-sm-none"></div>
<div class="col-md-3 nav-container">
<div class="nav">
<div class="nav-item">
<a href="./"><i class="fa fa-home"></i><span><?php echo $LANG['m_home']?></span></a>
</div>
<div class="nav-item">
<a href="dashboard"><i class="fa fa-tachometer" aria-hidden="true"></i><span><?php echo $LANG['m_dashboard']?></span></a>
</div>
<div class="nav-item">
<a href="setting"><i class="fa fa-wrench" aria-hidden="true"></i></i><span><?php echo $LANG['m_settings']?></span></a>
</div>
<div class="nav-item is-active">
<a href="automation"><i class="fa fa-calendar-o" aria-hidden="true"></i><span><?php echo $LANG['m_automatization']?></span></a>
</div>
<div class="nav-item">
<a href="scene"><i class="fa fa-terminal" aria-hidden="true"></i><span><?php echo $LANG['m_scenes']?></span></a>
</div>
</div>
</div>
<div class="col-md-9 main-body">
<a href="#modal" class="button is-primary m-1">Create Automation</a>
<a id="remove" class="button m-1"><i class="fa fa-trash" aria-hidden="true"></i></a>
<div class="row no-gutters">
<?php foreach ($AUTOMATIONS as $automationId => $automationData) { ?>
<div class="col-12 col-md-6 col-xl-4 square-wrap">
<div class="rectangle-2">
<div class="square-content double <?php echo ($automationData['active'] == 0 ? 'paused' : ''); ?>" onClick="ajaxPost('./ajax.php',{automation_id:'<?php echo $automationId; ?>'}, this, true);">
<div class="delete">delete</div>
<div class="row">
<div class="col-1">
<h5 class="fa">
<?php
switch ($automationData['ifSomething']) {
case 'sunSet':
echo'&#xf186';
break;
case 'sunRise':
echo'&#xf185 ';
break;
default:
echo'&#xf017';
break;
}
?>
</h5>
</div>
<div class="col">
<h5 class="text-right break-all">
<?php
if (!in_array($automationData['ifSomething'], ["sunRise", "sunSet"])) {
echo $automationData['ifSomething'];
}
?>
</h5>
</div>
</div>
<div class="row">
<div class="col">
<?php echo $automationData['onDays'];?>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
</div>
</div>
</div>
<div class="modal-container modal-container-hiden" id="modal">
<div class="modal">
<a href=""><i class="fa fa-times close"></i></a>
<h4 class="mb-4">Modal bitch</h4>
<?php if (!isset($_POST['modalNext'])) { ?>
<form method="post">
<div class="field">
<div class="label">Run at:</div>
<div class="field">
<select class="input" name="atSelector" id="valueSelector" required>
<option value="sunSet">Západu Slunce</option>
<option value="sunRise">Východu Slunce</option>
<option value="time">Čase</option>
<option value="atDeviceValue">Hodnbotě Zařízení</option>
</select>
<input class="input" type="time" name="atTime" id="atTime" disabled/>
<select class="input" name="atDeviceValue" id="atDeviceValue" disabled>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="num" name="atDeviceValueInt" id="atDeviceValueInt" required disabled/>
</div>
<div class="label">Select Affected Devices:</div>
<div class="field">
<select class="input" name="devices[]" multiple>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){
if ($subDeviceValue['type'] != 'on/off') continue;?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?></option>
<?php } ?>
</select>
</div>
<div class="label">ve dny:</div>
<div class="field">
<input type="checkbox" name="day[]" value="mon"/> Pondělí
</div>
<div class="field">
<input type="checkbox" name="day[]" value="tue"/> Úterý
</div>
<div class="field">
<input type="checkbox" name="day[]" value="wed"/> Středa
</div>
<div class="field">
<input type="checkbox" name="day[]" value="thu"/> Čtvrtek
</div>
<div class="field">
<input type="checkbox" name="day[]" value="fri"/> Pátek
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sat"/> Sobota
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sun"/> Neděle
</div>
</div>
<input type="submit" class="button" name="modalNext" value="Next"/>
</form>
<?php } else if (isset($_POST['modalNext'])) { ?>
<form method="post" action="controls/automation.php">
<div class="field">
<input type="hidden" name="atSelector" value="<?php if (isset($_POST['atTime'])) {
echo $_POST['atTime'];
} else if (isset($_POST['atDeviceValue'])) {
$subDeviceId = $_POST['atDeviceValue'];
$subDeviceValue = $_POST['atDeviceValueInt'];
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
$subDeviceMaster = SubDeviceManager::getSubDeviceMaster($subDeviceId,$subDevice['type']);
$json = json_encode([
'deviceID' => $subDeviceMaster['device_id'],
'type'=> htmlspecialchars($subDevice['type']),
'value'=> $subDeviceValue,
]);
echo htmlspecialchars($json);
}
else {
echo $_POST['atSelector'];
} ?>" required/>
<input type="hidden" name="atDays" value="<?php echo htmlspecialchars(($_POST['day'] != '' ? json_encode($_POST['day']) : '')); ?>" required/>
<?php foreach ($_POST['devices'] as $value) { ?>
<?php $deviceData = DeviceManager::getDeviceById($value); ?>
<div class="label"><?php echo $deviceData['name'];?></div>
<select class="input" name="device[<?php echo $deviceData['device_id'];?>]">
<option value="1">ON</option>
<option value="0">OFF</option>
</select>
<?php } ?>
</div>
<input type="submit" class="button" name="modalFinal" value="Next"/>
</form>
<?php } ?>
</div>
</div>
<?php
$partial = new Partial('footer');
$partial->render();
?>
</body>
</html>

6
templates/css/font-awesome.min.css vendored Normal file

File diff suppressed because one or more lines are too long

19
templates/css/loading.css Normal file
View File

@ -0,0 +1,19 @@
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid rgb(101, 30, 122);;
width: 100%;
height: 100%;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

2956
templates/css/main.css Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

28
templates/css/modal.css Normal file
View File

@ -0,0 +1,28 @@
.modal-container-hiden {
display: none !important;
}
#modal:target {
display: flex;
}
#modal2:target {
display: flex;
}
#modal3:target {
display: flex;
}
#modal4:target {
display: flex;
}
@media (max-width: 767px){
.modal>.overflow {
height: calc(100% - 44px);
overflow-y: scroll;
overflow-x: hidden;
}
}

17
templates/css/pre.css Normal file
View File

@ -0,0 +1,17 @@
pre{
border-radius: 3px;
border: 0px solid transparent;
color: #d4def7;
padding: 0.5em 0.8em;
line-height: 1.5;
background: #121a2b;
width: 100%;
display: block;
}
.rectangle-content{
width: 100%;
background: linear-gradient(135deg, rgba(116, 34, 189, 0.5), rgba(185, 19, 121, 0.5));
border-radius: 8px;
padding: .25rem !important;
}

75
templates/dashboard.phtml Normal file
View File

@ -0,0 +1,75 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="row no-gutters main">
<div class="col-md-3 d-sm-none"></div>
<div class="col-md-3 nav-container">
<div class="nav">
<div class="nav-item">
<a href="./"><i class="fa fa-home"></i><span><?php echo $LANG['m_home']?></span></a>
</div>
<div class="nav-item is-active">
<a href="dashboard"><i class="fa fa-tachometer" aria-hidden="true"></i><span><?php echo $LANG['m_dashboard']?></span></a>
</div>
<div class="nav-item">
<a href="setting"><i class="fa fa-wrench" aria-hidden="true"></i></i><span><?php echo $LANG['m_settings']?></span></a>
</div>
<div class="nav-item">
<a href="automation"><i class="fa fa-calendar-o" aria-hidden="true"></i><span><?php echo $LANG['m_automatization']?></span></a>
</div>
<div class="nav-item">
<a href="scene"><i class="fa fa-terminal" aria-hidden="true"></i><span><?php echo $LANG['m_scenes']?></span></a>
</div>
</div>
</div>
<div class="col-md-9 main-body">
<a href="#modal" class="button is-primary m-1">Add Device</a>
<a id="remove" class="button m-1"><i class="fa fa-trash" aria-hidden="true"></i></a>
<div class="row no-gutters">
<?php foreach ($DASHBOARD as $dashboardItemId => $dashboardItemData) {
$partialDeviceButton = new Partial('dashboardButton');
$partialDeviceButton->prepare('dashboardItemData', $dashboardItemData);
$partialDeviceButton->render();
} ?>
</div>
</div>
</div>
<div class="modal-container modal-container-hiden" id="modal">
<div class="modal">
<a href=""><i class="fa fa-times close"></i></a>
<h4 class="mb-4">Modal bitch</h4>
<form method="post" action="controls/dashboard.php">
<div class="field px-2">
<div class="label">Zvolte zařízení:</div>
<select class="input" name="devices[]" multiple>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name'] . '[' . $subDeviceValue['type'] . ']'; ?></option>
<?php } ?>
</select>
</div>
<input type="submit" class="button" name="modalFinal" value="Next"/>
</form>
</div>
</div>
<?php
if (isset($_POST['deviceId'])) {
$partial = new Partial('deviceEdit');
$partial->prepare('DEVICEDATA', $DEVICEDATA);
$partial->render();
}
$partial = new Partial('footer');
$partial->render();
?>
</body>
</html>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

100
templates/home.phtml Normal file
View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="row no-gutters main">
<div class="col-md-3 d-sm-none"></div>
<div class="col-md-3 nav-container">
<div class="nav">
<div class="nav-item is-active">
<a href="./"><i class="fa fa-home"></i><span><?php echo $LANG['m_home']?></span></a>
</div>
<div class="nav-item">
<a href="dashboard"><i class="fa fa-tachometer" aria-hidden="true"></i><span><?php echo $LANG['m_dashboard']?></span></a>
</div>
<div class="nav-item">
<a href="setting"><i class="fa fa-wrench" aria-hidden="true"></i></i><span><?php echo $LANG['m_settings']?></span></a>
</div>
<div class="nav-item">
<a href="automation"><i class="fa fa-calendar-o" aria-hidden="true"></i><span><?php echo $LANG['m_automatization']?></span></a>
</div>
<div class="nav-item">
<a href="scene"><i class="fa fa-terminal" aria-hidden="true"></i><span><?php echo $LANG['m_scenes']?></span></a>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<div class="col-md-9 main-body">
<div class="label m-1">
doma jsou:
<?php
foreach ($USERS as $user) {
if (trim($user['at_home']) === "entered") {
echo $user['username'];
}
if (trim($user['at_home']) === "connected to") {
echo $user['username'];
}
} ?>
</div>
<select class="select m-1" name="room">
<option value="all">All</option>
<?php foreach ($ROOMS as $key => $room) {
if ($room['device_count'] > 0) { ?>
<option value="<?php echo $room['room_id']?>"><?php echo $room['name'] ?></option>
<?php } ?>
<?php } ?>
</select>
<div class="row no-gutters">
<?php foreach ($DATA as $roomId => $room) { ?>
<?php foreach ($room['devices'] as $deviceId => $device) { ?>
<?php foreach ($device['subDevices'] as $subDeviceKey => $subDevice) {
//BUTTON
$partialDeviceButton = new Partial('deviceButton');
$partialDeviceButton->prepare('roomid',$roomId);
$partialDeviceButton->prepare('subdeviceid',$subDeviceKey);
$partialDeviceButton->prepare('subdevice',$subDevice);
$partialDeviceButton->prepare('deviceid',$deviceId);
$partialDeviceButton->prepare('device',$device);
$partialDeviceButton->render();
//DETAIL
$partialDetail = new Partial('deviceDetail');
$partialDetail->prepare('subdeviceid',$subDeviceKey);
$partialDetail->prepare('subdevice',$subDevice);
$partialDetail->prepare('device',$device);
$partialDetail->prepare('lang',$LANG);
$partialDetail->render();
//SETTING
$partialEdit = new Partial('deviceEdit');
$partialEdit->prepare('deviceid',$deviceId);
$partialEdit->prepare('subdevice',$subDevice);
$partialEdit->prepare('device',$device);
$partialEdit->prepare('users',$USERS);
$partialEdit->prepare('rooms',$ROOMS);
$partialEdit->prepare('lang',$LANG);
$partialEdit->render();
}
}
} ?>
</div>
</div>
</div>
<?php
$partial = new Partial('footer');
$partial->render();
?>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

2
templates/js/jquery.js vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,182 @@
/*
jQuery Redirect v1.1.3
Copyright (c) 2013-2018 Miguel Galante
Copyright (c) 2011-2013 Nemanja Avramovic, www.avramovic.info
Licensed under CC BY-SA 4.0 License: http://creativecommons.org/licenses/by-sa/4.0/
This means everyone is allowed to:
Share - copy and redistribute the material in any medium or format
Adapt - remix, transform, and build upon the material for any purpose, even commercially.
Under following conditions:
Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use.
ShareAlike - If you remix, transform, or build upon the material, you must distribute your contributions under the same license as the original.
*/
;(function ($) {
'use strict';
//Defaults configuration
var defaults = {
url: null,
values: null,
method: "POST",
target: null,
traditional: false,
redirectTop: false
};
/**
* jQuery Redirect
* @param {string} url - Url of the redirection
* @param {Object} values - (optional) An object with the data to send. If not present will look for values as QueryString in the target url.
* @param {string} method - (optional) The HTTP verb can be GET or POST (defaults to POST)
* @param {string} target - (optional) The target of the form. "_blank" will open the url in a new window.
* @param {boolean} traditional - (optional) This provides the same function as jquery's ajax function. The brackets are omitted on the field name if its an array. This allows arrays to work with MVC.net among others.
* @param {boolean} redirectTop - (optional) If its called from a iframe, force to navigate the top window.
*//**
* jQuery Redirect
* @param {string} opts - Options object
* @param {string} opts.url - Url of the redirection
* @param {Object} opts.values - (optional) An object with the data to send. If not present will look for values as QueryString in the target url.
* @param {string} opts.method - (optional) The HTTP verb can be GET or POST (defaults to POST)
* @param {string} opts.target - (optional) The target of the form. "_blank" will open the url in a new window.
* @param {boolean} opts.traditional - (optional) This provides the same function as jquery's ajax function. The brackets are omitted on the field name if its an array. This allows arrays to work with MVC.net among others.
* @param {boolean} opts.redirectTop - (optional) If its called from a iframe, force to navigate the top window.
*/
$.redirect = function (url, values, method, target, traditional, redirectTop) {
var opts = url;
if (typeof url !== "object") {
var opts = {
url: url,
values: values,
method: method,
target: target,
traditional: traditional,
redirectTop: redirectTop
};
}
var config = $.extend({}, defaults, opts);
var generatedForm = $.redirect.getForm(config.url, config.values, config.method, config.target, config.traditional);
$('body', config.redirectTop ? window.top.document : undefined).append(generatedForm.form);
generatedForm.submit();
generatedForm.form.remove();
};
$.redirect.getForm = function (url, values, method, target, traditional) {
method = (method && ["GET", "POST", "PUT", "DELETE"].indexOf(method.toUpperCase()) !== -1) ? method.toUpperCase() : 'POST';
url = url.split("#");
var hash = url[1] ? ("#" + url[1]) : "";
url = url[0];
if (!values) {
var obj = $.parseUrl(url);
url = obj.url;
values = obj.params;
}
values = removeNulls(values);
var form = $('<form>')
.attr("method", method)
.attr("action", url + hash);
if (target) {
form.attr("target", target);
}
var submit = form[0].submit;
iterateValues(values, [], form, null, traditional);
return { form: form, submit: function () { submit.call(form[0]); } };
}
//Utility Functions
/**
* Url and QueryString Parser.
* @param {string} url - a Url to parse.
* @returns {object} an object with the parsed url with the following structure {url: URL, params:{ KEY: VALUE }}
*/
$.parseUrl = function (url) {
if (url.indexOf('?') === -1) {
return {
url: url,
params: {}
};
}
var parts = url.split('?'),
query_string = parts[1],
elems = query_string.split('&');
url = parts[0];
var i, pair, obj = {};
for (i = 0; i < elems.length; i += 1) {
pair = elems[i].split('=');
obj[pair[0]] = pair[1];
}
return {
url: url,
params: obj
};
};
//Private Functions
var getInput = function (name, value, parent, array, traditional) {
var parentString;
if (parent.length > 0) {
parentString = parent[0];
var i;
for (i = 1; i < parent.length; i += 1) {
parentString += "[" + parent[i] + "]";
}
if (array) {
if (traditional)
name = parentString;
else
name = parentString + "[" + name + "]";
} else {
name = parentString + "[" + name + "]";
}
}
return $("<input>").attr("type", "hidden")
.attr("name", name)
.attr("value", value);
};
var iterateValues = function (values, parent, form, isArray, traditional) {
var i, iterateParent = [];
Object.keys(values).forEach(function (i) {
if (typeof values[i] === "object") {
iterateParent = parent.slice();
iterateParent.push(i);
iterateValues(values[i], iterateParent, form, Array.isArray(values[i]), traditional);
} else {
form.append(getInput(i, values[i], parent, isArray, traditional));
}
});
};
var removeNulls = function (values) {
var propNames = Object.getOwnPropertyNames(values);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (values[propName] === null || values[propName] === undefined) {
delete values[propName];
} else if (typeof values[propName] === 'object') {
values[propName] = removeNulls(values[propName]);
} else if (values[propName].length < 1) {
delete values[propName];
}
}
return values;
};
}(window.jQuery || window.Zepto || window.jqlite));

54
templates/js/post.js Normal file
View File

@ -0,0 +1,54 @@
function ajaxPost(path, params, self, reload = false) {
navigator.vibrate([200]);
$.ajax({
url: path,
type: 'POST',
data: params,
success: function(msg){
if (msg != '' && msg != 1){
$(self).find('.content').addClass( "loader" );
$(self).find('.row').hide();
waitForExecution(params, self, msg);
} else {
}
console.log(msg);
if (reload){
location.reload();
}
},
error: function (request, status, error) {
console.log('0');
}
});
return false;
}
function waitForExecution(params, elements, msg_state){
console.log('Waiting FOR Executed');
var interval = setInterval(
function(){
$.ajax({
url: 'ajax',
type: 'POST',
data: {
lastRecord:'',
subDevice_id : params['subDevice_id']
},
success: function(msg){
if (msg == 1){
$(elements).find('.text-right').text(msg_state);
$(elements).find('.content').removeClass( "loader" );
$(elements).find('.row').show();
console.log('Executed');
clearInterval(interval);
}
console.log('Waiting FOR Executed');
console.log(msg);
},
error: function (request, status, error) {
console.log('0');
}
});
}, 1000);
}

226
templates/js/script.js Normal file
View File

@ -0,0 +1,226 @@
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('serviceWorker.js')
.then(registration => {
console.log('Service Worker is registered', registration);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
$('#valueSelector').change(function() {
console.log($(this).val());
if( $(this).val() == 'time') {
$('#atTime').prop( "disabled", false );
} else if( $(this).val() == 'atDeviceValue') {
$('#atDeviceValue').prop( "disabled", false );
$('#atDeviceValueInt').prop( "disabled", false );
} else {
$('#atDeviceValue').prop( "disabled", true );
}
});
var pressTimer;
var touch = 0;
var touchSubId = "";
$("div.square-content").on('touchend', function (e){
clearTimeout(pressTimer);
});
$("div.square-content").on('touchstart', function (eTarget) {
var id = $(this).attr('id').replace('device-', '');
var subId = $(this).attr('data-sub-device-id');
touch++;
if(touch == 2 && touchSubId == subId){
console.log("Detail");
$("#modal-detail-"+subId).removeClass('modal-container-hiden').show();
ajaxChart(subId);
touch = 0;
touchSubId = "";
return;
}
touchSubId = subId;
pressTimer = window.setTimeout(function (e) {
console.log("Setting");
$("#modal-setting-"+id).removeClass('modal-container-hiden').show();
}, 500);
});
$("div.square-content").mousedown(function(e) {
if (event.which == 3) {
var windowLoc = $(location).attr('pathname');
windowLoc = windowLoc.substring(windowLoc.lastIndexOf("/"));
console.log(windowLoc);
var id = null;
if (windowLoc == "/") {
id = $(this).attr('id').replace('device-', '');
} else if (windowLoc == "/scene") {
id = $(this).attr('id').replace('scene-', '');
}
$("#modal-setting-"+id).removeClass('modal-container-hiden').show();
console.log("Setting");
console.log("modal" + id);
}
});
$(".close").on('click', function (e) {
var a = $(this).parent().parent();
a.hide();
});
$(this).bind("contextmenu", function(e) {
e.preventDefault();
});
$("div.square-content").on('dblclick', function (eTarget) {
windowLoc = windowLoc.substring(windowLoc.lastIndexOf("/"));
if (windowLoc == "/") {
console.log("Detail");
var subId = $(this).attr('data-sub-device-id');
ajaxChart(subId);
$("#modal-detail-"+subId).removeClass('modal-container-hiden').show();
}
});
$("input#sleepTime").change(function() {
console.log("Input text changed!");
});
var element = $('div.delete');
element.hide();
$("a#remove").on('click', function (e) {
console.log("Show/Hide Button");
var element = $('div.delete');
element.toggle();
});
function ajaxChart(id, period = 'day', group = 'hour'){
$.ajax({
url: 'ajax',
type: 'POST',
dataType: 'json',
data: {
"subDevice": id,
"action": 'chart',
"period": period,
"group": group
},
success: function(data){
console.log('ID: ',id, 'DATA: ', data);
var ctx = document.getElementById('canvas-'+id).getContext('2d');
var myChart = new Chart(ctx, data);
},
error: function (request, status, error) {
console.log("ERROR ajaxChart():", request, error);
}
});
}
//select room on load
var windowLoc = $(location).attr('pathname');
windowLoc = windowLoc.substring(windowLoc.lastIndexOf("/"));
console.log();
if (windowLoc == "/") {
var selectRoomId = localStorage.getItem("selectedRoomId");
console.log('Saved Selected Room ID '+ selectRoomId);
$('[name="room"]').val(selectRoomId);
$('.device-button').each(function(){
if (selectRoomId != 'all'){
if($(this).data('room-id') != selectRoomId){
$(this).hide();
} else {
$(this).show();
}
}
});
}
//Room selector
$( '[name="room"]' ).change(function (e) {
console.log('Selected Room ID ' + this.value)
var roomId = this.value;
localStorage.setItem("selectedRoomId", roomId);
$('.device-button').show();
if (roomId != 'all'){
$('.device-button').each(function(){
if($(this).data('room-id') != roomId){
$(this).hide();
}
});
}
});
var autoUpdate = setInterval(function(){
$.ajax({
url: 'ajax',
type: 'POST',
dataType: 'json',
data: {
"action": 'getState'
},
success: function(data){
// console.log('DATA: ', data);
for (const key in data) {
if (data.hasOwnProperty(key)) {
const device = data[key];
$('[data-sub-device-id="'+key+'"]')
.find('.device-button-value')
.text(device['value'])
.attr('title',device['time'])
}
}
},
error: function (request, status, error) {
console.log("ERROR ajaxChart():", request, error);
}
});
},2000);
//Graphs
$('.graph-period').on('click', function (e) {
var subId = $(this).attr('data-sub-device-id');
var period = $(this).attr('data-period');
var groupBy = $(this).attr('data-group');
ajaxChart(subId, period, groupBy);
});

20
templates/loading.css Normal file
View File

@ -0,0 +1,20 @@
.loader {
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite; /* Safari */
animation: spin 2s linear infinite;
}
/* Safari */
@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

37
templates/login.phtml Normal file
View File

@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="modal-container">
<div class="modal">
<h4 class="mb-4">Login</h4>
<form method="post">
<div class="field">
<div class="label">Name:</div>
<input class="input" type="text" name="username" placeholder="Jméno.."/>
</div>
<div class="field">
<div class="label">Password:</div>
<input class="input" type="password" name="password" placeholder="Heslo.."/>
</div>
<div class="field">
<div class="label">Remember me:</div>
<input class="" type="checkbox" name="remember" value="true"/>
</div>
<input type="submit" class="button" name="login" value="Login"/>
</form>
</div>
</div>
<?php
$partial = new Partial('footer');
$partial->render();
?>
</body>
</html>

View File

@ -0,0 +1,85 @@
<div class="modal-container modal-container-hiden" id="modal">
<div class="modal">
<a href=""><i class="fa fa-times close"></i></a>
<h4 class="mb-4"><?php echo $LANG['t_createAutomation']?></h4>
<form method="post">
<div class="field">
<div class="label"><?php echo $LANG['l_runAt']?></div>
<div class="field">
<select class="input" name="atSelector" id="valueSelector" required>
<option value="sunSet"><?php echo $LANG['l_sunSet']?></option>
<option value="sunRise"><?php echo $LANG['l_sunRice']?></option>
<option value="inHome"><?php echo $LANG['l_inHome']?></option>
<option value="outHome"><?php echo $LANG['l_outHome']?></option>
<option value="time"><?php echo $LANG['l_time']?></option>
<option value="atDeviceValue"><?php echo $LANG['l_deviceValue']?></option>
</select>
<input class="input" type="time" name="atTime" id="atTime" disabled/>
<select class="input" name="atDeviceValue" id="atDeviceValue" disabled>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="num" name="atDeviceValueInt" id="atDeviceValueInt" required disabled/>
</div>
<div class="label"><?php echo $LANG['l_resetAt']?></div>
<div class="field">
<select class="input" name="restartAtSelector" id="valueSelector" required>
<option value="sunSet"><?php echo $LANG['l_sunSet']?></option>
<option value="sunRise"><?php echo $LANG['l_sunRice']?></option>
<option value="inHome"><?php echo $LANG['l_inHome']?></option>
<option value="outHome"><?php echo $LANG['l_outHome']?></option>
<option value="time"><?php echo $LANG['l_time']?></option>
<option value="atDeviceValue"><?php echo $LANG['l_deviceValue']?></option>
</select>
<input class="input" type="time" name="restartAtTime" id="atTime" disabled/>
<select class="input" name="restartAtDeviceValue" id="atDeviceValue" disabled>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="num" name="restartAtDeviceValueInt" id="atDeviceValueInt" required disabled/>
</div>
<div class="label"><?php echo $LANG['l_affectedDevices']?></div>
<div class="field">
<select class="input" name="devices[]" multiple>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){
if ($subDeviceValue['type'] != 'on/off') continue;?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?></option>
<?php } ?>
</select>
</div>
<div class="label"><?php echo $LANG['l_atDays']?></div>
<div class="field">
<input type="checkbox" name="day[]" value="mon"/> Pondělí
</div>
<div class="field">
<input type="checkbox" name="day[]" value="tue"/> Úterý
</div>
<div class="field">
<input type="checkbox" name="day[]" value="wed"/> Středa
</div>
<div class="field">
<input type="checkbox" name="day[]" value="thu"/> Čtvrtek
</div>
<div class="field">
<input type="checkbox" name="day[]" value="fri"/> Pátek
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sat"/> Sobota
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sun"/> Neděle
</div>
</div>
<input type="submit" class="button" name="modalNext" value="<?php echo $LANG['b_next']?>"/>
</form>
</div>
</div>

View File

@ -0,0 +1,38 @@
<div class="modal-container" id="modal">
<div class="modal">
<a href=""><i class="fa fa-times close"></i></a>
<h4 class="mb-4"><?php echo $LANG['t_createAutomation']?></h4>
<form method="post">
<div class="field">
<input type="hidden" name="atSelector" value="<?php if (isset($_POST['atTime'])) {
echo $_POST['atTime'];
} else if (isset($_POST['atDeviceValue'])) {
$subDeviceId = $_POST['atDeviceValue'];
$subDeviceValue = $_POST['atDeviceValueInt'];
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
$subDeviceMaster = SubDeviceManager::getSubDeviceMaster($subDeviceId,$subDevice['type']);
$json = json_encode([
'deviceID' => $subDeviceMaster['device_id'],
'type'=> htmlspecialchars($subDevice['type']),
'value'=> $subDeviceValue,
]);
echo htmlspecialchars($json);
}
else {
echo $_POST['atSelector'];
} ?>" required/>
<input type="hidden" name="atDays" value="<?php echo htmlspecialchars(($_POST['day'] != '' ? json_encode($_POST['day']) : '')); ?>" required/>
<?php foreach ($_POST['devices'] as $value) { ?>
<?php $deviceData = DeviceManager::getDeviceById($value); ?>
<div class="label"><?php echo $deviceData['name'];?></div>
<select class="input" name="device[<?php echo $deviceData['device_id'];?>]">
<option value="1">ON</option>
<option value="0">OFF</option>
</select>
<?php } ?>
</div>
<input type="submit" class="button" name="modalFinal" value="Next"/>
</form>
</div>
</div>

View File

@ -0,0 +1,97 @@
<div class="modal-container modal-container-hiden" id="modal-setting-<?php echo $AUTOMATIONID; ?>">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php echo $LANG['t_createAutomation']?></h4>
<form method="post">
<div class="field">
<div class="label"><?php echo $LANG['l_runAt']?></div>
<div class="field">
<?php //TODO Dodělat identifikaci pro Selctor události a selector času zařízení hodnoty ?>
<select class="input" name="atSelector" id="valueSelector" required>
<option value="sunSet" <?php ECHO ($AUTOMATION['ifSomething'] == "sunSet" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_sunSet']?></option>
<option value="sunRise" <?php ECHO ($AUTOMATION['ifSomething'] == "sunRise" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_sunRice']?></option>
<option value="inHome" <?php ECHO ($AUTOMATION['ifSomething'] == "inHome" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_inHome']?></option>
<option value="outHome" <?php ECHO ($AUTOMATION['ifSomething'] == "outHome" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_outHome']?></option>
<option value="time" <?php ECHO ($AUTOMATION['ifSomething'] == "time" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_time']?></option>
<option value="atDeviceValue" <?php ECHO ($AUTOMATION['ifSomething'] == "atDeviceValue" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_deviceValue']?></option>
</select>
<input class="input" type="time" name="atTime" id="atTime" <?php ECHO ($AUTOMATION['ifSomething'] == "time" ? '' : 'disabled'); ?>/>
<select class="input" name="atDeviceValue" id="atDeviceValue" <?php ECHO ($AUTOMATION['ifSomething'] == "atDeviceValue" ? '' : 'disabled'); ?>>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="num" name="atDeviceValueInt" id="atDeviceValueInt" required <?php ECHO ($AUTOMATION['ifSomething'] == "atDeviceValue" ? '' : 'disabled'); ?>/>
</div>
<div class="label"><?php echo $LANG['l_resetAt']?></div>
<div class="field">
<?php //TODO Dodělat identifikaci pro Selctor události a selector času zařízení hodnoty ?>
<select class="input" name="restartAtSelector" id="valueSelector" required>
<option value="sunSet" <?php ECHO ($AUTOMATION['ifSomething'] == "sunSet" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_sunSet']?></option>
<option value="sunRise" <?php ECHO ($AUTOMATION['ifSomething'] == "sunRise" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_sunRice']?></option>
<option value="inHome" <?php ECHO ($AUTOMATION['ifSomething'] == "inHome" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_inHome']?></option>
<option value="outHome" <?php ECHO ($AUTOMATION['ifSomething'] == "outHome" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_outHome']?></option>
<option value="time" <?php ECHO ($AUTOMATION['ifSomething'] == "time" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_time']?></option>
<option value="atDeviceValue" <?php ECHO ($AUTOMATION['ifSomething'] == "atDeviceValue" ? 'selected="selected"' : ''); ?>><?php echo $LANG['l_deviceValue']?></option>
</select>
<input class="input" type="time" name="restartAtTime" id="atTime" <?php ECHO ($AUTOMATION['ifSomething'] == "time" ? '' : 'disabled'); ?>/>
<select class="input" name="restartAtDeviceValue" id="atDeviceValue" <?php ECHO ($AUTOMATION['ifSomething'] == "atDeviceValue" ? '' : 'disabled'); ?>>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="num" name="restartAtDeviceValueInt" id="atDeviceValueInt" required <?php ECHO ($AUTOMATION['ifSomething'] == "atDeviceValue" ? '' : 'disabled'); ?>/>
</div>
<div class="label"><?php echo $LANG['l_affectedDevices'];?></div>
<div class="field">
<div class="field px-2">
<?php
$i = 0;
foreach($AUTOMATION['doSomething'] as $subDeviceId => $subDeviceData){ ?>
<div id="automation-<?php echo $AUTOMATIONID; ?>-content">
<div class="label"><?php echo $subDeviceData['name']; ?></div>
<select class="input" name="devices[<?php echo $subDeviceId; ?>]">
<option value="0" <?php echo ($subDeviceData['state'] == "0" ? 'selected="selected"' : ''); ?>>off</option>
<option value="1" <?php echo ($subDeviceData['state'] == "1" ? 'selected="selected"' : ''); ?>>on</option>
</select>
<button name="remove" type="button" class="button is-danger fa" data-automation-id="<?php echo $AUTOMATIONID; ?>">&#xf1f8;</button>
</div>
<?php
$i++;
} ?>
</div>
</div>
<div class="label"><?php echo $LANG['l_atDays'];?></div>
<div class="field">
<input type="checkbox" name="day[]" value="mon" <?php ECHO (in_array("mon", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Pondělí
</div>
<div class="field">
<input type="checkbox" name="day[]" value="tue" <?php ECHO (in_array("tue", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Úterý
</div>
<div class="field">
<input type="checkbox" name="day[]" value="wed" <?php ECHO (in_array("wed", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Středa
</div>
<div class="field">
<input type="checkbox" name="day[]" value="thu" <?php ECHO (in_array("thu", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Čtvrtek
</div>
<div class="field">
<input type="checkbox" name="day[]" value="fri" <?php ECHO (in_array("fri", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Pátek
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sat" <?php ECHO (in_array("sat", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Sobota
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sun" <?php ECHO (in_array("sun", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> Neděle
</div>
</div>
<input type="submit" class="button" name="modalFinal" value="<?php echo $LANG['b_edit'];?>"/>
<input type="submit" class="button is-danger" onClick="ajaxPost('ajax',{automation_id:'<?php echo $AUTOMATIONID ?>', 'action':'delete'}, this, true);" name="remove" value="<?php echo $LANG['b_remove'];?>"/>
</form>
</div>
</div>

View File

@ -0,0 +1,22 @@
<div class="col-4 col-sm-3 col-xl-2 square-wrap">
<div class="square">
<div class="square-content" id="device-<?php echo $DASHBOARDITEMDATA['masterId'] ?>" onClick="ajaxPost('./ajax.php',{subDevice_id:'<?php echo $DASHBOARDITEMDATA['id']; ?>'}, this);">
<div class="content">
<div class="delete">delete</div>
<div class="row">
<div class="col">
<h5 class="fa">&#x<?php echo $DASHBOARDITEMDATA['icon'] ?></h5>
</div>
<div class="col">
<h5 class="text-right"><?php echo $DASHBOARDITEMDATA['lastRecord']['value'].''.$DASHBOARDITEMDATA['unit'] ?></h5>
</div>
</div>
<div class="row">
<div class="col">
<?php echo $DASHBOARDITEMDATA['name'] ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,29 @@
<?php
$action = "";
if ($SUBDEVICE['type'] == 'on/off') {
$action = 'onClick="ajaxPost(\'ajax\',{subDevice_id:\'' . $SUBDEVICEID . '\'}, this);"';
}
//neaktivní zařízení is-inactive
?>
<div class="device-button col-4 col-sm-3 col-xl-2 square-wrap" <?php echo $action; ?> data-room-id="<?php echo $ROOMID; ?>">
<div class="square">
<div class="square-content <?php echo ($SUBDEVICE['comError'] ? "is-inactive" : "") ;?>" id="device-<?php echo $DEVICEID ?>" data-sub-device-id="<?php echo $SUBDEVICEID;?>">
<div class="content">
<div class="row">
<div class="col">
<h5 unselectable="on" class="fa">&#x<?php echo $DEVICE['icon'] ?></h5>
</div>
<div class="col">
<h5 unselectable="on" class="device-button-value text-right" title="<?php echo $SUBDEVICE['lastRecort']['time']; ?>"><?php echo $SUBDEVICE['lastRecort']['value'] . $SUBDEVICE['unit']?></h5>
</div>
</div>
<div class="row">
<div class="col" unselectable="on" >
<?php echo $DEVICE['name']; ?>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,80 @@
<!-- Detail -->
<div class="modal-container modal-container-hiden" id="modal-detail-<?php echo $SUBDEVICEID;?>">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php echo $DEVICE['name']; ?></h4>
<h5 class="mb-4"><?php echo $SUBDEVICE['lastRecort']['value'] . $SUBDEVICE['unit']?></h5>
<p>Last Seen <?php echo $SUBDEVICE['lastRecort']['niceTime']; ?></p>
<div class="">
<canvas id="canvas-<?php echo $SUBDEVICEID;?>"></canvas>
</div>
<input
type="submit"
class="button col-2 graph-period"
data-period="year"
data-group="month"
data-sub-device-id="<?php echo $SUBDEVICEID;?>"
value="<?php echo $LANG['b_year']?>"
/>
<input
type="submit"
class="button col-2 graph-period"
data-period="month"
data-group="day"
data-sub-device-id="<?php echo $SUBDEVICEID;?>"
value="<?php echo $LANG['b_month']?>"
/>
<input
type="submit"
class="button col-2 graph-period"
data-period="week"
data-group="day"
data-sub-device-id="<?php echo $SUBDEVICEID;?>"
value="<?php echo $LANG['b_week']?>"
/>
<input
type="submit"
class="button col-2 graph-period"
data-period="day"
data-group="hour"
data-sub-device-id="<?php echo $SUBDEVICEID;?>"
value="<?php echo $LANG['b_day']?>"
/>
<input
type="submit"
class="button col-2 graph-period"
data-period="hour"
data-group="minute"
data-sub-device-id="<?php echo $SUBDEVICEID;?>"
value="<?php echo $LANG['b_hour']?>"
/>
<div>
<table class="table is-fluid">
<thead>
<tr>
<th>Time</th>
<th>State</th>
</tr>
</thead>
<tbody>
<?php foreach ($SUBDEVICE['events'] as $key => $value) { ?>
<tr>
<th><?php echo (new DateTime($value['time']))->format(DATEFORMAT); ?></th>
<th title="test"><?php echo $value['value'] . $SUBDEVICE['unit'];?></th>
<?php //TODO: P5IDAT TOOLTIP PRO RAW VALUE?>
</tr>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>

View File

@ -0,0 +1,160 @@
<div class="modal-container modal-container-hiden" id="modal-setting-<?php echo $DEVICEID ?>">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php echo $LANG['t_editDevice']; ?></h4>
<form method="post" action="">
<input class="input" type="hidden" name="deviceId" value="<?php echo $DEVICEID; ?>">
<?php if ($DEVICE['approved'] != 0) { ?>
<?php if ($DEVICE['userIsAdmin']) { ?>
<div class="field">
<div class="label"><?php echo $LANG['l_owner']; ?></div>
<select class="input" name="deviceOwnerUserId">
<option value=""><?php echo $LANG['w_noOne']; ?></option>
<?php foreach ($USERS as $user) {
$userId = $user['user_id'];
$userName = $user['username'];
?>
<option value="<?php echo $userId; ?>" <?php ECHO ((int) $userId === (int) $DEVICE['owner'] ? 'selected="selected"' : ''); ?>><?php echo $userName; ?></option>
<?php } ?>
</select>
</div>
<div class="label"> <?php echo $LANG['l_permission']; ?></div>
<div class="row">
<div class="col-6">
<div class="label"> - <?php echo $LANG['l_owner']; ?></div>
</div>
<div class="col-6">
<?php
$permissions = $DEVICE['permission'];
//Debug
if (DEBUGMOD == 1) {
echo '<pre>';
VAR_DUMP($permissions);
echo '</pre>';
}
?>
<input type="radio" name="permissionOwner" value=1 <?php ECHO ($permissions[0] == 1 ? 'checked' : ''); ?>/> <?php echo $LANG['l_read']; ?>
<input type="radio" name="permissionOwner" value=2 <?php ECHO ($permissions[0] == 2 ? 'checked' : ''); ?>/> <?php echo $LANG['l_use']; ?>
<input type="radio" name="permissionOwner" value=3 <?php ECHO ($permissions[0] == 3 ? 'checked' : ''); ?>/> <?php echo $LANG['l_edit']; ?>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="label"> - <?php echo $LANG['l_member']; ?></div>
</div>
<div class="col-6">
<input type="radio" name="permissionOther" value=1 <?php ECHO ($permissions[1] == 1 ? 'checked' : ''); ?>/> <?php echo $LANG['l_read']; ?>
<input type="radio" name="permissionOther" value=2 <?php ECHO ($permissions[1] == 2 ? 'checked' : ''); ?>/> <?php echo $LANG['l_use']; ?>
<input type="radio" name="permissionOther" value=3 <?php ECHO ($permissions[1] == 3 ? 'checked' : ''); ?>/> <?php echo $LANG['l_edit']; ?>
</div>
</div>
<div class="field">
<div class="label"><?php echo $LANG['w_title']; ?></div>
<input class="input" type="text" name="deviceName" value="<?php echo $DEVICE['name']; ?>" <?php echo (!$DEVICE['userIsAdmin'] ? 'disabled' : ''); ?>>
</div>
<?php } ?>
<div class="field">
<div class="label">Token:</div>
<input class="input" type="text" name="deviceToken" value="<?php echo $DEVICE['token']; ?>" disabled>
</div>
<?php if ($DEVICE['userIsAdmin']) { ?>
<?php if (!in_array($SUBDEVICE['type'], ['on/off', 'door'])) { ?>
<div class="field">
<div class="label"><?php echo $LANG['l_sleepTime']; ?></div>
<input class="input" type="int" name="sleepTime" value="<?php echo $DEVICE['sleepTime']; ?>" <?php echo (!$DEVICE['userIsAdmin'] ? 'disabled' : ''); ?>>
<p>* - <?php echo $LANG['l_inMinutes']; ?></p>
</div>
<?php }?>
<div class="field">
<div class="label"><?php echo $LANG['w_room']; ?></div>
<select class="input" name="deviceOwnerId">
<?php foreach ($ROOMS as $room) {
$roomId = $room['room_id'];
$roomName = $room['name'];
?>
<option value="<?php echo $roomName; ?>" <?php ECHO ((int) $roomId === (int) $DEVICE['room'] ? 'selected="selected"' : ''); ?>><?php echo $roomName; ?></option>
<?php } ?>
</select>
</div>
<div class="field">
<div class="label"><?php echo $LANG['w_icon']; ?></div>
<select class="input fa" name="deviceIcon" <?php echo (!$DEVICE['userIsAdmin'] ? 'disabled' : ''); ?>>
<option value=""><?php echo $LANG['w_no'] . ' ' . $LANG['w_icon']; ?></option>
<option value="f0eb" <?php ECHO ($DEVICE['icon'] == "f0eb" ? 'selected="selected"' : ''); ?>>&#xf0eb; - fa-lightbulb-o</option>
<option value="f2dc" <?php ECHO ($DEVICE['icon'] == "f2dc" ? 'selected="selected"' : ''); ?>>&#xf2dc; - fa-snowflake-o</option>
<option value="f0e7" <?php ECHO ($DEVICE['icon'] == "f0e7" ? 'selected="selected"' : ''); ?>>&#xf0e7; - fa-bolt</option>
<option value="f2c7" <?php ECHO ($DEVICE['icon'] == "f2c7" ? 'selected="selected"' : ''); ?>>&#xf2c7; - fa-thermometer-full</option>
<option value="f236" <?php ECHO ($DEVICE['icon'] == "f236" ? 'selected="selected"' : ''); ?>>&#xf236; - fa-bed</option>
<option value="f185" <?php ECHO ($DEVICE['icon'] == "f185" ? 'selected="selected"' : ''); ?>>&#xf185; - fa-sun-o</option>
<option value="f2db" <?php ECHO ($DEVICE['icon'] == "f2db" ? 'selected="selected"' : ''); ?>>&#xf2db; - fa-microchip</option>
<option value="f011" <?php ECHO ($DEVICE['icon'] == "f011" ? 'selected="selected"' : ''); ?>>&#xf011; - fa-power-off</option>
<option value="f011" <?php ECHO ($DEVICE['icon'] == "f011" ? 'selected="selected"' : ''); ?>>&#xf108; - fa-desktop</option>
</select>
</div>
<?php } ?>
<div class="field">
<div class="label"><?php echo $LANG['w_moduls']; ?></div>
<div class="row no-gutters">
<?php foreach ($DEVICE['subDevices'] as $subDeviceKey => $subDevice) { ?>
<div class="col-4 col-sm-3 col-xl-2 square-wrap">
<div class="square">
<div class="square-content">
<div class="row">
<div class="col">
<h3 class="fa">&#x<?php echo $DEVICE['icon']; ?></h3>
</div>
<div class="col">
<h3><?php echo $subDevice['unit']; ?></h3>
</div>
</div>
<div class="row">
<div class="col">
<?php echo $DEVICE['name']; ?>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
</div>
</div>
<input type="submit" class="button" name="saveDevice" value="<?php echo $LANG['b_save']; ?>" <?php echo (!$DEVICE['userIsAdmin'] ? 'disabled' : ''); ?>/>
<input type="submit" class="button is-danger" name="disableDevice" value="<?php echo $LANG['b_disable']; ?>"/>
<?php } else { ?>
<div class="field">
<div class="label"><?php echo $LANG['w_moduls']; ?></div>
<div class="row no-gutters">
<?php foreach ($DEVICE['subDevices'] as $subDeviceKey => $subDevice) { ?>
<div class="col-4 col-sm-3 col-xl-2 square-wrap">
<div class="square">
<div class="square-content">
<div class="row">
<div class="col">
<h3 class="fa">&#x<?php echo $DEVICE['icon']; ?></h3>
</div>
<div class="col">
<h3><?php echo $subDevice['unit']; ?></h3>
</div>
</div>
<div class="row">
<div class="col">
<?php echo $DEVICE['name']; ?>
</div>
</div>
</div>
</div>
</div>
<?php } ?>
</div>
</div>
<input type="submit" class="button is-primary" name="approveDevice" value="<?php echo $LANG['b_approve']; ?>"/>
<input type="submit" class="button is-danger" name="disableDevice" value="<?php echo $LANG['b_disable']; ?>"/>
<?php } ?>
</form>
</div>
</div>

View File

@ -0,0 +1,3 @@
<script src="./templates/js/jquery.js"></script>
<script src="./templates/js/post.js"></script>
<script src="./templates/js/script.js"></script>

25
templates/part/head.phtml Normal file
View File

@ -0,0 +1,25 @@
<link rel="manifest" href="manifest.json">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="application-name" content="Home">
<meta name="apple-mobile-web-app-title" content="Home">
<meta name="theme-color" content="#182239">
<meta name="msapplication-navbutton-color" content="#182239">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="msapplication-starturl" content="/vasek/home/">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" sizes="192x192" href="/vasek/home/templates/images/icon-192x192.png">
<link rel="apple-touch-icon" sizes="192x192" href="/vasek/home/templates/images/icon-192x192.png">
<link rel="icon" sizes="512x512" href="/vasek/home/templates/images/icon-512x512.png">
<link rel="apple-touch-icon" sizes="512x512" href="/vasek/home/templates/images/icon-512x512.png">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./templates/css/main.css">
<link rel="stylesheet" href="./templates/css/font-awesome.min.css">
<link rel="stylesheet" href="./templates/css/modal.css">
<link rel="stylesheet" href="./templates/css/pre.css">
<link rel="stylesheet" href="./templates/css/loading.css">

View File

@ -0,0 +1,40 @@
<div class="modal-container modal-container-hiden" id="modal">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php echo $LANG['t_createScene'];?></h4>
<form method="post" action="" >
<div class="field">
<div class="label"><?php echo $LANG['w_title'];?>:</div>
<input type="text" class="input" name="sceneName" value=""/>
</div>
<div class="field">
<div class="label"><?php echo $LANG['w_icon'];?>:</div>
<select class="input fa" name="sceneIcon" <?php echo (!$DEVICE['userIsAdmin'] ? 'disabled' : ''); ?>>
<option value="">No icon</option>
<option value="f0eb">&#xf0eb; - fa-lightbulb-o</option>
<option value="f2dc">&#xf2dc; - fa-snowflake-o</option>
<option value="f0e7">&#xf0e7; - fa-bolt</option>
<option value="f2c7">&#xf2c7; - fa-thermometer-full</option>
<option value="f236">&#xf236; - fa-bed</option>
<option value="f185">&#xf185; - fa-sun-o</option>
<option value="f2db">&#xf2db; - fa-microchip</option>
<option value="f011">&#xf011; - fa-power-off</option>
<option value="f011">&#xf108; - fa-desktop</option>
</select>
</div>
<div class="field">
<div class="label"><?php echo $LANG['l_choseDevice'];?></div>
<select class="input" name="devices[]" multiple>
<?php
foreach ($SUBDEVICES as $subdeviceId => $subdeviceData) {
echo '<option value="'.$subdeviceId.'">'.$subdeviceData['name'].'</option>';
}
?>
</select>
</div>
<input type="submit" class="button" name="submit" value="<?php echo $LANG['b_next'];?>"/>
</form>
</div>
</div>

View File

@ -0,0 +1,26 @@
<div class="modal-container" id="modal">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php echo $LANG['t_createScene'];?></h4>
<form method="post">
<input type="hidden" name="sceneName" value="<?php echo $SCENENAME; ?>">
<input type="hidden" name="sceneIcon" value="<?php echo $SCENEICON; ?>">
<?php
$i = 0;
foreach($SETSTATEFORMDEVICES as $device){ ?>
<div class="field px-2">
<div class="label"><?php echo $device['name']; ?></div>
<select class="input" name="devices[<?php echo $device['setableSubDevices']; ?>]">
<option value="0">off</option>
<option value="1">on</option>
</select>
</div>
<?php
$i++;
} ?>
<input type="submit" class="button" name="submit" value="<?php echo $LANG['b_create'];?>"/>
</form>
</div>
</div>

View File

@ -0,0 +1,48 @@
<?php //TODO DOD2LAT UKL8D8N9?>
<div class="modal-container modal-container-hiden" id="modal-setting-<?php echo $SCENEID ?>">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php echo $LANG['t_editScene']?></h4>
<form method="post">
<div class="field">
<div class="label"><?php echo $LANG['w_title'];?>:</div>
<input type="text" class="input" name="sceneName" value="<?php echo $SCENE['name']; ?>"/>
</div>
<div class="field">
<div class="label"><?php echo $LANG['w_icon'];?>:</div>
<select class="input fa" name="sceneIcon">
<option value=""><?php echo $LANG['w_no'].$LANG['w_icon'];?></option>
<option value="f0eb" <?php ECHO ($SCENE['icon'] == "f0eb" ? 'selected="selected"' : ''); ?>>&#xf0eb; - fa-lightbulb-o</option>
<option value="f2dc" <?php ECHO ($SCENE['icon'] == "f2dc" ? 'selected="selected"' : ''); ?>>&#xf2dc; - fa-snowflake-o</option>
<option value="f0e7" <?php ECHO ($SCENE['icon'] == "f0e7" ? 'selected="selected"' : ''); ?>>&#xf0e7; - fa-bolt</option>
<option value="f2c7" <?php ECHO ($SCENE['icon'] == "f2c7" ? 'selected="selected"' : ''); ?>>&#xf2c7; - fa-thermometer-full</option>
<option value="f236" <?php ECHO ($SCENE['icon'] == "f236" ? 'selected="selected"' : ''); ?>>&#xf236; - fa-bed</option>
<option value="f185" <?php ECHO ($SCENE['icon'] == "f185" ? 'selected="selected"' : ''); ?>>&#xf185; - fa-sun-o</option>
<option value="f2db" <?php ECHO ($SCENE['icon'] == "f2db" ? 'selected="selected"' : ''); ?>>&#xf2db; - fa-microchip</option>
<option value="f011" <?php ECHO ($SCENE['icon'] == "f011" ? 'selected="selected"' : ''); ?>>&#xf011; - fa-power-off</option>
<option value="f011" <?php ECHO ($SCENE['icon'] == "f011" ? 'selected="selected"' : ''); ?>>&#xf108; - fa-desktop</option>
</select>
</div>
<div class="field px-2">
<?php
$i = 0;
foreach($SCENE['doSomething'] as $subDeviceId => $subDeviceData){ ?>
<div id="scene-<?php echo $SCENEID; ?>-content">
<div class="label"><?php echo $subDeviceData['name']; ?></div>
<select class="input" name="devices[<?php echo $subDeviceId; ?>]">
<option value="0" <?php ECHO ($subDeviceData['state'] == "0" ? 'selected="selected"' : ''); ?>>off</option>
<option value="1" <?php ECHO ($subDeviceData['state'] == "1" ? 'selected="selected"' : ''); ?>>on</option>
</select>
<button name="remove" type="button" class="button is-danger fa" data-scene-id="<?php echo $SCENEID; ?>">&#xf1f8;</button>
</div>
<?php
$i++;
} ?>
</div>
<input type="submit" class="button" name="saveDevice" value="<?php echo $LANG['b_edit'];?>"/>
<input type="button" class="button is-danger" onClick="ajaxPost('ajax',{scene_id:'<?php echo $SCENEID ?>', 'action':'delete'}, this, true);" name="saveDevice" value="<?php echo $LANG['b_remove'];?>"/>
</form>
</div>
</div>

View File

@ -0,0 +1,3 @@
<H1>
TEST - TEST
</H1>

Some files were not shown because too many files have changed in this diff Show More