CleanUp After Docker Try

This commit is contained in:
JonatanRek 2020-05-16 17:18:27 +02:00
parent 2f638d8091
commit 090b9f7a7b
123 changed files with 5265 additions and 0 deletions

View File

@ -10,6 +10,7 @@ RewriteRule . - [e=HTTP_AUTHORIZATION:%1]
# serve all files from public subfolder
RewriteCond %{REQUEST_FILENAME} !.php
RewriteCond %{REQUEST_FILENAME} !.log
RewriteCond %{REQUEST_FILENAME} \.
RewriteRule (.*) ./public/$1 [L]

93
app/Bootstrap.php Normal file
View File

@ -0,0 +1,93 @@
<?php
//Autoloader
class Autoloader {
protected static $extension = ".php";
protected static $root = __DIR__;
protected static $files = [];
static function ClassLoader ($className = ""){
$directorys = new RecursiveDirectoryIterator(static::$root, RecursiveDirectoryIterator::SKIP_DOTS);
//echo '<pre>';
//var_dump($directorys);
//echo '</pre>';
$files = new RecursiveIteratorIterator($directorys, RecursiveIteratorIterator::LEAVES_ONLY);
$filename = $className . static::$extension;
foreach ($files as $key => $file) {
if (strtolower($file->getFilename()) === strtolower($filename) && $file->isReadable()) {
include_once $file->getPathname();
return;
}
}
}
static function setRoot($rootPath){
static::$root = $rootPath;
}
}
spl_autoload_register("Autoloader::ClassLoader");
Autoloader::setRoot('/var/www/dev.steelants.cz/vasek/home-update/');
class ErrorHandler {
static function exception($exception){
error_log($exception);
http_response_code($exception->getCode());
$message = [
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
];
echo json_encode($message);
$apiLogManager = new LogManager('../logs/'. date("Y-m-d").'.log');
$apiLogManager->write("[APACHE] ERROR\n" . json_encode($message, JSON_PRETTY_PRINT), LogRecordType::INFO);
}
}
set_exception_handler("ErrorHandler::exception");
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
$apiLogManager->write("[API] request body\n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO);
$apiLogManager->write("[API] POST body\n" . json_encode($_POST, JSON_PRETTY_PRINT), LogRecordType::INFO);
$apiLogManager->write("[API] GET body\n" . json_encode($_GET, JSON_PRETTY_PRINT), LogRecordType::INFO);
//Debug
error_reporting(E_ALL);
ini_set( 'display_errors','1');
//setup
ini_set ('session.cookie_httponly', '1');
ini_set('session.cookie_domain', $_SERVER['HTTP_HOST']);
ini_set('session.cookie_path', str_replace("login", "", str_replace('https://' . $_SERVER['HTTP_HOST'], "", $_SERVER['REQUEST_URI'])));
ini_set('session.cookie_secure', '1');
session_start ();
mb_internal_encoding ("UTF-8");
// import configs
require_once '../config/config.php';
// Logs
$logManager = new LogManager();
// Language
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
$langTag = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
$langMng = new LanguageManager($langTag);
$langMng->load();
}
//D B Conector
Db::connect (DBHOST, DBUSER, DBPASS, DBNAME);
// TODO: Přesunout do Login Pohledu
$userManager = new UserManager();
// import routes
require_once '../app/Routes.php';

31
app/Routes.php Normal file
View File

@ -0,0 +1,31 @@
<?php
$router = new Router();
$router->setDefault(function(){
echo $_GET['url'].': 404';
});
//Pages
$router->any('/', 'Log');
$router->any('/login', 'Login');
$router->any('/logout', 'Logout');
$router->any('/automation', 'Automation');
$router->any('/setting', 'Setting');
$router->any('/ajax', 'Ajax');
$router->post('/api/login', 'AuthApi@login');
$router->post('/api/logout', 'AuthApi@logout');
$router->get('/api/devices', 'DevicesApi@default');
$router->get('/api/rooms', 'RoomsApi@default');
$router->get('/api/HA/auth', 'GoogleHomeApi@autorize');
$router->any('/api/HA', 'GoogleHomeApi@response');
// examples
$router->any('/api/example', 'ExampleApi@example');
$router->any('/example', 'ExampleController@index');
$router->any('/example/subpage', 'ExampleController@subpage');
$router->run($_SERVER['REQUEST_METHOD'], '/'.(isset($_GET['url']) ? $_GET['url'] : ''));

25
app/api/AuthApi.php Normal file
View File

@ -0,0 +1,25 @@
<?php
class AuthApi {
public function login(){
$token = (new AuthManager)->getToken($this->input->username,$this->input->password);
if (!$token) {
throw new Exception("Auth failed", 401);
}
$this->response(['token' => $token]);
}
public function logout(){
$authenticationBearrer = $_SERVER['HTTP_AUTHORIZATION'];
if (!(new AuthManager)->deleteToken($authenticationBearrer)) {
throw new Exception("logout Failed", 401);
}
}
public function registration(){
}
public function restartPassword(){
}
}

17
app/api/DevicesApi.php Normal file
View File

@ -0,0 +1,17 @@
<?php
class DevicesApi extends ApiController{
public function default(){
$this->requireAuth();
$response = [];
// TODO: process the request
$this->response($response);
}
public function getDevicesByRoom($roomId){
}
}

24
app/api/ExampleApi.php Normal file
View File

@ -0,0 +1,24 @@
<?php
class ExampleApi extends ApiController{
public function example(){
// if this function should be accessible only for logged users uncomment next line
// $this->requireAuth();
// if user is logged in, next lines will be processed
// otherwise script get terminated with 401 UNAUTHORIZED
// input data are stored in $this->input
// in this example we just copy input to response
$response = $this->input;
// this method returns response as json
$this->response($response);
// you can specify returned http code by second optional parameter
// default value is 200
// $this->response($response, $httpCode);
}
}

46
app/api/GoogleHomeApi.php Normal file
View File

@ -0,0 +1,46 @@
<?php
class GoogleHomeApi {
static function response(){
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
header('Content-Type: application/json');
switch ($obj['inputs'][0]['intent']) {
case 'action.devices.SYNC':
GoogleHome::sync($obj['requestId']);
$apiLogManager->write("[Google Home] action.devices.SYNC", LogRecordType::INFO);
break;
case 'action.devices.QUERY':
GoogleHome::query($obj['requestId'], $obj['inputs'][0]['payload']);
//$apiLogManager->write("[Google Home] action.devices.QUERY", LogRecordType::INFO);
break;
case 'action.devices.EXECUTE':
GoogleHome::execute($obj['requestId'], $obj['inputs'][0]['payload']);
$apiLogManager->write("[Google Home] action.devices.EXECUTE", LogRecordType::INFO);
break;
}
}
static function autorize(){
$json = file_get_contents('php://input');
$obj = json_decode($json, true);
$apiLogManager = new LogManager('../logs/api/HA/'. date("Y-m-d").'.log');
$apiLogManager->write("[API] request body\n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO);
$apiLogManager->write("[API] GET body\n" . json_encode($_GET, JSON_PRETTY_PRINT), LogRecordType::INFO);
$get = [
"access_token"=>"2222255888",
"token_type"=>"Bearer",
"state"=>$_GET["state"],
];
echo $_GET["redirect_uri"] . '#' . http_build_query($get) ;
echo '<a href="'.$_GET["redirect_uri"] . '#' . http_build_query($get) . '">FINISH</a>';
}
}

View File

@ -0,0 +1,14 @@
<?php
class ExampleController extends Controller{
public function index(){
$this->view->title = 'Example title';
$this->view->render('example.phtml');
}
public function subpage(){
echo 'subpage';
}
}

View File

@ -0,0 +1,77 @@
<?php
if (isset($_POST) && !empty($_POST)){
if (isset($_POST['modalFinal']) && $_POST['action'] == "add") {
$doCode = json_encode($_POST['device'], JSON_PRETTY_PRINT);
$value = $_POST['atSelector'];
if ($_POST['atSelector'] == 'time'){
$value = $_POST['atSelectorValue'];
} else if ($_POST['atSelector'] == 'atDeviceValue') {
$value = json_decode($_POST['atSelectorValue']);
} else if ($_POST['atSelector'] == 'inHome' || $_POST['atSelector'] == 'outHome') {
$value = UserManager::getUserData('user_id');
}
$ifCode = json_encode([
"type" => $_POST['atSelector'],
"value" => $value,
], JSON_PRETTY_PRINT);
$onDays = $_POST['atDays'];
//Debug
// if (DEBUGMOD == 1) {
// echo '<pre>';
// echo $permissionsInJson;
// echo $deviceId;
// var_dump(json_decode ($permissionsInJson));
// echo '</pre>';
// echo '<a href="' . BASEDIR .'">CONTINUE</a>';
// die();
// }
AutomationManager::create($_POST['name'], $onDays, $doCode, $ifCode);
header('Location: ' . BASEURL . strtolower(basename(__FILE__, '.php')));
die();
} else if (isset($_POST['modalFinal']) && $_POST['action'] == "edit") {
$doCode = json_encode($_POST['device'], JSON_PRETTY_PRINT);
if (isset ($_POST['atDeviceValue'])) {
$subDeviceId = $_POST['atDeviceValue'];
$subDeviceValue = $_POST['atDeviceValueInt'];
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
$subDeviceMaster = SubDeviceManager::getSubDeviceMaster($subDeviceId,$subDevice['type']);
$device = [
'deviceID' => $subDeviceMaster['device_id'],
'type'=> $subDevice['type'],
'value'=> $subDeviceValue,
];
}
$value = $_POST['atSelector'];
if (isset($_POST['atTime'])){
$value = $_POST['atTime'];
} else if (isset($_POST['atDeviceValue'])) {
$value = $device;
} else if ($_POST['atSelector'] == 'inHome' || $_POST['atSelector'] == 'outHome') {
//TODO: opravit edit aby vkládal id původního uživatele
$value = UserManager::getUserData('user_id');
}
$value = (isset($_POST['atTime']) ? $_POST['atTime'] : (isset($_POST['atDeviceValue']) ? $device : $_POST['atSelector']));
$ifCode = json_encode([
"type" => $_POST['atSelector'],
"value" => $value,
], JSON_PRETTY_PRINT);
$onDays = ($_POST['day'] != '' ? json_encode($_POST['day']) : '');
AutomationManager::create($_POST['name'], $onDays, $doCode, $ifCode, (isset ($_POST['automation_id']) ? $_POST['automation_id'] : ""));
header('Location: ' . BASEURL . strtolower(basename(__FILE__, '.php')));
die();
}
}
?>

View File

@ -0,0 +1,51 @@
<?php
global $userManager;
if (
isset($_POST['username']) &&
$_POST['username'] != '' &&
isset($_POST['password']) &&
$_POST['password'] != ''
){
$ota = false;
$userName = $_POST['username'];
$userPassword = $_POST['password'];
$rememberMe = (isset ($_POST['remember']) ? $_POST['remember'] : "");
$ota = $userManager->haveOtaEnabled($userName);
if ($ota == "") {
$landingPage = $userManager->login($userName, $userPassword, $rememberMe);
header('Location: ' . BASEURL . $landingPage);
die();
}
$_SESSION['USERNAME'] = $userName;
$_SESSION['PASSWORD'] = $userPassword;
$_SESSION['REMEMBER'] = $rememberMe;
$_SESSION['OTA'] = $ota;
} else if (
isset($_POST['otaCode']) &&
$_POST['otaCode'] != ''
) {
$otaCode = $_POST['otaCode'];
$otaSecret = $_POST['otaSecret'];
$ga = new PHPGangsta_GoogleAuthenticator();
$ota = $_SESSION['OTA'];
$userName = $_SESSION['USERNAME'];
$userPassword = $_SESSION['PASSWORD'];
$rememberMe = $_SESSION['REMEMBER'];
unset($_SESSION['OTA']);
$checkResult = $ga->verifyCode($otaSecret, $otaCode, 2); // 2 = 2*30sec clock tolerance
if ($checkResult) {
$landingPage = $userManager->login($userName, $userPassword, $rememberMe);
header('Location: ' . BASEURL . '/');
echo 'OK';
} else {
echo 'FAILED';
}
//TODO: upravi a ověřit jeslti ja zabezpečené
//TODO:
die();
}

View File

@ -0,0 +1,29 @@
<?php
if (isset($_POST) && !empty($_POST)){
if (isset($_POST['submitPasswordChange']) && $_POST['submitPasswordChange'] != "") {
$oldPassword = $_POST['oldPassword'];
$newPassword = $_POST['newPassword1'];
$newPassword2 = $_POST['newPassword2'];
UserManager::changePassword($oldPassword, $newPassword, $newPassword2);
header('Location: ' . BASEURL . 'logout');
die();
} else if (isset($_POST['submitCreateUser']) && $_POST['submitCreateUser'] != "") {
$userName = $_POST['userName'];
$password = $_POST['userPassword'];
UserManager::createUser($userName, $password);
header('Location: ' . BASEURL . 'setting');
die();
} else if (isset($_POST['submitEnableOta']) && $_POST['submitEnableOta'] != "") {
echo $otaCode = $_POST['otaCode'];
echo $otaSecret = $_POST['otaSecret'];
$ga = new PHPGangsta_GoogleAuthenticator();
$checkResult = $ga->verifyCode($otaSecret, $otaCode, 2); // 2 = 2*30sec clock tolerance
if ($checkResult) {
UserManager::setOta($otaCode, $otaSecret);
}
header('Location: ' . BASEURL . 'setting');
die();
}
}

View File

@ -0,0 +1,45 @@
<?php
class AuthManager {
public function getToken($username, $password){
$userManager = new UserManager();
if ($username != '' || $password != ''){
$userLogedIn = $userManager->loginNew($username, $password);
if ($userLogedIn != false){
// Create token header as a JSON string
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
// Create token payload as a JSON string
$payload = json_encode(['user_id' => $userLogedIn]);
// Encode Header to Base64Url String
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
// Encode Payload to Base64Url String
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
// Create Signature Hash
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, 'abC123!', true);
// Encode Signature to Base64Url String
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
// Create JWT
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
return $jwt;
}
}
return false;
}
public function deleteToken($token){
Db::command ('DELETE FROM tokens WHERE token=?', array ($token));
return true;
}
public function validateToken($token){
$tokens = Db::loadAll('SELECT * FROM tokens WHERE token = ? AND expire >= CURRENT_TIMESTAMP AND blocked = 0;', array($token));
if (count($tokens) == 1) {
return true;
} else if (count($tokens) == 0) {
return false;
};
return false;
}
}

