Archived
To docker Image
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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();
|
||||
@@ -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';
|
||||
@@ -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'] : ''));
|
||||
@@ -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(){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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>';
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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'];
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
class Logout extends Template
|
||||
{
|
||||
function __construct()
|
||||
{
|
||||
global $userManager;
|
||||
$userManager->logout();
|
||||
header('Location: ' . BASEURL . 'login');
|
||||
die();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1 @@
|
||||
Example template
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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">
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -0,0 +1,3 @@
|
||||
<H1>
|
||||
TEST - TEST
|
||||
</H1>
|
||||
@@ -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>
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
'' => '',
|
||||
];
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
class Controller{
|
||||
public $view = null;
|
||||
|
||||
public function __construct(){
|
||||
$this->view = new View();
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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 . '$@';
|
||||
}
|
||||
}
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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,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"
|
||||
}
|
||||
@@ -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
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
Vendored
+6
File diff suppressed because one or more lines are too long
@@ -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); }
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 7.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../app/Bootstrap.php';
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
Vendored
+2
File diff suppressed because one or more lines are too long
@@ -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));
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -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