To docker Image
This commit is contained in:
19
www/.htaccess
Normal file
19
www/.htaccess
Normal file
@@ -0,0 +1,19 @@
|
||||
RewriteEngine On
|
||||
|
||||
# require https
|
||||
RewriteCond %{HTTPS} off
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
#token to HTTP_AUTHORIZATION
|
||||
RewriteCond %{HTTP:Authorization} ^(.)
|
||||
RewriteRule . - [e=HTTP_AUTHORIZATION:%1]
|
||||
|
||||
# serve all files from public subfolder
|
||||
RewriteCond %{REQUEST_FILENAME} !.php
|
||||
RewriteCond %{REQUEST_FILENAME} \.
|
||||
RewriteRule (.*) ./public/$1 [L]
|
||||
|
||||
# serve all other request as query parameters
|
||||
RewriteRule (.*) ./public/index.php?url=$1 [L,QSA]
|
||||
|
||||
AddType application/x-httpd-php .php .phtml
|
255
www/New_JS_EDITOR_ TEST.php
Normal file
255
www/New_JS_EDITOR_ TEST.php
Normal file
@@ -0,0 +1,255 @@
|
||||
<pre>
|
||||
<?php
|
||||
var_dump($_POST);
|
||||
var_dump(file_exists("./app/updater/" . "3C71BF22FDCF" . ".bin"));
|
||||
?>
|
||||
</pre>
|
||||
|
||||
<form class="" action="" method="post">
|
||||
<label for="operator">Typ podmínky</label>
|
||||
<select class="" name="operator">
|
||||
<option value="or">OR</option>
|
||||
<option value="and">AND</option>
|
||||
</select>
|
||||
<div class="variableArea">
|
||||
|
||||
<button name="addButton" id="addButton">+</button>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<label for="resetOperator">Typ podmínky</label>
|
||||
<select class="" name="resetOperator">
|
||||
<option value="or">OR</option>
|
||||
<option value="and">AND</option>
|
||||
</select>
|
||||
<div class="resetvariableArea">
|
||||
|
||||
<button name="restartaAddButton" id="restartAddButton">+</button>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<button type="submit" name="button">Odeslat</button>
|
||||
|
||||
</form>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
function foo(element){
|
||||
var id = element.attr("name").match(/\d+/)[0]
|
||||
$("[name='variable["+id+"][value]']").remove();
|
||||
$("[name='variable["+id+"][equaler]']").remove();
|
||||
|
||||
if (element.val() == "atDeviceValue") {
|
||||
var arrVarOperator = [
|
||||
{val : '>', text: '>'},
|
||||
{val : '<', text: '<'},
|
||||
];
|
||||
|
||||
var varOperator = $('<select name="variable['+id+'][equaler]">');
|
||||
$(arrVarOperator).each(function() {
|
||||
varOperator.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
element.parent().append(varOperator);
|
||||
|
||||
|
||||
var input = $("<input/>");
|
||||
input.attr("type","text");
|
||||
input.attr("name","variable["+id+"][value]");
|
||||
element.parent().append(input);
|
||||
} else if (element.val() == "time") {
|
||||
var arrVarOperator = [
|
||||
{val : '>', text: '>'},
|
||||
{val : '<', text: '<'},
|
||||
];
|
||||
|
||||
var varOperator = $('<select name="variable['+id+'][equaler]">');
|
||||
$(arrVarOperator).each(function() {
|
||||
varOperator.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
element.parent().append(varOperator);
|
||||
|
||||
var input = $("<input/>");
|
||||
input.attr("type","time");
|
||||
input.attr("name","variable["+id+"][value]");
|
||||
element.parent().append(input);
|
||||
}else {
|
||||
var arrVarOperator = [
|
||||
{val : '=', text: '=='},
|
||||
{val : '!=', text: '!='},
|
||||
];
|
||||
|
||||
var varOperator = $('<select name="variable['+id+'][equaler]">');
|
||||
$(arrVarOperator).each(function() {
|
||||
varOperator.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
element.parent().append(varOperator);
|
||||
|
||||
var arrVarValue = [
|
||||
{val : 'true', text: 'True'},
|
||||
{val : 'false', text: 'False'},
|
||||
];
|
||||
|
||||
var varValue = $('<select name="variable['+id+'][value]">');
|
||||
$(arrVarValue).each(function() {
|
||||
varValue.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
element.parent().append(varValue);
|
||||
}
|
||||
}
|
||||
$("#addButton,#restartAddButton").click( function (event) {
|
||||
event.preventDefault();
|
||||
var numItems = $('.var').length
|
||||
var arrVarSelect = [
|
||||
{val : 'sunSet', text: 'Západ Slunce'},
|
||||
{val : 'sunRise', text: 'Východ Slunce'},
|
||||
{val : 'inHome', text: 'Příchod'},
|
||||
{val : 'outHome', text: 'Odchod'},
|
||||
{val : 'time', text: 'Čas'},
|
||||
{val : 'atDeviceValue', text: 'Při hodnotě zařízení'},
|
||||
{val : 'sunRise', text: 'Východ Slunce'},
|
||||
{val : 'noOneHome', text: 'Nikdo Doma'},
|
||||
{val : 'someOneHome', text: 'Nekdo Doma'},
|
||||
];
|
||||
|
||||
var varSelect = $('<select name="variable['+numItems+'][what]">');
|
||||
$(arrVarSelect).each(function() {
|
||||
varSelect.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
varSelect.attr("onchange", "foo($(this))");
|
||||
|
||||
/*onchange = function(e) {
|
||||
console.log(this.value);
|
||||
if (this.value == 'atDeviceValue') {
|
||||
alert("ok");
|
||||
}
|
||||
};*/
|
||||
|
||||
var arrVarOperator = [
|
||||
{val : '>', text: '>'},
|
||||
{val : '<', text: '<'},
|
||||
{val : '=', text: '=='},
|
||||
{val : '!=', text: '!='},
|
||||
];
|
||||
|
||||
var varOperator = $('<select name="variable['+numItems+'][equaler]">');
|
||||
$(arrVarOperator).each(function() {
|
||||
varOperator.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
var arrVarValue = [
|
||||
{val : 'true', text: 'True'},
|
||||
{val : 'false', text: 'False'},
|
||||
];
|
||||
|
||||
var varValue = $('<select name="variable['+numItems+'][value]">');
|
||||
$(arrVarValue).each(function() {
|
||||
varValue.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
var newDiv = $("<div class=var>").append(varSelect);
|
||||
newDiv = newDiv.append(varOperator);
|
||||
newDiv = newDiv.append(varValue);
|
||||
$(this).parent().append(newDiv);
|
||||
|
||||
});
|
||||
|
||||
/*var arrVarSelect = [
|
||||
{val : 'sunSet', text: 'Západ Slunce'},
|
||||
{val : 'sunRise', text: 'Východ Slunce'},
|
||||
{val : 'inHome', text: 'Příchod'},
|
||||
{val : 'outHome', text: 'Odchod'},
|
||||
{val : 'time', text: 'Čas'},
|
||||
{val : 'atDeviceValue', text: 'Při hodnotě zařízení'},
|
||||
{val : 'sunRise', text: 'Východ Slunce'},
|
||||
{val : 'noOneHome', text: 'Nikdo Doma'},
|
||||
{val : 'someOneHome', text: 'Nekdo Doma'},
|
||||
];
|
||||
|
||||
var varSelect = $('<select name="variable['+numItems+'][]">');
|
||||
$(arrVarSelect).each(function() {
|
||||
varSelect.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
var arrVarOperator = [
|
||||
{val : '>', text: '>'},
|
||||
{val : '<', text: '<'},
|
||||
{val : '=', text: '=='},
|
||||
{val : '!=', text: '!='},
|
||||
];
|
||||
|
||||
var varOperator = $('<select name="variable['+numItems+'][]">');
|
||||
$(arrVarOperator).each(function() {
|
||||
varOperator.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
var arrVarValue = [
|
||||
{val : 'true', text: 'True'},
|
||||
{val : 'false', text: 'False'},
|
||||
];
|
||||
|
||||
var varValue = $('<select name="variable['+numItems+'][]">');
|
||||
$(arrVarValue).each(function() {
|
||||
varValue.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
//TODO změna výstupní proměné na základě vstupu date,num etc
|
||||
var newDiv = $("<div class=var>").append(varSelect);/*.change(
|
||||
function (subEvent) {
|
||||
alert(subEvent);
|
||||
}
|
||||
);*/
|
||||
/*newDiv = newDiv.append(varOperator);
|
||||
newDiv = newDiv.append(varValue);
|
||||
$(".restartaAddButton")append(newDiv);*/
|
||||
|
||||
|
||||
/*
|
||||
var arrVarSelect = [
|
||||
{val : 'sunSet', text: 'Západ Slunce'},
|
||||
{val : 'sunRise', text: 'Východ Slunce'},
|
||||
{val : 'inHome', text: 'Příchod'},
|
||||
{val : 'outHome', text: 'Odchod'},
|
||||
{val : 'time', text: 'Čas'},
|
||||
{val : 'atDeviceValue', text: 'Při hodnotě zařízení'},
|
||||
{val : 'sunRise', text: 'Východ Slunce'},
|
||||
{val : 'noOneHome', text: 'Nikdo Doma'},
|
||||
{val : 'someOneHome', text: 'Nekdo Doma'},
|
||||
];
|
||||
|
||||
var varSelect = $('<select name="variable['+numItems+'][]">');
|
||||
$(arrVarSelect).each(function() {
|
||||
varSelect.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
var arrVarOperator = [
|
||||
{val : '>', text: '>'},
|
||||
{val : '<', text: '<'},
|
||||
{val : '=', text: '=='},
|
||||
{val : '!=', text: '!='},
|
||||
];
|
||||
|
||||
var varOperator = $('<select name="variable['+numItems+'][]">');
|
||||
$(arrVarOperator).each(function() {
|
||||
varOperator.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
var arrVarValue = [
|
||||
{val : 'true', text: 'True'},
|
||||
{val : 'false', text: 'False'},
|
||||
];
|
||||
|
||||
var varValue = $('<select name="variable['+numItems+'][]">');
|
||||
$(arrVarValue).each(function() {
|
||||
varValue.append($('<option>').attr('value',this.val).text(this.text));
|
||||
});
|
||||
|
||||
//TODO změna výstupní proměné na základě vstupu date,num etc
|
||||
var newDiv = $("<div class=var>").append(varSelect);/*.change(
|
||||
function (subEvent) {
|
||||
alert(subEvent);
|
||||
}
|
||||
);*/
|
||||
/* newDiv = newDiv.append(varOperator);
|
||||
newDiv = newDiv.append(varValue);
|
||||
$(".variableArea").parent().append(newDiv);*/
|
||||
|
||||
</script>
|
319
www/api.php
Normal file
319
www/api.php
Normal file
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/** Includes **/
|
||||
include_once('./config.php');
|
||||
|
||||
//Autoloader
|
||||
$files = scandir('./app/class/');
|
||||
$files = array_diff($files, array(
|
||||
'.',
|
||||
'..',
|
||||
'app',
|
||||
'ChartJS.php',
|
||||
'ChartJS_Line.php',
|
||||
'ChartManager.php',
|
||||
'DashboardManager.php',
|
||||
'Partial.php',
|
||||
'Form.php',
|
||||
'Route.php',
|
||||
'Template.php',
|
||||
'Ajax.php',
|
||||
));
|
||||
|
||||
foreach($files as $file) {
|
||||
include './app/class/'. $file;
|
||||
}
|
||||
|
||||
//Allow acces only wia Curl, Ajax ETC
|
||||
$restAcess = 'XMLHttpRequest' == ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );
|
||||
if (!$restAcess){
|
||||
header('Location: ./');
|
||||
}
|
||||
|
||||
//Log
|
||||
$logManager = new LogManager();
|
||||
$apiLogManager = new LogManager('./app/logs/api/'. date("Y-m-d").'.log');
|
||||
|
||||
//DB Conector
|
||||
Db::connect (DBHOST, DBUSER, DBPASS, DBNAME);
|
||||
|
||||
//Read API data
|
||||
$json = file_get_contents('php://input');
|
||||
$obj = json_decode($json, true);
|
||||
|
||||
//Log RAW api request
|
||||
if (API_DEBUGMOD == 1) {
|
||||
$apiLogManager->write("[API] request body\n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
}
|
||||
|
||||
//zabespecit proti Ddosu
|
||||
if (isset($obj['user']) && $obj['user'] != ''){
|
||||
//user at home
|
||||
$user = UserManager::getUser($obj['user']);
|
||||
$userAtHome = $user['at_home'];
|
||||
if (!empty($user)) {
|
||||
$userId = $user['user_id'];
|
||||
$atHome = $obj['atHome'];
|
||||
if($userAtHome != $atHome){
|
||||
UserManager::atHome($userId, $atHome);
|
||||
$logManager->write("[USER] user " . $userId . " changet his home state to " . $atHome , LogRecordType::INFO);
|
||||
}
|
||||
echo 'Saved: ' . $atHome;
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
//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 insnt alowed!",
|
||||
), JSON_PRETTY_PRINT);
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
|
||||
$logManager->write("[API] acces denied from " . $_SERVER['REMOTE_ADDR'], LogRecordType::WARNING);
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
||||
//automationExecution
|
||||
try {
|
||||
AutomationManager::executeAll();
|
||||
$fallbackManager = new FallbackManager(RANGES);
|
||||
$fallbackManager->check();
|
||||
//LogKeeper::purge(LOGTIMOUT);
|
||||
} catch (\Exception $e) {
|
||||
$logManager->write("[Automation] Something happen during automation execution", LogRecordType::ERROR);
|
||||
}
|
||||
|
||||
//Record Cleaning
|
||||
try {
|
||||
RecordManager::clean(RECORDTIMOUT);
|
||||
} catch (\Exception $e) {
|
||||
$logManager->write("[Record] cleaning record older that " . RECORDTIMOUT , LogRecordType::ERROR);
|
||||
}
|
||||
|
||||
//Variables
|
||||
$token = $obj['token'];
|
||||
$values = null;
|
||||
$settings = null;
|
||||
$deviceLogs = null;
|
||||
$command = "null";
|
||||
|
||||
if (isset($obj['values'])) {
|
||||
$values = $obj['values'];
|
||||
}
|
||||
|
||||
if (isset($obj['settings'])) {
|
||||
$settings = $obj['settings'];
|
||||
}
|
||||
|
||||
if (isset($obj['logs'])) {
|
||||
$deviceLogs = $obj['logs'];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Checks
|
||||
if ($token == null || $token == "") {
|
||||
echo json_encode(array(
|
||||
'state' => 'unsuccess',
|
||||
'errorMSG' => "Missing Value Token in JSON payload",
|
||||
), JSON_PRETTY_PRINT);
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
|
||||
die();
|
||||
}
|
||||
|
||||
//Vstupní Checky
|
||||
if (!DeviceManager::registeret($token)) {
|
||||
//Notification data setup
|
||||
$notificationMng = new NotificationManager;
|
||||
$notificationData = [
|
||||
'title' => 'Info',
|
||||
'body' => 'New device Detected Found',
|
||||
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
|
||||
];
|
||||
|
||||
//Subdevice Registration
|
||||
$deviceId = DeviceManager::create($token, $token);
|
||||
foreach ($values as $key => $value) {
|
||||
if (!SubDeviceManager::getSubDeviceByMaster($deviceId, $key)) {
|
||||
SubDeviceManager::create($deviceId, $key, UNITS[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
//Notification for newly added Device
|
||||
if ($notificationData != []) {
|
||||
$subscribers = $notificationMng::getSubscription();
|
||||
foreach ($subscribers as $key => $subscriber) {
|
||||
$logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " ", LogRecordType::INFO);
|
||||
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
|
||||
}
|
||||
}
|
||||
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
|
||||
echo json_encode(array(
|
||||
'state' => 'unsuccess',
|
||||
'errorMSG' => "Device not registeret",
|
||||
), JSON_PRETTY_PRINT);
|
||||
$logManager->write("[API] Registering Device", LogRecordType::INFO);
|
||||
exit();
|
||||
}
|
||||
|
||||
if (!DeviceManager::approved($token)) {
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
|
||||
echo json_encode(array(
|
||||
'state' => 'unsuccess',
|
||||
'errorMSG' => "Unaproved Device",
|
||||
), JSON_PRETTY_PRINT);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Diagnostic Data Write to DB
|
||||
if ($settings != null && $settings != ""){
|
||||
$data = ['mac' => $settings["network"]["mac"], 'ip_address' => $settings["network"]["ip"]];
|
||||
if (array_key_exists("firmware_hash", $settings)) {
|
||||
$data['firmware_hash'] = $settings["firmware_hash"];
|
||||
}
|
||||
DeviceManager::editByToken($token, $data);
|
||||
$jsonAnswer = [
|
||||
'state' => 'succes',
|
||||
'command' => $command,
|
||||
];
|
||||
echo json_encode($jsonAnswer, JSON_PRETTY_PRINT);
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
|
||||
die();
|
||||
}
|
||||
|
||||
// Issuing command
|
||||
if ($command == "null"){
|
||||
$device = DeviceManager::getDeviceByToken($token);
|
||||
$deviceId = $device['device_id'];
|
||||
$deviceCommand = $device["command"];
|
||||
if ($deviceCommand != '' && $deviceCommand != null && $deviceCommand != "null")
|
||||
{
|
||||
$command = $deviceCommand;
|
||||
$data = [
|
||||
'command'=>'null'
|
||||
];
|
||||
DeviceManager::editByToken($token, $data);
|
||||
$logManager->write("[API] Device_ID " . $deviceId . " executing command " . $command, LogRecordType::INFO);
|
||||
}
|
||||
}
|
||||
|
||||
// Diagnostic Logs Write To log File
|
||||
if ($deviceLogs != null && $deviceLogs != ""){
|
||||
foreach ($deviceLogs as $log) {
|
||||
$logManager->write("[Device Log Msg] Device_ID " . $deviceId . "->" . $log, LogRecordType::ERROR);
|
||||
}
|
||||
$jsonAnswer = [
|
||||
'state' => 'succes',
|
||||
'command' => $command,
|
||||
];
|
||||
echo json_encode($jsonAnswer, JSON_PRETTY_PRINT);
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
|
||||
die();
|
||||
}
|
||||
|
||||
// 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'],3));
|
||||
$logManager->write("[API] Device_ID " . $deviceId . " writed value " . $key . ' ' . $value['value'], LogRecordType::INFO);
|
||||
|
||||
//notification
|
||||
if ($key == 'door' || $key == 'water') {
|
||||
$notificationMng = new NotificationManager;
|
||||
$notificationData = [];
|
||||
|
||||
switch ($key) {
|
||||
case 'door':
|
||||
$notificationData = [
|
||||
'title' => 'Info',
|
||||
'body' => 'Someone just open up '.$device['name'],
|
||||
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
|
||||
];
|
||||
|
||||
break;
|
||||
case 'water':
|
||||
$notificationData = [
|
||||
'title' => 'Alert',
|
||||
'body' => 'Wather leak detected by '.$device['name'],
|
||||
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
|
||||
];
|
||||
break;
|
||||
}
|
||||
if (DEBUGMOD) $notificationData['body'] .= ' value='.$value['value'];
|
||||
if ($notificationData != []) {
|
||||
$subscribers = $notificationMng::getSubscription();
|
||||
foreach ($subscribers as $key => $subscriber) {
|
||||
$logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " ", LogRecordType::INFO);
|
||||
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$hostname = strtolower($device['name']);
|
||||
$hostname = str_replace(' ', '_', $hostname);
|
||||
//upravit format na setings-> netvork etc
|
||||
$jsonAnswer = [
|
||||
'device' => [
|
||||
'hostname' => $hostname,
|
||||
'ipAddress' => $device['ip_address'],
|
||||
'subnet' => $device['subnet'],
|
||||
'gateway' => $device['gateway'],
|
||||
],
|
||||
'state' => 'succes',
|
||||
'command' => $command,
|
||||
];
|
||||
|
||||
$subDevicesTypeList = SubDeviceManager::getSubDeviceSTypeForMater($deviceId);
|
||||
if (!in_array($subDevicesTypeList, ['on/off', 'door', 'water'])) {
|
||||
$jsonAnswer['device']['sleepTime'] = $device['sleep_time'];
|
||||
}
|
||||
echo json_encode($jsonAnswer, JSON_PRETTY_PRINT);
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
|
||||
} else {
|
||||
//Vypis
|
||||
$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'];
|
||||
|
||||
if ($subDeviceLastReord['execuded'] == 0){
|
||||
$logManager->write("[API] subDevice_ID ".$subDeviceId . " executed comand with value " .$subDeviceLastReordValue . " record id " . $subDeviceLastReord['record_id'] . " executed " . $subDeviceLastReord['execuded'], LogRecordType::INFO);
|
||||
RecordManager::setExecuted($subDeviceLastReord['record_id']);
|
||||
}
|
||||
|
||||
echo json_encode(array(
|
||||
'device' => [
|
||||
'hostname' => $device['name'],
|
||||
'ipAddress' => $device['ip_address'],
|
||||
'subnet' => $device['subnet'],
|
||||
'gateway' => $device['gateway'],
|
||||
],
|
||||
'state' => 'succes',
|
||||
'value' => $subDeviceLastReordValue,
|
||||
'command' => $command,
|
||||
), JSON_PRETTY_PRINT);
|
||||
header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
|
||||
}
|
||||
|
||||
unset($logManager);
|
||||
Db::disconect();
|
||||
die();
|
93
www/app/Bootstrap.php
Normal file
93
www/app/Bootstrap.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
//Autoloader
|
||||
class Autoloader {
|
||||
protected static $extension = ".php";
|
||||
protected static $root = __DIR__;
|
||||
protected static $files = [];
|
||||
|
||||
static function ClassLoader ($className = ""){
|
||||
$directorys = new RecursiveDirectoryIterator(static::$root, RecursiveDirectoryIterator::SKIP_DOTS);
|
||||
|
||||
//echo '<pre>';
|
||||
//var_dump($directorys);
|
||||
//echo '</pre>';
|
||||
|
||||
$files = new RecursiveIteratorIterator($directorys, RecursiveIteratorIterator::LEAVES_ONLY);
|
||||
|
||||
$filename = $className . static::$extension;
|
||||
|
||||
foreach ($files as $key => $file) {
|
||||
if (strtolower($file->getFilename()) === strtolower($filename) && $file->isReadable()) {
|
||||
include_once $file->getPathname();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function setRoot($rootPath){
|
||||
static::$root = $rootPath;
|
||||
}
|
||||
}
|
||||
|
||||
spl_autoload_register("Autoloader::ClassLoader");
|
||||
Autoloader::setRoot('/var/www/dev.steelants.cz/vasek/home-update/');
|
||||
|
||||
class ErrorHandler {
|
||||
static function exception($exception){
|
||||
error_log($exception);
|
||||
http_response_code($exception->getCode());
|
||||
$message = [
|
||||
'code' => $exception->getCode(),
|
||||
'message' => $exception->getMessage(),
|
||||
];
|
||||
echo json_encode($message);
|
||||
|
||||
$apiLogManager = new LogManager('../logs/'. date("Y-m-d").'.log');
|
||||
$apiLogManager->write("[APACHE] ERROR\n" . json_encode($message, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
}
|
||||
}
|
||||
set_exception_handler("ErrorHandler::exception");
|
||||
|
||||
$json = file_get_contents('php://input');
|
||||
$obj = json_decode($json, true);
|
||||
|
||||
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
|
||||
|
||||
$apiLogManager->write("[API] request body\n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
$apiLogManager->write("[API] POST body\n" . json_encode($_POST, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
$apiLogManager->write("[API] GET body\n" . json_encode($_GET, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
|
||||
//Debug
|
||||
error_reporting(E_ALL);
|
||||
ini_set( 'display_errors','1');
|
||||
|
||||
//setup
|
||||
ini_set ('session.cookie_httponly', '1');
|
||||
ini_set('session.cookie_domain', $_SERVER['HTTP_HOST']);
|
||||
ini_set('session.cookie_path', str_replace("login", "", str_replace('https://' . $_SERVER['HTTP_HOST'], "", $_SERVER['REQUEST_URI'])));
|
||||
ini_set('session.cookie_secure', '1');
|
||||
session_start ();
|
||||
mb_internal_encoding ("UTF-8");
|
||||
|
||||
// import configs
|
||||
require_once '../config/config.php';
|
||||
|
||||
// Logs
|
||||
$logManager = new LogManager();
|
||||
|
||||
// Language
|
||||
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
|
||||
$langTag = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
|
||||
$langMng = new LanguageManager($langTag);
|
||||
$langMng->load();
|
||||
}
|
||||
|
||||
//D B Conector
|
||||
Db::connect (DBHOST, DBUSER, DBPASS, DBNAME);
|
||||
|
||||
// TODO: Přesunout do Login Pohledu
|
||||
$userManager = new UserManager();
|
||||
|
||||
// import routes
|
||||
require_once '../app/Routes.php';
|
31
www/app/Routes.php
Normal file
31
www/app/Routes.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
$router = new Router();
|
||||
|
||||
$router->setDefault(function(){
|
||||
echo $_GET['url'].': 404';
|
||||
});
|
||||
|
||||
//Pages
|
||||
$router->any('/', 'Log');
|
||||
$router->any('/login', 'Login');
|
||||
$router->any('/logout', 'Logout');
|
||||
$router->any('/automation', 'Automation');
|
||||
$router->any('/setting', 'Setting');
|
||||
$router->any('/ajax', 'Ajax');
|
||||
|
||||
$router->post('/api/login', 'AuthApi@login');
|
||||
$router->post('/api/logout', 'AuthApi@logout');
|
||||
|
||||
$router->get('/api/devices', 'DevicesApi@default');
|
||||
$router->get('/api/rooms', 'RoomsApi@default');
|
||||
|
||||
$router->get('/api/HA/auth', 'GoogleHomeApi@autorize');
|
||||
$router->any('/api/HA', 'GoogleHomeApi@response');
|
||||
|
||||
// examples
|
||||
$router->any('/api/example', 'ExampleApi@example');
|
||||
$router->any('/example', 'ExampleController@index');
|
||||
$router->any('/example/subpage', 'ExampleController@subpage');
|
||||
|
||||
$router->run($_SERVER['REQUEST_METHOD'], '/'.(isset($_GET['url']) ? $_GET['url'] : ''));
|
25
www/app/api/AuthApi.php
Normal file
25
www/app/api/AuthApi.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
class AuthApi {
|
||||
public function login(){
|
||||
$token = (new AuthManager)->getToken($this->input->username,$this->input->password);
|
||||
if (!$token) {
|
||||
throw new Exception("Auth failed", 401);
|
||||
}
|
||||
$this->response(['token' => $token]);
|
||||
}
|
||||
|
||||
public function logout(){
|
||||
$authenticationBearrer = $_SERVER['HTTP_AUTHORIZATION'];
|
||||
if (!(new AuthManager)->deleteToken($authenticationBearrer)) {
|
||||
throw new Exception("logout Failed", 401);
|
||||
}
|
||||
}
|
||||
|
||||
public function registration(){
|
||||
|
||||
}
|
||||
|
||||
public function restartPassword(){
|
||||
|
||||
}
|
||||
}
|
17
www/app/api/DevicesApi.php
Normal file
17
www/app/api/DevicesApi.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
class DevicesApi extends ApiController{
|
||||
|
||||
public function default(){
|
||||
$this->requireAuth();
|
||||
$response = [];
|
||||
|
||||
// TODO: process the request
|
||||
|
||||
$this->response($response);
|
||||
}
|
||||
|
||||
public function getDevicesByRoom($roomId){
|
||||
|
||||
}
|
||||
}
|
24
www/app/api/ExampleApi.php
Normal file
24
www/app/api/ExampleApi.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class ExampleApi extends ApiController{
|
||||
|
||||
public function example(){
|
||||
// if this function should be accessible only for logged users uncomment next line
|
||||
// $this->requireAuth();
|
||||
// if user is logged in, next lines will be processed
|
||||
// otherwise script get terminated with 401 UNAUTHORIZED
|
||||
|
||||
|
||||
// input data are stored in $this->input
|
||||
// in this example we just copy input to response
|
||||
$response = $this->input;
|
||||
|
||||
|
||||
// this method returns response as json
|
||||
$this->response($response);
|
||||
// you can specify returned http code by second optional parameter
|
||||
// default value is 200
|
||||
// $this->response($response, $httpCode);
|
||||
}
|
||||
|
||||
}
|
46
www/app/api/GoogleHomeApi.php
Normal file
46
www/app/api/GoogleHomeApi.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
class GoogleHomeApi {
|
||||
static function response(){
|
||||
|
||||
$json = file_get_contents('php://input');
|
||||
$obj = json_decode($json, true);
|
||||
|
||||
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
|
||||
header('Content-Type: application/json');
|
||||
|
||||
switch ($obj['inputs'][0]['intent']) {
|
||||
case 'action.devices.SYNC':
|
||||
GoogleHome::sync($obj['requestId']);
|
||||
$apiLogManager->write("[Google Home] action.devices.SYNC", LogRecordType::INFO);
|
||||
break;
|
||||
|
||||
case 'action.devices.QUERY':
|
||||
GoogleHome::query($obj['requestId'], $obj['inputs'][0]['payload']);
|
||||
//$apiLogManager->write("[Google Home] action.devices.QUERY", LogRecordType::INFO);
|
||||
break;
|
||||
|
||||
case 'action.devices.EXECUTE':
|
||||
GoogleHome::execute($obj['requestId'], $obj['inputs'][0]['payload']);
|
||||
$apiLogManager->write("[Google Home] action.devices.EXECUTE", LogRecordType::INFO);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static function autorize(){
|
||||
$json = file_get_contents('php://input');
|
||||
$obj = json_decode($json, true);
|
||||
|
||||
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
|
||||
$apiLogManager->write("[API] request body\n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
$apiLogManager->write("[API] GET body\n" . json_encode($_GET, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
|
||||
$get = [
|
||||
"access_token"=>"2222255888",
|
||||
"token_type"=>"Bearer",
|
||||
"state"=>$_GET["state"],
|
||||
];
|
||||
|
||||
echo $_GET["redirect_uri"] . '#' . http_build_query($get) ;
|
||||
echo '<a href="'.$_GET["redirect_uri"] . '#' . http_build_query($get) . '">FINISH</a>';
|
||||
}
|
||||
}
|
26
www/app/api/RoomsApi.php
Normal file
26
www/app/api/RoomsApi.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class RoomsApi extends ApiController{
|
||||
|
||||
public function default(){
|
||||
//$this->requireAuth();
|
||||
$response = [];
|
||||
$roomIds = [];
|
||||
$roomsData = RoomManager::getRoomsDefault();
|
||||
|
||||
foreach ($roomsData as $roomKey => $room) {
|
||||
$roomIds[] = $room['room_id'];
|
||||
}
|
||||
|
||||
$subDevicesData = SubDeviceManager::getSubdevicesByRoomIds($roomIds);
|
||||
|
||||
foreach ($roomsData as $roomKey => $roomData) {
|
||||
$response[] = [
|
||||
'room_id' => $roomData['room_id'],
|
||||
'name' => $roomData['name'],
|
||||
'widgets' => isset($subDevicesData[$roomData['room_id']]) ? $subDevicesData[$roomData['room_id']] : [],
|
||||
];
|
||||
}
|
||||
$this->response($response);
|
||||
}
|
||||
}
|
14
www/app/controllers/ExampleController.php
Normal file
14
www/app/controllers/ExampleController.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class ExampleController extends Controller{
|
||||
|
||||
public function index(){
|
||||
$this->view->title = 'Example title';
|
||||
$this->view->render('example.phtml');
|
||||
}
|
||||
|
||||
public function subpage(){
|
||||
echo 'subpage';
|
||||
}
|
||||
|
||||
}
|
77
www/app/controllers/automationController.php
Normal file
77
www/app/controllers/automationController.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
if (isset($_POST) && !empty($_POST)){
|
||||
if (isset($_POST['modalFinal']) && $_POST['action'] == "add") {
|
||||
$doCode = json_encode($_POST['device'], JSON_PRETTY_PRINT);
|
||||
|
||||
$value = $_POST['atSelector'];
|
||||
if ($_POST['atSelector'] == 'time'){
|
||||
$value = $_POST['atSelectorValue'];
|
||||
} else if ($_POST['atSelector'] == 'atDeviceValue') {
|
||||
$value = json_decode($_POST['atSelectorValue']);
|
||||
} else if ($_POST['atSelector'] == 'inHome' || $_POST['atSelector'] == 'outHome') {
|
||||
$value = UserManager::getUserData('user_id');
|
||||
}
|
||||
|
||||
|
||||
$ifCode = json_encode([
|
||||
"type" => $_POST['atSelector'],
|
||||
"value" => $value,
|
||||
], JSON_PRETTY_PRINT);
|
||||
$onDays = $_POST['atDays'];
|
||||
|
||||
//Debug
|
||||
// if (DEBUGMOD == 1) {
|
||||
// echo '<pre>';
|
||||
// echo $permissionsInJson;
|
||||
// echo $deviceId;
|
||||
// var_dump(json_decode ($permissionsInJson));
|
||||
// echo '</pre>';
|
||||
// echo '<a href="' . BASEDIR .'">CONTINUE</a>';
|
||||
// die();
|
||||
// }
|
||||
|
||||
AutomationManager::create($_POST['name'], $onDays, $doCode, $ifCode);
|
||||
|
||||
header('Location: ' . BASEURL . strtolower(basename(__FILE__, '.php')));
|
||||
die();
|
||||
} else if (isset($_POST['modalFinal']) && $_POST['action'] == "edit") {
|
||||
$doCode = json_encode($_POST['device'], JSON_PRETTY_PRINT);
|
||||
|
||||
if (isset ($_POST['atDeviceValue'])) {
|
||||
$subDeviceId = $_POST['atDeviceValue'];
|
||||
$subDeviceValue = $_POST['atDeviceValueInt'];
|
||||
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
|
||||
$subDeviceMaster = SubDeviceManager::getSubDeviceMaster($subDeviceId,$subDevice['type']);
|
||||
|
||||
$device = [
|
||||
'deviceID' => $subDeviceMaster['device_id'],
|
||||
'type'=> $subDevice['type'],
|
||||
'value'=> $subDeviceValue,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$value = $_POST['atSelector'];
|
||||
if (isset($_POST['atTime'])){
|
||||
$value = $_POST['atTime'];
|
||||
} else if (isset($_POST['atDeviceValue'])) {
|
||||
$value = $device;
|
||||
} else if ($_POST['atSelector'] == 'inHome' || $_POST['atSelector'] == 'outHome') {
|
||||
//TODO: opravit edit aby vkládal id původního uživatele
|
||||
$value = UserManager::getUserData('user_id');
|
||||
}
|
||||
|
||||
$value = (isset($_POST['atTime']) ? $_POST['atTime'] : (isset($_POST['atDeviceValue']) ? $device : $_POST['atSelector']));
|
||||
$ifCode = json_encode([
|
||||
"type" => $_POST['atSelector'],
|
||||
"value" => $value,
|
||||
], JSON_PRETTY_PRINT);
|
||||
$onDays = ($_POST['day'] != '' ? json_encode($_POST['day']) : '');
|
||||
|
||||
AutomationManager::create($_POST['name'], $onDays, $doCode, $ifCode, (isset ($_POST['automation_id']) ? $_POST['automation_id'] : ""));
|
||||
|
||||
header('Location: ' . BASEURL . strtolower(basename(__FILE__, '.php')));
|
||||
die();
|
||||
}
|
||||
}
|
||||
?>
|
51
www/app/controllers/loginController.php
Normal file
51
www/app/controllers/loginController.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
global $userManager;
|
||||
|
||||
|
||||
if (
|
||||
isset($_POST['username']) &&
|
||||
$_POST['username'] != '' &&
|
||||
isset($_POST['password']) &&
|
||||
$_POST['password'] != ''
|
||||
){
|
||||
$ota = false;
|
||||
$userName = $_POST['username'];
|
||||
$userPassword = $_POST['password'];
|
||||
$rememberMe = (isset ($_POST['remember']) ? $_POST['remember'] : "");
|
||||
$ota = $userManager->haveOtaEnabled($userName);
|
||||
if ($ota == "") {
|
||||
$landingPage = $userManager->login($userName, $userPassword, $rememberMe);
|
||||
header('Location: ' . BASEURL . $landingPage);
|
||||
die();
|
||||
}
|
||||
|
||||
$_SESSION['USERNAME'] = $userName;
|
||||
$_SESSION['PASSWORD'] = $userPassword;
|
||||
$_SESSION['REMEMBER'] = $rememberMe;
|
||||
$_SESSION['OTA'] = $ota;
|
||||
} else if (
|
||||
isset($_POST['otaCode']) &&
|
||||
$_POST['otaCode'] != ''
|
||||
) {
|
||||
|
||||
$otaCode = $_POST['otaCode'];
|
||||
$otaSecret = $_POST['otaSecret'];
|
||||
|
||||
$ga = new PHPGangsta_GoogleAuthenticator();
|
||||
$ota = $_SESSION['OTA'];
|
||||
$userName = $_SESSION['USERNAME'];
|
||||
$userPassword = $_SESSION['PASSWORD'];
|
||||
$rememberMe = $_SESSION['REMEMBER'];
|
||||
unset($_SESSION['OTA']);
|
||||
$checkResult = $ga->verifyCode($otaSecret, $otaCode, 2); // 2 = 2*30sec clock tolerance
|
||||
if ($checkResult) {
|
||||
$landingPage = $userManager->login($userName, $userPassword, $rememberMe);
|
||||
header('Location: ' . BASEURL . '/');
|
||||
echo 'OK';
|
||||
} else {
|
||||
echo 'FAILED';
|
||||
}
|
||||
//TODO: upravi a ověřit jeslti ja zabezpečené
|
||||
//TODO:
|
||||
die();
|
||||
}
|
29
www/app/controllers/settingController.php
Normal file
29
www/app/controllers/settingController.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
if (isset($_POST) && !empty($_POST)){
|
||||
if (isset($_POST['submitPasswordChange']) && $_POST['submitPasswordChange'] != "") {
|
||||
$oldPassword = $_POST['oldPassword'];
|
||||
$newPassword = $_POST['newPassword1'];
|
||||
$newPassword2 = $_POST['newPassword2'];
|
||||
UserManager::changePassword($oldPassword, $newPassword, $newPassword2);
|
||||
header('Location: ' . BASEURL . 'logout');
|
||||
die();
|
||||
} else if (isset($_POST['submitCreateUser']) && $_POST['submitCreateUser'] != "") {
|
||||
$userName = $_POST['userName'];
|
||||
$password = $_POST['userPassword'];
|
||||
UserManager::createUser($userName, $password);
|
||||
header('Location: ' . BASEURL . 'setting');
|
||||
die();
|
||||
} else if (isset($_POST['submitEnableOta']) && $_POST['submitEnableOta'] != "") {
|
||||
echo $otaCode = $_POST['otaCode'];
|
||||
echo $otaSecret = $_POST['otaSecret'];
|
||||
|
||||
|
||||
$ga = new PHPGangsta_GoogleAuthenticator();
|
||||
$checkResult = $ga->verifyCode($otaSecret, $otaCode, 2); // 2 = 2*30sec clock tolerance
|
||||
if ($checkResult) {
|
||||
UserManager::setOta($otaCode, $otaSecret);
|
||||
}
|
||||
header('Location: ' . BASEURL . 'setting');
|
||||
die();
|
||||
}
|
||||
}
|
194
www/app/models/ChartJS.php
Normal file
194
www/app/models/ChartJS.php
Normal 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
www/app/models/ChartJS_Line.php
Normal file
21
www/app/models/ChartJS_Line.php
Normal 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;
|
||||
}
|
||||
}
|
268
www/app/models/GoogleHome.php
Normal file
268
www/app/models/GoogleHome.php
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
class GoogleHome {
|
||||
static function sync($requestId){
|
||||
$devices = [];
|
||||
$roomsData = RoomManager::getAllRooms();
|
||||
foreach ($roomsData as $roomKey => $roomData) {
|
||||
$devicesData = DeviceManager::getAllDevicesInRoom($roomData['room_id']);
|
||||
foreach ($devicesData as $deviceKey => $deviceData) {
|
||||
$subDevicesData = SubDeviceManager::getAllSubDevices($deviceData['device_id']);
|
||||
foreach ($subDevicesData as $subDeviceKey => $subDeviceData) {
|
||||
if ($subDeviceData['type'] != "on/off" && $subDeviceData['type'] != "temp_cont") continue;
|
||||
|
||||
//Google Compatibile Action Type
|
||||
$actionType = GoogleHomeDeviceTypes::getAction($subDeviceData['type']);
|
||||
|
||||
if (
|
||||
strpos($deviceData['name'], 'Světlo') !== false ||
|
||||
strpos($deviceData['name'], 'světlo') !== false
|
||||
) {
|
||||
$actionType = 'action.devices.types.LIGHT';
|
||||
}
|
||||
|
||||
$tempDevice = [
|
||||
'id' => (string) $subDeviceData['subdevice_id'],
|
||||
'type' => $actionType,
|
||||
'name' => [
|
||||
'name' => $deviceData['name'],
|
||||
],
|
||||
'willReportState' => false,
|
||||
'roomHint' => $roomData['name']
|
||||
];
|
||||
|
||||
//traids & Attributes
|
||||
$devices[] = GoogleHomeDeviceTypes::getSyncObj($tempDevice, $actionType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'requestId' => $requestId,
|
||||
'payload' => [
|
||||
'agentUserId'=>'651351531531',
|
||||
'devices' => $devices,
|
||||
],
|
||||
];
|
||||
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
|
||||
$apiLogManager->write("[API][$requestId] request response\n" . json_encode($response, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
static function query($requestId, $payload){
|
||||
$devices = [];
|
||||
foreach ($payload['devices'] as $deviceId) {
|
||||
$subDeviceData = SubDeviceManager::getSubDevice($deviceId['id']);
|
||||
if ($subDeviceData['type'] != "on/off" && $subDeviceData['type'] != "temp_cont") continue;
|
||||
|
||||
$state = false;
|
||||
if (RecordManager::getLastRecord($deviceId['id'])['value'] == 1){
|
||||
$state = true;
|
||||
}
|
||||
|
||||
$online = false;
|
||||
$status = 'OFFLINE';
|
||||
|
||||
if (RecordManager::getLastRecord($deviceId['id'])['execuded'] == 1){
|
||||
$online = true;
|
||||
$status = 'SUCCESS';
|
||||
} else {
|
||||
$executed = 0;
|
||||
$waiting = 0;
|
||||
foreach (RecordManager::getLastRecord($deviceId['id'], 6) as $key => $value) {
|
||||
if ($value['execuded'] == 1){
|
||||
$executed++;
|
||||
} else {
|
||||
$waiting++;
|
||||
}
|
||||
}
|
||||
if ($waiting < $executed){
|
||||
$status = "PENDING";
|
||||
$online = true;
|
||||
}
|
||||
}
|
||||
|
||||
$tempDevice = [
|
||||
$deviceId['id'] => [
|
||||
'online' => $online,
|
||||
'status'=> $status,
|
||||
]
|
||||
];
|
||||
|
||||
if ($subDeviceData['type'] == "temp_cont"){
|
||||
$tempDevice[$deviceId['id']]['thermostatMode'] = 'off';
|
||||
if (RecordManager::getLastRecord($deviceId['id'])['value'] != 0) {
|
||||
$tempDevice[$deviceId['id']]['thermostatMode'] = 'heat';
|
||||
$tempDevice[$deviceId['id']]['thermostatTemperatureAmbient'] = RecordManager::getLastRecord($deviceId['id'])['value'];
|
||||
$tempDevice[$deviceId['id']]['thermostatTemperatureSetpoint'] = RecordManager::getLastRecord($deviceId['id'])['value'];
|
||||
}
|
||||
} else {
|
||||
$tempDevice[$deviceId['id']]['on'] = $state;
|
||||
}
|
||||
$devices = $tempDevice;
|
||||
if (count($devices)> 1){
|
||||
$devices[] = $tempDevice;
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'requestId' => $requestId,
|
||||
'payload' => [
|
||||
'devices' => $devices,
|
||||
],
|
||||
];
|
||||
|
||||
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
|
||||
$apiLogManager->write("[API][$requestId] request response\n" . json_encode($response, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
static function execute($requestId, $payload){
|
||||
$commands = [];
|
||||
|
||||
foreach ($payload['commands'] as $key => $command) {
|
||||
foreach ($command['devices'] as $key => $device) {
|
||||
$executionCommand = $command['execution'][0];
|
||||
if (isset($command['execution'][$key])) {
|
||||
$executionCommand = $command['execution'][$key];
|
||||
}
|
||||
|
||||
$subDeviceId = $device['id'];
|
||||
|
||||
switch ($executionCommand['command']) {
|
||||
case 'action.devices.commands.OnOff':
|
||||
$commands[] = self::executeSwitch($subDeviceId, $executionCommand);
|
||||
break;
|
||||
|
||||
case 'action.devices.commands.ThermostatTemperatureSetpoint':
|
||||
$commands[] = self::executeTermostatValue($subDeviceId, $executionCommand);
|
||||
break;
|
||||
|
||||
case 'action.devices.commands.ThermostatSetMode':
|
||||
$commands[] = self::executeTermostatMode($subDeviceId, $executionCommand);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response = [
|
||||
'requestId' => $requestId,
|
||||
'payload' => [
|
||||
'commands' => $commands,
|
||||
],
|
||||
];
|
||||
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
|
||||
$apiLogManager->write("[API][EXECUTE][$requestId]\n" . json_encode($response, JSON_PRETTY_PRINT), LogRecordType::INFO);
|
||||
|
||||
echo json_encode($response);
|
||||
}
|
||||
|
||||
static function executeSwitch($subDeviceId, $executionCommand){
|
||||
$value = 0;
|
||||
$status = 'SUCCESS';
|
||||
if ($executionCommand['params']['on']) $value = 1;
|
||||
|
||||
RecordManager::createWithSubId($subDeviceId, $value);
|
||||
|
||||
$executed = 0;
|
||||
$waiting = 0;
|
||||
foreach (RecordManager::getLastRecord($subDeviceId, 4) as $key => $value) {
|
||||
if ($value['execuded'] == 1){
|
||||
$executed++;
|
||||
} else {
|
||||
$waiting++;
|
||||
}
|
||||
}
|
||||
if ($waiting < $executed){
|
||||
$status = "PENDING";
|
||||
} else {
|
||||
$status = "OFFLINE";
|
||||
}
|
||||
|
||||
$commandTemp = [
|
||||
'ids' => [$subDeviceId],
|
||||
'status' => $status,
|
||||
'states' => [
|
||||
'on' => $executionCommand['params']['on'],
|
||||
],
|
||||
];
|
||||
return $commandTemp;
|
||||
}
|
||||
|
||||
static function executeTermostatValue($subDeviceId, $executionCommand){
|
||||
$value = 0;
|
||||
$status = 'SUCCESS';
|
||||
|
||||
if (isset($executionCommand['params']['thermostatTemperatureSetpoint'])) {
|
||||
$value = $executionCommand['params']['thermostatTemperatureSetpoint'];
|
||||
}
|
||||
|
||||
RecordManager::createWithSubId($subDeviceId, $value);
|
||||
|
||||
$executed = 0;
|
||||
$waiting = 0;
|
||||
foreach (RecordManager::getLastRecord($subDeviceId, 4) as $key => $lastValue) {
|
||||
if ($lastValue['execuded'] == 1){
|
||||
$executed++;
|
||||
} else {
|
||||
$waiting++;
|
||||
}
|
||||
}
|
||||
if ($waiting < $executed){
|
||||
$status = "PENDING";
|
||||
} else {
|
||||
$status = "OFFLINE";
|
||||
}
|
||||
|
||||
$commandTemp = [
|
||||
'ids' => [$subDeviceId],
|
||||
'status' => $status,
|
||||
'states' => [
|
||||
'thermostatMode' => 'heat',
|
||||
'thermostatTemperatureSetpoint' => $value,
|
||||
'thermostatTemperatureAmbient' => $value,
|
||||
//ambient z dalšího zenzoru v roomu
|
||||
],
|
||||
];
|
||||
|
||||
if ($timeout >= 5){
|
||||
$commandTemp['status'] = "OFFLINE";
|
||||
}
|
||||
return $commandTemp;
|
||||
}
|
||||
|
||||
static function executeTermostatMode($subDeviceId, $executionCommand){
|
||||
$mode = "off";
|
||||
$value = 0;
|
||||
$status = "SUCCESS";
|
||||
|
||||
if (isset($executionCommand['params']['thermostatMode']) && $executionCommand['params']['thermostatMode'] != 'off') {
|
||||
$mode = $executionCommand['params']['thermostatMode'];
|
||||
$value = RecordManager::getLastRecordNotNull($subDeviceId)['value'];
|
||||
}
|
||||
|
||||
RecordManager::createWithSubId($subDeviceId, $value);
|
||||
|
||||
$executed = 0;
|
||||
$waiting = 0;
|
||||
foreach (RecordManager::getLastRecord($deviceId['id'], 4) as $key => $value) {
|
||||
if ($value['execuded'] == 1){
|
||||
$executed++;
|
||||
} else {
|
||||
$waiting++;
|
||||
}
|
||||
}
|
||||
if ($waiting < $executed){
|
||||
$status = "PENDING";
|
||||
}
|
||||
|
||||
$commandTemp = [
|
||||
'ids' => [$subDeviceId],
|
||||
'status' => $status,
|
||||
'states' => [
|
||||
'thermostatMode' => $mode
|
||||
],
|
||||
];
|
||||
|
||||
return $commandTemp;
|
||||
}
|
||||
}
|
45
www/app/models/managers/AuthManager.php
Normal file
45
www/app/models/managers/AuthManager.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
class AuthManager {
|
||||
public function getToken($username, $password){
|
||||
$userManager = new UserManager();
|
||||
if ($username != '' || $password != ''){
|
||||
$userLogedIn = $userManager->loginNew($username, $password);
|
||||
|
||||
if ($userLogedIn != false){
|
||||
// Create token header as a JSON string
|
||||
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
|
||||
// Create token payload as a JSON string
|
||||
$payload = json_encode(['user_id' => $userLogedIn]);
|
||||
// Encode Header to Base64Url String
|
||||
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
|
||||
// Encode Payload to Base64Url String
|
||||
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
|
||||
// Create Signature Hash
|
||||
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, 'abC123!', true);
|
||||
// Encode Signature to Base64Url String
|
||||
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
|
||||
// Create JWT
|
||||
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
|
||||
|
||||
return $jwt;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function deleteToken($token){
|
||||
Db::command ('DELETE FROM tokens WHERE token=?', array ($token));
|
||||
return true;
|
||||
}
|
||||
|
||||
public function validateToken($token){
|
||||
$tokens = Db::loadAll('SELECT * FROM tokens WHERE token = ? AND expire >= CURRENT_TIMESTAMP AND blocked = 0;', array($token));
|
||||
if (count($tokens) == 1) {
|
||||
return true;
|
||||
} else if (count($tokens) == 0) {
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
}
|
175
www/app/models/managers/AutomationManager.php
Normal file
175
www/app/models/managers/AutomationManager.php
Normal file
@@ -0,0 +1,175 @@
|
||||
<?php
|
||||
|
||||
class AutomationManager{
|
||||
public static $automation;
|
||||
|
||||
public static function remove($automationId) {
|
||||
return Db::command ('DELETE FROM automation WHERE automation_id=?', array ($automationId));
|
||||
}
|
||||
|
||||
public static 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 static function restart($automationId) {
|
||||
return Db::command ('UPDATE automation SET executed = 0 WHERE automation_id=?', array ($automationId));
|
||||
}
|
||||
|
||||
public static function create ($name, $onDays, $doCode, $ifCode, $automationId = "") {
|
||||
$userId = UserManager::getUserData('user_id');
|
||||
$scene = array (
|
||||
'name' => $name,
|
||||
'owner_id' => $userId,
|
||||
'on_days' => $onDays,
|
||||
'if_something' => $ifCode,
|
||||
'do_something' => $doCode,
|
||||
);
|
||||
try {
|
||||
if ($automationId == "") {
|
||||
Db::add ('automation', $scene);
|
||||
} else {
|
||||
Db::edit ('automation', $scene, 'WHERE automation_id = ?', array ($automationId));
|
||||
}
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAll(){
|
||||
return Db::loadAll ("SELECT * FROM automation");
|
||||
|
||||
}
|
||||
|
||||
public static function executeAll(){
|
||||
global $logManager;
|
||||
|
||||
$automations = Db::loadAll ("SELECT * FROM automation");
|
||||
$dayNameNow = strtolower (date('D', time()));
|
||||
|
||||
foreach ($automations as $automation) {
|
||||
$onValue = json_decode($automation['if_something'], true);
|
||||
$sceneDoJson = $automation['do_something'];
|
||||
$actionDays = json_decode($automation['on_days'], true);
|
||||
$value = time();
|
||||
$run = false;
|
||||
$restart = false;
|
||||
|
||||
if ($automation['active'] == 1 && $automation['locked'] != 1){
|
||||
Db::edit('automation', array('locked' => 1), 'WHERE automation_id = ?', array($automation['automation_id']));
|
||||
if (in_array($dayNameNow, $actionDays)){
|
||||
if (in_array($onValue['type'], ['sunSet', 'sunRise', 'time','now'])) {
|
||||
if ($onValue['type'] == 'sunSet') {
|
||||
$value = date_sunset($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90);
|
||||
} else if ($onValue['type'] == 'sunRise') {
|
||||
$value = date_sunrise($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90);
|
||||
} else if ($onValue['type'] == 'time') {
|
||||
$onValue = explode(':',$onValue['value']);
|
||||
$today = date_create('now');
|
||||
$onValue = $today->setTime($onValue[0], $onValue[1]);
|
||||
$value = $today->getTimestamp();
|
||||
}
|
||||
|
||||
if (time() > $value && $automation['executed'] == 0){
|
||||
$run = true;
|
||||
} else if (time() < $value && $automation['executed'] == 1) { //recovery realowing of automation
|
||||
$restart = true;
|
||||
}
|
||||
|
||||
} else if ($onValue['type'] == 'outHome') {
|
||||
//TODO: Add Ovner to automation
|
||||
$userHomeStatus = UserManager::getUserData('at_home', $onValue['value']);
|
||||
if ($userHomeStatus == 'false' && $automation['executed'] == 0) {
|
||||
$run = true;
|
||||
} else if ($userHomeStatus == 'true' && $automation['executed'] == 1) {
|
||||
$restart = true;
|
||||
}
|
||||
} else if ($onValue['type'] == 'inHome') {
|
||||
//TODO: Add Ovner to automation
|
||||
$userHomeStatus = UserManager::getUserData('at_home', $onValue['value']);
|
||||
if ($userHomeStatus == 'true' && $automation['executed'] == 0) {
|
||||
$run = true;
|
||||
} else if ($userHomeStatus == 'false' && $automation['executed'] == 1) {
|
||||
$restart = true;
|
||||
}
|
||||
} else if ($onValue['type'] == 'noOneHome') {
|
||||
$users = UserManager::getUsers();
|
||||
$membersHome = 0;
|
||||
foreach ($users as $key => $user) {
|
||||
if ($user['at_home'] == 'true'){
|
||||
$membersHome++;
|
||||
}
|
||||
}
|
||||
if ($membersHome == 0 && $automation['executed'] == 0) {
|
||||
$run = true;
|
||||
} else if ($membersHome > 0 && $automation['executed'] == 1){
|
||||
$restart = true;
|
||||
}
|
||||
} else if ($onValue['type'] == 'someOneHome') {
|
||||
$users = UserManager::getUsers();
|
||||
$membersHome = 0;
|
||||
foreach ($users as $key => $user) {
|
||||
if ($user['at_home'] == 'true'){
|
||||
$membersHome++;
|
||||
}
|
||||
}
|
||||
if ($membersHome == 0 && $automation['executed'] == 1) {
|
||||
$restart = true;
|
||||
} else if ($membersHome > 0 && $automation['executed'] == 0){
|
||||
$run = true;
|
||||
}
|
||||
} else if ($onValue['type'] == 'atDeviceValue') {
|
||||
|
||||
$subDeviceId = SubDeviceManager::getSubDeviceByMaster($onValue['value']['deviceID'], $onValue['value']['type'])["subdevice_id"];
|
||||
$lastValue = RecordManager::getLastRecord($subDeviceId);
|
||||
|
||||
if ($lastValue['value'] == $onValue['value']['value'] && $automation['executed'] == 0) {
|
||||
$run = true;
|
||||
|
||||
} else if ($lastValue['value'] != $onValue['value']['value'] && $automation['executed'] == 1){
|
||||
$restart = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//finalization
|
||||
if ($run) {
|
||||
$body = '';
|
||||
|
||||
$sceneDoArray = json_decode($sceneDoJson);
|
||||
foreach ($sceneDoArray as $deviceId => $deviceState) {
|
||||
RecordManager::create($deviceId, 'on/off', $deviceState);
|
||||
}
|
||||
|
||||
$subscribers = NotificationManager::getSubscription();
|
||||
$i = 0;
|
||||
|
||||
$notificationMng = new NotificationManager;
|
||||
$notificationData = [
|
||||
'title' => 'Automatization',
|
||||
'body' => 'Automatization '.$automation['name']." was just executed",
|
||||
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
|
||||
];
|
||||
|
||||
if ($notificationData != []) {
|
||||
$subscribers = $notificationMng::getSubscription();
|
||||
foreach ($subscribers as $key => $subscriber) {
|
||||
$logManager->write("[NOTIFICATION/AUTOOMATION] SENDING TO" . $subscriber['id'] . " ");
|
||||
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
|
||||
}
|
||||
}
|
||||
|
||||
$logManager->write("[AUTOMATIONS] automation id ". $automation['automation_id'] . " was executed");
|
||||
Db::edit('automation', array('executed' => 1, 'execution_time' => date("Y-m-d H:i:s")), 'WHERE automation_id = ?', array($automation['automation_id']));
|
||||
} else if ($restart) {
|
||||
$logManager->write("[AUTOMATIONS] automation id ". $automation['automation_id'] . " was restarted");
|
||||
Db::edit('automation', array('executed' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
|
||||
}
|
||||
Db::edit('automation', array('locked' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
129
www/app/models/managers/ChartManager.php
Normal file
129
www/app/models/managers/ChartManager.php
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
class ChartScale{
|
||||
const HOUR = 'info';
|
||||
const DAY = 'warning';
|
||||
const MONTH = 'warning';
|
||||
const YEAR = 'error';
|
||||
}
|
||||
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>';
|
||||
}
|
||||
|
||||
function generateChartData(int $subDeviceId, string $periode, string $groupBy) {
|
||||
$chartData = [];
|
||||
|
||||
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
|
||||
$records = RecordManager::getAllRecordForGraph($subDeviceId, $periode, $groupBy);
|
||||
|
||||
$array = array_column($records, 'value');
|
||||
$arrayTime = array_column($records, 'time');
|
||||
$output = [];
|
||||
|
||||
foreach ($array as $key => $value) {
|
||||
$output[$key]['y'] = $value;
|
||||
if ($subDevice['type'] == 'light'){
|
||||
if ($value > 810){
|
||||
$output[$key]['y'] = 1;
|
||||
} else {
|
||||
$output[$key]['y'] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$timeStamp = new DateTime($arrayTime[$key]);
|
||||
$output[$key]['t'] = $timeStamp->format("Y-m-d") . 'T' . $timeStamp->format("H:i:s") . 'Z';
|
||||
}
|
||||
|
||||
$data = json_encode($output);
|
||||
$data = $output;
|
||||
$arrayTimeStamps = array_column($records, 'time');
|
||||
foreach ($arrayTimeStamps as $key => $value) {
|
||||
$arrayTimeStamps[$key] = (new DateTime($value))->format(TIMEFORMAT);
|
||||
}
|
||||
|
||||
$chartData['graphRange'] = RANGES[$subDevice['type']];
|
||||
$chartData['graphType'] = RANGES[$subDevice['type']]['graph'];
|
||||
$chartData['graphData'] = $data;
|
||||
|
||||
return $chartData;
|
||||
}
|
||||
}
|
||||
?>
|
41
www/app/models/managers/DashboardManager.php
Normal file
41
www/app/models/managers/DashboardManager.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
class DashboardManager{
|
||||
public static $devices;
|
||||
|
||||
|
||||
static function getAllDashboards ($userId) {
|
||||
return Db::loadAll ("SELECT * FROM dashboard WHERE user_id=?", array($userId));
|
||||
}
|
||||
|
||||
static function getAllSubDevices ($userId) {
|
||||
return Db::loadAll ("SELECT * FROM subdevices WHERE subdevice_id IN (SELECT subdevice_id FROM dashboard WHERE user_id=?)", array($userId));
|
||||
}
|
||||
|
||||
static 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));
|
||||
}
|
||||
|
||||
static 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static function Remove ($subDeviceId){
|
||||
$userId = UserManager::getUserData('user_id');
|
||||
Db::command ('DELETE FROM dashboard WHERE subdevice_id=? AND user_id = ?', array ($subDeviceId, $userId));
|
||||
}
|
||||
}
|
96
www/app/models/managers/DeviceManager.php
Normal file
96
www/app/models/managers/DeviceManager.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
class DeviceManager{
|
||||
public static $devices;
|
||||
|
||||
static function getAllDevices () {
|
||||
return Db::loadAll ("SELECT * FROM devices WHERE approved != ?", Array(2));
|
||||
}
|
||||
|
||||
static function getAllDevicesInRoom ($roomId = "") {
|
||||
return Db::loadAll ("SELECT * FROM devices WHERE room_id = ? AND approved != ?", Array($roomId, 2));
|
||||
}
|
||||
|
||||
static function getOtherDevices(){
|
||||
return Db::loadAll ("SELECT * FROM devices WHERE room_id IS NULL ");
|
||||
}
|
||||
|
||||
static function getDeviceByToken($deviceToken) {
|
||||
return Db::loadOne("SELECT * FROM devices WHERE token = ?", array($deviceToken));
|
||||
}
|
||||
|
||||
static function getDeviceByMac($deviceMac) {
|
||||
return Db::loadOne("SELECT * FROM devices WHERE mac = ?", array($deviceMac));
|
||||
}
|
||||
|
||||
static function getDeviceById($deviceId) {
|
||||
return Db::loadOne("SELECT * FROM devices WHERE device_id = ?", array($deviceId));
|
||||
}
|
||||
|
||||
public static function create ($name, $token) {
|
||||
$defaultRoom = RoomManager::getDefaultRoomId();
|
||||
$device = array (
|
||||
'name' => $name,
|
||||
'token' => $token,
|
||||
'room_id' => $defaultRoom,
|
||||
);
|
||||
try {
|
||||
Db::add ('devices', $device);
|
||||
return Db::loadOne("SELECT device_id FROM devices WHERE token = ?", array($token))['device_id'];
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function edit ($deviceId, $values = []) {
|
||||
try {
|
||||
Db::edit ('devices', $values, 'WHERE device_id = ?', array($deviceId));
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function editByToken ($token, $values = []) {
|
||||
try {
|
||||
Db::edit ('devices', $values, 'WHERE token = ?', array($token));
|
||||
} 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 má zařízení přiřadit]
|
||||
* @param [type] $deviceId [Číslo zařízení které chcete přiřadit do místnosti]
|
||||
*/
|
||||
public static 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 static function delete ($deviceId) {
|
||||
Db::command ('DELETE FROM devices WHERE device_id=?', array ($deviceId));
|
||||
}
|
||||
|
||||
public static function registeret ($deviceToken) {
|
||||
return (count(Db::loadAll ("SELECT * FROM devices WHERE token=?", array($deviceToken))) == 1 ? true : false);
|
||||
}
|
||||
|
||||
public static function approved ($deviceToken) {
|
||||
return (count(Db::loadAll ("SELECT * FROM devices WHERE token=? AND approved = ?", array($deviceToken, 1))) == 1 ? true : false);
|
||||
}
|
||||
}
|
||||
?>
|
44
www/app/models/managers/FallbackManager.php
Normal file
44
www/app/models/managers/FallbackManager.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
class FallbackManager
|
||||
{
|
||||
public $deviceDefinitions = "";
|
||||
|
||||
function __construct($deviceDefinition)
|
||||
{
|
||||
$this->deviceDefinitions = $deviceDefinition;
|
||||
}
|
||||
|
||||
function check(){
|
||||
//TODO: FIX IT
|
||||
$allDevicesData = DeviceManager::getAllDevices();
|
||||
foreach ($allDevicesData as $deviceKey => $deviceValue) {
|
||||
$allSubDevicesData = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
|
||||
foreach ($allSubDevicesData as $subDeviceKey => $subDeviceValue) {
|
||||
if (!isset($this->deviceDefinitions[$subDeviceValue['type']]["fallBack"])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isset($this->deviceDefinitions[$subDeviceValue['type']]["fallBackTime"])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$lastRecord = RecordManager::getLastRecord($subDeviceValue['subdevice_id']);
|
||||
if ($lastRecord["value"] == $this->deviceDefinitions[$subDeviceValue['type']]["fallBack"]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$minutes = (time() - strtotime($lastRecord['time'])) / 60;
|
||||
|
||||
if ( $minutes > $this->deviceDefinitions[$subDeviceValue['type']]["fallBackTime"]){
|
||||
RecordManager::create($deviceValue['device_id'], $subDeviceValue['type'], $this->deviceDefinitions[$subDeviceValue['type']]["fallBack"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
60
www/app/models/managers/LanguageManager.php
Normal file
60
www/app/models/managers/LanguageManager.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Language Manager
|
||||
*/
|
||||
class LanguageManager
|
||||
{
|
||||
|
||||
private $lngCode = 'en';
|
||||
private $lngDatabase = [];
|
||||
private $debug = false;
|
||||
|
||||
function __construct(string $lngCode, bool $debug = false)
|
||||
{
|
||||
$this->lngCode = $lngCode;
|
||||
$this->debug = $debug;
|
||||
}
|
||||
|
||||
function load()
|
||||
{
|
||||
$file = '../lang/en.php';
|
||||
if (!file_exists($file)){
|
||||
echo 'ERROR: en.php not found';
|
||||
die();
|
||||
//TODO add lng EXEPTIONS
|
||||
}
|
||||
$arrayFirst = include($file);
|
||||
$file = '../lang/' . $this->lngCode . '.php';
|
||||
$arraySecond = [];
|
||||
if (file_exists($file)){
|
||||
$arraySecond = include($file);
|
||||
}
|
||||
$this->lngDatabase = array_merge($arrayFirst, $arraySecond);
|
||||
return true;
|
||||
}
|
||||
|
||||
function get(string $stringKey)
|
||||
{
|
||||
if ($this->debug) {
|
||||
return $stringKey;
|
||||
}
|
||||
if (isset($this->lngDatabase[$stringKey])) {
|
||||
return $this->lngDatabase[$stringKey];
|
||||
}
|
||||
return $stringKey;
|
||||
}
|
||||
|
||||
function echo(string $stringKey)
|
||||
{
|
||||
if ($this->debug) {
|
||||
echo $stringKey;
|
||||
return;
|
||||
}
|
||||
if (isset($this->lngDatabase[$stringKey])) {
|
||||
echo $this->lngDatabase[$stringKey];
|
||||
return;
|
||||
}
|
||||
echo $stringKey;
|
||||
return;
|
||||
}
|
||||
}
|
57
www/app/models/managers/LogManager.php
Normal file
57
www/app/models/managers/LogManager.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
class LogRecordType{
|
||||
const WARNING = 'warning';
|
||||
const ERROR = 'error';
|
||||
const INFO = 'info';
|
||||
}
|
||||
|
||||
class LogKeeper
|
||||
{
|
||||
function purge($days){
|
||||
$todayFileName = date("Y-m-d").'.log';
|
||||
$seconds = $days * 86400;
|
||||
|
||||
$logFiles = scandir('../logs/');
|
||||
foreach ($logFiles as $key => $file) {
|
||||
if (in_array($file,array(".","..", ".gitkeep", $todayFileName)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (filemtime($file) > $seconds) {
|
||||
unlink('../logs/'.$file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LogManager
|
||||
{
|
||||
|
||||
private $logFile;
|
||||
function __construct($fileName = "")
|
||||
{
|
||||
if ($fileName == ""){
|
||||
$fileName = '../logs/'. date("Y-m-d").'.log';
|
||||
}
|
||||
if(!is_dir("../logs/"))
|
||||
{
|
||||
mkdir("../logs/");
|
||||
}
|
||||
$this->logFile = fopen($fileName, "a") or die("Unable to open file!");
|
||||
}
|
||||
|
||||
function write($value, $type = LogRecordType::ERROR){
|
||||
$record = "[".date("H:m:s")."][".$type."]" . $value . "\n";
|
||||
fwrite($this->logFile, $record);
|
||||
}
|
||||
|
||||
function __destruct(){
|
||||
if (isset($this->logFile)) {
|
||||
fclose($this->logFile);
|
||||
}
|
||||
}
|
||||
}
|
18
www/app/models/managers/NetworkManager.php
Normal file
18
www/app/models/managers/NetworkManager.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class NetvorkManager
|
||||
{
|
||||
|
||||
function __construct()
|
||||
{
|
||||
// code...
|
||||
}
|
||||
|
||||
function validateIp($ip = '0.0.0.0'){
|
||||
if (!filter_var($ip, FILTER_VALIDATE_IP)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
107
www/app/models/managers/NotificationManager.php
Normal file
107
www/app/models/managers/NotificationManager.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* Notification Manager
|
||||
*/
|
||||
//TODO: Working timestamp to body or $title
|
||||
class NotificationManager
|
||||
{
|
||||
function addSubscriber($userID = '', $token = ''){
|
||||
$notificationSubscriber = $subDeviceId = Db::loadOne('SELECT id FROM notifications WHERE token = ?;', array($token));
|
||||
if ($notificationSubscriber == ''){
|
||||
$notification = array (
|
||||
'user_id' => $userID,
|
||||
'token' => $token,
|
||||
);
|
||||
Db::add ('notifications', $notification);
|
||||
}
|
||||
}
|
||||
|
||||
function getSubscription () {
|
||||
return Db::loadAll ("SELECT * FROM notifications");
|
||||
}
|
||||
|
||||
function sendSimpleNotification(string $serverKey, string $to, array $data, bool $timeStamp = false){
|
||||
$dataTemplate = [
|
||||
'title' => '',
|
||||
'body' => '',
|
||||
'icon' => '',
|
||||
];
|
||||
|
||||
if (array_diff_key ($dataTemplate , $data)){
|
||||
return;
|
||||
}
|
||||
|
||||
if ($timeStamp) {
|
||||
$data['title'] = $data['title'] . date();
|
||||
}
|
||||
|
||||
$notification = new Notification($serverKey);
|
||||
$notification->to($to);
|
||||
$notification->notification($data['title'], $data['body'], $data['icon'], '');
|
||||
$answer = $notification->send();
|
||||
$notification = null;
|
||||
|
||||
return $answer;
|
||||
}
|
||||
}
|
||||
|
||||
class Notification
|
||||
{
|
||||
public $server_key = '';
|
||||
public $jsonPayload = [
|
||||
"to" => '',
|
||||
"data" => [
|
||||
"notification" => [
|
||||
"body" => '',
|
||||
"title" => '',
|
||||
"icon" => '',
|
||||
"click_action" => '',
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
function __construct($serverKey = '')
|
||||
{
|
||||
$this->server_key = $serverKey;
|
||||
}
|
||||
|
||||
function to($to = ''){
|
||||
$this->jsonPayload["to"] = $to;
|
||||
}
|
||||
|
||||
function notification($title = '', $body = '', $icon = '', $action = '', bool $timeStamp = false)
|
||||
{
|
||||
if ($timeStamp) {
|
||||
$data['title'] = $data['title'] . date();
|
||||
}
|
||||
|
||||
$this->jsonPayload["data"]["notification"]["title"] = $title;
|
||||
$this->jsonPayload["data"]["notification"]["body"] = $body;
|
||||
$this->jsonPayload["data"]["notification"]["icon"] = $icon;
|
||||
$this->jsonPayload["data"]["notification"]["click_action"] = $action;
|
||||
}
|
||||
|
||||
function send(){
|
||||
$data = json_encode($this->jsonPayload);
|
||||
$url = 'https://fcm.googleapis.com/fcm/send';
|
||||
$headers = array(
|
||||
'Content-Type:application/json',
|
||||
'Authorization:key='.$this->server_key,
|
||||
);
|
||||
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_POST, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||||
$result = curl_exec($ch);
|
||||
if ($result === FALSE) {
|
||||
die('Oops! FCM Send Error: ' . curl_error($ch));
|
||||
}
|
||||
curl_close($ch);
|
||||
return $result;
|
||||
}
|
||||
}
|
106
www/app/models/managers/RecordManager.php
Normal file
106
www/app/models/managers/RecordManager.php
Normal file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
class RecordManager{
|
||||
public static $records;
|
||||
|
||||
public static function createWithSubId ($subDeviceId, $value) {
|
||||
try {
|
||||
$record = [
|
||||
'execuded' => 1,
|
||||
];
|
||||
Db::edit ('records', $record, 'WHERE subdevice_id = ?', array ($subDeviceId));
|
||||
$record = array (
|
||||
'subdevice_id' => $subDeviceId,
|
||||
'value' => $value,
|
||||
);
|
||||
return Db::add ('records', $record);
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static 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;
|
||||
};
|
||||
try {
|
||||
$record = [
|
||||
'execuded' => 1,
|
||||
];
|
||||
Db::edit ('records', $record, 'WHERE subdevice_id = ?', array ($subDeviceId));
|
||||
$record = array (
|
||||
'subdevice_id' => $subDeviceId,
|
||||
'value' => $value,
|
||||
);
|
||||
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 getLastRecordNotNull($subDeviceId) {
|
||||
return Db::loadOne('SELECT * FROM records WHERE subdevice_id = ? AND value != ? ORDER BY time DESC;', array($subDeviceId, 0));
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO: zkontrolovat jestli neco nezbilo po smazaní
|
||||
public static function cleanSubdeviceRecords ($subDeviceId) {
|
||||
Db::command ('DELETE FROM records WHERE subdevice_id = ?);', array($subDeviceId));
|
||||
}
|
||||
}
|
||||
?>
|
36
www/app/models/managers/RoomManager.php
Normal file
36
www/app/models/managers/RoomManager.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
class RoomManager{
|
||||
public static $rooms;
|
||||
|
||||
static function getDefaultRoomId() {
|
||||
$defaultRoom = Db::loadOne("SELECT room_id FROM rooms WHERE 'default' = 1");
|
||||
return $defaultRoom['room_id'];
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static function getRoomsDefault () {
|
||||
$allRoom = Db::loadAll ("SELECT room_id, name FROM rooms");
|
||||
return $allRoom;
|
||||
}
|
||||
|
||||
public static function create ($name) {
|
||||
$room = array (
|
||||
'name' => $name,
|
||||
);
|
||||
try {
|
||||
Db::add ('rooms', $room);
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function delete ($roomId) {
|
||||
Db::command ('DELETE FROM rooms WHERE room_id=?', array ($roomId));
|
||||
}
|
||||
}
|
||||
?>
|
41
www/app/models/managers/SceneManager.php
Normal file
41
www/app/models/managers/SceneManager.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
class SceneManager{
|
||||
public static $scenes;
|
||||
|
||||
public static 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 static function getAllScenes () {
|
||||
return Db::loadAll ("SELECT * FROM scenes");
|
||||
}
|
||||
|
||||
public static function getScene ($sceneId) {
|
||||
return Db::loadOne("SELECT * FROM scenes WHERE scene_id = ?", array($sceneId));
|
||||
}
|
||||
|
||||
public static 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 static function delete($sceneId){
|
||||
Db::command ('DELETE FROM scenes WHERE scene_id=?', array ($sceneId));
|
||||
}
|
||||
}
|
||||
?>
|
97
www/app/models/managers/SubDeviceManager.php
Normal file
97
www/app/models/managers/SubDeviceManager.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
class SubDeviceManager
|
||||
{
|
||||
public static $devices;
|
||||
|
||||
public static function getAllSubDevices($deviceId = null)
|
||||
{
|
||||
if ($deviceId == null){
|
||||
return Db::loadAll("SELECT * FROM subdevices");
|
||||
}
|
||||
return Db::loadAll("SELECT * FROM subdevices WHERE device_id = ?", array($deviceId));
|
||||
}
|
||||
|
||||
public static function getSubDeviceMaster($subDeviceId)
|
||||
{
|
||||
return Db::loadOne("SELECT * FROM devices WHERE device_id = (SELECT device_id FROM subdevices WHERE subdevice_id = ?)", array($subDeviceId));
|
||||
}
|
||||
|
||||
public static 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 static 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 static function getSubDevice($subDeviceId)
|
||||
{
|
||||
return Db::loadOne("SELECT * FROM subdevices WHERE subdevice_id = ?;", array($subDeviceId));
|
||||
}
|
||||
|
||||
public static function getSubDevicesTypeForMater($deviceId)
|
||||
{
|
||||
$parsedTypes = [];
|
||||
$types = Db::loadAll("SELECT type FROM subdevices WHERE device_id = ?;", array($deviceId));
|
||||
foreach ($types as $orderNum => $type) {
|
||||
$parsedTypes[$orderNum] = $type['type'];
|
||||
}
|
||||
return $parsedTypes;
|
||||
}
|
||||
|
||||
//check if dubdevice exist
|
||||
|
||||
public static 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();
|
||||
}
|
||||
}
|
||||
|
||||
public static function remove($subDeviceId)
|
||||
{
|
||||
RecordManager::cleanSubdeviceRecords($subDeviceId);
|
||||
return Db::loadAll("DELETE FROM subdevices WHERE subdevice_id = ?", array($subDeviceId));
|
||||
}
|
||||
|
||||
public static function getSubdevicesByRoomIds($roomIds = NULL) {
|
||||
if(empty($roomIds)) return NULL;
|
||||
|
||||
$rows = Db::loadAll("
|
||||
SELECT d.room_id, sd.subdevice_id, sd.device_id, d.name, sd.type, sd.unit, r.value FROM subdevices sd
|
||||
JOIN devices d ON sd.device_id = d.device_id
|
||||
JOIN records r ON r.subdevice_id = sd.subdevice_id
|
||||
WHERE d.room_id IN (".str_repeat("?,", count($roomIds)-1)."?)
|
||||
AND r.record_id IN (
|
||||
SELECT MAX(record_id)
|
||||
FROM records
|
||||
GROUP BY subdevice_id
|
||||
)
|
||||
", $roomIds);
|
||||
|
||||
$ret = [];
|
||||
foreach($rows as $row){
|
||||
$ret[$row['room_id']][] = $row;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
210
www/app/models/managers/UserManager.php
Normal file
210
www/app/models/managers/UserManager.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
class UserManager
|
||||
{
|
||||
public static function getUsers () {
|
||||
try {
|
||||
$allUsers = Db::loadAll ("SELECT user_id, username, at_home, ota FROM users");
|
||||
return $allUsers;
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getUser ($userName) {
|
||||
try {
|
||||
$user = Db::loadOne ("SELECT * FROM users WHERE username = ?", [$userName]);
|
||||
return $user;
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getUserId ($userId) {
|
||||
try {
|
||||
$user = Db::loadOne ("SELECT * FROM users WHERE user_id = ?", [$userId]);
|
||||
return $user;
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getAvatarUrl($userId = null){
|
||||
$email = self::getUserData('email');
|
||||
if ($userId != null){
|
||||
$email = self::getUserData('email',$userId);
|
||||
}
|
||||
return 'https://secure.gravatar.com/avatar/' . md5( strtolower( trim( $email ) ) );
|
||||
}
|
||||
|
||||
public static 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", self::setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), BASEDIR, $_SERVER['HTTP_HOST'], 1);
|
||||
}
|
||||
$_SESSION['user']['id'] = $user['user_id'];
|
||||
$page = "";
|
||||
if ($user["startPage"] == 1) {
|
||||
$page = "dashboard";
|
||||
}
|
||||
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 static function loginNew ($username, $password) {
|
||||
try {
|
||||
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) {
|
||||
if ($user['password'] == UserManager::getHashPassword($password)) {
|
||||
echo "user loged in";
|
||||
return $user['user_id'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static 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 (self::getDecryptedCookie($_COOKIE['rememberMe'])))) {
|
||||
$_SESSION['user']['id'] = $user['user_id'];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function logout () {
|
||||
unset($_SESSION['user']);
|
||||
session_destroy();
|
||||
if (isset($_COOKIE['rememberMe'])){
|
||||
unset($_COOKIE['rememberMe']);
|
||||
setcookie("rememberMe", 'false', time(), BASEDIR, $_SERVER['HTTP_HOST']);
|
||||
}
|
||||
}
|
||||
|
||||
public static 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 static 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, $userId = '') {
|
||||
if ($userId == '') {
|
||||
$userId = $_SESSION['user']['id'];
|
||||
}
|
||||
$user = Db::loadOne ('SELECT ' . $type . ' FROM users WHERE user_id=?', array ($userId));
|
||||
return $user[$type];
|
||||
}
|
||||
|
||||
public static function setUserData ($type, $value) {
|
||||
if (isset ($_SESSION['user']['id'])) {
|
||||
Db::command ('UPDATE users SET ' . $type . '=? WHERE user_id=?', array ($value, $_SESSION['user']['id']));
|
||||
}
|
||||
}
|
||||
|
||||
public static function getHashPassword ($password) {
|
||||
$salt = "s0mRIdlKvI";
|
||||
$hashPassword = hash('sha512', ($password . $salt));
|
||||
return $hashPassword;
|
||||
}
|
||||
|
||||
public static function atHome($userId, $atHome){
|
||||
try {
|
||||
Db::edit ('users', ['at_home' => $atHome], 'WHERE user_id = ?', array($userId));
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function changePassword($oldPassword, $newPassword, $newPassword2){
|
||||
if ($newPassword == $newPassword2) {
|
||||
//Password Criteria
|
||||
$oldPasswordSaved = self::getUserData('password');
|
||||
if (self::getHashPassword($oldPassword) == $oldPasswordSaved) {
|
||||
self::setUserData('password', self::getHashPassword($newPassword));
|
||||
} else {
|
||||
throw new Exception ("old password did not match");
|
||||
}
|
||||
} else {
|
||||
throw new Exception ("new password arent same");
|
||||
}
|
||||
}
|
||||
|
||||
public static function createUser($userName, $password){
|
||||
$userId = Db::loadOne('SELECT * FROM users WHERE username = ?;', array($userName))['user_id'];
|
||||
if ($userId != null) {
|
||||
return false;
|
||||
};
|
||||
try {
|
||||
$user = [
|
||||
'username' => $userName,
|
||||
'password' => self::getHashPassword($password),
|
||||
];
|
||||
return Db::add ('users', $user);
|
||||
} catch(PDOException $error) {
|
||||
echo $error->getMessage();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
public static function haveOtaEnabled($userName){
|
||||
$ota = self::getUser($userName)['ota'];
|
||||
|
||||
if ($ota != ''){
|
||||
return ($ota != '' ? $ota : false);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
144
www/app/models/managers/Utilities.php
Normal file
144
www/app/models/managers/Utilities.php
Normal file
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
*/
|
||||
class Utilities
|
||||
{
|
||||
static 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);
|
||||
}
|
||||
|
||||
static function stringInsert($str,$insertstr,$pos)
|
||||
{
|
||||
$str = substr($str, 0, $pos) . $insertstr . substr($str, $pos);
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* [generateGraphJson description]
|
||||
* @param string $type [line/bar]
|
||||
* @param array $data [description]
|
||||
* @param array $options [description]
|
||||
* @return [type] [description]
|
||||
*/
|
||||
|
||||
static function generateGraphJson(string $type = 'line', array $data = [], array $options = []){
|
||||
$array = [
|
||||
'type' => $type,
|
||||
'data' => [
|
||||
'datasets' => [
|
||||
[
|
||||
'data' => $data,
|
||||
'borderColor' => "#d4def7",
|
||||
'backgroundColor' => "#d4def7"
|
||||
]
|
||||
]
|
||||
],
|
||||
'options' => [
|
||||
'scales' => [
|
||||
'xAxes' => [
|
||||
[
|
||||
'type' => 'time',
|
||||
'distribution' => 'linear',
|
||||
]
|
||||
],
|
||||
'yAxes' => [
|
||||
[
|
||||
'ticks' => [
|
||||
'min' => $options['min'],
|
||||
'max' => $options['max'],
|
||||
'steps' => $options['scale']
|
||||
]
|
||||
]
|
||||
]
|
||||
],
|
||||
'legend' => [
|
||||
'display' => false
|
||||
],
|
||||
'tooltips' => [
|
||||
'enabled' => true
|
||||
],
|
||||
'hover' => [
|
||||
'mode' => true
|
||||
]
|
||||
]
|
||||
];
|
||||
return json_encode($array, JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
static function ago( $datetime )
|
||||
{
|
||||
$interval = date_create('now')->diff( $datetime );
|
||||
$suffix = ( $interval->invert ? ' ago' : '' );
|
||||
if ( $v = $interval->y >= 1 ) return self::pluralize( $interval->m, 'month' ) . $suffix;
|
||||
if ( $v = $interval->d >= 1 ) return self::pluralize( $interval->d, 'day' ) . $suffix;
|
||||
if ( $v = $interval->h >= 1 ) return self::pluralize( $interval->h, 'hour' ) . $suffix;
|
||||
if ( $v = $interval->i >= 1 ) return self::pluralize( $interval->i, 'minute' ) . $suffix;
|
||||
return self::pluralize( $interval->s, 'second' ) . $suffix;
|
||||
}
|
||||
|
||||
static function pluralize( $count, $text )
|
||||
{
|
||||
return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
|
||||
}
|
||||
|
||||
static function checkOperator($value1, $operator, $value2) {
|
||||
switch ($operator) {
|
||||
case '<': // Less than
|
||||
return $value1 < $value2;
|
||||
case '<=': // Less than or equal to
|
||||
return $value1 <= $value2;
|
||||
case '>': // Greater than
|
||||
return $value1 > $value2;
|
||||
case '>=': // Greater than or equal to
|
||||
return $value1 >= $value2;
|
||||
case '==': // Equal
|
||||
return ($value1 == $value2);
|
||||
case '===': // Identical
|
||||
return $value1 === $value2;
|
||||
case '!==': // Not Identical
|
||||
return $value1 !== $value2;
|
||||
case '!=': // Not equal
|
||||
case '<>': // Not equal
|
||||
return $value1 != $value2;
|
||||
case '||': // Or
|
||||
case 'or': // Or
|
||||
return $value1 || $value2;
|
||||
case '&&': // And
|
||||
case 'and': // And
|
||||
return $value1 && $value2;
|
||||
case 'xor': // Or
|
||||
return $value1 xor $value2;
|
||||
default:
|
||||
return FALSE;
|
||||
} // end switch
|
||||
}
|
||||
}
|
107
www/app/models/types/GoogleHomeDeviceTypes.php
Normal file
107
www/app/models/types/GoogleHomeDeviceTypes.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
class GoogleHomeDeviceTypes {
|
||||
/*const AirConditioningUnit = 'action.devices.types.AC_UNIT';
|
||||
const AirFreshener = 'action.devices.types.AIRFRESHENER';
|
||||
const AirPurifier = 'action.devices.types.AIRPURIFIER';
|
||||
const Awning = 'action.devices.types.AWNING';
|
||||
const Bathtub = 'action.devices.types.BATHTUB';
|
||||
const Bed = 'action.devices.types.BED';
|
||||
const Blender = 'action.devices.types.BLENDER';
|
||||
const Blinds = 'action.devices.types.BLINDS';
|
||||
const Boiler = 'action.devices.types.BOILER';
|
||||
const Camera = 'action.devices.types.CAMERA';
|
||||
const CarbonMonoxideDetector = 'action.devices.types.CARBON_MONOXIDE_DETECTOR';
|
||||
const Charger = 'action.devices.types.CHARGER';
|
||||
const Closet = 'action.devices.types.CLOSET';
|
||||
const CoffeeMaker = 'action.devices.types.COFFEE_MAKER';
|
||||
const Cooktop = 'action.devices.types.COOKTOP';
|
||||
const Curtain = 'action.devices.types.CURTAIN';
|
||||
const Dehumidifier = 'action.devices.types.DEHUMIDIFIER';
|
||||
const Dehydrator = 'action.devices.types.DEHYDRATOR';
|
||||
const Dishwasher = 'action.devices.types.DISHWASHER';
|
||||
const Door = 'action.devices.types.DOOR';
|
||||
const Drawer = 'action.devices.types.DRAWER';
|
||||
const Dryer = 'action.devices.types.DRYER';
|
||||
const Fan = 'action.devices.types.FAN';
|
||||
const Faucet = 'action.devices.types.FAUCET';
|
||||
const Fireplace = 'action.devices.types.FIREPLACE';
|
||||
const Fryer = 'action.devices.types.FRYER';
|
||||
const GarageDoor = 'action.devices.types.GARAGE';
|
||||
const Gate = 'action.devices.types.GATE';
|
||||
const Grill = 'action.devices.types.GRILL';
|
||||
const Heater = 'action.devices.types.HEATER';
|
||||
const Hood = 'action.devices.types.HOOD';
|
||||
const Humidifier = 'action.devices.types.HUMIDIFIER';
|
||||
const Kettle = 'action.devices.types.KETTLE';
|
||||
const Light = 'action.devices.types.LIGHT';
|
||||
const Lock = 'action.devices.types.LOCK';
|
||||
const MediaRemote = 'action.devices.types.REMOTECONTROL';
|
||||
const Mop = 'action.devices.types.MOP';
|
||||
const Mower = 'action.devices.types.MOWER';
|
||||
const Microwave = 'action.devices.types.MICROWAVE';
|
||||
const Multicooker = 'action.devices.types.MULTICOOKER';
|
||||
const Network = 'action.devices.types.NETWORK';
|
||||
|
||||
const Oven = 'action.devices.types.OVEN';
|
||||
const Pergola = 'action.devices.types.PERGOLA';
|
||||
const PetFeeder = 'action.devices.types.PETFEEDER';
|
||||
const PressureCooker = 'action.devices.types.PRESSURECOOKER';
|
||||
const Radiator = 'action.devices.types.RADIATOR';
|
||||
const Refrigerator = 'action.devices.types.REFRIGERATOR';
|
||||
const Router = 'action.devices.types.ROUTER';
|
||||
const Scene = 'action.devices.types.SCENE';
|
||||
const Sensor = 'action.devices.types.SENSOR';
|
||||
const SecuritySystem = 'action.devices.types.SECURITYSYSTEM';
|
||||
const SettopBox = 'action.devices.types.SETTOP';
|
||||
const Shutter = 'action.devices.types.SHUTTER';
|
||||
const Shower = 'action.devices.types.SHOWER';
|
||||
const SmokeDetector = 'action.devices.types.SMOKE_DETECTOR';
|
||||
const SousVide = 'action.devices.types.SOUSVIDE';
|
||||
const Sprinkler = 'action.devices.types.SPRINKLER';
|
||||
const StandMixer = 'action.devices.types.STANDMIXER';
|
||||
const Switch = 'action.devices.types.SWITCH';
|
||||
const Television = 'action.devices.types.TV';
|
||||
const Thermostat = 'action.devices.types.THERMOSTAT';
|
||||
const Vacuum = 'action.devices.types.VACUUM';
|
||||
const Valve = 'action.devices.types.VALVE';
|
||||
const Washer = 'action.devices.types.WASHER';
|
||||
const WaterHeater = 'action.devices.types.WATERHEATER';
|
||||
const WaterPurifier = 'action.devices.types.WATERPURIFIER';
|
||||
const WaterSoftener = 'action.devices.types.WATERSOFTENER';
|
||||
const Window = 'action.devices.types.WINDOW';
|
||||
const YogurtMaker = 'action.devices.types.YOGURTMAKER';*/
|
||||
|
||||
private static $actionWordBook = [
|
||||
'on/off' => 'action.devices.types.OUTLET',
|
||||
'temp_cont' => 'action.devices.types.THERMOSTAT',
|
||||
];
|
||||
|
||||
static function getAction($deviceType){
|
||||
return self::$actionWordBook[$deviceType];
|
||||
}
|
||||
|
||||
static function getSyncObj($deviceBaseObj, $deviceType){
|
||||
switch ($deviceType) {
|
||||
case 'action.devices.types.LIGHT':
|
||||
case 'action.devices.types.OUTLET':
|
||||
$deviceBaseObj['traits'] = [
|
||||
'action.devices.traits.OnOff'
|
||||
];
|
||||
break;
|
||||
case 'action.devices.types.THERMOSTAT':
|
||||
$deviceBaseObj['traits'] = [
|
||||
'action.devices.traits.TemperatureSetting',
|
||||
];
|
||||
$deviceBaseObj['attributes'] = [
|
||||
"availableThermostatModes" => "off,heat",
|
||||
"thermostatTemperatureUnit" => "C",
|
||||
];
|
||||
break;
|
||||
}
|
||||
return $deviceBaseObj;
|
||||
}
|
||||
|
||||
static function getQueryJson($deviceType, $type){
|
||||
return self::$wordBook[$type];
|
||||
}
|
||||
}
|
45
www/app/models/types/WidgetTypes.php
Normal file
45
www/app/models/types/WidgetTypes.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
class WidgetTypes {
|
||||
const VALUE = 0;
|
||||
const ICON = 1;
|
||||
const BUTTON = 2;
|
||||
const SWITH = 3;
|
||||
const RANGE = 4;
|
||||
const CUSTOM = 5;
|
||||
|
||||
private $types = [
|
||||
self::VALUE => [
|
||||
'name' => 'value',
|
||||
'active' => false
|
||||
],
|
||||
self::ICON => [
|
||||
'name' => 'icon',
|
||||
'active' => false
|
||||
],
|
||||
self::BUTTON => [
|
||||
'name' => 'button',
|
||||
'active' => true
|
||||
],
|
||||
self::SWITH => [
|
||||
'name' => 'switch',
|
||||
'active' => true
|
||||
],
|
||||
self::RANGE => [
|
||||
'name' => 'range',
|
||||
'active' => true
|
||||
],
|
||||
self::CUSTOM => [
|
||||
'name' => 'custom',
|
||||
'active' => true
|
||||
],
|
||||
];
|
||||
|
||||
public static function getName($type){
|
||||
return self::$types[$type];
|
||||
}
|
||||
|
||||
public static function isActive($type){
|
||||
return isset(self::$types[$type]) && self::$types[$type]['active'];
|
||||
}
|
||||
}
|
223
www/app/views/Ajax.php
Normal file
223
www/app/views/Ajax.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
|
||||
class Ajax extends Template
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
global $userManager;
|
||||
global $lang;
|
||||
|
||||
if (!$userManager->isLogin()){
|
||||
header('Location: ' . BASEURL);
|
||||
}
|
||||
|
||||
$is_ajax = 'XMLHttpRequest' == ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );
|
||||
if (!$is_ajax){
|
||||
header('Location: ' . BASEURL);
|
||||
}
|
||||
|
||||
if (
|
||||
isset($_POST['automation_id']) &&
|
||||
$_POST['automation_id'] != '' &&
|
||||
isset($_POST['action']) &&
|
||||
$_POST['action'] != ''
|
||||
) {
|
||||
$automationId = $_POST['automation_id'];
|
||||
//Automation Editation of Automations from Buttons/Details
|
||||
switch ($_POST['action']) {
|
||||
case 'delete':
|
||||
AutomationManager::remove($automationId);
|
||||
die();
|
||||
break;
|
||||
|
||||
case 'deactive':
|
||||
AutomationManager::deactive($automationId);
|
||||
die();
|
||||
break;
|
||||
|
||||
case 'restart':
|
||||
AutomationManager::restart($automationId);
|
||||
die();
|
||||
break;
|
||||
|
||||
default:
|
||||
echo 'no action detected';
|
||||
break;
|
||||
}
|
||||
} else if (
|
||||
isset($_POST['subDevice_id']) &&
|
||||
$_POST['subDevice_id'] != '' &&
|
||||
isset($_POST['action']) &&
|
||||
$_POST['action'] != ''
|
||||
) {
|
||||
$subDeviceId = $_POST['subDevice_id'];
|
||||
switch ($_POST['action']) {
|
||||
case 'chart':
|
||||
$period = $_POST['period'];
|
||||
$groupBy = $_POST['group'];
|
||||
header('Content-Type: application/json');
|
||||
$graphData = ChartManager::generateChartData($subDeviceId, $period, $groupBy);
|
||||
echo Utilities::generateGraphJson($graphData['graphType'], $graphData['graphData'], $graphData['graphRange']);
|
||||
die();
|
||||
break;
|
||||
|
||||
//Change On/Off Device State of Device Button
|
||||
case 'change':
|
||||
$subDeviceData = SubDeviceManager::getSubDevice($subDeviceId);
|
||||
$deviceId = SubDeviceManager::getSubDeviceMaster($subDeviceId)['device_id'];
|
||||
if ($subDeviceData['type'] == 'on/off'){
|
||||
$lastValue = RecordManager::getLastRecord($subDeviceData['subdevice_id'])['value'];
|
||||
RecordManager::create($deviceId, 'on/off', !$lastValue);
|
||||
echo (!$lastValue ? 'ON' : 'OFF');
|
||||
}
|
||||
die();
|
||||
break;
|
||||
|
||||
//Waitin for execution of Changet walue for Device Button
|
||||
case 'executed':
|
||||
echo RecordManager::getLastRecord($subDeviceId)['execuded'];
|
||||
die();
|
||||
break;
|
||||
|
||||
case 'set':
|
||||
$value = $_POST['value'];
|
||||
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
|
||||
RecordManager::create($subDevice['device_id'], $subDevice['type'], $value);
|
||||
echo 'test id' . $subDevice['device_id'] .$subDevice['type'] . $value ;
|
||||
die();
|
||||
break;
|
||||
|
||||
default:
|
||||
echo 'no action detected';
|
||||
break;
|
||||
}
|
||||
} else if (
|
||||
isset($_POST['scene_id']) &&
|
||||
$_POST['scene_id'] != '' &&
|
||||
isset($_POST['action']) &&
|
||||
$_POST['action'] != ''
|
||||
) {
|
||||
$sceneId = $_POST['scene_id'];
|
||||
switch ($_POST['action']) {
|
||||
case 'delete':
|
||||
SceneManager::delete($sceneId);
|
||||
die();
|
||||
break;
|
||||
|
||||
case 'execute':
|
||||
echo SceneManager::execScene($sceneId);
|
||||
die();
|
||||
break;
|
||||
|
||||
default:
|
||||
echo 'no action detected';
|
||||
break;
|
||||
}
|
||||
} else if (
|
||||
isset($_POST['notification']) &&
|
||||
$_POST['notification'] != '' &&
|
||||
isset($_POST['action']) &&
|
||||
$_POST['action'] != ''
|
||||
) {
|
||||
switch ($_POST['action']) {
|
||||
//add suscription to database
|
||||
case 'subscribe':
|
||||
$subscriptionToken = $_POST['token'];
|
||||
NotificationManager::addSubscriber($_SESSION['user']['id'], $subscriptionToken);
|
||||
die();
|
||||
break;
|
||||
|
||||
case 'sendTest':
|
||||
$notificationData = [
|
||||
'title' => 'Alert',
|
||||
'body' => 'test notification',
|
||||
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
|
||||
];
|
||||
$notificationMng = new NotificationManager;
|
||||
$subscribers = $notificationMng::getSubscription();
|
||||
foreach ($subscribers as $key => $subscriber) {
|
||||
echo $subscriber['user_id'];
|
||||
if ($subscriber['user_id'] != $_SESSION['user']['id']) continue;
|
||||
echo $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
|
||||
}
|
||||
die();
|
||||
break;
|
||||
|
||||
default:
|
||||
echo 'no action detected';
|
||||
break;
|
||||
}
|
||||
} else if (
|
||||
isset($_POST['action']) &&
|
||||
$_POST['action'] != ''
|
||||
) {
|
||||
$updateData = [];
|
||||
$allDevicesData = DeviceManager::getAllDevices();
|
||||
foreach ($allDevicesData as $deviceKey => $deviceValue) {
|
||||
$allSubDevices = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
|
||||
foreach ($allSubDevices as $key => $subDevicesData) {
|
||||
|
||||
$lastRecord = RecordManager::getLastRecord($subDevicesData['subdevice_id']);
|
||||
$parsedValue = $lastRecord['value'] . $subDevicesData['unit'];
|
||||
|
||||
//TODO: udělat parser a ten použít jak v houmu tak zde
|
||||
switch ($subDevicesData['type']) {
|
||||
case 'on/off':
|
||||
$replacementTrue = 'On';
|
||||
$replacementFalse = 'Off';
|
||||
$operator = '==';
|
||||
$breakValue = 1;
|
||||
break;
|
||||
|
||||
case 'door':
|
||||
$replacementTrue = 'Closed';
|
||||
$replacementFalse = 'Open';
|
||||
$operator = '==';
|
||||
$breakValue = 1;
|
||||
break;
|
||||
|
||||
case 'light':
|
||||
$replacementTrue = 'Light';
|
||||
$replacementFalse = 'Dark';
|
||||
$operator = '==';
|
||||
$breakValue = 1;
|
||||
if ($lastRecord['value'] != 1 && $lastRecord['value'] != 0) { //Digital Light Senzor
|
||||
$operator = '<';
|
||||
$breakValue = 810;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'water':
|
||||
$replacementTrue = 'Wet';
|
||||
$replacementFalse = 'Dry';
|
||||
$operator = '==';
|
||||
$breakValue = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
$replacementTrue = '';
|
||||
$replacementFalse = '';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($replacementTrue != '' && $replacementFalse != '') {
|
||||
//parsing last values
|
||||
$parsedValue = $replacementFalse;
|
||||
|
||||
if (Utilities::checkOperator($lastRecord['value'], $operator, $breakValue)) {
|
||||
$parsedValue = $replacementTrue;
|
||||
}
|
||||
}
|
||||
|
||||
$updateData[$subDevicesData['subdevice_id']] = [
|
||||
'time' => $lastRecord['time'],
|
||||
'value' => $parsedValue,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: PRO JS VRACET DATA
|
||||
echo json_encode($updateData, JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
||||
}
|
66
www/app/views/Automation.php
Normal file
66
www/app/views/Automation.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
class Automation extends Template
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
global $userManager;
|
||||
global $langMng;
|
||||
|
||||
if (!$userManager->isLogin()){
|
||||
header('Location: ' . BASEURL . 'login');
|
||||
}
|
||||
|
||||
$automations = [];
|
||||
$automationsData = AutomationManager::getAll();
|
||||
foreach ($automationsData as $automationKey => $automationData) {
|
||||
$doSomething = [];
|
||||
foreach (json_decode($automationData['do_something']) as $deviceId => $subDeviceState) {
|
||||
$subDeviceMasterDeviceData = DeviceManager::getDeviceById($deviceId);
|
||||
$doSomething[$deviceId] = [
|
||||
'name' => $subDeviceMasterDeviceData['name'],
|
||||
'state' => $subDeviceState,
|
||||
];
|
||||
}
|
||||
//TODO: Transaltion add
|
||||
$executionTime = 'never';
|
||||
if ($automationData['execution_time'] != '0000-00-00 00:00:00') {
|
||||
$executionTime = date(DATEFORMAT,strtotime($automationData['execution_time']));
|
||||
}
|
||||
$automations[$automationData['automation_id']] = [
|
||||
'name' => $automationData['name'],
|
||||
'owner_name' => $userManager->getUserId($automationData['owner_id'])['username'],
|
||||
'onDays' => json_decode($automationData['on_days']),
|
||||
'ifSomething' => $automationData['if_something'],
|
||||
'doSomething' => $doSomething,
|
||||
'active' => $automationData['active'],
|
||||
'execution_time' => $executionTime,
|
||||
];
|
||||
}
|
||||
|
||||
$approvedSubDevices = [];
|
||||
$allDevicesData = DeviceManager::getAllDevices();
|
||||
foreach ($allDevicesData as $deviceKey => $deviceValue) {
|
||||
if (!$deviceValue['approved']) continue;
|
||||
$allSubDevicesData = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
|
||||
foreach ($allSubDevicesData as $subDeviceKey => $subDeviceValue) {
|
||||
$approvedSubDevices[$subDeviceValue['subdevice_id']] = [
|
||||
'name' => $allDevicesData[$deviceKey]['name'],
|
||||
'type' => $subDeviceValue['type'],
|
||||
'masterDevice' => $subDeviceValue['device_id'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$template = new Template('automation');
|
||||
$template->prepare('baseDir', BASEDIR);
|
||||
$template->prepare('debugMod', DEBUGMOD);
|
||||
$template->prepare('title', 'Automation');
|
||||
$template->prepare('langMng', $langMng);
|
||||
$template->prepare('userManager', $userManager);
|
||||
|
||||
$template->prepare('automations', $automations);
|
||||
$template->prepare('subDevices', $approvedSubDevices);
|
||||
|
||||
$template->render();
|
||||
}
|
||||
}
|
63
www/app/views/Log.php
Normal file
63
www/app/views/Log.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
|
||||
class Log extends Template
|
||||
{
|
||||
//TODO: to server manager
|
||||
function getSystemMemInfo()
|
||||
{
|
||||
$data = explode("\n", file_get_contents("/proc/meminfo"));
|
||||
$meminfo = array();
|
||||
foreach ($data as $line) {
|
||||
$data = explode(":", $line);
|
||||
if (count($data)!=2) continue;
|
||||
$meminfo[$data[0]] = trim($data[1]);
|
||||
}
|
||||
return $meminfo;
|
||||
}
|
||||
|
||||
function __construct()
|
||||
{
|
||||
global $userManager;
|
||||
global $langMng;
|
||||
|
||||
if (!$userManager->isLogin()){
|
||||
header('Location: ' . BASEURL . 'login');
|
||||
}
|
||||
|
||||
$template = new Template('log');
|
||||
$template->prepare('title', 'Log');
|
||||
|
||||
$result = array();
|
||||
$cdir = scandir('../logs/');
|
||||
foreach ($cdir as $key => $value)
|
||||
{
|
||||
if (!in_array($value,array(".","..", ".gitkeep")))
|
||||
{
|
||||
$result[$value] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$template->prepare('baseDir', BASEDIR);
|
||||
$template->prepare('debugMod', DEBUGMOD);
|
||||
$template->prepare('logToLiveTime', LOGTIMOUT);
|
||||
$template->prepare('title', 'Logy');
|
||||
$template->prepare('logsFiles', $result);
|
||||
$template->prepare('langMng', $langMng);
|
||||
$template->prepare('CPU', sys_getloadavg()[0]);
|
||||
$template->prepare('UPTIME', shell_exec('uptime -p'));
|
||||
$template->prepare('ramFree', $this->getSystemMemInfo()["MemFree"]);
|
||||
$template->prepare('ramTotal', $this->getSystemMemInfo()["MemTotal"]);
|
||||
$template->prepare('diskTotal', disk_total_space("/"));
|
||||
$template->prepare('serverTime', date('m. d. Y H:i:s - e'));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$template->render();
|
||||
|
||||
}
|
||||
}
|
22
www/app/views/Login.php
Normal file
22
www/app/views/Login.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
class Login extends Template
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
global $userManager;
|
||||
global $lang;
|
||||
|
||||
if ($userManager->isLogin()){
|
||||
header('Location: ' . BASEURL);
|
||||
}
|
||||
|
||||
$template = new Template('login');
|
||||
$template->prepare('baseDir', BASEDIR);
|
||||
$template->prepare('title', 'Home');
|
||||
$template->prepare('lang', $lang);
|
||||
|
||||
|
||||
|
||||
$template->render();
|
||||
}
|
||||
}
|
11
www/app/views/Logout.php
Normal file
11
www/app/views/Logout.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
class Logout extends Template
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
global $userManager;
|
||||
$userManager->logout();
|
||||
header('Location: ' . BASEURL . 'login');
|
||||
die();
|
||||
}
|
||||
}
|
62
www/app/views/Setting.php
Normal file
62
www/app/views/Setting.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
class Setting extends Template
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
|
||||
global $userManager;
|
||||
global $langMng;
|
||||
|
||||
if (!$userManager->isLogin()){
|
||||
header('Location: ' . BASEURL . 'login');
|
||||
}
|
||||
|
||||
$automations = [];
|
||||
$automationsData = AutomationManager::getAll();
|
||||
foreach ($automationsData as $automationKey => $automationData) {
|
||||
$automations[$automationData['automation_id']] = [
|
||||
'name' => '',
|
||||
'onDays' => $automationData['on_days'],
|
||||
'ifSomething' => $automationData['if_something'],
|
||||
'doSomething' => $automationData['do_something'],
|
||||
];
|
||||
}
|
||||
|
||||
$template = new Template('setting');
|
||||
$template->prepare('baseDir', BASEDIR);
|
||||
$template->prepare('debugMod', DEBUGMOD);
|
||||
$template->prepare('title', 'Automation');
|
||||
$template->prepare('langMng', $langMng);
|
||||
$template->prepare('automations', $automations);
|
||||
|
||||
$users = $userManager->getUsers();
|
||||
foreach ($users as $key => $value) {
|
||||
$users[$key]['gavatar_url'] = $userManager->getAvatarUrl($value['user_id']);
|
||||
}
|
||||
$template->prepare('users', $users);
|
||||
|
||||
$template->prepare('userName', $userManager->getUserData('username'));
|
||||
$template->prepare('userEmail', $userManager->getUserData('email'));
|
||||
$template->prepare('userAvatarUrl', $userManager->getAvatarUrl());
|
||||
|
||||
if ($userManager->getUserData('ota') == ''){
|
||||
$ga = new PHPGangsta_GoogleAuthenticator();
|
||||
$otaSecret = $ga->createSecret();
|
||||
$qrCodeUrl = $ga->getQRCodeGoogleUrl('Smart Home', $otaSecret);
|
||||
$oneCode = $ga->getCode($otaSecret);
|
||||
$template->prepare('qrUrl', $qrCodeUrl);
|
||||
$template->prepare('otaSecret', $otaSecret);
|
||||
$template->prepare('otaCode', $oneCode);
|
||||
|
||||
// echo "Secret is: ".$secret."\n\n";
|
||||
// echo "Google Charts URL for the QR-Code: ".$qrCodeUrl."\n\n";
|
||||
// echo "Checking Code '$oneCode' and Secret '$otaSecret':\n";
|
||||
}
|
||||
|
||||
$rooms = RoomManager::getAllRooms();
|
||||
$template->prepare('rooms', $rooms);
|
||||
|
||||
|
||||
$template->render();
|
||||
}
|
||||
}
|
20
www/app/views/layouts/default.phtml
Normal file
20
www/app/views/layouts/default.phtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title><?php echo $this->title ?></title>
|
||||
<link rel="stylesheet" href="css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
{HEADER}
|
||||
</header>
|
||||
|
||||
<?php echo $this->content(); ?>
|
||||
|
||||
<footer>
|
||||
{FOOTER}
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
66
www/app/views/templates/automation.phtml
Normal file
66
www/app/views/templates/automation.phtml
Normal file
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php
|
||||
$partial = new Partial('head');
|
||||
$partial->prepare('baseDir', $BASEDIR);
|
||||
$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">
|
||||
<?php
|
||||
$partial = new Partial('menu');
|
||||
$partial->prepare('item','automation');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
$partial->prepare('debugMod',$DEBUGMOD);
|
||||
$partial->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-md-9 main-body">
|
||||
<a class="button is-primary m-1" onClick="$('#modal').removeClass('modal-container-hiden').show();"><?php $LANGMNG->echo('t_createAutomation'); ?></a>
|
||||
<div class="row no-gutters">
|
||||
<?php foreach ($AUTOMATIONS as $automationId => $automationData) {
|
||||
//BUTTON
|
||||
$partial = new Partial('automationButton');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
$partial->prepare('automationId',$automationId);
|
||||
$partial->prepare('automationData',$automationData);
|
||||
$partial->render();
|
||||
|
||||
//EDIT
|
||||
$partial = new Partial('automationEdit');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
$partial->prepare('userManager',$USERMANAGER);
|
||||
$partial->prepare('automationId',$automationId);
|
||||
$partial->prepare('automation',$automationData);
|
||||
$partial->prepare('subDevices',$SUBDEVICES);
|
||||
$partial->render();
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
if (isset($_POST['modalNext'])) {
|
||||
$partial = new Partial('automationCreateFinal');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
$partial->prepare('userManager',$USERMANAGER);
|
||||
$partial->prepare('subDevices',$SUBDEVICES);
|
||||
$partial->render();
|
||||
} else {
|
||||
$partial = new Partial('automationCreate');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
|
||||
$partial->prepare('subDevices',$SUBDEVICES);
|
||||
$partial->render();
|
||||
}?>
|
||||
<script src="./app/templates/js/automation.js"></script>
|
||||
<?php
|
||||
$partial = new Partial('footer');
|
||||
$partial->render();
|
||||
?>
|
||||
</body>
|
||||
</html>
|
1
www/app/views/templates/example.phtml
Normal file
1
www/app/views/templates/example.phtml
Normal file
@@ -0,0 +1 @@
|
||||
Example template
|
70
www/app/views/templates/log.phtml
Normal file
70
www/app/views/templates/log.phtml
Normal file
@@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php
|
||||
$partial = new Partial('head');
|
||||
$partial->prepare('baseDir', $BASEDIR);
|
||||
$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">
|
||||
<?php
|
||||
$partial = new Partial('menu');
|
||||
$partial->prepare('item', 'log');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
$partial->prepare('debugMod',$DEBUGMOD);
|
||||
$partial->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-md-9 main-body">
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<label><?php echo $LANGMNG->get('l_logMaxLiveTime') . " " . $LOGTOLIVETIME . " days";?></label></br>
|
||||
|
||||
<label>CPU: <?php echo $CPU;?></label></br>
|
||||
<progress value="<?php echo $CPU;?>" max="1"> <?php echo $RAMFREE;?> </progress></br>
|
||||
<label>UPTIME: <?php echo $UPTIME;?></label></br>
|
||||
<label>RAM TOTAL: <?php echo $RAMTOTAL;?></label></br>
|
||||
<label>RAM FREE: <?php echo $RAMFREE;?></label></br>
|
||||
<progress value="<?php echo explode(" ", $RAMFREE)[0];?>" max="<?php echo explode(" ", $RAMTOTAL)[0];?>"> <?php echo $RAMFREE;?> </progress></br>
|
||||
|
||||
<label>DISKTOTAL: <?php echo $DISKTOTAL;?> bytes available</label></br>
|
||||
<label>SERVER TIME: <?php echo $SERVERTIME;?></label></br>
|
||||
|
||||
|
||||
|
||||
<form method="post" action="">
|
||||
<div class="field">
|
||||
<select class="input" name="LogFile">
|
||||
<?php foreach ($LOGSFILES as $key => $value) { ?>
|
||||
<option value="<?php echo $value; ?>"><?php echo $value; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="submit" class="button" name="selectFile" value="<?php $LANGMNG->echo('b_select');?>"/>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
if (isset($_POST['LogFile'])) {
|
||||
$file_lines = file('./app/logs/' . $_POST['LogFile']);
|
||||
echo '<pre style="overflow: auto;">';
|
||||
foreach ($file_lines as $line) {
|
||||
echo $line;
|
||||
}
|
||||
echo '</pre>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$partial = new Partial('footer');
|
||||
$partial->render();
|
||||
//TODO js do main.js
|
||||
?>
|
||||
</body>
|
||||
</html>
|
27
www/app/views/templates/login.phtml
Normal file
27
www/app/views/templates/login.phtml
Normal file
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php
|
||||
$partial = new Partial('head');
|
||||
$partial->render();
|
||||
?>
|
||||
<title><?php echo $TITLE ?></title>
|
||||
</head>
|
||||
<body class="no-transitions">
|
||||
<?php
|
||||
if (isset($ota) && $ota != '') {
|
||||
$partial = new Partial('loginOta');
|
||||
$partial->prepare('ota',$ota);
|
||||
$partial->render();
|
||||
} else {
|
||||
$partial = new Partial('loginForm');
|
||||
$partial->render();
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
$partial = new Partial('footer');
|
||||
$partial->render();
|
||||
?>
|
||||
</body>
|
||||
</html>
|
70
www/app/views/templates/part/automationButton.phtml
Normal file
70
www/app/views/templates/part/automationButton.phtml
Normal file
@@ -0,0 +1,70 @@
|
||||
<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 ? 'is-inactive' : ''); ?>" id="automation-<?php echo $AUTOMATIONID; ?>">
|
||||
<div class="row">
|
||||
<div class="col-1">
|
||||
<h5 class="fa">
|
||||
<?php
|
||||
//echo $AUTOMATIONDATA['ifSomething'];
|
||||
$ifCode = json_decode($AUTOMATIONDATA['ifSomething']);
|
||||
switch ($ifCode->type) {
|
||||
case 'sunSet':
|
||||
echo'';
|
||||
break;
|
||||
|
||||
case 'sunRise':
|
||||
echo' ';
|
||||
break;
|
||||
|
||||
case 'inHome':
|
||||
echo'';
|
||||
break;
|
||||
|
||||
case 'outHome':
|
||||
echo'';
|
||||
break;
|
||||
|
||||
case 'outDevice':
|
||||
echo'';
|
||||
break;
|
||||
|
||||
default:
|
||||
echo'';
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</h5>
|
||||
</div>
|
||||
<div class="col">
|
||||
<h5 class="text-right break-all">
|
||||
<?php
|
||||
/*if (!in_array($AUTOMATIONDATA['ifSomething'], ["sunRise", "sunSet"])) {
|
||||
echo $AUTOMATIONDATA['ifSomething'];
|
||||
}*/
|
||||
echo $AUTOMATIONDATA['name'];
|
||||
?>
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<?php echo implode(', ',$AUTOMATIONDATA['onDays']);?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<?php echo $AUTOMATIONDATA['owner_name'];?>
|
||||
</div>
|
||||
<div class="col">
|
||||
<?php echo $AUTOMATIONDATA['execution_time'];?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<a class="button is-primary m-1" onClick="restartAutomation(<?php echo $AUTOMATIONID; ?>);"><?php $LANGMNG->echo('b_restart')?></a>
|
||||
</div>
|
||||
<div class="col">
|
||||
<a class="button is-primary m-1" onClick="toggleAutomation(<?php echo $AUTOMATIONID; ?>);"><?php $LANGMNG->echo('b_disable')?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
69
www/app/views/templates/part/automationCreate.phtml
Normal file
69
www/app/views/templates/part/automationCreate.phtml
Normal file
@@ -0,0 +1,69 @@
|
||||
<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 $LANGMNG->echo('t_createAutomation')?></h4>
|
||||
<form method="post" action="" >
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_nameAt')?></div>
|
||||
<div class="field">
|
||||
<input class="input" type="text" name="name" required/>
|
||||
</div>
|
||||
<div class="label"><?php $LANGMNG->echo('l_runAt')?></div>
|
||||
<div class="field">
|
||||
<select class="input" name="atSelector" id="valueSelector" required>
|
||||
<option value="sunSet"><?php $LANGMNG->echo('l_sunSet')?></option>
|
||||
<option value="sunRise"><?php $LANGMNG->echo('l_sunRice')?></option>
|
||||
<option value="inHome"><?php $LANGMNG->echo('l_inHome')?></option>
|
||||
<option value="outHome"><?php $LANGMNG->echo('l_outHome')?></option>
|
||||
<option value="time"><?php $LANGMNG->echo('l_time')?></option>
|
||||
<option value="atDeviceValue"><?php $LANGMNG->echo('l_deviceValue');?></option>
|
||||
<option value="noOneHome"><?php $LANGMNG->echo('w_noOne') . ' ' . $LANGMNG->get('w_neni') . ' ' . $LANGMNG->get('w_home');?></option>
|
||||
<option value="someOneHome"><?php $LANGMNG->echo('w_someOne') . ' ' . $LANGMNG->get('w_is') . ' ' . $LANGMNG->get('w_home');?></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 $LANGMNG->echo('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 $subDeviceValue['masterDevice']; ?>"><?php echo $subDeviceValue['name']; ?></option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
|
||||
</div>
|
||||
<div class="label"><?php $LANGMNG->echo('l_atDays')?></div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="mon"/> <?php $LANGMNG->echo('d_monday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="tue"/> <?php $LANGMNG->echo('d_tuesday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="wed"/> <?php $LANGMNG->echo('d_wednesday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="thu"/> <?php $LANGMNG->echo('d_thursday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="fri"/> <?php $LANGMNG->echo('d_friday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="sat"/> <?php $LANGMNG->echo('d_saturday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="sun"/> <?php $LANGMNG->echo('d_sunday'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="button" name="modalNext" value="<?php $LANGMNG->echo('b_next')?>"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
44
www/app/views/templates/part/automationCreateFinal.phtml
Normal file
44
www/app/views/templates/part/automationCreateFinal.phtml
Normal file
@@ -0,0 +1,44 @@
|
||||
<div class="modal-container" id="modal">
|
||||
<div class="modal" action="" >
|
||||
<a href=""><i class="fa fa-times close"></i></a>
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_createAutomation'); ?></h4>
|
||||
<form method="post">
|
||||
<div class="field">
|
||||
<input type="hidden" name="action" value="add" required/>
|
||||
<input type="hidden" name="atSelector" value="<?php echo $_POST['atSelector']; ?>" required/>
|
||||
<input type="hidden" name="name" value="<?php echo $_POST['name']; ?>" required/>
|
||||
<input type="hidden" name="atSelectorValue" 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 {
|
||||
if ($_POST['atSelector'] == "inHome" || $_POST['atSelector'] == "outHome") {
|
||||
echo $USERMANAGER->getUserData('user_id');
|
||||
} 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="<?php $LANGMNG->echo('b_finish'); ?>"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
85
www/app/views/templates/part/automationEdit.phtml
Normal file
85
www/app/views/templates/part/automationEdit.phtml
Normal file
@@ -0,0 +1,85 @@
|
||||
<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 $LANGMNG->echo('t_createAutomation');?></h4>
|
||||
<form method="post">
|
||||
<input type="hidden" name="action" value="edit" required/>
|
||||
<input name="automation_id" type="hidden" value="<?php echo $AUTOMATIONID; ?>">
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_nameAt');?></div>
|
||||
<div class="field">
|
||||
<input class="input" type="text" name="name" value="<?php echo (isset ($AUTOMATION['name']) ? $AUTOMATION['name'] : ""); ?>" required/>
|
||||
</div>
|
||||
<div class="label"><?php $LANGMNG->echo('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 (json_decode($AUTOMATION['ifSomething'], true)['type'] == "sunSet" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_sunSet');?></option>
|
||||
<option value="sunRise" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "sunRise" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_sunRice');?></option>
|
||||
<option value="inHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "inHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_inHome');?></option>
|
||||
<option value="outHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "outHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_outHome');?></option>
|
||||
<option value="time" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "time" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_time');?></option>
|
||||
<option value="atDeviceValue" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "atDeviceValue" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_deviceValue');;?></option>
|
||||
<option value="noOneHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "noOneHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('w_noOne'); echo ' ' . $LANGMNG->get('w_neni') . ' ' . $LANGMNG->get('w_home');?></option>
|
||||
<option value="someOneHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "someOneHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('w_someOne'); echo ' ' . $LANGMNG->get('w_is') . ' ' . $LANGMNG->get('w_home');?></option>
|
||||
</select>
|
||||
<input class="input" type="time" name="atTime" id="atTime" value="<?php echo (json_decode($AUTOMATION['ifSomething'], true)['type'] == "time" ? json_decode($AUTOMATION['ifSomething'], true)['value'] : ""); ?>" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "time" ? '' : 'disabled'); ?>/>
|
||||
<select class="input" name="atDeviceValue" id="atDeviceValue" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "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="text" name="atDeviceValueInt" id="atDeviceValueInt" required <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "atDeviceValue" ? '' : 'disabled'); ?>/>
|
||||
</div>
|
||||
|
||||
<div class="label"><?php $LANGMNG->echo('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="device[<?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; ?>"></button>
|
||||
</div>
|
||||
<?php
|
||||
$i++;
|
||||
} ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="label"><?php $LANGMNG->echo('l_atDays');?></div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="mon" <?php ECHO (in_array("mon", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_monday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="tue" <?php ECHO (in_array("tue", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_tuesday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="wed" <?php ECHO (in_array("wed", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_wednesday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="thu" <?php ECHO (in_array("thu", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_thursday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="fri" <?php ECHO (in_array("fri", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_friday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="sat" <?php ECHO (in_array("sat", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_saturday'); ?>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="checkbox" name="day[]" value="sun" <?php ECHO (in_array("sun", $AUTOMATION['onDays']) ? 'checked' : ''); ?>/> <?php $LANGMNG->echo('d_sunday'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="button" name="modalFinal" value="<?php $LANGMNG->echo('b_edit'); ?>"/>
|
||||
<input type="submit" class="button is-danger" onClick="ajaxPostSimple('ajax',{automation_id: '<?php echo $AUTOMATIONID ?>', action:'delete'}, true);" name="remove" value="<?php $LANGMNG->echo('b_remove');?>"/>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
5
www/app/views/templates/part/footer.phtml
Normal file
5
www/app/views/templates/part/footer.phtml
Normal file
@@ -0,0 +1,5 @@
|
||||
<script src="./app/templates/js/jquery.js"></script>
|
||||
<script src="https://www.gstatic.com/firebasejs/7.1.0/firebase-app.js"></script>
|
||||
<script src="https://www.gstatic.com/firebasejs/7.1.0/firebase-messaging.js"></script>
|
||||
<script src="./app/templates/js/script.js"></script>
|
||||
<script src="./app/templates/js/post.js"></script>
|
26
www/app/views/templates/part/head.phtml
Normal file
26
www/app/views/templates/part/head.phtml
Normal file
@@ -0,0 +1,26 @@
|
||||
<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="<?php echo $BASEDIR; ?>">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<link rel="icon" sizes="192x192" href="<?php echo $BASEDIR; ?>app/templates/images/icon-192x192.png">
|
||||
<link rel="apple-touch-icon" sizes="192x192" href="<?php echo $BASEDIR; ?>app/templates/images/icon-192x192.png">
|
||||
<link rel="icon" sizes="512x512" href="<?php echo $BASEDIR; ?>app/templates/images/icon-512x512.png">
|
||||
<link rel="apple-touch-icon" sizes="512x512" href="<?php echo $BASEDIR; ?>app/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="./css/main.css?v2">
|
||||
<link rel="stylesheet" href="./css/font-awesome.min.css">
|
||||
<link rel="stylesheet" href="./css/modal.css">
|
||||
<link rel="stylesheet" href="./css/pre.css">
|
||||
<link rel="stylesheet" href="./css/loading.css">
|
||||
<link rel="stylesheet" href="./css/override.css">
|
20
www/app/views/templates/part/loginForm.phtml
Normal file
20
www/app/views/templates/part/loginForm.phtml
Normal file
@@ -0,0 +1,20 @@
|
||||
<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>
|
13
www/app/views/templates/part/loginOta.phtml
Normal file
13
www/app/views/templates/part/loginOta.phtml
Normal file
@@ -0,0 +1,13 @@
|
||||
<div class="modal-container">
|
||||
<div class="modal">
|
||||
<h4 class="mb-4">OTA</h4>
|
||||
<form method="post">
|
||||
<input type="hidden" name="otaSecret" value="<?php echo $OTA; ?>"/>
|
||||
<div class="field">
|
||||
<div class="label">Code:</div>
|
||||
<input class="input" type="text" name="otaCode" placeholder=""/>
|
||||
</div>
|
||||
<input type="submit" class="button" name="login" value="Login"/>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
35
www/app/views/templates/part/menu.phtml
Normal file
35
www/app/views/templates/part/menu.phtml
Normal file
@@ -0,0 +1,35 @@
|
||||
<div class="nav">
|
||||
<?php
|
||||
$menuItems = [
|
||||
'fa-wrench' => [
|
||||
'slug' => 'setting',
|
||||
'lngKey' => 'settings',
|
||||
'path' => 'setting',
|
||||
],
|
||||
'fa-calendar-o' => [
|
||||
'slug' => 'automation',
|
||||
'lngKey' => 'automatization',
|
||||
'path' => 'automation',
|
||||
],
|
||||
'fa-bug' =>[
|
||||
'slug' => 'log',
|
||||
'lngKey' => 'log',
|
||||
'path' => '',
|
||||
],
|
||||
];
|
||||
foreach ( $menuItems as $key => $value) {
|
||||
if ($DEBUGMOD == 0 && $value['path'] == 'log') {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<div class="nav-item <?php echo ($ITEM == $value ? 'is-active' : ''); ?>">
|
||||
<a href="<?php echo $value['path']?>">
|
||||
<i class="fa <?php echo $key ?>"></i>
|
||||
<span>
|
||||
<?php $LANGMNG->echo('m_'.$value['lngKey']); ?>
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<?php }?>
|
||||
|
||||
</div>
|
3
www/app/views/templates/part/test.phtml
Normal file
3
www/app/views/templates/part/test.phtml
Normal file
@@ -0,0 +1,3 @@
|
||||
<H1>
|
||||
TEST - TEST
|
||||
</H1>
|
203
www/app/views/templates/setting.phtml
Normal file
203
www/app/views/templates/setting.phtml
Normal file
@@ -0,0 +1,203 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<?php
|
||||
$partial = new Partial('head');
|
||||
$partial->prepare('baseDir', $BASEDIR);
|
||||
$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">
|
||||
<?php
|
||||
$partial = new Partial('menu');
|
||||
$partial->prepare('item', 'setting');
|
||||
$partial->prepare('langMng',$LANGMNG);
|
||||
$partial->prepare('debugMod',$DEBUGMOD);
|
||||
$partial->render();
|
||||
?>
|
||||
</div>
|
||||
<div class="col-md-9 main-body">
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4">
|
||||
|
||||
<?php $LANGMNG->echo('t_pageAfterLogIn') ?>
|
||||
</h4>
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="">
|
||||
<div class="field">
|
||||
<select class="input" name="loadPage">
|
||||
<option value="0" <?php echo (UserManager::getUserData("startPage") == 0 ? "selected" : ""); ?>>Default</option>
|
||||
<option value="1" <?php echo (UserManager::getUserData("startPage") == 1 ? "selected" : ""); ?>>Dashboard</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="submit" name="submit" class="button" value="<?php $LANGMNG->echo('b_save') ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_profile') ?></h4>
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_userAvatar') ?>:</div>
|
||||
<img src="<?php echo $USERAVATARURL; ?>" />
|
||||
<div class="label">* providet by Gavatar</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_userName') ?>:</div>
|
||||
<input class="input" value="<?php echo $USERNAME; ?>" disabled>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_userEmail') ?>:</div>
|
||||
<input class="input" value="<?php echo $USEREMAIL; ?>" disabled>
|
||||
</div>
|
||||
<div class="field">
|
||||
<a href="logout" class="button is-primary"><?php $LANGMNG->echo('b_logOut') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_notification') ?></h4>
|
||||
<input id="notifications" type="checkbox" onChange="toggleNotificationPermissions(this);" />
|
||||
<div class="label"><?php $LANGMNG->echo('l_notificationStatus') ?></div>
|
||||
<div class="field">
|
||||
<a onClick="sendTestNotification();" class="button"><?php $LANGMNG->echo('b_sendTestNotification');?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_experimental') ?></h4>
|
||||
<div class="field">
|
||||
<a href="rooms" class="button"><?php $LANGMNG->echo('b_rooms') ?></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_changePassword') ?></h4>
|
||||
<form method="post">
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_oldPassword') ?>:</div>
|
||||
<input type="password" class="input" name="oldPassword" value="" data-cip-id="cIPJQ342845639">
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_newPassword') ?>:</div>
|
||||
<input type="password" class="input" name="newPassword1" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_newPassword') ?>:</div>
|
||||
<input type="password" class="input" name="newPassword2" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="submit" name="submitPasswordChange" class="button" value="Uložit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_ota') ?></h4>
|
||||
<?php if (!empty($QRURL)) {?>
|
||||
<img src="<?php echo $QRURL;?>" />
|
||||
<?php echo $OTACODE; ?>
|
||||
<form method="post" action="setting">
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_gooleAutenticatorOtaCode') ?>:</div>
|
||||
<input type="text" class="input" name="otaCode" value="" required>
|
||||
<input type="hidden" class="input" name="otaSecret" value="<?php echo $OTASECRET;?>" required>
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="submit" name="submitEnableOta" class="button" value="Uložit">
|
||||
</div>
|
||||
</form>
|
||||
<?php } else {?>
|
||||
<button name="deactivateOta" type="button" class="button is-danger fa"><?php $LANGMNG->echo('b_disable');?> <?php $LANGMNG->echo('b_ota'); ?></button>
|
||||
<?php }?>
|
||||
</div>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_listUsers') ?></h4>
|
||||
<table class="table is-fluid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php $LANGMNG->echo('t_avatar');?></th>
|
||||
<th><?php $LANGMNG->echo('t_userName');?></th>
|
||||
<th><?php $LANGMNG->echo('t_ota');?></th>
|
||||
<th><?php $LANGMNG->echo('t_action');?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($USERS as $key => $user) { ?>
|
||||
<tr>
|
||||
<td><img src="<?php echo $user['gavatar_url']; ?>" /></td>
|
||||
<td><?php echo $user['username']; ?></td>
|
||||
<td><?php echo ($user['ota'] ? '<span class="fa"></span>' : ''); ?></td>
|
||||
<td><button name="deleteUser" type="button" class="button is-danger fa"></button></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_createuser') ?></h4>
|
||||
<form method="post">
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_userName') ?>:</div>
|
||||
<input type="text" class="input" name="userName" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_password') ?>:</div>
|
||||
<input type="password" class="input" name="userPassword" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="submit" name="submitCreateUser" class="button" value="Uložit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!--Room Managment-->
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_listRooms') ?></h4>
|
||||
<table class="table is-fluid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php $LANGMNG->echo('t_roomName');?></th>
|
||||
<th><?php $LANGMNG->echo('t_action');?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($ROOMS as $key => $room) { ?>
|
||||
<tr>
|
||||
<td><?php echo $room['name']; ?></td>
|
||||
<td>
|
||||
<button name="deleteRoom" type="button" class="button is-danger fa"></button>
|
||||
<button name="defaultRoom" type="button" class="button fa" <?php echo ($room['default'] ? 'disabled' : ''); ?>></button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!--Room Creation-->
|
||||
<div class="col-12 col-sm-9 mx-auto mt-4">
|
||||
<h4 class="mb-4"><?php $LANGMNG->echo('t_createRoom') ?></h4>
|
||||
<form method="post">
|
||||
<div class="field">
|
||||
<div class="label"><?php $LANGMNG->echo('l_roomName') ?>:</div>
|
||||
<input type="text" class="input" name="roomName" value="">
|
||||
</div>
|
||||
<div class="field">
|
||||
<input type="submit" name="submitCreateUser" class="button" value="<?php $LANGMNG->echo('b_create') ?>">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<?php
|
||||
$partial = new Partial('footer');
|
||||
$partial->render();
|
||||
?>
|
||||
<script src="./app/templates/js/setting.js"></script>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
37
www/docker-compose.yml
Normal file
37
www/docker-compose.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
|
||||
php:
|
||||
build:
|
||||
context: ./docker/php
|
||||
ports:
|
||||
- 9000:9000
|
||||
volumes:
|
||||
- ./:/srv/www/api
|
||||
- ./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf
|
||||
environment:
|
||||
MYSQL_USER: ${MYSQL_USER}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
|
||||
nginx:
|
||||
image: nginx:1.13.8
|
||||
ports:
|
||||
- 80:80
|
||||
volumes:
|
||||
- ./:/srv/www/api
|
||||
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
|
||||
depends_on:
|
||||
- php
|
||||
|
||||
mysql:
|
||||
image: mysql:5.7
|
||||
ports:
|
||||
- 3306:3306
|
||||
depends_on:
|
||||
- php
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
||||
MYSQL_USER: ${MYSQL_USER}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
123
www/lang/cs.php
Normal file
123
www/lang/cs.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
return $lang = [
|
||||
//Menu
|
||||
'm_home' => 'Domů',
|
||||
'm_dashboard' => 'Nástěnka',
|
||||
'm_settings' => 'Nastavení',
|
||||
'm_automatization' => 'Automatizace',
|
||||
'm_scenes' => 'Scény',
|
||||
'm_log' => 'Log',
|
||||
|
||||
//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_finish' => 'Dokončit',
|
||||
'b_approve' => 'Povolit',
|
||||
'b_disable' => 'Zakázat',
|
||||
'b_save' => 'Uložit',
|
||||
'b_logOut' => 'Odhlásit',
|
||||
'b_sendTestNotification' => 'Odeslat testovací notifikaci',
|
||||
'b_rooms' => 'Místnosti',
|
||||
'b_restart' => 'Restart',
|
||||
'b_disable' => 'Deaktivovat',
|
||||
'b_select' => 'Zvolit',
|
||||
'b_ota' => 'ota',
|
||||
|
||||
//labels
|
||||
'l_choseDevice' => 'Zvolte zařízení:',
|
||||
'l_inHome' => 'Při příchodu',
|
||||
'l_outHome' => 'Pri odchodu',
|
||||
'l_sunSet' => 'Západ Slunce',
|
||||
'l_sunRice' => 'Východ 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í',
|
||||
'l_atHome' => 'Doma Jsou',
|
||||
'l_nameAt' => 'Název',
|
||||
'l_lastSeen' => 'Naposledy připojeno',
|
||||
'l_notificationStatus' => 'Notification status',
|
||||
'l_userName' => 'Uživatelské jméno',
|
||||
'l_password' => 'Heslo',
|
||||
'l_oldPassword' => 'Staré Heslo',
|
||||
'l_newPassword' => 'Nové Heslo',
|
||||
'l_uploadFirmware' => 'Nahrát Firmware',
|
||||
'l_userAvatar' => 'Avatar',
|
||||
'l_userEmail' => 'Email',
|
||||
'l_roomName' => 'Jméno Místnosti',
|
||||
|
||||
//Title
|
||||
't_createScene' => 'Vytvořit scénu',
|
||||
't_editScene' => 'Upravit scénu',
|
||||
't_createAutomation' => 'Vytvořit Automatizaci',
|
||||
't_addDevice' => 'Přidat Zařízení',
|
||||
't_editDevice' => 'Upravit Zařízení',
|
||||
't_pageAfterLogIn' => 'stránka po přihlášení',
|
||||
't_profile' => 'Profil',
|
||||
't_notification' => 'Notificatifikace',
|
||||
't_experimental' => 'Experimental',
|
||||
't_createuser' => 'Vytvořit Uživatele',
|
||||
't_changePassword' => 'Změnit Heslo',
|
||||
't_networkSetting' => 'Nastavení Sítě',
|
||||
't_deviceVersion' => 'Nastavení Verze',
|
||||
't_ota' => 'OTA',
|
||||
't_listUsers' => 'Seznam Uživatelů',
|
||||
't_avatar' => 'Avatar',
|
||||
't_listRooms' => 'Seznam Místností',
|
||||
't_roomName' => 'Jméno Místnosti',
|
||||
't_createRoom' => 'Vytvořit Místnost',
|
||||
|
||||
//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_someOne' => 'Někdo',
|
||||
'w_room' => 'Místnost',
|
||||
'w_moduls' => 'Moduly',
|
||||
'w_home' => 'Doma',
|
||||
'w_neni' => 'Není',
|
||||
'w_is' => 'je',
|
||||
|
||||
//tables
|
||||
't_time' => 'Čas',
|
||||
't_state' => 'Stav',
|
||||
't_userName' => 'Uživatelské Jméno',
|
||||
't_action' => 'Akce',
|
||||
|
||||
//Days Long
|
||||
'd_monday' => 'Pondělí',
|
||||
'd_tuesday' => 'Ůterí',
|
||||
'd_wednesday' => 'Středa',
|
||||
'd_thursday' => 'Čtvrtek',
|
||||
'd_friday' => 'Pátek',
|
||||
'd_saturday' => 'Sobota',
|
||||
'd_sunday' => 'Neděle',
|
||||
|
||||
//example
|
||||
'' => '',
|
||||
];
|
123
www/lang/en.php
Normal file
123
www/lang/en.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
return $lang = [
|
||||
//Menu
|
||||
'm_home' => 'Home',
|
||||
'm_dashboard' => 'Dashboard',
|
||||
'm_settings' => 'Setting',
|
||||
'm_automatization' => 'Automatization',
|
||||
'm_scenes' => 'Scenes',
|
||||
'm_log' => 'Log',
|
||||
|
||||
//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_finish' => 'Finish',
|
||||
'b_approve' => 'Approve',
|
||||
'b_disable' => 'Disable',
|
||||
'b_save' => 'Save',
|
||||
'b_logOut' => 'Logout',
|
||||
'b_sendTestNotification' => 'Send Test Notification',
|
||||
'b_rooms' => 'Rooms',
|
||||
'b_restart' => 'Restart',
|
||||
'b_disable' => 'disabele',
|
||||
'b_select' => 'Select',
|
||||
'b_ota' => 'ota',
|
||||
|
||||
//labels
|
||||
'l_choseDevice' => 'Chose device:',
|
||||
'l_inHome' => 'When entering',
|
||||
'l_outHome' => 'When exiting',
|
||||
'l_sunSet' => 'Sun Set',
|
||||
'l_sunRice' => 'Sun Rise',
|
||||
'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',
|
||||
'l_atHome' => 'At home',
|
||||
'l_nameAt' => 'Name',
|
||||
'l_lastSeen' => 'Last Seen',
|
||||
'l_notificationStatus' => 'Notification status',
|
||||
'l_userName' => 'Username',
|
||||
'l_password' => 'Password',
|
||||
'l_oldPassword' => 'Old Password',
|
||||
'l_newPassword' => 'New Password',
|
||||
'l_uploadFirmware' => 'Upload Firmware',
|
||||
'l_userAvatar' => 'Avatar',
|
||||
'l_userEmail' => 'Email',
|
||||
'l_roomName' => 'Room Name',
|
||||
|
||||
//Title
|
||||
't_createScene' => 'Create Scene',
|
||||
't_editScene' => 'Edit scénu',
|
||||
't_createAutomation' => 'Create Automation',
|
||||
't_addDevice' => 'Add Device',
|
||||
't_editDevice' => 'Edit Device',
|
||||
't_pageAfterLogIn' => 'Page After Login',
|
||||
't_profile' => 'Profile',
|
||||
't_notification' => 'Notification',
|
||||
't_experimental' => 'Experimental',
|
||||
't_createuser' => 'Create User',
|
||||
't_changePassword' => 'Change Password',
|
||||
't_networkSetting' => 'Network Setting',
|
||||
't_deviceVersion' => 'Version Setting',
|
||||
't_ota' => 'OTA',
|
||||
't_listUsers' => 'User List',
|
||||
't_avatar' => 'Avatar',
|
||||
't_listRooms' => 'Room List',
|
||||
't_roomName' => 'Room Name',
|
||||
't_createRoom' => 'Create Rom',
|
||||
|
||||
//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_someOne' => 'Some',
|
||||
'w_room' => 'Room',
|
||||
'w_moduls' => 'Moduls',
|
||||
'w_home' => 'Home',
|
||||
'w_neni' => 'At',
|
||||
'w_is' => 'is',
|
||||
|
||||
//tables
|
||||
't_time' => 'Time',
|
||||
't_state' => 'State',
|
||||
't_userName' => 'State',
|
||||
't_action' => 'Action',
|
||||
|
||||
//Days Long
|
||||
'd_monday' => 'Monday',
|
||||
'd_tuesday' => 'Tuesday',
|
||||
'd_wednesday' => 'Wednesday',
|
||||
'd_thursday' => 'Thursday',
|
||||
'd_friday' => 'Friday',
|
||||
'd_saturday' => 'Saturday',
|
||||
'd_sunday' => 'Sunday',
|
||||
|
||||
//example
|
||||
'' => '',
|
||||
];
|
102
www/lang/nl.php
Normal file
102
www/lang/nl.php
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
return $lang = [
|
||||
//Menu
|
||||
'm_home' => 'Home',
|
||||
'm_dashboard' => 'Controlepaneel',
|
||||
'm_settings' => 'Instellingen',
|
||||
'm_automatization' => 'Automatisatie',
|
||||
'm_scenes' => 'Scénes',
|
||||
'm_log' => 'Log',
|
||||
|
||||
//Buttons
|
||||
'b_year' => 'Jaar',
|
||||
'b_month' => 'Maand',
|
||||
'b_week' => 'Week',
|
||||
'b_day' => 'Dag',
|
||||
'b_hour' => 'Uur',
|
||||
'b_next' => 'Volgende',
|
||||
'b_create' => 'Maak',
|
||||
'b_edit' => 'Bewerk',
|
||||
'b_remove' => 'Verwijder',
|
||||
'b_approve' => 'Keur goed',
|
||||
'b_disable' => 'Zet uit',
|
||||
'b_save' => 'Opslaan',
|
||||
'b_logOut' => 'Log Uit',
|
||||
'b_sendTestNotification' => 'Verzend Test Notificatie',
|
||||
'b_rooms' => 'Kamers',
|
||||
'b_restart' => 'Herstart',
|
||||
'b_disable' => 'Zet uit',
|
||||
'b_select' => 'Selecteer',
|
||||
|
||||
|
||||
//labels
|
||||
'l_choseDevice' => 'Kies apparaat:',
|
||||
'l_inHome' => 'Bij het inkomen',
|
||||
'l_outHome' => 'Bij het buitengaan',
|
||||
'l_sunSet' => 'Zonsondergang',
|
||||
'l_sunRice' => 'Zonsopkomst',
|
||||
'l_time' => 'Tijd',
|
||||
'l_deviceValue' => 'Apparaat Waarde',
|
||||
'l_runAt' => 'Voer uit bij',
|
||||
'l_resetAt' => 'Reset bij',
|
||||
'l_affectedDevices' => 'Getroffen apparaten',
|
||||
'l_atDays' => 'Op dagen ',
|
||||
'l_read' => 'Lees',
|
||||
'l_use' => 'Gebruik',
|
||||
'l_edit' => 'Bewerk',
|
||||
'l_owner' => 'eigenaar',
|
||||
'l_member' => 'Huis lid',
|
||||
'l_permission' => 'Permissie',
|
||||
'l_inMinutes' => 'in minuten',
|
||||
'l_sleepTime' => 'Apparaat slaaptijd',
|
||||
'l_atHome' => 'Thuis',
|
||||
'l_nameAt' => 'Naam',
|
||||
'l_lastSeen' => 'Laatst gezien',
|
||||
'l_notificationStatus' => 'Notificatie status',
|
||||
|
||||
//Title
|
||||
't_createScene' => 'Maak scéne',
|
||||
't_editScene' => 'Bewerk scéne',
|
||||
't_createAutomation' => 'Maak automatisatie',
|
||||
't_addDevice' => 'Voeg apparaat toe',
|
||||
't_editDevice' => 'Bewerk apparaat',
|
||||
't_pageAfterLogIn' => 'Pagina na Login',
|
||||
't_profile' => 'Profiel',
|
||||
't_notification' => 'Notificatie',
|
||||
't_experimental' => 'experimenteel',
|
||||
|
||||
//constants
|
||||
'humi' => 'Vochtigheid',
|
||||
'temp' => 'Temperatuur',
|
||||
'light' => 'Licht',
|
||||
'battery' => 'Batterij',
|
||||
'on/off' => 'Schakelaar',
|
||||
|
||||
//words
|
||||
'w_title' => 'Naam',
|
||||
'w_icon' => 'Icoon',
|
||||
'w_no' => 'nee',
|
||||
'w_noOne' => 'niemand',
|
||||
'w_someOne' => 'Sommige',
|
||||
'w_room' => 'Kamer',
|
||||
'w_moduls' => 'Modules',
|
||||
'w_home' => 'Huis',
|
||||
'w_neni' => 'Bij',
|
||||
'w_is' => 'is',
|
||||
|
||||
//tables
|
||||
't_time' => 'Tijd',
|
||||
't_state' => 'Status',
|
||||
|
||||
//Days Long
|
||||
'd_monday' => 'Maandag',
|
||||
'd_tuesday' => 'Dinsdag',
|
||||
'd_wednesday' => 'Woensdag',
|
||||
'd_thursday' => 'Donderdag',
|
||||
'd_friday' => 'Vrijdag',
|
||||
'd_saturday' => 'Zaterdag',
|
||||
'd_sunday' => 'Zondag',
|
||||
|
||||
//example
|
||||
'' => '',
|
||||
];
|
110
www/lang/pl.php
Normal file
110
www/lang/pl.php
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
return $lang = [
|
||||
//Menu
|
||||
'm_home' => 'Strona główna',
|
||||
'm_dashboard' => 'Panel urządzeń',
|
||||
'm_settings' => 'Ustawienia',
|
||||
'm_automatization' => 'Zaplanowane działania',
|
||||
'm_scenes' => 'Scenariusze',
|
||||
'm_log' => 'Logi',
|
||||
|
||||
//Buttons
|
||||
'b_year' => 'Rok',
|
||||
'b_month' => 'Miesiąc',
|
||||
'b_week' => 'Tydzień',
|
||||
'b_day' => 'Dzień',
|
||||
'b_hour' => 'Godzina',
|
||||
'b_next' => 'Dalej',
|
||||
'b_create' => 'Utwórz',
|
||||
'b_edit' => 'Edytuj',
|
||||
'b_remove' => 'Usuń',
|
||||
'b_finish' => 'Dokončit', //newOne
|
||||
'b_approve' => 'Zaakceptuj',
|
||||
'b_disable' => 'Wyłącz',
|
||||
'b_save' => 'Zapisz',
|
||||
'b_logOut' => 'Wyloguj',
|
||||
'b_sendTestNotification' => 'Wyślij próbne powiadomienie',
|
||||
'b_rooms' => 'Pokoje',
|
||||
'b_restart' => 'Zrestartuj',
|
||||
'b_disable' => 'Wyłącz',
|
||||
'b_select' => 'Wybierz',
|
||||
|
||||
//labels
|
||||
'l_choseDevice' => 'Wybierz urządzenie:',
|
||||
'l_inHome' => 'Przy wchodzeniu',
|
||||
'l_outHome' => 'Przy wychodzeniu',
|
||||
'l_sunSet' => 'Zachodzie słońca',
|
||||
'l_sunRice' => 'Zschodzie słońca',
|
||||
'l_time' => 'O określonym czasie',
|
||||
'l_deviceValue' => 'Przy wartości urządzenia',
|
||||
'l_runAt' => 'Uruchom o',
|
||||
'l_resetAt' => 'Resetuj o',
|
||||
'l_affectedDevices' => 'Ma wpływ na urządzenia',
|
||||
'l_atDays' => 'W dni',
|
||||
'l_read' => 'Odczytywanie',
|
||||
'l_use' => 'Używanie',
|
||||
'l_edit' => 'Edytowanie',
|
||||
'l_owner' => 'Właściciel',
|
||||
'l_member' => 'Domownik',
|
||||
'l_permission' => 'Uprawnienia',
|
||||
'l_inMinutes' => 'w minutach',
|
||||
'l_sleepTime' => 'Czas snu urządzenia',
|
||||
'l_atHome' => 'W domu',
|
||||
'l_nameAt' => 'Nazwa',
|
||||
'l_lastSeen' => 'Ostatnio zaktualizowany',
|
||||
'l_notificationStatus' => 'Stan powiadomienia',
|
||||
'l_userName' => 'Username', //newOne
|
||||
'l_password' => 'Password', //newOne
|
||||
'l_oldPassword' => 'Old Password', //newOne
|
||||
'l_newPassword' => 'New Password', //newOne
|
||||
|
||||
//Title
|
||||
't_createScene' => 'Utwórz scenariusz',
|
||||
't_editScene' => 'Edytuj scenariusz',
|
||||
't_createAutomation' => 'Utwórz automację',
|
||||
't_addDevice' => 'Dodaj Urządzenie',
|
||||
't_editDevice' => 'Edutuj urządzenie',
|
||||
't_pageAfterLogIn' => 'Strona Po Zalogowaniu',
|
||||
't_profile' => 'Profil',
|
||||
't_notification' => 'Powiadomienie',
|
||||
't_experimental' => 'Eksperymentalne',
|
||||
't_createuser' => 'Vytvořit Uživatele', //newOne
|
||||
't_changePassword' => 'Změnit Heslo', //newOne
|
||||
|
||||
//constants
|
||||
'humi' => 'Wilgotność',
|
||||
'temp' => 'Temperatura',
|
||||
'light' => 'Światło',
|
||||
'battery' => 'Bateria',
|
||||
'on/off' => 'Przełącznik',
|
||||
|
||||
//words
|
||||
'w_title' => 'Nazwa',
|
||||
'w_icon' => 'ikony',
|
||||
'w_no' => 'Brak',
|
||||
'w_noOne' => 'nikt',
|
||||
'w_someOne' => 'Ktoś',
|
||||
'w_room' => 'Pokój',
|
||||
'w_moduls' => 'Moduły',
|
||||
'w_home' => 'Dom',
|
||||
'w_neni' => 'W',
|
||||
'w_is' => 'jest',
|
||||
|
||||
//tables
|
||||
't_time' => 'Czas',
|
||||
't_state' => 'Stan',
|
||||
't_userName' => 'State', //newOne
|
||||
't_action' => 'Action', //newOne
|
||||
|
||||
//Days Long
|
||||
'd_monday' => 'Poniedziałek',
|
||||
'd_tuesday' => 'Wtorek',
|
||||
'd_wednesday' => 'Środa',
|
||||
'd_thursday' => 'Czwartek',
|
||||
'd_friday' => 'Piątek',
|
||||
'd_saturday' => 'Sobota',
|
||||
'd_sunday' => 'Niedziela',
|
||||
|
||||
//example
|
||||
'' => '',
|
||||
];
|
36
www/library/ApiController.php
Normal file
36
www/library/ApiController.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
class ApiController {
|
||||
protected $input;
|
||||
protected $authenticated = false;
|
||||
|
||||
function __construct() {
|
||||
$input = file_get_contents('php://input');
|
||||
|
||||
if(empty($input)){
|
||||
$this->input = NULL;
|
||||
}else{
|
||||
$this->input = json_decode($input, true);
|
||||
if(json_last_error() != JSON_ERROR_NONE){
|
||||
throw new Exception("Invalid request payload", 400);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function requireAuth(){
|
||||
if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||
// TODO: call appropriate class/method
|
||||
$authManager = new AuthManager();
|
||||
$this->authenticated = $authManager>validateToken($_SERVER['HTTP_AUTHORIZATION']);
|
||||
if(!$this->authenticated){
|
||||
throw new Exception("Authorization required", 401);
|
||||
}
|
||||
} else {
|
||||
throw new Exception("Authorization required", 401);
|
||||
}
|
||||
}
|
||||
|
||||
protected function response($data = [], $httpCode = '200'){
|
||||
http_response_code($httpCode);
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
}
|
9
www/library/Controller.php
Normal file
9
www/library/Controller.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class Controller{
|
||||
public $view = null;
|
||||
|
||||
public function __construct(){
|
||||
$this->view = new View();
|
||||
}
|
||||
}
|
98
www/library/DB.php
Normal file
98
www/library/DB.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?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 disconect(){
|
||||
self::$join = null;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
}
|
121
www/library/Form.php
Normal file
121
www/library/Form.php
Normal file
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
/**
|
||||
* [InputTypes datatype for input types]
|
||||
*/
|
||||
class InputTypes
|
||||
{
|
||||
const TEXT = 'text';
|
||||
const NUMBER = 'number';
|
||||
const COLOR = 'color';
|
||||
const CHECK = 'checkbox';
|
||||
const BUTTON = 'button';
|
||||
const DATE = 'date';
|
||||
const DATETIME = 'datetime';
|
||||
const SUBMIT = 'submit';
|
||||
const HIDEN = 'hidden';
|
||||
const EMAIL = 'email';
|
||||
}
|
||||
/**
|
||||
* [Form Form Generator Class]
|
||||
*/
|
||||
class Form {
|
||||
|
||||
public $formContent = "";
|
||||
private $formName;
|
||||
private $formId;
|
||||
private $method;
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* [__construct description]
|
||||
* @param String $name [description]
|
||||
* @param String $id [description]
|
||||
* @param String $method [description]
|
||||
* @param String $action [description]
|
||||
*/
|
||||
function __construct(String $name, String $id, String $method, String $action) {
|
||||
if ($name != "") {
|
||||
$this->formName = 'name="'.$name.'"';
|
||||
}
|
||||
if ($id != "") {
|
||||
$this->formId = 'id="'.$id.'"';
|
||||
}
|
||||
if ($method != "") {
|
||||
$this->method = 'method="'.$method.'"';
|
||||
}
|
||||
if ($action != "") {
|
||||
$this->$action = 'action="'.$action.'"';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* [addInput description]
|
||||
* @param String $type Type of input element (text, number, color,checkbox, button, date, datetime, submit)
|
||||
* @param String $name name of element
|
||||
* @param String $id id of element
|
||||
* @param String $label label of element
|
||||
* @param String $value value of element
|
||||
* @param boolean $require require selector toggle
|
||||
* @param boolean $enabled enable selector toggle
|
||||
*/
|
||||
function addInput(String $type, String $name, String $id, String $label, String $value, Bool $require = false, Bool $enabled = true){
|
||||
$this->formContent .= '<div class="field">';
|
||||
if ($label != "") {
|
||||
$this->formContent .= '<div class="label">'.$label.'</div>';
|
||||
}
|
||||
$this->formContent .= '<input class="input" type="'.$type.'" name="'.$name.'" value="'.$value.'" ' . ($enabled ? '' : 'disabled') . ($require ? '' : 'required') .'>';
|
||||
$this->formContent .= '</div>';
|
||||
}
|
||||
|
||||
//TODO: add Group support
|
||||
/**
|
||||
* [addSelect description]
|
||||
* @param String $name name of element
|
||||
* @param String $id id of element
|
||||
* @param String $label label of element
|
||||
* @param Array $data array of options [value => valueName]
|
||||
* @param boolean $multiple multiple selector toggle
|
||||
* @param boolean $enabled enable selector toggle
|
||||
*/
|
||||
function addSelect(String $name, String $id, String $label, Array $data, Bool $multiple = false, Bool $require = false, Bool $enabled = true){
|
||||
$this->formContent .= '<div class="field">';
|
||||
if ($label != "") {
|
||||
$this->formContent .= '<div class="label">'.$label.'</div>';
|
||||
}
|
||||
$this->formContent .= '<select class="input"' . ($multiple ? '' : 'multiple') . ($enabled ? '' : 'disabled') . ($require ? '' : 'required') .'>';
|
||||
foreach ($data as $value => $text) {
|
||||
$this->formContent .= '<option value="' . $value . '">' . $text . '</option>';
|
||||
}
|
||||
$this->formContent .= '</select>';
|
||||
$this->formContent .= '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* [addTextarea description]
|
||||
* @param String $name name of element
|
||||
* @param String $id id of element
|
||||
* @param String $label label of element
|
||||
* @param String $value value of element
|
||||
* @param boolean $enabled enable selector toggle
|
||||
*/
|
||||
function addTextarea(String $name, String $id, String $label, Array $value, Bool $require = false, Bool $enabled = true){
|
||||
$this->formContent .= '<div class="field">';
|
||||
if ($label != "") {
|
||||
$this->formContent .= '<div class="label">'.$label.'</div>';
|
||||
}
|
||||
$this->formContent .= '<textarea class="input"' . ($enabled ? '' : 'disabled') . ($require ? '' : 'required') .'>';
|
||||
$this->formContent .= $value;
|
||||
$this->formContent .= '</textarea>';
|
||||
$this->formContent .= '</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* [render function whitch dysplay generated form]
|
||||
*/
|
||||
function render(){
|
||||
self::addInput(InputTypes::SUBMIT, 'formSubmit', '', 'Submit', 'Submit');
|
||||
$form = '<form '.$this->formName.$this->formId.$this->method.$this->action.'">';
|
||||
$form .= $this->formContent;
|
||||
$form .= '</form>';
|
||||
echo $form;
|
||||
}
|
||||
}
|
34
www/library/Partial.php
Normal file
34
www/library/Partial.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
class Partial{
|
||||
private $assignedValues = [];
|
||||
private $partBuffer;
|
||||
private $path;
|
||||
private $debug;
|
||||
|
||||
function __construct($path = "", $debug = false) {
|
||||
$this->debug = $debug;
|
||||
if (!empty('../app/views/templates/part/' . $path . '.phtml') && file_exists('../app/views/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('../app/views/templates/part/' . $this->path . '.phtml');
|
||||
}
|
||||
}
|
105
www/library/Router.php
Normal file
105
www/library/Router.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
/**
|
||||
* Mini Router
|
||||
* @author github.com/Xinatorus
|
||||
* https://github.com/Xinatorus/MiniRouter
|
||||
*/
|
||||
class Router{
|
||||
|
||||
private $routes;
|
||||
private $defaultFunction;
|
||||
private $params;
|
||||
private $function;
|
||||
|
||||
public function __construct(){
|
||||
$this->routes = [];
|
||||
$this->function = NULL;
|
||||
$this->defaultFunction = NULL;
|
||||
$this->params = [];
|
||||
}
|
||||
|
||||
public function add($method, $pattern, $function){
|
||||
$this->routes[] = [
|
||||
'method' => $method,
|
||||
'pattern' => $pattern,
|
||||
'function' => $function,
|
||||
];
|
||||
}
|
||||
|
||||
public function any($pattern, $function){
|
||||
$this->add(NULL, $pattern, $function);
|
||||
}
|
||||
|
||||
public function get($pattern, $function){
|
||||
$this->add('GET', $pattern, $function);
|
||||
}
|
||||
|
||||
public function post($pattern, $function){
|
||||
$this->add('POST', $pattern, $function);
|
||||
}
|
||||
|
||||
public function put($pattern, $function){
|
||||
$this->add('PUT', $pattern, $function);
|
||||
}
|
||||
|
||||
public function patch($pattern, $function){
|
||||
$this->add('PATCH', $pattern, $function);
|
||||
}
|
||||
|
||||
public function delete($pattern, $function){
|
||||
$this->add('DELETE', $pattern, $function);
|
||||
}
|
||||
|
||||
public function setDefault($function){
|
||||
$this->defaultFunction = $function;
|
||||
}
|
||||
|
||||
public function run($method, $uri){
|
||||
if(!$this->matchRoute($method, $uri)){
|
||||
$this->function = $this->defaultFunction;
|
||||
}
|
||||
|
||||
if($this->function !== NULL){
|
||||
if(is_string($this->function)){
|
||||
if(strpos($this->function, '@') !== false){
|
||||
list($class, $function) = explode('@', $this->function);
|
||||
$method = new ReflectionMethod($class, $function);
|
||||
if($method->isStatic()){
|
||||
call_user_func_array([$class, $function], $this->params);
|
||||
}else{
|
||||
call_user_func_array([new $class, $function], $this->params);
|
||||
}
|
||||
}else if(class_exists($this->function)){
|
||||
new $this->function(...$this->params);
|
||||
}else if (is_callable($this->function)) {
|
||||
call_user_func_array($this->function, $this->params);
|
||||
}
|
||||
}else if (is_callable($this->function)) {
|
||||
call_user_func_array($this->function, $this->params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function matchRoute($method, $uri){
|
||||
foreach($this->routes as $route){
|
||||
$patternRegex = $this->convertPatternToRegex($route['pattern']);
|
||||
$params = [];
|
||||
if(($route['method'] === NULL || $route['method'] === $method) && preg_match($patternRegex, $uri, $params)){
|
||||
array_shift($params);
|
||||
$this->params = $params;
|
||||
$this->function = $route['function'];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function convertPatternToRegex($pattern){
|
||||
$regex = preg_replace('@{\w+}@', '([\w\d\-\.,]+)', $pattern);
|
||||
if ( substr($regex, -1) === '/' ) {
|
||||
$regex .= '?';
|
||||
}
|
||||
return '@^' . $regex . '$@';
|
||||
}
|
||||
}
|
34
www/library/Template.php
Normal file
34
www/library/Template.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
class Template{
|
||||
private $assignedValues = [];
|
||||
private $partBuffer;
|
||||
private $path;
|
||||
private $debug;
|
||||
|
||||
function __construct($path = "", $debug = false) {
|
||||
$this->debug = $debug;
|
||||
if (!empty('../app/views/templates/' . $path . '.phtml') && file_exists('../app/views/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('../app/controllers/' . $this->path . 'Controller.php') && file_exists('../app/controllers/' . $this->path . 'Controller.php')) {
|
||||
include('../app/controllers/' . $this->path . 'Controller.php');
|
||||
}
|
||||
require_once('../app/views/templates/' . $this->path . '.phtml');
|
||||
}
|
||||
}
|
63
www/library/View.php
Normal file
63
www/library/View.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
class View{
|
||||
protected $_content = "";
|
||||
protected $_layout = 'default';
|
||||
|
||||
protected $_viewEnabled = true;
|
||||
protected $_layoutEnabled = true;
|
||||
|
||||
protected $_data = array();
|
||||
|
||||
public function disableLayout(){
|
||||
$this->_layoutEnabled = false;
|
||||
}
|
||||
|
||||
public function enableLayout(){
|
||||
$this->_layoutEnabled = false;
|
||||
}
|
||||
|
||||
public function setLayout($layout){
|
||||
$this->_layout = $layout;
|
||||
}
|
||||
|
||||
public function disableView(){
|
||||
$this->_viewEnabled = false;
|
||||
}
|
||||
|
||||
public function __set($key, $value){
|
||||
$this->_data[$key] = $value;
|
||||
}
|
||||
|
||||
public function __get($key){
|
||||
if(array_key_exists($key, $this->_data)){
|
||||
return $this->_data[$key];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function content(){
|
||||
return $this->_content;
|
||||
}
|
||||
|
||||
public function render($template){
|
||||
if($template && $this->_viewEnabled){
|
||||
$this->_fetchContent($template);
|
||||
}
|
||||
|
||||
if($this->_layoutEnabled){
|
||||
include('../app/views/layouts/' . $this->_layout . '.phtml');
|
||||
} else {
|
||||
echo $this->_content;
|
||||
}
|
||||
}
|
||||
|
||||
protected function _fetchContent($template){
|
||||
ob_start();
|
||||
|
||||
include('../app/views/templates/' . $template);
|
||||
|
||||
$this->_content = ob_get_clean();
|
||||
}
|
||||
}
|
252
www/library/vendor/PHPGangsta_GoogleAuthenticator.php
vendored
Normal file
252
www/library/vendor/PHPGangsta_GoogleAuthenticator.php
vendored
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* PHP Class for handling Google Authenticator 2-factor authentication.
|
||||
*
|
||||
* @author Michael Kliewe
|
||||
* @copyright 2012 Michael Kliewe
|
||||
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
|
||||
*
|
||||
* @link http://www.phpgangsta.de/
|
||||
*/
|
||||
class PHPGangsta_GoogleAuthenticator
|
||||
{
|
||||
protected $_codeLength = 6;
|
||||
|
||||
/**
|
||||
* Create new secret.
|
||||
* 16 characters, randomly chosen from the allowed base32 characters.
|
||||
*
|
||||
* @param int $secretLength
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function createSecret($secretLength = 16)
|
||||
{
|
||||
$validChars = $this->_getBase32LookupTable();
|
||||
|
||||
// Valid secret lengths are 80 to 640 bits
|
||||
if ($secretLength < 16 || $secretLength > 128) {
|
||||
throw new Exception('Bad secret length');
|
||||
}
|
||||
$secret = '';
|
||||
$rnd = false;
|
||||
if (function_exists('random_bytes')) {
|
||||
$rnd = random_bytes($secretLength);
|
||||
} elseif (function_exists('mcrypt_create_iv')) {
|
||||
$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
|
||||
} elseif (function_exists('openssl_random_pseudo_bytes')) {
|
||||
$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
|
||||
if (!$cryptoStrong) {
|
||||
$rnd = false;
|
||||
}
|
||||
}
|
||||
if ($rnd !== false) {
|
||||
for ($i = 0; $i < $secretLength; ++$i) {
|
||||
$secret .= $validChars[ord($rnd[$i]) & 31];
|
||||
}
|
||||
} else {
|
||||
throw new Exception('No source of secure random');
|
||||
}
|
||||
|
||||
return $secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the code, with given secret and point in time.
|
||||
*
|
||||
* @param string $secret
|
||||
* @param int|null $timeSlice
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCode($secret, $timeSlice = null)
|
||||
{
|
||||
if ($timeSlice === null) {
|
||||
$timeSlice = floor(time() / 30);
|
||||
}
|
||||
|
||||
$secretkey = $this->_base32Decode($secret);
|
||||
|
||||
// Pack time into binary string
|
||||
$time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
|
||||
// Hash it with users secret key
|
||||
$hm = hash_hmac('SHA1', $time, $secretkey, true);
|
||||
// Use last nipple of result as index/offset
|
||||
$offset = ord(substr($hm, -1)) & 0x0F;
|
||||
// grab 4 bytes of the result
|
||||
$hashpart = substr($hm, $offset, 4);
|
||||
|
||||
// Unpak binary value
|
||||
$value = unpack('N', $hashpart);
|
||||
$value = $value[1];
|
||||
// Only 32 bits
|
||||
$value = $value & 0x7FFFFFFF;
|
||||
|
||||
$modulo = pow(10, $this->_codeLength);
|
||||
|
||||
return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get QR-Code URL for image, from google charts.
|
||||
*
|
||||
* @param string $name
|
||||
* @param string $secret
|
||||
* @param string $title
|
||||
* @param array $params
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
|
||||
{
|
||||
$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
|
||||
$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
|
||||
$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
|
||||
|
||||
$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
|
||||
if (isset($title)) {
|
||||
$urlencoded .= urlencode('&issuer='.urlencode($title));
|
||||
}
|
||||
|
||||
return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
|
||||
*
|
||||
* @param string $secret
|
||||
* @param string $code
|
||||
* @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
|
||||
* @param int|null $currentTimeSlice time slice if we want use other that time()
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
|
||||
{
|
||||
if ($currentTimeSlice === null) {
|
||||
$currentTimeSlice = floor(time() / 30);
|
||||
}
|
||||
|
||||
if (strlen($code) != 6) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
|
||||
$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
|
||||
if ($this->timingSafeEquals($calculatedCode, $code)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the code length, should be >=6.
|
||||
*
|
||||
* @param int $length
|
||||
*
|
||||
* @return PHPGangsta_GoogleAuthenticator
|
||||
*/
|
||||
public function setCodeLength($length)
|
||||
{
|
||||
$this->_codeLength = $length;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to decode base32.
|
||||
*
|
||||
* @param $secret
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
protected function _base32Decode($secret)
|
||||
{
|
||||
if (empty($secret)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$base32chars = $this->_getBase32LookupTable();
|
||||
$base32charsFlipped = array_flip($base32chars);
|
||||
|
||||
$paddingCharCount = substr_count($secret, $base32chars[32]);
|
||||
$allowedValues = array(6, 4, 3, 1, 0);
|
||||
if (!in_array($paddingCharCount, $allowedValues)) {
|
||||
return false;
|
||||
}
|
||||
for ($i = 0; $i < 4; ++$i) {
|
||||
if ($paddingCharCount == $allowedValues[$i] &&
|
||||
substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
$secret = str_replace('=', '', $secret);
|
||||
$secret = str_split($secret);
|
||||
$binaryString = '';
|
||||
for ($i = 0; $i < count($secret); $i = $i + 8) {
|
||||
$x = '';
|
||||
if (!in_array($secret[$i], $base32chars)) {
|
||||
return false;
|
||||
}
|
||||
for ($j = 0; $j < 8; ++$j) {
|
||||
$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
|
||||
}
|
||||
$eightBits = str_split($x, 8);
|
||||
for ($z = 0; $z < count($eightBits); ++$z) {
|
||||
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
|
||||
}
|
||||
}
|
||||
|
||||
return $binaryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array with all 32 characters for decoding from/encoding to base32.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function _getBase32LookupTable()
|
||||
{
|
||||
return array(
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
|
||||
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
|
||||
'=', // padding char
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A timing safe equals comparison
|
||||
* more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
|
||||
*
|
||||
* @param string $safeString The internal (safe) value to be checked
|
||||
* @param string $userString The user submitted (unsafe) value
|
||||
*
|
||||
* @return bool True if the two strings are identical
|
||||
*/
|
||||
private function timingSafeEquals($safeString, $userString)
|
||||
{
|
||||
if (function_exists('hash_equals')) {
|
||||
return hash_equals($safeString, $userString);
|
||||
}
|
||||
$safeLen = strlen($safeString);
|
||||
$userLen = strlen($userString);
|
||||
|
||||
if ($userLen != $safeLen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$result = 0;
|
||||
|
||||
for ($i = 0; $i < $userLen; ++$i) {
|
||||
$result |= (ord($safeString[$i]) ^ ord($userString[$i]));
|
||||
}
|
||||
|
||||
// They are only identical strings if $result is exactly 0...
|
||||
return $result === 0;
|
||||
}
|
||||
}
|
0
www/logs/.gitkeep
Normal file
0
www/logs/.gitkeep
Normal file
22
www/manifest.json
Normal file
22
www/manifest.json
Normal 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/app/templates/images/icon-192x192.png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "/vasek/home/app/templates/images/icon-512x512.png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"background_color": "#182239"
|
||||
}
|
15
www/public/.htaccess
Normal file
15
www/public/.htaccess
Normal file
@@ -0,0 +1,15 @@
|
||||
RewriteEngine On
|
||||
DirectoryIndex ./index.php
|
||||
|
||||
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
|
||||
RewriteCond %{REQUEST_FILENAME} !apiFront.php
|
||||
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
|
||||
|
||||
AddType application/x-httpd-php .php .phtml
|
69
www/public/Elementum/scss/elements/_buttons.scss
Normal file
69
www/public/Elementum/scss/elements/_buttons.scss
Normal 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');
|
||||
}
|
||||
}
|
6
www/public/css/font-awesome.min.css
vendored
Normal file
6
www/public/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
20
www/public/css/loading.css
Normal file
20
www/public/css/loading.css
Normal 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); }
|
||||
}
|
2966
www/public/css/main.css
Normal file
2966
www/public/css/main.css
Normal file
File diff suppressed because it is too large
Load Diff
44
www/public/css/main.css.map
Normal file
44
www/public/css/main.css.map
Normal file
File diff suppressed because one or more lines are too long
28
www/public/css/modal.css
Normal file
28
www/public/css/modal.css
Normal 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;
|
||||
}
|
||||
}
|
21
www/public/css/override.css
Normal file
21
www/public/css/override.css
Normal file
@@ -0,0 +1,21 @@
|
||||
table.table td, table.table th {
|
||||
border: 2px solid #121a2b;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/*tr:nth-child(even){background-color: #f2f2f2;}*/
|
||||
|
||||
table.table tr:hover {background-color: #121a2b;}
|
||||
|
||||
table.table th {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
text-align: left;
|
||||
background-color: #121a2b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
button:disabled,
|
||||
button[disabled] {
|
||||
opacity: .4;
|
||||
}
|
17
www/public/css/pre.css
Normal file
17
www/public/css/pre.css
Normal 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;
|
||||
}
|
BIN
www/public/fonts/FontAwesome.otf
Normal file
BIN
www/public/fonts/FontAwesome.otf
Normal file
Binary file not shown.
BIN
www/public/fonts/Metropolis-Medium.otf
Normal file
BIN
www/public/fonts/Metropolis-Medium.otf
Normal file
Binary file not shown.
BIN
www/public/fonts/Metropolis-Regular.otf
Normal file
BIN
www/public/fonts/Metropolis-Regular.otf
Normal file
Binary file not shown.
BIN
www/public/fonts/Metropolis-SemiBold.otf
Normal file
BIN
www/public/fonts/Metropolis-SemiBold.otf
Normal file
Binary file not shown.
BIN
www/public/fonts/fontawesome-webfont.eot
Normal file
BIN
www/public/fonts/fontawesome-webfont.eot
Normal file
Binary file not shown.
2671
www/public/fonts/fontawesome-webfont.svg
Normal file
2671
www/public/fonts/fontawesome-webfont.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 434 KiB |
BIN
www/public/fonts/fontawesome-webfont.ttf
Normal file
BIN
www/public/fonts/fontawesome-webfont.ttf
Normal file
Binary file not shown.
BIN
www/public/fonts/fontawesome-webfont.woff
Normal file
BIN
www/public/fonts/fontawesome-webfont.woff
Normal file
Binary file not shown.
BIN
www/public/fonts/fontawesome-webfont.woff2
Normal file
BIN
www/public/fonts/fontawesome-webfont.woff2
Normal file
Binary file not shown.
BIN
www/public/images/icon-192x192.png
Normal file
BIN
www/public/images/icon-192x192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
BIN
www/public/images/icon-512x512.png
Normal file
BIN
www/public/images/icon-512x512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
3
www/public/index.php
Normal file
3
www/public/index.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../app/Bootstrap.php';
|
35
www/public/js/automation.js
Normal file
35
www/public/js/automation.js
Normal file
@@ -0,0 +1,35 @@
|
||||
function restartAutomation(automationId){
|
||||
console.log("restartingAutomation" + automationId);
|
||||
$.ajax({
|
||||
url: 'ajax',
|
||||
type: 'POST',
|
||||
data: {
|
||||
"automation_id" : automationId,
|
||||
"action": "restart"
|
||||
},
|
||||
success: function(data){
|
||||
console.log(data);
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
console.log("ERROR ", request, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function toggleAutomation(automationId){
|
||||
console.log("togglingAutomation" + automationId);
|
||||
$.ajax({
|
||||
url: 'ajax',
|
||||
type: 'POST',
|
||||
data: {
|
||||
"automation_id" : automationId,
|
||||
"action": "deactive"
|
||||
},
|
||||
success: function(data){
|
||||
$('#automation-'+automationId).toggleClass("is-inactive");
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
console.log("ERROR ", request, error);
|
||||
}
|
||||
});
|
||||
}
|
2
www/public/js/jquery.js
vendored
Normal file
2
www/public/js/jquery.js
vendored
Normal file
File diff suppressed because one or more lines are too long
182
www/public/js/jquery.redirect.js
Normal file
182
www/public/js/jquery.redirect.js
Normal 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));
|
74
www/public/js/post.js
Normal file
74
www/public/js/post.js
Normal file
@@ -0,0 +1,74 @@
|
||||
function ajaxPostSimple(path, params, reload = false) {
|
||||
navigator.vibrate([200]);
|
||||
$.ajax({
|
||||
url: path,
|
||||
type: 'POST',
|
||||
data: params,
|
||||
success: function(msg){
|
||||
console.log("message");
|
||||
console.log(msg);
|
||||
if (reload){
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
console.log('0');
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
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: {
|
||||
action:'executed',
|
||||
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);
|
||||
}
|
299
www/public/js/script.js
Normal file
299
www/public/js/script.js
Normal file
@@ -0,0 +1,299 @@
|
||||
var pending = false;
|
||||
|
||||
var firebaseConfig = {
|
||||
apiKey: "AIzaSyBFZjXvnCMpGurSWEuVgHkE9jD9jxGJhx8",
|
||||
authDomain: "test-push-notf.firebaseapp.com",
|
||||
databaseURL: "https://test-push-notf.firebaseio.com",
|
||||
projectId: "test-push-notf",
|
||||
storageBucket: "",
|
||||
messagingSenderId: "93473765978",
|
||||
appId: "1:93473765978:web:5d959a487fe5382480f663"
|
||||
};
|
||||
firebase.initializeApp(firebaseConfig);
|
||||
|
||||
const messaging = firebase.messaging();
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('serviceWorker.js')
|
||||
.then(registration => {
|
||||
console.log('Service Worker is registered', registration);
|
||||
|
||||
messaging.useServiceWorker(registration);
|
||||
messaging.usePublicVapidKey('BDYQ7X7J7PX0aOFNqB-CivQeqLq4-SqCxQJlDfJ6yNnQeYRoK8H2KOqxHRh47fLrbUhC8O3tve67MqJAIqox7Ng');
|
||||
messaging.requestPermission().then(function () {
|
||||
console.log("Notification permission granted.");
|
||||
return messaging.getToken()
|
||||
})
|
||||
.then(function (token) {
|
||||
console.log("token is : " + token);
|
||||
$.ajax({
|
||||
url: 'ajax',
|
||||
type: 'POST',
|
||||
data: {
|
||||
"notification": 'X',
|
||||
"action": 'subscribe',
|
||||
"token": token
|
||||
},
|
||||
success: function (data) {
|
||||
console.log('saved', data);
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
console.log("ERROR ", request, error);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(function (err) {
|
||||
console.log("Unable to get permission to notify.", err);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('Registration failed:', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$('select[name="atSelector"]').change(function (e) {
|
||||
console.log($(this).val());
|
||||
if ($(this).val() == 'time') {
|
||||
|
||||
$('input[name="atTime"]').prop("disabled", false);
|
||||
|
||||
$('select[name="atDeviceValueInt"]').prop("disabled", true);
|
||||
$('input[name="atDeviceValue"]').prop("disabled", true);
|
||||
} else if ($(this).val() == 'atDeviceValue') {
|
||||
|
||||
$('select[name="atDeviceValue"]').prop("disabled", false);
|
||||
$('input[name="atDeviceValueInt"]').prop("disabled", false);
|
||||
|
||||
$('input[name="atTime"]').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) {
|
||||
navigator.vibrate([500]);
|
||||
var id = '';
|
||||
|
||||
var windowLoc = $(location).attr('pathname');
|
||||
windowLoc = windowLoc.substring(windowLoc.lastIndexOf("/"));
|
||||
console.log(windowLoc);
|
||||
if (windowLoc == "/") {
|
||||
id = $(this).attr('id').replace('device-', '');
|
||||
} else if (windowLoc == "/scene") {
|
||||
id = $(this).attr('id').replace('scene-', '');
|
||||
} else if (windowLoc == "/automation") {
|
||||
id = $(this).attr('id').replace('automation-', '');
|
||||
}
|
||||
|
||||
var subId = $(this).attr('data-sub-device-id');
|
||||
|
||||
touch++;
|
||||
if (touch == 2 && touchSubId == subId) {
|
||||
console.log("Detail");
|
||||
if (windowLoc == "/") {
|
||||
$("#modal-detail-" + subId).removeClass('modal-container-hiden').show();
|
||||
ajaxChart(subId);
|
||||
} else if (windowLoc == "/scene") {
|
||||
|
||||
} else if (windowLoc == "/automation") {
|
||||
}
|
||||
touch = 0;
|
||||
touchSubId = "";
|
||||
return;
|
||||
}
|
||||
touchSubId = subId;
|
||||
|
||||
pressTimer = window.setTimeout(function (e) {
|
||||
console.log("Setting");
|
||||
$("#modal-setting-" + id).removeClass('modal-container-hiden').show();
|
||||
touch = 0;
|
||||
}, 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-', '');
|
||||
} else if (windowLoc == "/automation") {
|
||||
id = $(this).attr('id').replace('automation-', '');
|
||||
}
|
||||
$("#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": 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");
|
||||
|
||||
if (selectRoomId == null) {
|
||||
selectRoomId = 'all';
|
||||
}
|
||||
|
||||
|
||||
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 windowLoc = $(location).attr('pathname');
|
||||
windowLoc = windowLoc.substring(windowLoc.lastIndexOf("/"));
|
||||
console.log();
|
||||
if (windowLoc == "/") {
|
||||
var autoUpdate = setInterval(function(){
|
||||
if (pending == false) {
|
||||
pending = true;
|
||||
$.ajax({
|
||||
url: 'ajax',
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
data: {
|
||||
"action": 'getState'
|
||||
},
|
||||
success: function(data){
|
||||
console.log(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);
|
||||
},
|
||||
complete: function (){
|
||||
pending = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
},4000);
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
|
||||
//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);
|
||||
});
|
||||
|
||||
$("button[name=remove]").click(function (e) {
|
||||
if (confirm('Are you shure ?')) {
|
||||
var windowLoc = $(location).attr('pathname');
|
||||
windowLoc = windowLoc.substring(windowLoc.lastIndexOf("/"));
|
||||
console.log(windowLoc);
|
||||
var id = null;
|
||||
if (windowLoc == "/scene") {
|
||||
id = $(this).data('scene-id');
|
||||
$("#scene-" + id + "-content").remove();
|
||||
} else if (windowLoc == "/automation") {
|
||||
$(this).parent().remove();
|
||||
}
|
||||
}
|
||||
});
|
58
www/public/js/setting.js
Normal file
58
www/public/js/setting.js
Normal file
@@ -0,0 +1,58 @@
|
||||
navigator.permissions.query({name:'notifications'}).then(function(result) {
|
||||
var element = document.getElementById("notifications");
|
||||
if (result.state === 'granted') {
|
||||
element.checked = true;
|
||||
} else if (result.state === 'denied') {
|
||||
element.checked = false;
|
||||
} else if (result.state === 'prompt') {
|
||||
element.checked = false;
|
||||
}
|
||||
});
|
||||
|
||||
function toggleNotificationPermissions(input){
|
||||
navigator.permissions.query({name:'notifications'}).then(function(result) {
|
||||
if (result.state === 'granted') {
|
||||
input.checked = true;
|
||||
} else if (result.state === 'denied') {
|
||||
input.checked = false;
|
||||
} else if (result.state === 'prompt') {
|
||||
input.checked = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendTestNotification(){
|
||||
console.log("sending test notification");
|
||||
$.ajax({
|
||||
url: 'ajax',
|
||||
type: 'POST',
|
||||
data: {
|
||||
"notification" : 'X',
|
||||
"action": 'sendTest'
|
||||
},
|
||||
success: function(data){
|
||||
console.log(data);
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
console.log("ERROR ", request, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$( "button[name='deactivateOta']" ).click(function(){
|
||||
console.log("Didabling ota");
|
||||
$.ajax({
|
||||
url: 'ajax',
|
||||
type: 'POST',
|
||||
data: {
|
||||
"ota" : 'X',
|
||||
"action": 'disable'
|
||||
},
|
||||
success: function(data){
|
||||
console.log(data);
|
||||
},
|
||||
error: function (request, status, error) {
|
||||
console.log("ERROR ", request, error);
|
||||
}
|
||||
});
|
||||
})
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user