View File

@ -0,0 +1,175 @@
<?php
class AutomationManager{
public static $automation;
public static function remove($automationId) {
return Db::command ('DELETE FROM automation WHERE automation_id=?', array ($automationId));
}
public static function deactive($automationId) {
$automation = Db::loadOne ("SELECT * FROM automation WHERE automation_id=?" , array ($automationId));
$flipedValue = ($automation['active'] == 1 ? 0 : 1);
return Db::command ('UPDATE automation SET active = ? WHERE automation_id=?', array ($flipedValue,$automationId));
}
public static function restart($automationId) {
return Db::command ('UPDATE automation SET executed = 0 WHERE automation_id=?', array ($automationId));
}
public static function create ($name, $onDays, $doCode, $ifCode, $automationId = "") {
$userId = UserManager::getUserData('user_id');
$scene = array (
'name' => $name,
'owner_id' => $userId,
'on_days' => $onDays,
'if_something' => $ifCode,
'do_something' => $doCode,
);
try {
if ($automationId == "") {
Db::add ('automation', $scene);
} else {
Db::edit ('automation', $scene, 'WHERE automation_id = ?', array ($automationId));
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getAll(){
return Db::loadAll ("SELECT * FROM automation");
}
public static function executeAll(){
global $logManager;
$automations = Db::loadAll ("SELECT * FROM automation");
$dayNameNow = strtolower (date('D', time()));
foreach ($automations as $automation) {
$onValue = json_decode($automation['if_something'], true);
$sceneDoJson = $automation['do_something'];
$actionDays = json_decode($automation['on_days'], true);
$value = time();
$run = false;
$restart = false;
if ($automation['active'] == 1 && $automation['locked'] != 1){
Db::edit('automation', array('locked' => 1), 'WHERE automation_id = ?', array($automation['automation_id']));
if (in_array($dayNameNow, $actionDays)){
if (in_array($onValue['type'], ['sunSet', 'sunRise', 'time','now'])) {
if ($onValue['type'] == 'sunSet') {
$value = date_sunset($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90);
} else if ($onValue['type'] == 'sunRise') {
$value = date_sunrise($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90);
} else if ($onValue['type'] == 'time') {
$onValue = explode(':',$onValue['value']);
$today = date_create('now');
$onValue = $today->setTime($onValue[0], $onValue[1]);
$value = $today->getTimestamp();
}
if (time() > $value && $automation['executed'] == 0){
$run = true;
} else if (time() < $value && $automation['executed'] == 1) { //recovery realowing of automation
$restart = true;
}
} else if ($onValue['type'] == 'outHome') {
//TODO: Add Ovner to automation
$userHomeStatus = UserManager::getUserData('at_home', $onValue['value']);
if ($userHomeStatus == 'false' && $automation['executed'] == 0) {
$run = true;
} else if ($userHomeStatus == 'true' && $automation['executed'] == 1) {
$restart = true;
}
} else if ($onValue['type'] == 'inHome') {
//TODO: Add Ovner to automation
$userHomeStatus = UserManager::getUserData('at_home', $onValue['value']);
if ($userHomeStatus == 'true' && $automation['executed'] == 0) {
$run = true;
} else if ($userHomeStatus == 'false' && $automation['executed'] == 1) {
$restart = true;
}
} else if ($onValue['type'] == 'noOneHome') {
$users = UserManager::getUsers();
$membersHome = 0;
foreach ($users as $key => $user) {
if ($user['at_home'] == 'true'){
$membersHome++;
}
}
if ($membersHome == 0 && $automation['executed'] == 0) {
$run = true;
} else if ($membersHome > 0 && $automation['executed'] == 1){
$restart = true;
}
} else if ($onValue['type'] == 'someOneHome') {
$users = UserManager::getUsers();
$membersHome = 0;
foreach ($users as $key => $user) {
if ($user['at_home'] == 'true'){
$membersHome++;
}
}
if ($membersHome == 0 && $automation['executed'] == 1) {
$restart = true;
} else if ($membersHome > 0 && $automation['executed'] == 0){
$run = true;
}
} else if ($onValue['type'] == 'atDeviceValue') {
$subDeviceId = SubDeviceManager::getSubDeviceByMaster($onValue['value']['deviceID'], $onValue['value']['type'])["subdevice_id"];
$lastValue = RecordManager::getLastRecord($subDeviceId);
if ($lastValue['value'] == $onValue['value']['value'] && $automation['executed'] == 0) {
$run = true;
} else if ($lastValue['value'] != $onValue['value']['value'] && $automation['executed'] == 1){
$restart = true;
}
}
//finalization
if ($run) {
$body = '';
$sceneDoArray = json_decode($sceneDoJson);
foreach ($sceneDoArray as $deviceId => $deviceState) {
RecordManager::create($deviceId, 'on/off', $deviceState);
}
$subscribers = NotificationManager::getSubscription();
$i = 0;
$notificationMng = new NotificationManager;
$notificationData = [
'title' => 'Automatization',
'body' => 'Automatization '.$automation['name']." was just executed",
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
];
if ($notificationData != []) {
$subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) {
$logManager->write("[NOTIFICATION/AUTOOMATION] SENDING TO" . $subscriber['id'] . " ");
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
}
}
$logManager->write("[AUTOMATIONS] automation id ". $automation['automation_id'] . " was executed");
Db::edit('automation', array('executed' => 1, 'execution_time' => date("Y-m-d H:i:s")), 'WHERE automation_id = ?', array($automation['automation_id']));
} else if ($restart) {
$logManager->write("[AUTOMATIONS] automation id ". $automation['automation_id'] . " was restarted");
Db::edit('automation', array('executed' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
}
Db::edit('automation', array('locked' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
}
}
}
}
}

194
app/models/ChartJS.php Normal file
View File

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

View File

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

129
app/models/ChartManager.php Normal file
View File

@ -0,0 +1,129 @@
<?php
class ChartScale{
const HOUR = 'info';
const DAY = 'warning';
const MONTH = 'warning';
const YEAR = 'error';
}
class ChartManager{
function generateChart($data, $min = 0, $max = 100) {
echo '<br>Aktuální Hodnota: '.$data[0]['value'];
echo "<style>
.sloupec {
border-top: solid 2px red;
}
</style>";
echo '<div class=graph>';
echo '<div class="posuv " graf-max="'.$max.'" graf-min='.$min.'>';
for ($valuesRow = 0; $valuesRow < count($data); $valuesRow++) {
$row = $data[$valuesRow];
echo '<div class="sloupec " name="sloupec" value="' . $row['value'] . '" data-toggle="tooltip" title=""></div>';
}
echo '</div>';
echo '</div>';
echo '<script src="./include/js/chartDrwer.js"></script>';
echo 'Poslední Update: ';
echo '<style>
.graph {
width: 100%;
overflow: hidden;
margin-top: auto;
}
.posuv {
display: flex;
height: 200px;
background-image: url(./img/graph.png);
padding: 20px;
background-repeat: repeat;
border-bottom: 1px solid black;
}
.sloupec {
border-top: solid 2px blue;
background-color: grey;
float: left;
margin: auto 0 0;
display: inline-block;
width: 1%;
}
</style>
<script>
var posuvList = document.getElementsByClassName("posuv");
var maxHeight = posuvList[0].clientHeight;
for (i = 0; i < posuvList.length; i++) {
var maxPx = 0;
var grafMax = Number(posuvList[i].getAttribute("graf-max")); //100%
var grafMin = Number(posuvList[i].getAttribute("graf-min")); //0%
if (grafMin == 0 && grafMax == 100) {
var onePercent = 1;
} else {
var stepsBetWene = grafMax;
if (grafMin !== 0) {
if (grafMin < 0) {
stepsBetWene = grafMax + Math.abs(grafMin);
}
if (grafMin > 0) {
stepsBetWene = grafMax - grafMin;
}
}
var onePercent = stepsBetWene / 100;
}
var sloupceList = posuvList[i].querySelectorAll(".sloupec");
for (ai = 0; ai < sloupceList.length; ai++) {
var onePxPercent = maxHeight / 100;
var heightInPercent =
Math.abs(sloupceList[ai].getAttribute("value")) / onePercent;
var outputPx = onePxPercent * heightInPercent;
sloupceList[ai].style.height = outputPx + "px";
}
}
</script>';
}
function generateChartData(int $subDeviceId, string $periode, string $groupBy) {
$chartData = [];
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
$records = RecordManager::getAllRecordForGraph($subDeviceId, $periode, $groupBy);
$array = array_column($records, 'value');
$arrayTime = array_column($records, 'time');
$output = [];
foreach ($array as $key => $value) {
$output[$key]['y'] = $value;
if ($subDevice['type'] == 'light'){
if ($value > 810){
$output[$key]['y'] = 1;
} else {
$output[$key]['y'] = 0;
}
}
$timeStamp = new DateTime($arrayTime[$key]);
$output[$key]['t'] = $timeStamp->format("Y-m-d") . 'T' . $timeStamp->format("H:i:s") . 'Z';
}
$data = json_encode($output);
$data = $output;
$arrayTimeStamps = array_column($records, 'time');
foreach ($arrayTimeStamps as $key => $value) {
$arrayTimeStamps[$key] = (new DateTime($value))->format(TIMEFORMAT);
}
$chartData['graphRange'] = RANGES[$subDevice['type']];
$chartData['graphType'] = RANGES[$subDevice['type']]['graph'];
$chartData['graphData'] = $data;
return $chartData;
}
}
?>

View File

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

View File

@ -0,0 +1,96 @@
<?php
class DeviceManager{
public static $devices;
static function getAllDevices () {
return Db::loadAll ("SELECT * FROM devices WHERE approved != ?", Array(2));
}
static function getAllDevicesInRoom ($roomId = "") {
return Db::loadAll ("SELECT * FROM devices WHERE room_id = ? AND approved != ?", Array($roomId, 2));
}
static function getOtherDevices(){
return Db::loadAll ("SELECT * FROM devices WHERE room_id IS NULL ");
}
static function getDeviceByToken($deviceToken) {
return Db::loadOne("SELECT * FROM devices WHERE token = ?", array($deviceToken));
}
static function getDeviceByMac($deviceMac) {
return Db::loadOne("SELECT * FROM devices WHERE mac = ?", array($deviceMac));
}
static function getDeviceById($deviceId) {
return Db::loadOne("SELECT * FROM devices WHERE device_id = ?", array($deviceId));
}
public static function create ($name, $token) {
$defaultRoom = RoomManager::getDefaultRoomId();
$device = array (
'name' => $name,
'token' => $token,
'room_id' => $defaultRoom,
);
try {
Db::add ('devices', $device);
return Db::loadOne("SELECT device_id FROM devices WHERE token = ?", array($token))['device_id'];
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function edit ($deviceId, $values = []) {
try {
Db::edit ('devices', $values, 'WHERE device_id = ?', array($deviceId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function editByToken ($token, $values = []) {
try {
Db::edit ('devices', $values, 'WHERE token = ?', array($token));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
/**
* [assignRoom Přiřazení zařízení do třídy]
* @param [type] $roomId [číslo místnosti do kter se 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);
}
}
?>

View File

@ -0,0 +1,44 @@
<?php
/**
*
*/
class FallbackManager
{
public $deviceDefinitions = "";
function __construct($deviceDefinition)
{
$this->deviceDefinitions = $deviceDefinition;
}
function check(){
//TODO: FIX IT
$allDevicesData = DeviceManager::getAllDevices();
foreach ($allDevicesData as $deviceKey => $deviceValue) {
$allSubDevicesData = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
foreach ($allSubDevicesData as $subDeviceKey => $subDeviceValue) {
if (!isset($this->deviceDefinitions[$subDeviceValue['type']]["fallBack"])) {
continue;
}
if (!isset($this->deviceDefinitions[$subDeviceValue['type']]["fallBackTime"])) {
continue;
}
$lastRecord = RecordManager::getLastRecord($subDeviceValue['subdevice_id']);
if ($lastRecord["value"] == $this->deviceDefinitions[$subDeviceValue['type']]["fallBack"]) {
continue;
}
$minutes = (time() - strtotime($lastRecord['time'])) / 60;
if ( $minutes > $this->deviceDefinitions[$subDeviceValue['type']]["fallBackTime"]){
RecordManager::create($deviceValue['device_id'], $subDeviceValue['type'], $this->deviceDefinitions[$subDeviceValue['type']]["fallBack"]);
}
}
}
}
}

260
app/models/GoogleHome.php Normal file
View File

@ -0,0 +1,260 @@
<?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']);
$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;
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* Language Manager
*/
class LanguageManager
{
private $lngCode = 'en';
private $lngDatabase = [];
private $debug = false;
function __construct(string $lngCode, bool $debug = false)
{
$this->lngCode = $lngCode;
$this->debug = $debug;
}
function load()
{
$file = '../lang/en.php';
if (!file_exists($file)){
echo 'ERROR: en.php not found';
die();
//TODO add lng EXEPTIONS
}
$arrayFirst = include($file);
$file = '../lang/' . $this->lngCode . '.php';
$arraySecond = [];
if (file_exists($file)){
$arraySecond = include($file);
}
$this->lngDatabase = array_merge($arrayFirst, $arraySecond);
return true;
}
function get(string $stringKey)
{
if ($this->debug) {
return $stringKey;
}
if (isset($this->lngDatabase[$stringKey])) {
return $this->lngDatabase[$stringKey];
}
return $stringKey;
}
function echo(string $stringKey)
{
if ($this->debug) {
echo $stringKey;
return;
}
if (isset($this->lngDatabase[$stringKey])) {
echo $this->lngDatabase[$stringKey];
return;
}
echo $stringKey;
return;
}
}

57
app/models/LogManager.php Normal file
View File

@ -0,0 +1,57 @@
<?php
/**
*
*/
class LogRecordType{
const WARNING = 'warning';
const ERROR = 'error';
const INFO = 'info';
}
class LogKeeper
{
function purge($days){
$todayFileName = date("Y-m-d").'.log';
$seconds = $days * 86400;
$logFiles = scandir('../logs/');
foreach ($logFiles as $key => $file) {
if (in_array($file,array(".","..", ".gitkeep", $todayFileName)))
{
continue;
}
if (filemtime($file) > $seconds) {
unlink('../logs/'.$file);
}
}
}
}
class LogManager
{
private $logFile;
function __construct($fileName = "")
{
if ($fileName == ""){
$fileName = '../logs/'. date("Y-m-d").'.log';
}
if(!is_dir("../logs/"))
{
mkdir("../logs/");
}
$this->logFile = fopen($fileName, "a") or die("Unable to open file!");
}
function write($value, $type = LogRecordType::ERROR){
$record = "[".date("H:m:s")."][".$type."]" . $value . "\n";
fwrite($this->logFile, $record);
}
function __destruct(){
if (isset($this->logFile)) {
fclose($this->logFile);
}
}
}

View File

@ -0,0 +1,18 @@
<?php
/**
*
*/
class NetvorkManager
{
function __construct()
{
// code...
}
function validateIp($ip = '0.0.0.0'){
if (!filter_var($ip, FILTER_VALIDATE_IP)){
return false;
}
}
}

View File

@ -0,0 +1,107 @@
<?php
/**
* Notification Manager
*/
//TODO: Working timestamp to body or $title
class NotificationManager
{
function addSubscriber($userID = '', $token = ''){
$notificationSubscriber = $subDeviceId = Db::loadOne('SELECT id FROM notifications WHERE token = ?;', array($token));
if ($notificationSubscriber == ''){
$notification = array (
'user_id' => $userID,
'token' => $token,
);
Db::add ('notifications', $notification);
}
}
function getSubscription () {
return Db::loadAll ("SELECT * FROM notifications");
}
function sendSimpleNotification(string $serverKey, string $to, array $data, bool $timeStamp = false){
$dataTemplate = [
'title' => '',
'body' => '',
'icon' => '',
];
if (array_diff_key ($dataTemplate , $data)){
return;
}
if ($timeStamp) {
$data['title'] = $data['title'] . date();
}
$notification = new Notification($serverKey);
$notification->to($to);
$notification->notification($data['title'], $data['body'], $data['icon'], '');
$answer = $notification->send();
$notification = null;
return $answer;
}
}
class Notification
{
public $server_key = '';
public $jsonPayload = [
"to" => '',
"data" => [
"notification" => [
"body" => '',
"title" => '',
"icon" => '',
"click_action" => '',
]
]
];
function __construct($serverKey = '')
{
$this->server_key = $serverKey;
}
function to($to = ''){
$this->jsonPayload["to"] = $to;
}
function notification($title = '', $body = '', $icon = '', $action = '', bool $timeStamp = false)
{
if ($timeStamp) {
$data['title'] = $data['title'] . date();
}
$this->jsonPayload["data"]["notification"]["title"] = $title;
$this->jsonPayload["data"]["notification"]["body"] = $body;
$this->jsonPayload["data"]["notification"]["icon"] = $icon;
$this->jsonPayload["data"]["notification"]["click_action"] = $action;
}
function send(){
$data = json_encode($this->jsonPayload);
$url = 'https://fcm.googleapis.com/fcm/send';
$headers = array(
'Content-Type:application/json',
'Authorization:key='.$this->server_key,
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
if ($result === FALSE) {
die('Oops! FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
}

View File

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

View File

@ -0,0 +1,31 @@
<?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;
}
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));
}
}
?>

View File

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

210
app/models/UserManager.php Normal file
View File

@ -0,0 +1,210 @@
<?php
class UserManager
{
public static function getUsers () {
try {
$allUsers = Db::loadAll ("SELECT user_id, username, at_home, ota FROM users");
return $allUsers;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getUser ($userName) {
try {
$user = Db::loadOne ("SELECT * FROM users WHERE username = ?", [$userName]);
return $user;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getUserId ($userId) {
try {
$user = Db::loadOne ("SELECT * FROM users WHERE user_id = ?", [$userId]);
return $user;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getAvatarUrl($userId = null){
$email = self::getUserData('email');
if ($userId != null){
$email = self::getUserData('email',$userId);
}
return 'https://secure.gravatar.com/avatar/' . md5( strtolower( trim( $email ) ) );
}
public static function login ($username, $password, $rememberMe) {
try {
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) {
if ($user['password'] == UserManager::getHashPassword($password)) {
if (isset($rememberMe) && $rememberMe == 'true') {
setcookie ("rememberMe", self::setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), BASEDIR, $_SERVER['HTTP_HOST'], 1);
}
$_SESSION['user']['id'] = $user['user_id'];
$page = "";
if ($user["startPage"] == 1) {
$page = "dashboard";
}
unset($_POST['login']);
return $page;
} else {
throw new PDOException("Heslo není správné!");
}
} else {
throw new PDOException("Uživatel s tím to jménem neexistuje!");
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function loginNew ($username, $password) {
try {
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) {
if ($user['password'] == UserManager::getHashPassword($password)) {
echo "user loged in";
return $user['user_id'];
} else {
return false;
}
} else {
return false;
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function isLogin () {
if (isset ($_SESSION['user']) && isset($_SESSION['user']['id'])) {
return true;
} else {
if (isset ($_COOKIE['rememberMe'])){
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array (self::getDecryptedCookie($_COOKIE['rememberMe'])))) {
$_SESSION['user']['id'] = $user['user_id'];
return true;
}
}
}
return false;
}
public static function logout () {
unset($_SESSION['user']);
session_destroy();
if (isset($_COOKIE['rememberMe'])){
unset($_COOKIE['rememberMe']);
setcookie("rememberMe", 'false', time(), BASEDIR, $_SERVER['HTTP_HOST']);
}
}
public static function setEncryptedCookie($value){
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$method = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivlen);
$newvalue_raw = openssl_encrypt($value, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $newvalue_raw, $second_key, TRUE);
$newvalue = base64_encode ($iv.$hmac.$newvalue_raw);
return $newvalue;
}
public static function getDecryptedCookie($value){
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$c = base64_decode($value);
$method = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($method);
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, 32);
$newValue_raw = substr($c, $ivlen+32);
$newValue = openssl_decrypt($newValue_raw, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $newValue_raw, $second_key, TRUE);
if (hash_equals ($hmac, $calcmac)) {
return $newValue;
}
return false;
}
public static function getUserData ($type, $userId = '') {
if ($userId == '') {
$userId = $_SESSION['user']['id'];
}
$user = Db::loadOne ('SELECT ' . $type . ' FROM users WHERE user_id=?', array ($userId));
return $user[$type];
}
public static function setUserData ($type, $value) {
if (isset ($_SESSION['user']['id'])) {
Db::command ('UPDATE users SET ' . $type . '=? WHERE user_id=?', array ($value, $_SESSION['user']['id']));
}
}
public static function getHashPassword ($password) {
$salt = "s0mRIdlKvI";
$hashPassword = hash('sha512', ($password . $salt));
return $hashPassword;
}
public static function atHome($userId, $atHome){
try {
Db::edit ('users', ['at_home' => $atHome], 'WHERE user_id = ?', array($userId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function changePassword($oldPassword, $newPassword, $newPassword2){
if ($newPassword == $newPassword2) {
//Password Criteria
$oldPasswordSaved = self::getUserData('password');
if (self::getHashPassword($oldPassword) == $oldPasswordSaved) {
self::setUserData('password', self::getHashPassword($newPassword));
} else {
throw new Exception ("old password did not match");
}
} else {
throw new Exception ("new password arent same");
}
}
public static function createUser($userName, $password){
$userId = Db::loadOne('SELECT * FROM users WHERE username = ?;', array($userName))['user_id'];
if ($userId != null) {
return false;
};
try {
$user = [
'username' => $userName,
'password' => self::getHashPassword($password),
];
return Db::add ('users', $user);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function haveOtaEnabled($userName){
$ota = self::getUser($userName)['ota'];
if ($ota != ''){
return ($ota != '' ? $ota : false);
} else {
return false;
}
}
}
?>

144
app/models/Utilities.php Normal file
View File

@ -0,0 +1,144 @@
<?php
/**
*
*/
class Utilities
{
static function cleanString($text) {
$utf8 = array(
'/[áàâãªä]/u' => 'a',
'/[ÁÀÂÃÄ]/u' => 'A',
'/[ÍÌÎÏ]/u' => 'I',
'/[íìîï]/u' => 'i',
'/[ěéèêë]/u' => 'e',
'/[ĚÉÈÊË]/u' => 'E',
'/[óòôõºö]/u' => 'o',
'/[ÓÒÔÕÖ]/u' => 'O',
'/[úùûü]/u' => 'u',
'/[ÚÙÛÜ]/u' => 'U',
'/Š/' => 'S',
'/š/' => 's',
'/Č/' => 'C',
'/č/' => 'c',
'/ř/' => 'r',
'/Ř/' => 'R',
'/Ý/' => 'Y',
'/ý/' => 'y',
'/ç/' => 'c',
'/Ç/' => 'C',
'/ñ/' => 'n',
'/Ñ/' => 'N',
'//' => '-', // UTF-8 hyphen to "normal" hyphen
'/[]/u' => ' ', // Literally a single quote
'/[“”«»„]/u' => ' ', // Double quote
'/ /' => ' ', // nonbreaking space (equiv. to 0x160)
);
return preg_replace(array_keys($utf8), array_values($utf8), $text);
}
static function stringInsert($str,$insertstr,$pos)
{
$str = substr($str, 0, $pos) . $insertstr . substr($str, $pos);
return $str;
}
/**
* [generateGraphJson description]
* @param string $type [line/bar]
* @param array $data [description]
* @param array $options [description]
* @return [type] [description]
*/
static function generateGraphJson(string $type = 'line', array $data = [], array $options = []){
$array = [
'type' => $type,
'data' => [
'datasets' => [
[
'data' => $data,
'borderColor' => "#d4def7",
'backgroundColor' => "#d4def7"
]
]
],
'options' => [
'scales' => [
'xAxes' => [
[
'type' => 'time',
'distribution' => 'linear',
]
],
'yAxes' => [
[
'ticks' => [
'min' => $options['min'],
'max' => $options['max'],
'steps' => $options['scale']
]
]
]
],
'legend' => [
'display' => false
],
'tooltips' => [
'enabled' => true
],
'hover' => [
'mode' => true
]
]
];
return json_encode($array, JSON_PRETTY_PRINT);
}
static function ago( $datetime )
{
$interval = date_create('now')->diff( $datetime );
$suffix = ( $interval->invert ? ' ago' : '' );
if ( $v = $interval->y >= 1 ) return self::pluralize( $interval->m, 'month' ) . $suffix;
if ( $v = $interval->d >= 1 ) return self::pluralize( $interval->d, 'day' ) . $suffix;
if ( $v = $interval->h >= 1 ) return self::pluralize( $interval->h, 'hour' ) . $suffix;
if ( $v = $interval->i >= 1 ) return self::pluralize( $interval->i, 'minute' ) . $suffix;
return self::pluralize( $interval->s, 'second' ) . $suffix;
}
static function pluralize( $count, $text )
{
return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
}
static function checkOperator($value1, $operator, $value2) {
switch ($operator) {
case '<': // Less than
return $value1 < $value2;
case '<=': // Less than or equal to
return $value1 <= $value2;
case '>': // Greater than
return $value1 > $value2;
case '>=': // Greater than or equal to
return $value1 >= $value2;
case '==': // Equal
return ($value1 == $value2);
case '===': // Identical
return $value1 === $value2;
case '!==': // Not Identical
return $value1 !== $value2;
case '!=': // Not equal
case '<>': // Not equal
return $value1 != $value2;
case '||': // Or
case 'or': // Or
return $value1 || $value2;
case '&&': // And
case 'and': // And
return $value1 && $value2;
case 'xor': // Or
return $value1 xor $value2;
default:
return FALSE;
} // end switch
}
}

View File

@ -0,0 +1,45 @@
<?php
class AuthManager {
public function getToken($username, $password){
$userManager = new UserManager();
if ($username != '' || $password != ''){
$userLogedIn = $userManager->loginNew($username, $password);
if ($userLogedIn != false){
// Create token header as a JSON string
$header = json_encode(['typ' => 'JWT', 'alg' => 'HS256']);
// Create token payload as a JSON string
$payload = json_encode(['user_id' => $userLogedIn]);
// Encode Header to Base64Url String
$base64UrlHeader = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($header));
// Encode Payload to Base64Url String
$base64UrlPayload = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($payload));
// Create Signature Hash
$signature = hash_hmac('sha256', $base64UrlHeader . "." . $base64UrlPayload, 'abC123!', true);
// Encode Signature to Base64Url String
$base64UrlSignature = str_replace(['+', '/', '='], ['-', '_', ''], base64_encode($signature));
// Create JWT
$jwt = $base64UrlHeader . "." . $base64UrlPayload . "." . $base64UrlSignature;
return $jwt;
}
}
return false;
}
public function deleteToken($token){
Db::command ('DELETE FROM tokens WHERE token=?', array ($token));
return true;
}
public function validateToken($token){
$tokens = Db::loadAll('SELECT * FROM tokens WHERE token = ? AND expire >= CURRENT_TIMESTAMP AND blocked = 0;', array($token));
if (count($tokens) == 1) {
return true;
} else if (count($tokens) == 0) {
return false;
};
return false;
}
}

View File

@ -0,0 +1,175 @@
<?php
class AutomationManager{
public static $automation;
public static function remove($automationId) {
return Db::command ('DELETE FROM automation WHERE automation_id=?', array ($automationId));
}
public static function deactive($automationId) {
$automation = Db::loadOne ("SELECT * FROM automation WHERE automation_id=?" , array ($automationId));
$flipedValue = ($automation['active'] == 1 ? 0 : 1);
return Db::command ('UPDATE automation SET active = ? WHERE automation_id=?', array ($flipedValue,$automationId));
}
public static function restart($automationId) {
return Db::command ('UPDATE automation SET executed = 0 WHERE automation_id=?', array ($automationId));
}
public static function create ($name, $onDays, $doCode, $ifCode, $automationId = "") {
$userId = UserManager::getUserData('user_id');
$scene = array (
'name' => $name,
'owner_id' => $userId,
'on_days' => $onDays,
'if_something' => $ifCode,
'do_something' => $doCode,
);
try {
if ($automationId == "") {
Db::add ('automation', $scene);
} else {
Db::edit ('automation', $scene, 'WHERE automation_id = ?', array ($automationId));
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getAll(){
return Db::loadAll ("SELECT * FROM automation");
}
public static function executeAll(){
global $logManager;
$automations = Db::loadAll ("SELECT * FROM automation");
$dayNameNow = strtolower (date('D', time()));
foreach ($automations as $automation) {
$onValue = json_decode($automation['if_something'], true);
$sceneDoJson = $automation['do_something'];
$actionDays = json_decode($automation['on_days'], true);
$value = time();
$run = false;
$restart = false;
if ($automation['active'] == 1 && $automation['locked'] != 1){
Db::edit('automation', array('locked' => 1), 'WHERE automation_id = ?', array($automation['automation_id']));
if (in_array($dayNameNow, $actionDays)){
if (in_array($onValue['type'], ['sunSet', 'sunRise', 'time','now'])) {
if ($onValue['type'] == 'sunSet') {
$value = date_sunset($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90);
} else if ($onValue['type'] == 'sunRise') {
$value = date_sunrise($value, SUNFUNCS_RET_TIMESTAMP, 50.0755381 , 14.4378005, 90);
} else if ($onValue['type'] == 'time') {
$onValue = explode(':',$onValue['value']);
$today = date_create('now');
$onValue = $today->setTime($onValue[0], $onValue[1]);
$value = $today->getTimestamp();
}
if (time() > $value && $automation['executed'] == 0){
$run = true;
} else if (time() < $value && $automation['executed'] == 1) { //recovery realowing of automation
$restart = true;
}
} else if ($onValue['type'] == 'outHome') {
//TODO: Add Ovner to automation
$userHomeStatus = UserManager::getUserData('at_home', $onValue['value']);
if ($userHomeStatus == 'false' && $automation['executed'] == 0) {
$run = true;
} else if ($userHomeStatus == 'true' && $automation['executed'] == 1) {
$restart = true;
}
} else if ($onValue['type'] == 'inHome') {
//TODO: Add Ovner to automation
$userHomeStatus = UserManager::getUserData('at_home', $onValue['value']);
if ($userHomeStatus == 'true' && $automation['executed'] == 0) {
$run = true;
} else if ($userHomeStatus == 'false' && $automation['executed'] == 1) {
$restart = true;
}
} else if ($onValue['type'] == 'noOneHome') {
$users = UserManager::getUsers();
$membersHome = 0;
foreach ($users as $key => $user) {
if ($user['at_home'] == 'true'){
$membersHome++;
}
}
if ($membersHome == 0 && $automation['executed'] == 0) {
$run = true;
} else if ($membersHome > 0 && $automation['executed'] == 1){
$restart = true;
}
} else if ($onValue['type'] == 'someOneHome') {
$users = UserManager::getUsers();
$membersHome = 0;
foreach ($users as $key => $user) {
if ($user['at_home'] == 'true'){
$membersHome++;
}
}
if ($membersHome == 0 && $automation['executed'] == 1) {
$restart = true;
} else if ($membersHome > 0 && $automation['executed'] == 0){
$run = true;
}
} else if ($onValue['type'] == 'atDeviceValue') {
$subDeviceId = SubDeviceManager::getSubDeviceByMaster($onValue['value']['deviceID'], $onValue['value']['type'])["subdevice_id"];
$lastValue = RecordManager::getLastRecord($subDeviceId);
if ($lastValue['value'] == $onValue['value']['value'] && $automation['executed'] == 0) {
$run = true;
} else if ($lastValue['value'] != $onValue['value']['value'] && $automation['executed'] == 1){
$restart = true;
}
}
//finalization
if ($run) {
$body = '';
$sceneDoArray = json_decode($sceneDoJson);
foreach ($sceneDoArray as $deviceId => $deviceState) {
RecordManager::create($deviceId, 'on/off', $deviceState);
}
$subscribers = NotificationManager::getSubscription();
$i = 0;
$notificationMng = new NotificationManager;
$notificationData = [
'title' => 'Automatization',
'body' => 'Automatization '.$automation['name']." was just executed",
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
];
if ($notificationData != []) {
$subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) {
$logManager->write("[NOTIFICATION/AUTOOMATION] SENDING TO" . $subscriber['id'] . " ");
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
}
}
$logManager->write("[AUTOMATIONS] automation id ". $automation['automation_id'] . " was executed");
Db::edit('automation', array('executed' => 1, 'execution_time' => date("Y-m-d H:i:s")), 'WHERE automation_id = ?', array($automation['automation_id']));
} else if ($restart) {
$logManager->write("[AUTOMATIONS] automation id ". $automation['automation_id'] . " was restarted");
Db::edit('automation', array('executed' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
}
Db::edit('automation', array('locked' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
}
}
}
}
}

View File

@ -0,0 +1,129 @@
<?php
class ChartScale{
const HOUR = 'info';
const DAY = 'warning';
const MONTH = 'warning';
const YEAR = 'error';
}
class ChartManager{
function generateChart($data, $min = 0, $max = 100) {
echo '<br>Aktuální Hodnota: '.$data[0]['value'];
echo "<style>
.sloupec {
border-top: solid 2px red;
}
</style>";
echo '<div class=graph>';
echo '<div class="posuv " graf-max="'.$max.'" graf-min='.$min.'>';
for ($valuesRow = 0; $valuesRow < count($data); $valuesRow++) {
$row = $data[$valuesRow];
echo '<div class="sloupec " name="sloupec" value="' . $row['value'] . '" data-toggle="tooltip" title=""></div>';
}
echo '</div>';
echo '</div>';
echo '<script src="./include/js/chartDrwer.js"></script>';
echo 'Poslední Update: ';
echo '<style>
.graph {
width: 100%;
overflow: hidden;
margin-top: auto;
}
.posuv {
display: flex;
height: 200px;
background-image: url(./img/graph.png);
padding: 20px;
background-repeat: repeat;
border-bottom: 1px solid black;
}
.sloupec {
border-top: solid 2px blue;
background-color: grey;
float: left;
margin: auto 0 0;
display: inline-block;
width: 1%;
}
</style>
<script>
var posuvList = document.getElementsByClassName("posuv");
var maxHeight = posuvList[0].clientHeight;
for (i = 0; i < posuvList.length; i++) {
var maxPx = 0;
var grafMax = Number(posuvList[i].getAttribute("graf-max")); //100%
var grafMin = Number(posuvList[i].getAttribute("graf-min")); //0%
if (grafMin == 0 && grafMax == 100) {
var onePercent = 1;
} else {
var stepsBetWene = grafMax;
if (grafMin !== 0) {
if (grafMin < 0) {
stepsBetWene = grafMax + Math.abs(grafMin);
}
if (grafMin > 0) {
stepsBetWene = grafMax - grafMin;
}
}
var onePercent = stepsBetWene / 100;
}
var sloupceList = posuvList[i].querySelectorAll(".sloupec");
for (ai = 0; ai < sloupceList.length; ai++) {
var onePxPercent = maxHeight / 100;
var heightInPercent =
Math.abs(sloupceList[ai].getAttribute("value")) / onePercent;
var outputPx = onePxPercent * heightInPercent;
sloupceList[ai].style.height = outputPx + "px";
}
}
</script>';
}
function generateChartData(int $subDeviceId, string $periode, string $groupBy) {
$chartData = [];
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
$records = RecordManager::getAllRecordForGraph($subDeviceId, $periode, $groupBy);
$array = array_column($records, 'value');
$arrayTime = array_column($records, 'time');
$output = [];
foreach ($array as $key => $value) {
$output[$key]['y'] = $value;
if ($subDevice['type'] == 'light'){
if ($value > 810){
$output[$key]['y'] = 1;
} else {
$output[$key]['y'] = 0;
}
}
$timeStamp = new DateTime($arrayTime[$key]);
$output[$key]['t'] = $timeStamp->format("Y-m-d") . 'T' . $timeStamp->format("H:i:s") . 'Z';
}
$data = json_encode($output);
$data = $output;
$arrayTimeStamps = array_column($records, 'time');
foreach ($arrayTimeStamps as $key => $value) {
$arrayTimeStamps[$key] = (new DateTime($value))->format(TIMEFORMAT);
}
$chartData['graphRange'] = RANGES[$subDevice['type']];
$chartData['graphType'] = RANGES[$subDevice['type']]['graph'];
$chartData['graphData'] = $data;
return $chartData;
}
}
?>

View File

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

View File

@ -0,0 +1,96 @@
<?php
class DeviceManager{
public static $devices;
static function getAllDevices () {
return Db::loadAll ("SELECT * FROM devices WHERE approved != ?", Array(2));
}
static function getAllDevicesInRoom ($roomId = "") {
return Db::loadAll ("SELECT * FROM devices WHERE room_id = ? AND approved != ?", Array($roomId, 2));
}
static function getOtherDevices(){
return Db::loadAll ("SELECT * FROM devices WHERE room_id IS NULL ");
}
static function getDeviceByToken($deviceToken) {
return Db::loadOne("SELECT * FROM devices WHERE token = ?", array($deviceToken));
}
static function getDeviceByMac($deviceMac) {
return Db::loadOne("SELECT * FROM devices WHERE mac = ?", array($deviceMac));
}
static function getDeviceById($deviceId) {
return Db::loadOne("SELECT * FROM devices WHERE device_id = ?", array($deviceId));
}
public static function create ($name, $token) {
$defaultRoom = RoomManager::getDefaultRoomId();
$device = array (
'name' => $name,
'token' => $token,
'room_id' => $defaultRoom,
);
try {
Db::add ('devices', $device);
return Db::loadOne("SELECT device_id FROM devices WHERE token = ?", array($token))['device_id'];
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function edit ($deviceId, $values = []) {
try {
Db::edit ('devices', $values, 'WHERE device_id = ?', array($deviceId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function editByToken ($token, $values = []) {
try {
Db::edit ('devices', $values, 'WHERE token = ?', array($token));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
/**
* [assignRoom Přiřazení zařízení do třídy]
* @param [type] $roomId [číslo místnosti do kter se 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);
}
}
?>

View File

@ -0,0 +1,44 @@
<?php
/**
*
*/
class FallbackManager
{
public $deviceDefinitions = "";
function __construct($deviceDefinition)
{
$this->deviceDefinitions = $deviceDefinition;
}
function check(){
//TODO: FIX IT
$allDevicesData = DeviceManager::getAllDevices();
foreach ($allDevicesData as $deviceKey => $deviceValue) {
$allSubDevicesData = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
foreach ($allSubDevicesData as $subDeviceKey => $subDeviceValue) {
if (!isset($this->deviceDefinitions[$subDeviceValue['type']]["fallBack"])) {
continue;
}
if (!isset($this->deviceDefinitions[$subDeviceValue['type']]["fallBackTime"])) {
continue;
}
$lastRecord = RecordManager::getLastRecord($subDeviceValue['subdevice_id']);
if ($lastRecord["value"] == $this->deviceDefinitions[$subDeviceValue['type']]["fallBack"]) {
continue;
}
$minutes = (time() - strtotime($lastRecord['time'])) / 60;
if ( $minutes > $this->deviceDefinitions[$subDeviceValue['type']]["fallBackTime"]){
RecordManager::create($deviceValue['device_id'], $subDeviceValue['type'], $this->deviceDefinitions[$subDeviceValue['type']]["fallBack"]);
}
}
}
}
}

View File

@ -0,0 +1,60 @@
<?php
/**
* Language Manager
*/
class LanguageManager
{
private $lngCode = 'en';
private $lngDatabase = [];
private $debug = false;
function __construct(string $lngCode, bool $debug = false)
{
$this->lngCode = $lngCode;
$this->debug = $debug;
}
function load()
{
$file = '../lang/en.php';
if (!file_exists($file)){
echo 'ERROR: en.php not found';
die();
//TODO add lng EXEPTIONS
}
$arrayFirst = include($file);
$file = '../lang/' . $this->lngCode . '.php';
$arraySecond = [];
if (file_exists($file)){
$arraySecond = include($file);
}
$this->lngDatabase = array_merge($arrayFirst, $arraySecond);
return true;
}
function get(string $stringKey)
{
if ($this->debug) {
return $stringKey;
}
if (isset($this->lngDatabase[$stringKey])) {
return $this->lngDatabase[$stringKey];
}
return $stringKey;
}
function echo(string $stringKey)
{
if ($this->debug) {
echo $stringKey;
return;
}
if (isset($this->lngDatabase[$stringKey])) {
echo $this->lngDatabase[$stringKey];
return;
}
echo $stringKey;
return;
}
}

View File

@ -0,0 +1,57 @@
<?php
/**
*
*/
class LogRecordType{
const WARNING = 'warning';
const ERROR = 'error';
const INFO = 'info';
}
class LogKeeper
{
function purge($days){
$todayFileName = date("Y-m-d").'.log';
$seconds = $days * 86400;
$logFiles = scandir('../logs/');
foreach ($logFiles as $key => $file) {
if (in_array($file,array(".","..", ".gitkeep", $todayFileName)))
{
continue;
}
if (filemtime($file) > $seconds) {
unlink('../logs/'.$file);
}
}
}
}
class LogManager
{
private $logFile;
function __construct($fileName = "")
{
if ($fileName == ""){
$fileName = '../logs/'. date("Y-m-d").'.log';
}
if(!is_dir("../logs/"))
{
mkdir("../logs/");
}
$this->logFile = fopen($fileName, "a") or die("Unable to open file!");
}
function write($value, $type = LogRecordType::ERROR){
$record = "[".date("H:m:s")."][".$type."]" . $value . "\n";
fwrite($this->logFile, $record);
}
function __destruct(){
if (isset($this->logFile)) {
fclose($this->logFile);
}
}
}

View File

@ -0,0 +1,18 @@
<?php
/**
*
*/
class NetvorkManager
{
function __construct()
{
// code...
}
function validateIp($ip = '0.0.0.0'){
if (!filter_var($ip, FILTER_VALIDATE_IP)){
return false;
}
}
}

View File

@ -0,0 +1,107 @@
<?php
/**
* Notification Manager
*/
//TODO: Working timestamp to body or $title
class NotificationManager
{
function addSubscriber($userID = '', $token = ''){
$notificationSubscriber = $subDeviceId = Db::loadOne('SELECT id FROM notifications WHERE token = ?;', array($token));
if ($notificationSubscriber == ''){
$notification = array (
'user_id' => $userID,
'token' => $token,
);
Db::add ('notifications', $notification);
}
}
function getSubscription () {
return Db::loadAll ("SELECT * FROM notifications");
}
function sendSimpleNotification(string $serverKey, string $to, array $data, bool $timeStamp = false){
$dataTemplate = [
'title' => '',
'body' => '',
'icon' => '',
];
if (array_diff_key ($dataTemplate , $data)){
return;
}
if ($timeStamp) {
$data['title'] = $data['title'] . date();
}
$notification = new Notification($serverKey);
$notification->to($to);
$notification->notification($data['title'], $data['body'], $data['icon'], '');
$answer = $notification->send();
$notification = null;
return $answer;
}
}
class Notification
{
public $server_key = '';
public $jsonPayload = [
"to" => '',
"data" => [
"notification" => [
"body" => '',
"title" => '',
"icon" => '',
"click_action" => '',
]
]
];
function __construct($serverKey = '')
{
$this->server_key = $serverKey;
}
function to($to = ''){
$this->jsonPayload["to"] = $to;
}
function notification($title = '', $body = '', $icon = '', $action = '', bool $timeStamp = false)
{
if ($timeStamp) {
$data['title'] = $data['title'] . date();
}
$this->jsonPayload["data"]["notification"]["title"] = $title;
$this->jsonPayload["data"]["notification"]["body"] = $body;
$this->jsonPayload["data"]["notification"]["icon"] = $icon;
$this->jsonPayload["data"]["notification"]["click_action"] = $action;
}
function send(){
$data = json_encode($this->jsonPayload);
$url = 'https://fcm.googleapis.com/fcm/send';
$headers = array(
'Content-Type:application/json',
'Authorization:key='.$this->server_key,
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$result = curl_exec($ch);
if ($result === FALSE) {
die('Oops! FCM Send Error: ' . curl_error($ch));
}
curl_close($ch);
return $result;
}
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,97 @@
<?php
class SubDeviceManager
{
public static $devices;
public static function getAllSubDevices($deviceId = null)
{
if ($deviceId == null){
return Db::loadAll("SELECT * FROM subdevices");
}
return Db::loadAll("SELECT * FROM subdevices WHERE device_id = ?", array($deviceId));
}
public static function getSubDeviceMaster($subDeviceId)
{
return Db::loadOne("SELECT * FROM devices WHERE device_id = (SELECT device_id FROM subdevices WHERE subdevice_id = ?)", array($subDeviceId));
}
public static function getSubDeviceByMaster($deviceId, $subDeviceType = null)
{
if ($subDeviceType == null) {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ?;", array($deviceId));
} else {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ? AND type = ?;", array($deviceId, $subDeviceType));
}
}
public static function getSubDeviceByMasterAndType($deviceId, $subDeviceType = null)
{
if (!empty($subDeviceType)) {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ?;", array($deviceId));
} else {
return Db::loadOne("SELECT * FROM subdevices WHERE device_id = ? AND type = ?;", array($deviceId, $subDeviceType));
}
}
public static function getSubDevice($subDeviceId)
{
return Db::loadOne("SELECT * FROM subdevices WHERE subdevice_id = ?;", array($subDeviceId));
}
public static function getSubDevicesTypeForMater($deviceId)
{
$parsedTypes = [];
$types = Db::loadAll("SELECT type FROM subdevices WHERE device_id = ?;", array($deviceId));
foreach ($types as $orderNum => $type) {
$parsedTypes[$orderNum] = $type['type'];
}
return $parsedTypes;
}
//check if dubdevice exist
public static function create($deviceId, $type, $unit)
{
$record = array(
'device_id' => $deviceId,
'type' => $type,
'unit' => $unit,
);
try {
Db::add('subdevices', $record);
} catch (PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function remove($subDeviceId)
{
RecordManager::cleanSubdeviceRecords($subDeviceId);
return Db::loadAll("DELETE FROM subdevices WHERE subdevice_id = ?", array($subDeviceId));
}
public static function getSubdevicesByRoomIds($roomIds = NULL) {
if(empty($roomIds)) return NULL;
$rows = Db::loadAll("
SELECT d.room_id, sd.subdevice_id, sd.device_id, d.name, sd.type, sd.unit, r.value FROM subdevices sd
JOIN devices d ON sd.device_id = d.device_id
JOIN records r ON r.subdevice_id = sd.subdevice_id
WHERE d.room_id IN (".str_repeat("?,", count($roomIds)-1)."?)
AND r.record_id IN (
SELECT MAX(record_id)
FROM records
GROUP BY subdevice_id
)
", $roomIds);
$ret = [];
foreach($rows as $row){
$ret[$row['room_id']][] = $row;
}
return $ret;
}
}

View File

@ -0,0 +1,210 @@
<?php
class UserManager
{
public static function getUsers () {
try {
$allUsers = Db::loadAll ("SELECT user_id, username, at_home, ota FROM users");
return $allUsers;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getUser ($userName) {
try {
$user = Db::loadOne ("SELECT * FROM users WHERE username = ?", [$userName]);
return $user;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getUserId ($userId) {
try {
$user = Db::loadOne ("SELECT * FROM users WHERE user_id = ?", [$userId]);
return $user;
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function getAvatarUrl($userId = null){
$email = self::getUserData('email');
if ($userId != null){
$email = self::getUserData('email',$userId);
}
return 'https://secure.gravatar.com/avatar/' . md5( strtolower( trim( $email ) ) );
}
public static function login ($username, $password, $rememberMe) {
try {
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) {
if ($user['password'] == UserManager::getHashPassword($password)) {
if (isset($rememberMe) && $rememberMe == 'true') {
setcookie ("rememberMe", self::setEncryptedCookie($user['username']), time () + (30 * 24 * 60 * 60 * 1000), BASEDIR, $_SERVER['HTTP_HOST'], 1);
}
$_SESSION['user']['id'] = $user['user_id'];
$page = "";
if ($user["startPage"] == 1) {
$page = "dashboard";
}
unset($_POST['login']);
return $page;
} else {
throw new PDOException("Heslo není správné!");
}
} else {
throw new PDOException("Uživatel s tím to jménem neexistuje!");
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function loginNew ($username, $password) {
try {
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array ($username))) {
if ($user['password'] == UserManager::getHashPassword($password)) {
echo "user loged in";
return $user['user_id'];
} else {
return false;
}
} else {
return false;
}
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function isLogin () {
if (isset ($_SESSION['user']) && isset($_SESSION['user']['id'])) {
return true;
} else {
if (isset ($_COOKIE['rememberMe'])){
if ($user = Db::loadOne ('SELECT * FROM users WHERE LOWER(username)=LOWER(?)', array (self::getDecryptedCookie($_COOKIE['rememberMe'])))) {
$_SESSION['user']['id'] = $user['user_id'];
return true;
}
}
}
return false;
}
public static function logout () {
unset($_SESSION['user']);
session_destroy();
if (isset($_COOKIE['rememberMe'])){
unset($_COOKIE['rememberMe']);
setcookie("rememberMe", 'false', time(), BASEDIR, $_SERVER['HTTP_HOST']);
}
}
public static function setEncryptedCookie($value){
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$method = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($method);
$iv = openssl_random_pseudo_bytes($ivlen);
$newvalue_raw = openssl_encrypt($value, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $newvalue_raw, $second_key, TRUE);
$newvalue = base64_encode ($iv.$hmac.$newvalue_raw);
return $newvalue;
}
public static function getDecryptedCookie($value){
$first_key = base64_decode(FIRSTKEY);
$second_key = base64_decode(SECONDKEY);
$c = base64_decode($value);
$method = "aes-256-cbc";
$ivlen = openssl_cipher_iv_length($method);
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, 32);
$newValue_raw = substr($c, $ivlen+32);
$newValue = openssl_decrypt($newValue_raw, $method, $first_key, OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $newValue_raw, $second_key, TRUE);
if (hash_equals ($hmac, $calcmac)) {
return $newValue;
}
return false;
}
public static function getUserData ($type, $userId = '') {
if ($userId == '') {
$userId = $_SESSION['user']['id'];
}
$user = Db::loadOne ('SELECT ' . $type . ' FROM users WHERE user_id=?', array ($userId));
return $user[$type];
}
public static function setUserData ($type, $value) {
if (isset ($_SESSION['user']['id'])) {
Db::command ('UPDATE users SET ' . $type . '=? WHERE user_id=?', array ($value, $_SESSION['user']['id']));
}
}
public static function getHashPassword ($password) {
$salt = "s0mRIdlKvI";
$hashPassword = hash('sha512', ($password . $salt));
return $hashPassword;
}
public static function atHome($userId, $atHome){
try {
Db::edit ('users', ['at_home' => $atHome], 'WHERE user_id = ?', array($userId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function changePassword($oldPassword, $newPassword, $newPassword2){
if ($newPassword == $newPassword2) {
//Password Criteria
$oldPasswordSaved = self::getUserData('password');
if (self::getHashPassword($oldPassword) == $oldPasswordSaved) {
self::setUserData('password', self::getHashPassword($newPassword));
} else {
throw new Exception ("old password did not match");
}
} else {
throw new Exception ("new password arent same");
}
}
public static function createUser($userName, $password){
$userId = Db::loadOne('SELECT * FROM users WHERE username = ?;', array($userName))['user_id'];
if ($userId != null) {
return false;
};
try {
$user = [
'username' => $userName,
'password' => self::getHashPassword($password),
];
return Db::add ('users', $user);
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
public static function haveOtaEnabled($userName){
$ota = self::getUser($userName)['ota'];
if ($ota != ''){
return ($ota != '' ? $ota : false);
} else {
return false;
}
}
}
?>

View File

@ -0,0 +1,144 @@
<?php
/**
*
*/
class Utilities
{
static function cleanString($text) {
$utf8 = array(
'/[áàâãªä]/u' => 'a',
'/[ÁÀÂÃÄ]/u' => 'A',
'/[ÍÌÎÏ]/u' => 'I',
'/[íìîï]/u' => 'i',
'/[ěéèêë]/u' => 'e',
'/[ĚÉÈÊË]/u' => 'E',
'/[óòôõºö]/u' => 'o',
'/[ÓÒÔÕÖ]/u' => 'O',
'/[úùûü]/u' => 'u',
'/[ÚÙÛÜ]/u' => 'U',
'/Š/' => 'S',
'/š/' => 's',
'/Č/' => 'C',
'/č/' => 'c',
'/ř/' => 'r',
'/Ř/' => 'R',
'/Ý/' => 'Y',
'/ý/' => 'y',
'/ç/' => 'c',
'/Ç/' => 'C',
'/ñ/' => 'n',
'/Ñ/' => 'N',
'//' => '-', // UTF-8 hyphen to "normal" hyphen
'/[]/u' => ' ', // Literally a single quote
'/[“”«»„]/u' => ' ', // Double quote
'/ /' => ' ', // nonbreaking space (equiv. to 0x160)
);
return preg_replace(array_keys($utf8), array_values($utf8), $text);
}
static function stringInsert($str,$insertstr,$pos)
{
$str = substr($str, 0, $pos) . $insertstr . substr($str, $pos);
return $str;
}
/**
* [generateGraphJson description]
* @param string $type [line/bar]
* @param array $data [description]
* @param array $options [description]
* @return [type] [description]
*/
static function generateGraphJson(string $type = 'line', array $data = [], array $options = []){
$array = [
'type' => $type,
'data' => [
'datasets' => [
[
'data' => $data,
'borderColor' => "#d4def7",
'backgroundColor' => "#d4def7"
]
]
],
'options' => [
'scales' => [
'xAxes' => [
[
'type' => 'time',
'distribution' => 'linear',
]
],
'yAxes' => [
[
'ticks' => [
'min' => $options['min'],
'max' => $options['max'],
'steps' => $options['scale']
]
]
]
],
'legend' => [
'display' => false
],
'tooltips' => [
'enabled' => true
],
'hover' => [
'mode' => true
]
]
];
return json_encode($array, JSON_PRETTY_PRINT);
}
static function ago( $datetime )
{
$interval = date_create('now')->diff( $datetime );
$suffix = ( $interval->invert ? ' ago' : '' );
if ( $v = $interval->y >= 1 ) return self::pluralize( $interval->m, 'month' ) . $suffix;
if ( $v = $interval->d >= 1 ) return self::pluralize( $interval->d, 'day' ) . $suffix;
if ( $v = $interval->h >= 1 ) return self::pluralize( $interval->h, 'hour' ) . $suffix;
if ( $v = $interval->i >= 1 ) return self::pluralize( $interval->i, 'minute' ) . $suffix;
return self::pluralize( $interval->s, 'second' ) . $suffix;
}
static function pluralize( $count, $text )
{
return $count . ( ( $count == 1 ) ? ( " $text" ) : ( " ${text}s" ) );
}
static function checkOperator($value1, $operator, $value2) {
switch ($operator) {
case '<': // Less than
return $value1 < $value2;
case '<=': // Less than or equal to
return $value1 <= $value2;
case '>': // Greater than
return $value1 > $value2;
case '>=': // Greater than or equal to
return $value1 >= $value2;
case '==': // Equal
return ($value1 == $value2);
case '===': // Identical
return $value1 === $value2;
case '!==': // Not Identical
return $value1 !== $value2;
case '!=': // Not equal
case '<>': // Not equal
return $value1 != $value2;
case '||': // Or
case 'or': // Or
return $value1 || $value2;
case '&&': // And
case 'and': // And
return $value1 && $value2;
case 'xor': // Or
return $value1 xor $value2;
default:
return FALSE;
} // end switch
}
}

View File

@ -0,0 +1,107 @@
<?php
class GoogleHomeDeviceTypes {
/*const AirConditioningUnit = 'action.devices.types.AC_UNIT';
const AirFreshener = 'action.devices.types.AIRFRESHENER';
const AirPurifier = 'action.devices.types.AIRPURIFIER';
const Awning = 'action.devices.types.AWNING';
const Bathtub = 'action.devices.types.BATHTUB';
const Bed = 'action.devices.types.BED';
const Blender = 'action.devices.types.BLENDER';
const Blinds = 'action.devices.types.BLINDS';
const Boiler = 'action.devices.types.BOILER';
const Camera = 'action.devices.types.CAMERA';
const CarbonMonoxideDetector = 'action.devices.types.CARBON_MONOXIDE_DETECTOR';
const Charger = 'action.devices.types.CHARGER';
const Closet = 'action.devices.types.CLOSET';
const CoffeeMaker = 'action.devices.types.COFFEE_MAKER';
const Cooktop = 'action.devices.types.COOKTOP';
const Curtain = 'action.devices.types.CURTAIN';
const Dehumidifier = 'action.devices.types.DEHUMIDIFIER';
const Dehydrator = 'action.devices.types.DEHYDRATOR';
const Dishwasher = 'action.devices.types.DISHWASHER';
const Door = 'action.devices.types.DOOR';
const Drawer = 'action.devices.types.DRAWER';
const Dryer = 'action.devices.types.DRYER';
const Fan = 'action.devices.types.FAN';
const Faucet = 'action.devices.types.FAUCET';
const Fireplace = 'action.devices.types.FIREPLACE';
const Fryer = 'action.devices.types.FRYER';
const GarageDoor = 'action.devices.types.GARAGE';
const Gate = 'action.devices.types.GATE';
const Grill = 'action.devices.types.GRILL';
const Heater = 'action.devices.types.HEATER';
const Hood = 'action.devices.types.HOOD';
const Humidifier = 'action.devices.types.HUMIDIFIER';
const Kettle = 'action.devices.types.KETTLE';
const Light = 'action.devices.types.LIGHT';
const Lock = 'action.devices.types.LOCK';
const MediaRemote = 'action.devices.types.REMOTECONTROL';
const Mop = 'action.devices.types.MOP';
const Mower = 'action.devices.types.MOWER';
const Microwave = 'action.devices.types.MICROWAVE';
const Multicooker = 'action.devices.types.MULTICOOKER';
const Network = 'action.devices.types.NETWORK';
const Oven = 'action.devices.types.OVEN';
const Pergola = 'action.devices.types.PERGOLA';
const PetFeeder = 'action.devices.types.PETFEEDER';
const PressureCooker = 'action.devices.types.PRESSURECOOKER';
const Radiator = 'action.devices.types.RADIATOR';
const Refrigerator = 'action.devices.types.REFRIGERATOR';
const Router = 'action.devices.types.ROUTER';
const Scene = 'action.devices.types.SCENE';
const Sensor = 'action.devices.types.SENSOR';
const SecuritySystem = 'action.devices.types.SECURITYSYSTEM';
const SettopBox = 'action.devices.types.SETTOP';
const Shutter = 'action.devices.types.SHUTTER';
const Shower = 'action.devices.types.SHOWER';
const SmokeDetector = 'action.devices.types.SMOKE_DETECTOR';
const SousVide = 'action.devices.types.SOUSVIDE';
const Sprinkler = 'action.devices.types.SPRINKLER';
const StandMixer = 'action.devices.types.STANDMIXER';
const Switch = 'action.devices.types.SWITCH';
const Television = 'action.devices.types.TV';
const Thermostat = 'action.devices.types.THERMOSTAT';
const Vacuum = 'action.devices.types.VACUUM';
const Valve = 'action.devices.types.VALVE';
const Washer = 'action.devices.types.WASHER';
const WaterHeater = 'action.devices.types.WATERHEATER';
const WaterPurifier = 'action.devices.types.WATERPURIFIER';
const WaterSoftener = 'action.devices.types.WATERSOFTENER';
const Window = 'action.devices.types.WINDOW';
const YogurtMaker = 'action.devices.types.YOGURTMAKER';*/
private static $actionWordBook = [
'on/off' => 'action.devices.types.OUTLET',
'temp_cont' => 'action.devices.types.THERMOSTAT',
];
static function getAction($deviceType){
return self::$actionWordBook[$deviceType];
}
static function getSyncObj($deviceBaseObj, $deviceType){
switch ($deviceType) {
case 'action.devices.types.LIGHT':
case 'action.devices.types.OUTLET':
$deviceBaseObj['traits'] = [
'action.devices.traits.OnOff'
];
break;
case 'action.devices.types.THERMOSTAT':
$deviceBaseObj['traits'] = [
'action.devices.traits.TemperatureSetting',
];
$deviceBaseObj['attributes'] = [
"availableThermostatModes" => "off,heat",
"thermostatTemperatureUnit" => "C",
];
break;
}
return $deviceBaseObj;
}
static function getQueryJson($deviceType, $type){
return self::$wordBook[$type];
}
}

View File

@ -0,0 +1,45 @@
<?php
class WidgetTypes {
const VALUE = 0;
const ICON = 1;
const BUTTON = 2;
const SWITH = 3;
const RANGE = 4;
const CUSTOM = 5;
private $types = [
self::VALUE => [
'name' => 'value',
'active' => false
],
self::ICON => [
'name' => 'icon',
'active' => false
],
self::BUTTON => [
'name' => 'button',
'active' => true
],
self::SWITH => [
'name' => 'switch',
'active' => true
],
self::RANGE => [
'name' => 'range',
'active' => true
],
self::CUSTOM => [
'name' => 'custom',
'active' => true
],
];
public static function getName($type){
return self::$types[$type];
}
public static function isActive($type){
return isset(self::$types[$type]) && self::$types[$type]['active'];
}
}

223
app/views/Ajax.php Normal file
View File

@ -0,0 +1,223 @@
<?php
class Ajax extends Template
{
function __construct()
{
global $userManager;
global $lang;
if (!$userManager->isLogin()){
header('Location: ' . BASEURL);
}
$is_ajax = 'XMLHttpRequest' == ( $_SERVER['HTTP_X_REQUESTED_WITH'] ?? '' );
if (!$is_ajax){
header('Location: ' . BASEURL);
}
if (
isset($_POST['automation_id']) &&
$_POST['automation_id'] != '' &&
isset($_POST['action']) &&
$_POST['action'] != ''
) {
$automationId = $_POST['automation_id'];
//Automation Editation of Automations from Buttons/Details
switch ($_POST['action']) {
case 'delete':
AutomationManager::remove($automationId);
die();
break;
case 'deactive':
AutomationManager::deactive($automationId);
die();
break;
case 'restart':
AutomationManager::restart($automationId);
die();
break;
default:
echo 'no action detected';
break;
}
} else if (
isset($_POST['subDevice_id']) &&
$_POST['subDevice_id'] != '' &&
isset($_POST['action']) &&
$_POST['action'] != ''
) {
$subDeviceId = $_POST['subDevice_id'];
switch ($_POST['action']) {
case 'chart':
$period = $_POST['period'];
$groupBy = $_POST['group'];
header('Content-Type: application/json');
$graphData = ChartManager::generateChartData($subDeviceId, $period, $groupBy);
echo Utilities::generateGraphJson($graphData['graphType'], $graphData['graphData'], $graphData['graphRange']);
die();
break;
//Change On/Off Device State of Device Button
case 'change':
$subDeviceData = SubDeviceManager::getSubDevice($subDeviceId);
$deviceId = SubDeviceManager::getSubDeviceMaster($subDeviceId)['device_id'];
if ($subDeviceData['type'] == 'on/off'){
$lastValue = RecordManager::getLastRecord($subDeviceData['subdevice_id'])['value'];
RecordManager::create($deviceId, 'on/off', !$lastValue);
echo (!$lastValue ? 'ON' : 'OFF');
}
die();
break;
//Waitin for execution of Changet walue for Device Button
case 'executed':
echo RecordManager::getLastRecord($subDeviceId)['execuded'];
die();
break;
case 'set':
$value = $_POST['value'];
$subDevice = SubDeviceManager::getSubDevice($subDeviceId);
RecordManager::create($subDevice['device_id'], $subDevice['type'], $value);
echo 'test id' . $subDevice['device_id'] .$subDevice['type'] . $value ;
die();
break;
default:
echo 'no action detected';
break;
}
} else if (
isset($_POST['scene_id']) &&
$_POST['scene_id'] != '' &&
isset($_POST['action']) &&
$_POST['action'] != ''
) {
$sceneId = $_POST['scene_id'];
switch ($_POST['action']) {
case 'delete':
SceneManager::delete($sceneId);
die();
break;
case 'execute':
echo SceneManager::execScene($sceneId);
die();
break;
default:
echo 'no action detected';
break;
}
} else if (
isset($_POST['notification']) &&
$_POST['notification'] != '' &&
isset($_POST['action']) &&
$_POST['action'] != ''
) {
switch ($_POST['action']) {
//add suscription to database
case 'subscribe':
$subscriptionToken = $_POST['token'];
NotificationManager::addSubscriber($_SESSION['user']['id'], $subscriptionToken);
die();
break;
case 'sendTest':
$notificationData = [
'title' => 'Alert',
'body' => 'test notification',
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
];
$notificationMng = new NotificationManager;
$subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) {
echo $subscriber['user_id'];
if ($subscriber['user_id'] != $_SESSION['user']['id']) continue;
echo $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
}
die();
break;
default:
echo 'no action detected';
break;
}
} else if (
isset($_POST['action']) &&
$_POST['action'] != ''
) {
$updateData = [];
$allDevicesData = DeviceManager::getAllDevices();
foreach ($allDevicesData as $deviceKey => $deviceValue) {
$allSubDevices = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
foreach ($allSubDevices as $key => $subDevicesData) {
$lastRecord = RecordManager::getLastRecord($subDevicesData['subdevice_id']);
$parsedValue = $lastRecord['value'] . $subDevicesData['unit'];
//TODO: udělat parser a ten použít jak v houmu tak zde
switch ($subDevicesData['type']) {
case 'on/off':
$replacementTrue = 'On';
$replacementFalse = 'Off';
$operator = '==';
$breakValue = 1;
break;
case 'door':
$replacementTrue = 'Closed';
$replacementFalse = 'Open';
$operator = '==';
$breakValue = 1;
break;
case 'light':
$replacementTrue = 'Light';
$replacementFalse = 'Dark';
$operator = '==';
$breakValue = 1;
if ($lastRecord['value'] != 1 && $lastRecord['value'] != 0) { //Digital Light Senzor
$operator = '<';
$breakValue = 810;
}
break;
case 'water':
$replacementTrue = 'Wet';
$replacementFalse = 'Dry';
$operator = '==';
$breakValue = 1;
break;
default:
$replacementTrue = '';
$replacementFalse = '';
break;
}
if ($replacementTrue != '' && $replacementFalse != '') {
//parsing last values
$parsedValue = $replacementFalse;
if (Utilities::checkOperator($lastRecord['value'], $operator, $breakValue)) {
$parsedValue = $replacementTrue;
}
}
$updateData[$subDevicesData['subdevice_id']] = [
'time' => $lastRecord['time'],
'value' => $parsedValue,
];
}
}
//TODO: PRO JS VRACET DATA
echo json_encode($updateData, JSON_PRETTY_PRINT);
}
}
}

66
app/views/Automation.php Normal file
View File

@ -0,0 +1,66 @@
<?php
class Automation extends Template
{
function __construct()
{
global $userManager;
global $langMng;
if (!$userManager->isLogin()){
header('Location: ' . BASEURL . 'login');
}
$automations = [];
$automationsData = AutomationManager::getAll();
foreach ($automationsData as $automationKey => $automationData) {
$doSomething = [];
foreach (json_decode($automationData['do_something']) as $deviceId => $subDeviceState) {
$subDeviceMasterDeviceData = DeviceManager::getDeviceById($deviceId);
$doSomething[$deviceId] = [
'name' => $subDeviceMasterDeviceData['name'],
'state' => $subDeviceState,
];
}
//TODO: Transaltion add
$executionTime = 'never';
if ($automationData['execution_time'] != '0000-00-00 00:00:00') {
$executionTime = date(DATEFORMAT,strtotime($automationData['execution_time']));
}
$automations[$automationData['automation_id']] = [
'name' => $automationData['name'],
'owner_name' => $userManager->getUserId($automationData['owner_id'])['username'],
'onDays' => json_decode($automationData['on_days']),
'ifSomething' => $automationData['if_something'],
'doSomething' => $doSomething,
'active' => $automationData['active'],
'execution_time' => $executionTime,
];
}
$approvedSubDevices = [];
$allDevicesData = DeviceManager::getAllDevices();
foreach ($allDevicesData as $deviceKey => $deviceValue) {
if (!$deviceValue['approved']) continue;
$allSubDevicesData = SubDeviceManager::getAllSubDevices($deviceValue['device_id']);
foreach ($allSubDevicesData as $subDeviceKey => $subDeviceValue) {
$approvedSubDevices[$subDeviceValue['subdevice_id']] = [
'name' => $allDevicesData[$deviceKey]['name'],
'type' => $subDeviceValue['type'],
'masterDevice' => $subDeviceValue['device_id'],
];
}
}
$template = new Template('automation');
$template->prepare('baseDir', BASEDIR);
$template->prepare('debugMod', DEBUGMOD);
$template->prepare('title', 'Automation');
$template->prepare('langMng', $langMng);
$template->prepare('userManager', $userManager);
$template->prepare('automations', $automations);
$template->prepare('subDevices', $approvedSubDevices);
$template->render();
}
}

63
app/views/Log.php Normal file
View File

@ -0,0 +1,63 @@
<?php
class Log extends Template
{
//TODO: to server manager
function getSystemMemInfo()
{
$data = explode("\n", file_get_contents("/proc/meminfo"));
$meminfo = array();
foreach ($data as $line) {
$data = explode(":", $line);
if (count($data)!=2) continue;
$meminfo[$data[0]] = trim($data[1]);
}
return $meminfo;
}
function __construct()
{
global $userManager;
global $langMng;
if (!$userManager->isLogin()){
header('Location: ' . BASEURL . 'login');
}
$template = new Template('log');
$template->prepare('title', 'Log');
$result = array();
$cdir = scandir('../logs/');
foreach ($cdir as $key => $value)
{
if (!in_array($value,array(".","..", ".gitkeep")))
{
$result[$value] = $value;
}
}
$template->prepare('baseDir', BASEDIR);
$template->prepare('debugMod', DEBUGMOD);
$template->prepare('logToLiveTime', LOGTIMOUT);
$template->prepare('title', 'Logy');
$template->prepare('logsFiles', $result);
$template->prepare('langMng', $langMng);
$template->prepare('CPU', sys_getloadavg()[0]);
$template->prepare('UPTIME', shell_exec('uptime -p'));
$template->prepare('ramFree', $this->getSystemMemInfo()["MemFree"]);
$template->prepare('ramTotal', $this->getSystemMemInfo()["MemTotal"]);
$template->prepare('diskTotal', disk_total_space("/"));
$template->prepare('serverTime', date('m. d. Y H:i:s - e'));
$template->render();
}
}

22
app/views/Login.php Normal file
View File

@ -0,0 +1,22 @@
<?php
class Login extends Template
{
function __construct()
{
global $userManager;
global $lang;
if ($userManager->isLogin()){
header('Location: ' . BASEURL);
}
$template = new Template('login');
$template->prepare('baseDir', BASEDIR);
$template->prepare('title', 'Home');
$template->prepare('lang', $lang);
$template->render();
}
}

11
app/views/Logout.php Normal file
View File

@ -0,0 +1,11 @@
<?php
class Logout extends Template
{
function __construct()
{
global $userManager;
$userManager->logout();
header('Location: ' . BASEURL . 'login');
die();
}
}

62
app/views/Setting.php Normal file
View File

@ -0,0 +1,62 @@
<?php
class Setting extends Template
{
function __construct()
{
global $userManager;
global $langMng;
if (!$userManager->isLogin()){
header('Location: ' . BASEURL . 'login');
}
$automations = [];
$automationsData = AutomationManager::getAll();
foreach ($automationsData as $automationKey => $automationData) {
$automations[$automationData['automation_id']] = [
'name' => '',
'onDays' => $automationData['on_days'],
'ifSomething' => $automationData['if_something'],
'doSomething' => $automationData['do_something'],
];
}
$template = new Template('setting');
$template->prepare('baseDir', BASEDIR);
$template->prepare('debugMod', DEBUGMOD);
$template->prepare('title', 'Automation');
$template->prepare('langMng', $langMng);
$template->prepare('automations', $automations);
$users = $userManager->getUsers();
foreach ($users as $key => $value) {
$users[$key]['gavatar_url'] = $userManager->getAvatarUrl($value['user_id']);
}
$template->prepare('users', $users);
$template->prepare('userName', $userManager->getUserData('username'));
$template->prepare('userEmail', $userManager->getUserData('email'));
$template->prepare('userAvatarUrl', $userManager->getAvatarUrl());
if ($userManager->getUserData('ota') == ''){
$ga = new PHPGangsta_GoogleAuthenticator();
$otaSecret = $ga->createSecret();
$qrCodeUrl = $ga->getQRCodeGoogleUrl('Smart Home', $otaSecret);
$oneCode = $ga->getCode($otaSecret);
$template->prepare('qrUrl', $qrCodeUrl);
$template->prepare('otaSecret', $otaSecret);
$template->prepare('otaCode', $oneCode);
// echo "Secret is: ".$secret."\n\n";
// echo "Google Charts URL for the QR-Code: ".$qrCodeUrl."\n\n";
// echo "Checking Code '$oneCode' and Secret '$otaSecret':\n";
}
$rooms = RoomManager::getAllRooms();
$template->prepare('rooms', $rooms);
$template->render();
}
}

View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $this->title ?></title>
<link rel="stylesheet" href="css/main.css">
</head>
<body>
<header>
{HEADER}
</header>
<?php echo $this->content(); ?>
<footer>
{FOOTER}
</footer>
</body>
</html>

View File

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->prepare('baseDir', $BASEDIR);
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="row no-gutters main">
<div class="col-md-3 d-sm-none"></div>
<div class="col-md-3 nav-container">
<?php
$partial = new Partial('menu');
$partial->prepare('item','automation');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('debugMod',$DEBUGMOD);
$partial->render();
?>
</div>
<div class="col-md-9 main-body">
<a class="button is-primary m-1" onClick="$('#modal').removeClass('modal-container-hiden').show();"><?php $LANGMNG->echo('t_createAutomation'); ?></a>
<div class="row no-gutters">
<?php foreach ($AUTOMATIONS as $automationId => $automationData) {
//BUTTON
$partial = new Partial('automationButton');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('automationId',$automationId);
$partial->prepare('automationData',$automationData);
$partial->render();
//EDIT
$partial = new Partial('automationEdit');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('userManager',$USERMANAGER);
$partial->prepare('automationId',$automationId);
$partial->prepare('automation',$automationData);
$partial->prepare('subDevices',$SUBDEVICES);
$partial->render();
} ?>
</div>
</div>
</div>
<?php
if (isset($_POST['modalNext'])) {
$partial = new Partial('automationCreateFinal');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('userManager',$USERMANAGER);
$partial->prepare('subDevices',$SUBDEVICES);
$partial->render();
} else {
$partial = new Partial('automationCreate');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('subDevices',$SUBDEVICES);
$partial->render();
}?>
<script src="./app/templates/js/automation.js"></script>
<?php
$partial = new Partial('footer');
$partial->render();
?>
</body>
</html>

View File

@ -0,0 +1 @@
Example template

View File

@ -0,0 +1,70 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->prepare('baseDir', $BASEDIR);
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="row no-gutters main">
<div class="col-md-3 d-sm-none"></div>
<div class="col-md-3 nav-container">
<?php
$partial = new Partial('menu');
$partial->prepare('item', 'log');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('debugMod',$DEBUGMOD);
$partial->render();
?>
</div>
<div class="col-md-9 main-body">
<div class="col-12 col-sm-9 mx-auto mt-4">
<label><?php echo $LANGMNG->get('l_logMaxLiveTime') . " " . $LOGTOLIVETIME . " days";?></label></br>
<label>CPU: <?php echo $CPU;?></label></br>
<progress value="<?php echo $CPU;?>" max="1"> <?php echo $RAMFREE;?> </progress></br>
<label>UPTIME: <?php echo $UPTIME;?></label></br>
<label>RAM TOTAL: <?php echo $RAMTOTAL;?></label></br>
<label>RAM FREE: <?php echo $RAMFREE;?></label></br>
<progress value="<?php echo explode(" ", $RAMFREE)[0];?>" max="<?php echo explode(" ", $RAMTOTAL)[0];?>"> <?php echo $RAMFREE;?> </progress></br>
<label>DISKTOTAL: <?php echo $DISKTOTAL;?> bytes available</label></br>
<label>SERVER TIME: <?php echo $SERVERTIME;?></label></br>
<form method="post" action="">
<div class="field">
<select class="input" name="LogFile">
<?php foreach ($LOGSFILES as $key => $value) { ?>
<option value="<?php echo $value; ?>"><?php echo $value; ?></option>
<?php } ?>
</select>
</div>
<div class="field">
<input type="submit" class="button" name="selectFile" value="<?php $LANGMNG->echo('b_select');?>"/>
</div>
</form>
<?php
if (isset($_POST['LogFile'])) {
$file_lines = file('./app/logs/' . $_POST['LogFile']);
echo '<pre style="overflow: auto;">';
foreach ($file_lines as $line) {
echo $line;
}
echo '</pre>';
}
?>
</div>
</div>
<?php
$partial = new Partial('footer');
$partial->render();
//TODO js do main.js
?>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<?php
if (isset($ota) && $ota != '') {
$partial = new Partial('loginOta');
$partial->prepare('ota',$ota);
$partial->render();
} else {
$partial = new Partial('loginForm');
$partial->render();
}
?>
<?php
$partial = new Partial('footer');
$partial->render();
?>
</body>
</html>

View File

@ -0,0 +1,70 @@
<div class="col-12 col-md-6 col-xl-4 square-wrap">
<div class="rectangle-2">
<div class="square-content double <?php echo ($AUTOMATIONDATA['active'] == 0 ? 'is-inactive' : ''); ?>" id="automation-<?php echo $AUTOMATIONID; ?>">
<div class="row">
<div class="col-1">
<h5 class="fa">
<?php
//echo $AUTOMATIONDATA['ifSomething'];
$ifCode = json_decode($AUTOMATIONDATA['ifSomething']);
switch ($ifCode->type) {
case 'sunSet':
echo'&#xf186';
break;
case 'sunRise':
echo'&#xf185 ';
break;
case 'inHome':
echo'&#xf090';
break;
case 'outHome':
echo'&#xf08b';
break;
case 'outDevice':
echo'&#xf2db';
break;
default:
echo'&#xf017';
break;
}
?>
</h5>
</div>
<div class="col">
<h5 class="text-right break-all">
<?php
/*if (!in_array($AUTOMATIONDATA['ifSomething'], ["sunRise", "sunSet"])) {
echo $AUTOMATIONDATA['ifSomething'];
}*/
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>

View File

@ -0,0 +1,69 @@
<div class="modal-container modal-container-hiden" id="modal">
<div class="modal">
<a href=""><i class="fa fa-times close"></i></a>
<h4 class="mb-4"><?php $LANGMNG->echo('t_createAutomation')?></h4>
<form method="post" action="" >
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_nameAt')?></div>
<div class="field">
<input class="input" type="text" name="name" required/>
</div>
<div class="label"><?php $LANGMNG->echo('l_runAt')?></div>
<div class="field">
<select class="input" name="atSelector" id="valueSelector" required>
<option value="sunSet"><?php $LANGMNG->echo('l_sunSet')?></option>
<option value="sunRise"><?php $LANGMNG->echo('l_sunRice')?></option>
<option value="inHome"><?php $LANGMNG->echo('l_inHome')?></option>
<option value="outHome"><?php $LANGMNG->echo('l_outHome')?></option>
<option value="time"><?php $LANGMNG->echo('l_time')?></option>
<option value="atDeviceValue"><?php $LANGMNG->echo('l_deviceValue');?></option>
<option value="noOneHome"><?php $LANGMNG->echo('w_noOne') . ' ' . $LANGMNG->get('w_neni') . ' ' . $LANGMNG->get('w_home');?></option>
<option value="someOneHome"><?php $LANGMNG->echo('w_someOne') . ' ' . $LANGMNG->get('w_is') . ' ' . $LANGMNG->get('w_home');?></option>
</select>
<input class="input" type="time" name="atTime" id="atTime" disabled/>
<select class="input" name="atDeviceValue" id="atDeviceValue" disabled>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="num" name="atDeviceValueInt" id="atDeviceValueInt" required disabled/>
</div>
<div class="label"><?php $LANGMNG->echo('l_affectedDevices')?></div>
<div class="field">
<select class="input" name="devices[]" multiple>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){
if ($subDeviceValue['type'] != 'on/off') continue;?>
<option value="<?php echo $subDeviceValue['masterDevice']; ?>"><?php echo $subDeviceValue['name']; ?></option>
<?php } ?>
</select>
</div>
<div class="label"><?php $LANGMNG->echo('l_atDays')?></div>
<div class="field">
<input type="checkbox" name="day[]" value="mon"/> <?php $LANGMNG->echo('d_monday'); ?>
</div>
<div class="field">
<input type="checkbox" name="day[]" value="tue"/> <?php $LANGMNG->echo('d_tuesday'); ?>
</div>
<div class="field">
<input type="checkbox" name="day[]" value="wed"/> <?php $LANGMNG->echo('d_wednesday'); ?>
</div>
<div class="field">
<input type="checkbox" name="day[]" value="thu"/> <?php $LANGMNG->echo('d_thursday'); ?>
</div>
<div class="field">
<input type="checkbox" name="day[]" value="fri"/> <?php $LANGMNG->echo('d_friday'); ?>
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sat"/> <?php $LANGMNG->echo('d_saturday'); ?>
</div>
<div class="field">
<input type="checkbox" name="day[]" value="sun"/> <?php $LANGMNG->echo('d_sunday'); ?>
</div>
</div>
<input type="submit" class="button" name="modalNext" value="<?php $LANGMNG->echo('b_next')?>"/>
</form>
</div>
</div>

View File

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

View File

@ -0,0 +1,85 @@
<div class="modal-container modal-container-hiden" id="modal-setting-<?php echo $AUTOMATIONID; ?>">
<div class="modal">
<div class="close">
<i class="fa fa-times"></i>
</div>
<h4 class="mb-4"><?php $LANGMNG->echo('t_createAutomation');?></h4>
<form method="post">
<input type="hidden" name="action" value="edit" required/>
<input name="automation_id" type="hidden" value="<?php echo $AUTOMATIONID; ?>">
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_nameAt');?></div>
<div class="field">
<input class="input" type="text" name="name" value="<?php echo (isset ($AUTOMATION['name']) ? $AUTOMATION['name'] : ""); ?>" required/>
</div>
<div class="label"><?php $LANGMNG->echo('l_runAt');?></div>
<div class="field">
<?php //TODO Dodělat identifikaci pro Selctor události a selector času zařízení hodnoty ?>
<select class="input" name="atSelector" id="valueSelector" required>
<option value="sunSet" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "sunSet" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_sunSet');?></option>
<option value="sunRise" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "sunRise" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_sunRice');?></option>
<option value="inHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "inHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_inHome');?></option>
<option value="outHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "outHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_outHome');?></option>
<option value="time" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "time" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_time');?></option>
<option value="atDeviceValue" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "atDeviceValue" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('l_deviceValue');;?></option>
<option value="noOneHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "noOneHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('w_noOne'); echo ' ' . $LANGMNG->get('w_neni') . ' ' . $LANGMNG->get('w_home');?></option>
<option value="someOneHome" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "someOneHome" ? 'selected="selected"' : ''); ?>><?php $LANGMNG->echo('w_someOne'); echo ' ' . $LANGMNG->get('w_is') . ' ' . $LANGMNG->get('w_home');?></option>
</select>
<input class="input" type="time" name="atTime" id="atTime" value="<?php echo (json_decode($AUTOMATION['ifSomething'], true)['type'] == "time" ? json_decode($AUTOMATION['ifSomething'], true)['value'] : ""); ?>" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "time" ? '' : 'disabled'); ?>/>
<select class="input" name="atDeviceValue" id="atDeviceValue" <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "atDeviceValue" ? '' : 'disabled'); ?>>
<?php foreach ($SUBDEVICES as $subDeviceKey => $subDeviceValue){ ?>
<option value="<?php echo $subDeviceKey; ?>"><?php echo $subDeviceValue['name']; ?>[<?php echo $subDeviceValue['type']; ?>]</option>
<?php } ?>
</select>
=
<input class="input" type="text" name="atDeviceValueInt" id="atDeviceValueInt" required <?php ECHO (json_decode($AUTOMATION['ifSomething'], true)['type'] == "atDeviceValue" ? '' : 'disabled'); ?>/>
</div>
<div class="label"><?php $LANGMNG->echo('l_affectedDevices'); ?></div>
<div class="field">
<div class="field px-2">
<?php
$i = 0;
foreach($AUTOMATION['doSomething'] as $subDeviceId => $subDeviceData){ ?>
<div id="automation-<?php echo $AUTOMATIONID; ?>-content">
<div class="label"><?php echo $subDeviceData['name']; ?></div>
<select class="input" name="device[<?php echo $subDeviceId; ?>]">
<option value="0" <?php echo ($subDeviceData['state'] == "0" ? 'selected="selected"' : ''); ?>>off</option>
<option value="1" <?php echo ($subDeviceData['state'] == "1" ? 'selected="selected"' : ''); ?>>on</option>
</select>
<button name="remove" type="button" class="button is-danger fa" data-automation-id="<?php echo $AUTOMATIONID; ?>">&#xf1f8;</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>

View File

@ -0,0 +1,5 @@
<script src="./app/templates/js/jquery.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.1.0/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.1.0/firebase-messaging.js"></script>
<script src="./app/templates/js/script.js"></script>
<script src="./app/templates/js/post.js"></script>

View File

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

View File

@ -0,0 +1,20 @@
<div class="modal-container">
<div class="modal">
<h4 class="mb-4">Login</h4>
<form method="post">
<div class="field">
<div class="label">Name:</div>
<input class="input" type="text" name="username" placeholder="Jméno.."/>
</div>
<div class="field">
<div class="label">Password:</div>
<input class="input" type="password" name="password" placeholder="Heslo.."/>
</div>
<div class="field">
<div class="label">Remember me:</div>
<input class="" type="checkbox" name="remember" value="true"/>
</div>
<input type="submit" class="button" name="login" value="Login"/>
</form>
</div>
</div>

View File

@ -0,0 +1,13 @@
<div class="modal-container">
<div class="modal">
<h4 class="mb-4">OTA</h4>
<form method="post">
<input type="hidden" name="otaSecret" value="<?php echo $OTA; ?>"/>
<div class="field">
<div class="label">Code:</div>
<input class="input" type="text" name="otaCode" placeholder=""/>
</div>
<input type="submit" class="button" name="login" value="Login"/>
</form>
</div>
</div>

View File

@ -0,0 +1,35 @@
<div class="nav">
<?php
$menuItems = [
'fa-wrench' => [
'slug' => 'setting',
'lngKey' => 'settings',
'path' => 'setting',
],
'fa-calendar-o' => [
'slug' => 'automation',
'lngKey' => 'automatization',
'path' => 'automation',
],
'fa-bug' =>[
'slug' => 'log',
'lngKey' => 'log',
'path' => '',
],
];
foreach ( $menuItems as $key => $value) {
if ($DEBUGMOD == 0 && $value['path'] == 'log') {
continue;
}
?>
<div class="nav-item <?php echo ($ITEM == $value ? 'is-active' : ''); ?>">
<a href="<?php echo $value['path']?>">
<i class="fa <?php echo $key ?>"></i>
<span>
<?php $LANGMNG->echo('m_'.$value['lngKey']); ?>
</span>
</a>
</div>
<?php }?>
</div>

View File

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

View File

@ -0,0 +1,203 @@
<!DOCTYPE html>
<html lang="en">
<head>
<?php
$partial = new Partial('head');
$partial->prepare('baseDir', $BASEDIR);
$partial->render();
?>
<title><?php echo $TITLE ?></title>
</head>
<body class="no-transitions">
<div class="row no-gutters main">
<div class="col-md-3 d-sm-none"></div>
<div class="col-md-3 nav-container">
<?php
$partial = new Partial('menu');
$partial->prepare('item', 'setting');
$partial->prepare('langMng',$LANGMNG);
$partial->prepare('debugMod',$DEBUGMOD);
$partial->render();
?>
</div>
<div class="col-md-9 main-body">
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4">
<?php $LANGMNG->echo('t_pageAfterLogIn') ?>
</h4>
<form method="post" enctype="multipart/form-data">
<div class="">
<div class="field">
<select class="input" name="loadPage">
<option value="0" <?php echo (UserManager::getUserData("startPage") == 0 ? "selected" : ""); ?>>Default</option>
<option value="1" <?php echo (UserManager::getUserData("startPage") == 1 ? "selected" : ""); ?>>Dashboard</option>
</select>
</div>
<input type="submit" name="submit" class="button" value="<?php $LANGMNG->echo('b_save') ?>"/>
</div>
</div>
</form>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php $LANGMNG->echo('t_profile') ?></h4>
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_userAvatar') ?>:</div>
<img src="<?php echo $USERAVATARURL; ?>" />
<div class="label">* providet by Gavatar</div>
</div>
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_userName') ?>:</div>
<input class="input" value="<?php echo $USERNAME; ?>" disabled>
</div>
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_userEmail') ?>:</div>
<input class="input" value="<?php echo $USEREMAIL; ?>" disabled>
</div>
<div class="field">
<a href="logout" class="button is-primary"><?php $LANGMNG->echo('b_logOut') ?></a>
</div>
</div>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php $LANGMNG->echo('t_notification') ?></h4>
<input id="notifications" type="checkbox" onChange="toggleNotificationPermissions(this);" />
<div class="label"><?php $LANGMNG->echo('l_notificationStatus') ?></div>
<div class="field">
<a onClick="sendTestNotification();" class="button"><?php $LANGMNG->echo('b_sendTestNotification');?></a>
</div>
</div>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php $LANGMNG->echo('t_experimental') ?></h4>
<div class="field">
<a href="rooms" class="button"><?php $LANGMNG->echo('b_rooms') ?></a>
</div>
</div>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php $LANGMNG->echo('t_changePassword') ?></h4>
<form method="post">
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_oldPassword') ?>:</div>
<input type="password" class="input" name="oldPassword" value="" data-cip-id="cIPJQ342845639">
</div>
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_newPassword') ?>:</div>
<input type="password" class="input" name="newPassword1" value="">
</div>
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_newPassword') ?>:</div>
<input type="password" class="input" name="newPassword2" value="">
</div>
<div class="field">
<input type="submit" name="submitPasswordChange" class="button" value="Uložit">
</div>
</form>
</div>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php $LANGMNG->echo('t_ota') ?></h4>
<?php if (!empty($QRURL)) {?>
<img src="<?php echo $QRURL;?>" />
<?php echo $OTACODE; ?>
<form method="post" action="setting">
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_gooleAutenticatorOtaCode') ?>:</div>
<input type="text" class="input" name="otaCode" value="" required>
<input type="hidden" class="input" name="otaSecret" value="<?php echo $OTASECRET;?>" required>
</div>
<div class="field">
<input type="submit" name="submitEnableOta" class="button" value="Uložit">
</div>
</form>
<?php } else {?>
<button name="deactivateOta" type="button" class="button is-danger fa"><?php $LANGMNG->echo('b_disable');?> <?php $LANGMNG->echo('b_ota'); ?></button>
<?php }?>
</div>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php $LANGMNG->echo('t_listUsers') ?></h4>
<table class="table is-fluid">
<thead>
<tr>
<th><?php $LANGMNG->echo('t_avatar');?></th>
<th><?php $LANGMNG->echo('t_userName');?></th>
<th><?php $LANGMNG->echo('t_ota');?></th>
<th><?php $LANGMNG->echo('t_action');?></th>
</tr>
</thead>
<tbody>
<?php foreach ($USERS as $key => $user) { ?>
<tr>
<td><img src="<?php echo $user['gavatar_url']; ?>" /></td>
<td><?php echo $user['username']; ?></td>
<td><?php echo ($user['ota'] ? '<span class="fa">&#xf00c;</span>' : ''); ?></td>
<td><button name="deleteUser" type="button" class="button is-danger fa">&#xf1f8;</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">&#xf1f8;</button>
<button name="defaultRoom" type="button" class="button fa" <?php echo ($room['default'] ? 'disabled' : ''); ?>>&#xf140;</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>

View File

@ -0,0 +1,11 @@
<!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>
</head>
<body>
<?php echo $this->content(); ?>
</body>
</html>

34
library/Partial.php Normal file
View File

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

View File

@ -0,0 +1,252 @@
<?php
/**
* PHP Class for handling Google Authenticator 2-factor authentication.
*
* @author Michael Kliewe
* @copyright 2012 Michael Kliewe
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*
* @link http://www.phpgangsta.de/
*/
class PHPGangsta_GoogleAuthenticator
{
protected $_codeLength = 6;
/**
* Create new secret.
* 16 characters, randomly chosen from the allowed base32 characters.
*
* @param int $secretLength
*
* @return string
*/
public function createSecret($secretLength = 16)
{
$validChars = $this->_getBase32LookupTable();
// Valid secret lengths are 80 to 640 bits
if ($secretLength < 16 || $secretLength > 128) {
throw new Exception('Bad secret length');
}
$secret = '';
$rnd = false;
if (function_exists('random_bytes')) {
$rnd = random_bytes($secretLength);
} elseif (function_exists('mcrypt_create_iv')) {
$rnd = mcrypt_create_iv($secretLength, MCRYPT_DEV_URANDOM);
} elseif (function_exists('openssl_random_pseudo_bytes')) {
$rnd = openssl_random_pseudo_bytes($secretLength, $cryptoStrong);
if (!$cryptoStrong) {
$rnd = false;
}
}
if ($rnd !== false) {
for ($i = 0; $i < $secretLength; ++$i) {
$secret .= $validChars[ord($rnd[$i]) & 31];
}
} else {
throw new Exception('No source of secure random');
}
return $secret;
}
/**
* Calculate the code, with given secret and point in time.
*
* @param string $secret
* @param int|null $timeSlice
*
* @return string
*/
public function getCode($secret, $timeSlice = null)
{
if ($timeSlice === null) {
$timeSlice = floor(time() / 30);
}
$secretkey = $this->_base32Decode($secret);
// Pack time into binary string
$time = chr(0).chr(0).chr(0).chr(0).pack('N*', $timeSlice);
// Hash it with users secret key
$hm = hash_hmac('SHA1', $time, $secretkey, true);
// Use last nipple of result as index/offset
$offset = ord(substr($hm, -1)) & 0x0F;
// grab 4 bytes of the result
$hashpart = substr($hm, $offset, 4);
// Unpak binary value
$value = unpack('N', $hashpart);
$value = $value[1];
// Only 32 bits
$value = $value & 0x7FFFFFFF;
$modulo = pow(10, $this->_codeLength);
return str_pad($value % $modulo, $this->_codeLength, '0', STR_PAD_LEFT);
}
/**
* Get QR-Code URL for image, from google charts.
*
* @param string $name
* @param string $secret
* @param string $title
* @param array $params
*
* @return string
*/
public function getQRCodeGoogleUrl($name, $secret, $title = null, $params = array())
{
$width = !empty($params['width']) && (int) $params['width'] > 0 ? (int) $params['width'] : 200;
$height = !empty($params['height']) && (int) $params['height'] > 0 ? (int) $params['height'] : 200;
$level = !empty($params['level']) && array_search($params['level'], array('L', 'M', 'Q', 'H')) !== false ? $params['level'] : 'M';
$urlencoded = urlencode('otpauth://totp/'.$name.'?secret='.$secret.'');
if (isset($title)) {
$urlencoded .= urlencode('&issuer='.urlencode($title));
}
return "https://api.qrserver.com/v1/create-qr-code/?data=$urlencoded&size=${width}x${height}&ecc=$level";
}
/**
* Check if the code is correct. This will accept codes starting from $discrepancy*30sec ago to $discrepancy*30sec from now.
*
* @param string $secret
* @param string $code
* @param int $discrepancy This is the allowed time drift in 30 second units (8 means 4 minutes before or after)
* @param int|null $currentTimeSlice time slice if we want use other that time()
*
* @return bool
*/
public function verifyCode($secret, $code, $discrepancy = 1, $currentTimeSlice = null)
{
if ($currentTimeSlice === null) {
$currentTimeSlice = floor(time() / 30);
}
if (strlen($code) != 6) {
return false;
}
for ($i = -$discrepancy; $i <= $discrepancy; ++$i) {
$calculatedCode = $this->getCode($secret, $currentTimeSlice + $i);
if ($this->timingSafeEquals($calculatedCode, $code)) {
return true;
}
}
return false;
}
/**
* Set the code length, should be >=6.
*
* @param int $length
*
* @return PHPGangsta_GoogleAuthenticator
*/
public function setCodeLength($length)
{
$this->_codeLength = $length;
return $this;
}
/**
* Helper class to decode base32.
*
* @param $secret
*
* @return bool|string
*/
protected function _base32Decode($secret)
{
if (empty($secret)) {
return '';
}
$base32chars = $this->_getBase32LookupTable();
$base32charsFlipped = array_flip($base32chars);
$paddingCharCount = substr_count($secret, $base32chars[32]);
$allowedValues = array(6, 4, 3, 1, 0);
if (!in_array($paddingCharCount, $allowedValues)) {
return false;
}
for ($i = 0; $i < 4; ++$i) {
if ($paddingCharCount == $allowedValues[$i] &&
substr($secret, -($allowedValues[$i])) != str_repeat($base32chars[32], $allowedValues[$i])) {
return false;
}
}
$secret = str_replace('=', '', $secret);
$secret = str_split($secret);
$binaryString = '';
for ($i = 0; $i < count($secret); $i = $i + 8) {
$x = '';
if (!in_array($secret[$i], $base32chars)) {
return false;
}
for ($j = 0; $j < 8; ++$j) {
$x .= str_pad(base_convert(@$base32charsFlipped[@$secret[$i + $j]], 10, 2), 5, '0', STR_PAD_LEFT);
}
$eightBits = str_split($x, 8);
for ($z = 0; $z < count($eightBits); ++$z) {
$binaryString .= (($y = chr(base_convert($eightBits[$z], 2, 10))) || ord($y) == 48) ? $y : '';
}
}
return $binaryString;
}
/**
* Get array with all 32 characters for decoding from/encoding to base32.
*
* @return array
*/
protected function _getBase32LookupTable()
{
return array(
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 7
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 15
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 23
'Y', 'Z', '2', '3', '4', '5', '6', '7', // 31
'=', // padding char
);
}
/**
* A timing safe equals comparison
* more info here: http://blog.ircmaxell.com/2014/11/its-all-about-time.html.
*
* @param string $safeString The internal (safe) value to be checked
* @param string $userString The user submitted (unsafe) value
*
* @return bool True if the two strings are identical
*/
private function timingSafeEquals($safeString, $userString)
{
if (function_exists('hash_equals')) {
return hash_equals($safeString, $userString);
}
$safeLen = strlen($safeString);
$userLen = strlen($userString);
if ($userLen != $safeLen) {
return false;
}
$result = 0;
for ($i = 0; $i < $userLen; ++$i) {
$result |= (ord($safeString[$i]) ^ ord($userString[$i]));
}
// They are only identical strings if $result is exactly 0...
return $result === 0;
}
}

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

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

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