32 Commits

Author SHA1 Message Date
GamerClassN7
9d9304d30e Automation Fix 2021-02-24 17:20:49 +01:00
GamerClassN7
c6f57a3661 Damejídlo Value Fix 2021-02-24 17:20:35 +01:00
GamerClassN7
adfb564ccc Automation create Auth enable 2021-02-23 12:41:48 +01:00
GamerClassN7
a3eaf16fd6 Automation Endpoints Create 2021-02-23 12:41:34 +01:00
8b32ecc619 Automation API #FIX 2021-02-17 08:41:08 +01:00
7ea4a90980 Automations Endpoint Detail + Cron Endpoint 2021-02-16 14:59:27 +01:00
38b29a2a4a Automation api Endpoint 2021-02-16 14:28:31 +01:00
821c0926e8 DB Backup Plugin Sync Time Setting Fields 2021-02-15 14:18:44 +01:00
3d3b073131 Synch 2021-02-15 14:03:29 +01:00
GamerClassN7
485709d61f Git Stats + Remove Empty Rooms 2021-02-14 20:13:29 +01:00
GamerClassN7
1d44bd62e2 Pugins Fixes + Dame Jídlo Fix 2021-02-10 16:13:22 +01:00
GamerClassN7
75dab33c9a Repository Statistic 2021-02-10 16:12:51 +01:00
2410441b88 Keep record of record origin 2021-02-02 12:47:41 +01:00
GamerClassN7
1f49391b36 Google Home api Fix 2021-01-24 19:56:53 +01:00
haitem
c17e3090a8 repairt bug 2021-01-15 13:38:47 +01:00
dc77534bad Weather notifications 2021-01-07 18:02:01 +01:00
GamerClassN7
cb45cf9e22 Fixes 2021-01-06 19:23:12 +01:00
GamerClassN7
47a5f71d9b Tweeks 2021-01-05 21:35:12 +01:00
GamerClassN7
1642ece7f4 Subscribe 2021-01-05 20:27:53 +01:00
696ff07987 Fixes 2021-01-05 13:24:52 +01:00
Haitem
1415c0cf2d Repair Historie sorting 2021-01-05 13:01:06 +01:00
Haitem
d9952a59fb Merge branch 'remastering' of https://git.steelants.cz/SH/PHP_SMART_HOME_V3 into remastering 2021-01-05 12:19:41 +01:00
Haitem
b5b2bb95a7 Fix sorting room, fix form sending after sorting and add column Historie 2021-01-05 12:19:30 +01:00
bad58f82e2 Few Fixes in Database backup Plugin 2021-01-05 10:37:32 +01:00
GamerClassN7
64b50ead9f Notifications 2021-01-04 17:08:56 +01:00
GamerClassN7
a3a87d39d2 Fixes 2021-01-04 16:51:34 +01:00
GamerClassN7
c4f36235ab Google Home Heater controll Fix 2020-12-25 15:59:13 +01:00
daa0e0a2c5 Settings Save Mechanism an few fixes 2020-12-23 15:57:12 +01:00
GamerClassN7
464f229a16 Add Open Weather Settings 2020-12-17 19:42:29 +01:00
GamerClassN7
fe72097d75 Show Plugin Settings 2020-12-17 19:41:59 +01:00
GamerClassN7
98efb779b1 comment 2020-12-17 19:17:05 +01:00
30045b9f65 Merge pull request 'feature/bootstrap' (#2) from feature/bootstrap into remastering
Reviewed-on: #2
2020-12-15 21:22:52 +00:00
39 changed files with 830 additions and 505 deletions

1
.gitignore vendored
View File

@@ -2,6 +2,7 @@
.ftpconfig
.ftpconfig2
*.log
*.bin
config.php
_nemazat/index.html

View File

@@ -136,6 +136,17 @@ Distributed under the MIT License. See `LICENSE` for more information.
Project Link: [https://github.com/GamerClassN7/Smart_Home/](https://github.com/GamerClassN7/Smart_Home/) <br> <br>
<sup><sub>Tags (ignore): ESP32 ESP12 ESP08 ESP01 ESP Smart Home Automation System PWA PHP HTML JS DHT11 DHT22
## Code Statistics
Type | Files | Lines
-----|-------|-----------
php | 2 | 2298 (89%)
md | 1 | 171 (7%)
js | 1 | 64 (2%)
sh | 1 | 34 (1%)
json | 1 | 10 (0.4%)
-----|-------|-----------
All | 6 | 2577
## Folder structure
```
- /app # app specific files

View File

@@ -19,40 +19,58 @@ $router->any('/logout', 'Logout');
$router->any('/automation', 'Automation');
$router->any('/setting', 'Setting');
$router->any('/device', 'Device');
$router->get('/device/{sortBy}/{sortType}', 'Device');
$router->any('/device/{sortBy}/{sortType}', 'Device');
$router->any('/plugins', 'Plugins');
$router->any('/ajax', 'Ajax');
$router->any('/oauth', 'Oauth');
//Vue APP
//Vue APP - Authentication
$router->post('/api/login', 'AuthApi@login');
$router->post('/api/logout', 'AuthApi@logout');
//Vue APP - Rooms
$router->get('/api/rooms', 'RoomsApi@default');
$router->get('/api/rooms/{roomId}/update', 'RoomsApi@update');
$router->get('/api/devices', 'DevicesApi@default');
$router->get('/api/plugins', 'PluginsApi@default');
$router->get('/api/users', 'UsersApi@default');
//Vue APP - Server Info
$router->get('/api/server', 'ServerApi@default');
$router->get('/api/server/log', 'ServerApi@logStatus');
//Vue APP - Widgets
$router->post('/api/widgets/{widgetId}/run', 'WidgetApi@run');
$router->get('/api/widgets/{widgetId}/detail', 'WidgetApi@detail');
$router->get('/api/widgets/{widgetId}/detail/{period}', 'WidgetApi@detail');
//Vue APP - Automations Endpoints
$router->get('/api/automations', 'AutomationsApi@default');
$router->get('/api/automations/{automationId}/detail', 'AutomationsApi@detail');
$router->post('/api/automations/create', 'AutomationsApi@create');
//cron
$router->post('/cron/clean', 'CronApi@clean');
$router->post('/cron/fetch', 'CronApi@fetch');
$router->post('/cron/automations', 'CronApi@automations');
//Google Home - API
$router->any('/api/HA/auth', 'Oauth');
$router->any('/api/HA', 'GoogleHomeApi@response');
//Endpoints API
$router->post('/api/endpoint/', 'EndpointsApi@default');
$router->any('/api/update/', 'UpdatesApi@default');
$router->any('/api/users/status', 'UsersApi@status');
$router->any('/api/users/subscribe', 'UsersApi@subscribe');
// examples
$router->any('/api/example', 'ExampleApi@example');

View File

@@ -0,0 +1,44 @@
<?php
class AutomationsApi extends ApiController
{
public function default()
{
//$this->requireAuth();
$response = [];
$response = AutomationManager::getAll(["automation_id","name","enabled"]);
$this->response($response);
}
public function detail($automationId)
{
//$this->requireAuth();
$response = [];
$response = AutomationManager::getById($automationId, ["automation_id", "last_execution_time", "owner_id", "conditions", "tasks"]);
$this->response($response);
}
public function create()
{
$this->requireAuth();
$obj = $this->input;
if (
empty($obj['name']) ||
!isset($obj['name']) ||
!isset($obj['conditions']) ||
!isset($obj['tasks']) ||
!isset($obj['days'])
) {
throw new Exception("Invalid request payload", 400);
}
$response = [];
$response = AutomationManager::create($obj['name'],json_encode($obj['days']), json_encode($obj['tasks']), json_encode($obj['conditions']));
$this->response(['value'=>'OK']);
}
}

View File

@@ -12,11 +12,15 @@ class CronApi extends ApiController
$backupWorker = new DatabaseBackup();
$backupWorker->purge(5);
//Old Records Cleanup
foreach (SubDeviceManager::getAllSubDevices() as $key => $value) {
RecordManager::setHistory($value['subdevice_id']);
}
$this->response(['Value' => 'OK']);
}
public function fetch()
{
public function fetch(){
//Run Plugins
$result = [];
$dir = $_SERVER['DOCUMENT_ROOT'] . BASEDIR . 'app/plugins/';
@@ -55,4 +59,9 @@ class CronApi extends ApiController
//Print Result
$this->response($result);
}
public function automations(){
AutomationManager:executeAll();
$this->response(['Value' => 'OK']);
}
}

View File

@@ -7,11 +7,9 @@ class DevicesApi extends ApiController{
$response = [];
// TODO: process the request
$this->response($response);
}
public function getDevicesByRoom($roomId){
}
}

View File

@@ -62,6 +62,7 @@ class EndpointsApi extends ApiController{
}
$device = DeviceManager::getDeviceByToken($obj['token']);
DeviceManager::setHeartbeat($device['device_id']);
//Diagnostic
if (isset($obj['settings'])){
@@ -77,7 +78,9 @@ class EndpointsApi extends ApiController{
foreach ($obj['logs'] as $log) {
$deviceLogManager = new LogManager('../logs/devices/'. date("Y-m-d").'.log');
$deviceLogManager->setLevel(LOGLEVEL);
if ($log != 'HTTP_UPDATE_FAILD code-102 messageFile Not Found (404)'){
$deviceLogManager->write("[Device Log Msg] Device_ID " . $device['device_id'] . "->" . $log, LogRecordTypes::ERROR);
}
unset($deviceLogManager);
}
$this->response([
@@ -112,7 +115,7 @@ class EndpointsApi extends ApiController{
}
$subDeviceLastReordValue[$key] = $value['value'];
RecordManager::create($device['device_id'], $key, round($value['value'],3));
RecordManager::create($device['device_id'], $key, round($value['value'],3), 'device');
$logManager->write("[API] Device_ID " . $device['device_id'] . " writed value " . $key . ' ' . $value['value'], LogRecordTypes::INFO);
//notification

View File

@@ -54,6 +54,7 @@ class RoomsApi extends ApiController
foreach ($roomsData as $roomKey => $roomData) {
if ($roomData['device_count'] == 0) continue;
$subDevicesSorted = isset($subDevicesData[$roomData['room_id']]) ? Utilities::sortArrayByKey($subDevicesData[$roomData['room_id']], 'connection_error', 'asc') : [];
if (count($subDevicesSorted) == 0) continue;
$response[] = [
'room_id' => $roomData['room_id'],
'name' => $roomData['name'],

View File

@@ -34,4 +34,14 @@ class UsersApi extends ApiController{
}
$this->response(['value'=>'OK']);
}
public function subscribe(){
//$this->requireAuth();
$bearer = $_SERVER['HTTP_AUTHORIZATION'];
$authManager = new AuthManager();
$userId = $authManager->getUserId($bearer);
NotificationManager::addSubscriber($userId, $this->input['pushtoken']);
$this->response(['value'=>'OK']);
}
}

View File

@@ -14,7 +14,7 @@ class WidgetApi extends ApiController
$subDeviceData = SubDeviceManager::getSubDevice($subDeviceId);
if ($subDeviceData['type'] == 'on/off') {
$lastValue = RecordManager::getLastRecord($subDeviceData['subdevice_id'])['value'];
RecordManager::create($subDeviceData['device_id'], 'on/off', (int) !$lastValue);
RecordManager::create($subDeviceData['device_id'], 'on/off', (int) !$lastValue, "vue-app");
$response = !$lastValue;
} else {
throw new Exception("Bad Request", 403);

View File

@@ -1,6 +1,7 @@
<?php
if (!empty ($_POST)){
$deviceManager = new DeviceManager ();
$subDeviceManager = new SubDeviceManager ();
if (!empty ($_FILES['deviceFirmware']) && !empty ($_FILES['deviceFirmware']['tmp_name']) && !empty ($_POST['deviceId'])) {
$file = $_FILES['deviceFirmware'];
$deviceMac = $deviceManager->getDeviceById ($_POST['deviceId'])['mac'];
@@ -27,6 +28,9 @@ if (!empty ($_POST)){
if (!empty ($_POST['deviceName']) && !empty ($_POST['deviceId'])) {
$deviceManager->edit ($_POST['deviceId'], array ('name' => $_POST['deviceName']));
}
header('Location: ./device');
if (isset ($_POST['deviceHistory']) && !empty ($_POST['deviceId'])) {
$subDeviceManager->editSubDevicesByDevice($_POST['deviceId'], array ('history' => $_POST['deviceHistory']));
}
header('Location: ' . BASEURL . str_replace(BASEDIR, "", $_SERVER['REQUEST_URI']));
die();
}

View File

@@ -28,6 +28,17 @@ if (isset($_POST) && !empty($_POST)){
die();
} else if (isset ($_POST['userPermission']) && !empty ($_POST['userID'])) {
$userManager->setUserDataAdmin("permission", $_POST['userPermission'], $_POST['userID']);
header('Location: ' . BASEURL . 'setting');
die();
} else {
foreach ($_POST as $key => $value) {
if ($key == 'submit') continue;
$settingMng = new SettingsManager();
if ($settingMng->getByName($key)) {
$settingMng->update($key, $value);
}
}
header('Location: ' . BASEURL . 'setting');
die();
}

View File

@@ -1,6 +1,8 @@
<?php
class GoogleHome {
static function sync($requestId){
class GoogleHome
{
static function sync($requestId)
{
$devices = [];
$roomsData = RoomManager::getAllRooms();
foreach ($roomsData as $roomKey => $roomData) {
@@ -26,7 +28,7 @@ class GoogleHome {
}
}
if ($traids < 0){
if ($traids < 1) {
continue;
}
@@ -64,19 +66,21 @@ class GoogleHome {
echo json_encode($response);
}
static function query($requestId, $payload){
static function query($requestId, $payload)
{
$devices = [];
$num = 0;
foreach ($payload['devices'] as $deviceId) {
$subDevicesData = SubDeviceManager::getAllSubDevices($deviceId['id']);
$tempDevice[$deviceId['id']] = [
'online' => false,
'status' => 'OFFLINE',
];
if ($subDevicesData = SubDeviceManager::getAllSubDevices($deviceId['id'])) {
foreach ($subDevicesData as $key => $subDeviceData) {
$lastRecord = RecordManager::getLastRecord($subDeviceData['subdevice_id']);
if ($lastRecord['execuded'] == 1){
if ($lastRecord != false && $lastRecord['execuded'] == 1) {
$tempDevice[$deviceId['id']]['online'] = true;
$tempDevice[$deviceId['id']]['status'] = "SUCCESS";
} else {
@@ -121,11 +125,14 @@ class GoogleHome {
break;
}
}
}
if ($lastRecord['execuded'] == 1){
$online = true;
$status = 'SUCCESS';
} else {
// $lastRecord = RecordManager::getLastRecord($deviceId['id']);
// //var_dump($lastRecord);
// if ($lastRecord['execuded'] == 1) {
// $online = true;
// $status = 'SUCCESS';
// } else {
$executed = 0;
$waiting = 0;
foreach (RecordManager::getLastRecord($deviceId['id'], 6) as $key => $value) {
@@ -135,15 +142,16 @@ class GoogleHome {
$waiting++;
}
}
if ($waiting < $executed) {
$status = "PENDING";
$online = true;
}
}
// }
$devices = $tempDevice;
/*if (count($devices)> 1){
if (count($devices)> 1){
$devices[] = $tempDevice;
}*/
}
}
$response = [
'requestId' => $requestId,
@@ -157,7 +165,8 @@ class GoogleHome {
echo json_encode($response);
}
static function execute($requestId, $payload){
static function execute($requestId, $payload)
{
$commands = [];
foreach ($payload['commands'] as $key => $command) {
foreach ($command['devices'] as $key2 => $device) {
@@ -167,7 +176,8 @@ static function execute($requestId, $payload){
}
$deviceType = GoogleHomeDeviceTypes::getType($executionCommand['command']);
$subDeviceId = SubDeviceManager::getSubDeviceByMasterAndType($device['id'], $deviceType)['subdevice_id'];
if ($subDeviceId = SubDeviceManager::getSubDeviceByMasterAndType($device['id'], $deviceType)) {
$subDeviceId = $subDeviceId['subdevice_id'];
switch ($executionCommand['command']) {
case 'action.devices.commands.OnOff':
$commands[] = self::executeSwitch($subDeviceId, $executionCommand);
@@ -212,9 +222,10 @@ static function execute($requestId, $payload){
case 'action.devices.commands.mediaStop':
$commands[] = self::executeMediaCont($subDeviceId, $executionCommand);
break;
}
}
}
}
$response = [
'requestId' => $requestId,
@@ -230,14 +241,15 @@ static function execute($requestId, $payload){
echo json_encode($response);
}
static function executeSwitch($subDeviceId, $executionCommand){
static function executeSwitch($subDeviceId, $executionCommand)
{
$value = 0;
$status = 'OFFLINE';
$online = false;
if ($executionCommand['params']['on']) $value = 1;
RecordManager::createWithSubId($subDeviceId, $value);
RecordManager::createWithSubId($subDeviceId, $value, 'google');
$executed = 0;
$waiting = 0;
@@ -266,7 +278,8 @@ static function executeSwitch($subDeviceId, $executionCommand){
return $commandTemp;
}
static function executeTermostatValue($subDeviceId, $executionCommand){
static function executeTermostatValue($subDeviceId, $executionCommand)
{
$value = 0;
$status = 'OFFLINE';
$online = false;
@@ -275,7 +288,7 @@ static function executeTermostatValue($subDeviceId, $executionCommand){
$value = $executionCommand['params']['thermostatTemperatureSetpoint'];
}
RecordManager::createWithSubId($subDeviceId, $value);
RecordManager::createWithSubId($subDeviceId, $value, 'google');
$executed = 0;
$waiting = 0;
@@ -307,7 +320,8 @@ static function executeTermostatValue($subDeviceId, $executionCommand){
return $commandTemp;
}
static function executeTermostatMode($subDeviceId, $executionCommand){
static function executeTermostatMode($subDeviceId, $executionCommand)
{
$mode = "off";
$value = 0;
$status = 'OFFLINE';
@@ -318,7 +332,7 @@ static function executeTermostatMode($subDeviceId, $executionCommand){
$value = RecordManager::getLastRecordNotNull($subDeviceId)['value'];
}
RecordManager::createWithSubId($subDeviceId, $value);
RecordManager::createWithSubId($subDeviceId, $value, 'google');
$executed = 0;
$waiting = 0;
@@ -348,7 +362,8 @@ static function executeTermostatMode($subDeviceId, $executionCommand){
return $commandTemp;
}
static function executeVolume($subDeviceId, $executionCommand){
static function executeVolume($subDeviceId, $executionCommand)
{
//echo $executionCommand['params']['volumeLevel'];
$status = 'OFFLINE';
$online = false;
@@ -386,7 +401,8 @@ static function executeVolume($subDeviceId, $executionCommand){
return $commandTemp;
}
static function executeApp($subDeviceId, $executionCommand){
static function executeApp($subDeviceId, $executionCommand)
{
//echo $executionCommand['params']['newApplication'];
$status = 'OFFLINE';
$online = false;
@@ -424,7 +440,8 @@ static function executeApp($subDeviceId, $executionCommand){
return $commandTemp;
}
static function executeInput($subDeviceId, $executionCommand){
static function executeInput($subDeviceId, $executionCommand)
{
//echo $executionCommand['params']['newInput'];
$status = 'OFFLINE';
$online = false;
@@ -462,7 +479,8 @@ static function executeInput($subDeviceId, $executionCommand){
return $commandTemp;
}
static function executeMediaCont($subDeviceId, $executionCommand){
static function executeMediaCont($subDeviceId, $executionCommand)
{
$status = 'SUCCESS';
$online = true;

View File

@@ -187,20 +187,31 @@ class Utilities
* @param string $operator ('asc'/'desc')
* @return void
*/
static function sortArrayByKey($data = [], $key, $operator = "asc"){
if ($operator == "asc")
static function sortArrayByKey($data = [], $key, $operator = "asc")
{
if ($operator == "asc") {
uasort($data, function ($a, $b) use ($key) {
if ($a[$key] == $b[$key]) return 0;
return ($a[$key] < $b[$key]) ? -1 : 1;
$SortA = $a[$key];
$SortB = $b[$key];
if ($key == "room_id") {
$SortA = RoomManager::getRoomName($SortA);
$SortB = RoomManager::getRoomName($SortB);
}
if ($SortA == $SortB) return 0;
return ($SortA < $SortB) ? -1 : 1;
});
} else {
uasort($data, function ($a, $b) use ($key) {
if ($a[$key] == $b[$key]) return 0;
return ($a[$key] > $b[$key]) ? -1 : 1;
$SortA = $a[$key];
$SortB = $b[$key];
if ($key == "room_id") {
$SortA = RoomManager::getRoomName($SortA);
$SortB = RoomManager::getRoomName($SortB);
}
if ($SortA == $SortB) return 0;
return ($SortA > $SortB) ? -1 : 1;
});
}
return $data;
}
}

View File

@@ -61,4 +61,10 @@ class AuthManager {
};
return false;
}
public function getUserId($bearer){
$token = explode(' ', $bearer)[1];
$userid = Db::loadOne('SELECT user_id FROM tokens WHERE token = ? AND expire >= CURRENT_TIMESTAMP AND blocked = 0;', array($token))['user_id'];
return $userid;
}
}

View File

@@ -8,23 +8,23 @@ class AutomationManager{
}
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));
$automation = self::getById($automationId,["enabled"]);
$flipedValue = ($automation['enabled'] == 1 ? 0 : 1);
return Db::command ('UPDATE automation SET enabled = ? 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');
public static function create ($name, $onDays, $doCode, $ifCode, $userId = 1, $automationId = "") {
$userId = UserManager::getUserData('user_id', $userId);
$scene = array (
'name' => $name,
'owner_id' => $userId,
'on_days' => $onDays,
'if_something' => $ifCode,
'do_something' => $doCode,
'conditions' => $ifCode,
'tasks' => $doCode,
);
try {
if ($automationId == "") {
@@ -34,19 +34,24 @@ class AutomationManager{
}
} catch(PDOException $error) {
echo $error->getMessage();
return false;
die();
}
}
public static function getAll(){
return Db::loadAll ("SELECT * FROM automation");
public static function getAll($collums = ['*']){
return Db::loadAll ("SELECT ". implode("," , $collums)." FROM automation");
}
public static function getById($automationId, $collums = ['*']){
return Db::loadOne("SELECT ". implode("," , $collums)." FROM automation WHERE automation_id = ?", [$automationId]);
}
public static function executeAll(){
global $logManager;
$automations = Db::loadAll ("SELECT * FROM automation");
/*$automations = Db::loadAll ("SELECT * FROM automation");
$dayNameNow = strtolower (date('D', time()));
foreach ($automations as $automation) {
@@ -170,6 +175,6 @@ class AutomationManager{
Db::edit('automation', array('locked' => 0), 'WHERE automation_id = ?', array($automation['automation_id']));
}
}
}
}*/
}
}

View File

@@ -7,7 +7,9 @@ class DeviceManager{
WHERE approved != ?", Array(2));
}
static function setHeartbeat($deviceId){
self::edit($deviceId, ['heartbeat' => date("Y-m-d H:i:s", time())]);
}
static function getAllDevicesInRoom ($roomId = "") {
return Db::loadAll ("SELECT * FROM devices WHERE room_id = ? AND approved != ?", Array($roomId, 2));

View File

@@ -2,16 +2,21 @@
class RecordManager{
public static $records;
public static function createWithSubId ($subDeviceId, $value) {
public static function createWithSubId ($subDeviceId, $value, $origin = false) {
try {
$record = [
'execuded' => 1,
];
Db::edit ('records', $record, 'WHERE subdevice_id = ?', array ($subDeviceId));
$record = array (
'subdevice_id' => $subDeviceId,
'value' => $value,
);
if ($origin != false)
$record['Origin'] = $origin;
return Db::add ('records', $record);
} catch(PDOException $error) {
echo $error->getMessage();
@@ -19,7 +24,7 @@ class RecordManager{
}
}
public static function create ($deviceId, $type, $value) {
public static function create ($deviceId, $type, $value, $origin = false) {
$subDeviceId = Db::loadOne('SELECT * FROM subdevices WHERE device_id = ? AND type = ?;', array($deviceId, $type))['subdevice_id'];
if ($subDeviceId == '') {
return false;
@@ -28,7 +33,7 @@ class RecordManager{
//Ochrana proti duplicitním hodnotám zapisují se jen změny
$lastRecord = self::getLastRecord($subDeviceId, 1);
if ($lastRecord['value'] == $value){
if (isset($lastRecord['value']) && $lastRecord['value'] == $value){
return false;
}
@@ -42,6 +47,10 @@ class RecordManager{
'subdevice_id' => $subDeviceId,
'value' => $value,
);
if ($origin != false)
$record['Origin'] = $origin;
return Db::add ('records', $record);
} catch(PDOException $error) {
echo $error->getMessage();
@@ -87,7 +96,7 @@ class RecordManager{
$dateTime = $dateTime->modify($periodLocal);
$dateTime = $dateTime->format('Y-m-d H:i:s');
$groupBy = strtoupper($groupBy).'(time)';
$sql = 'SELECT value, time, execuded FROM records
$sql = 'SELECT value, time, execuded, origin FROM records
WHERE
subdevice_id = ?
AND
@@ -102,7 +111,7 @@ class RecordManager{
public static function clean ($day) {
if (isset($day)) {
Db::command ('DELETE FROM records WHERE `time` < ADDDATE(NOW(), INTERVAL -? DAY);', array($day));
Db::command ('DELETE FROM records WHERE `time` < ADDDATE(NOW(), INTERVAL ? DAY);', array($day));
}
}
@@ -110,5 +119,10 @@ class RecordManager{
public static function cleanSubdeviceRecords ($subDeviceId) {
Db::command ('DELETE FROM records WHERE subdevice_id = ?);', array($subDeviceId));
}
public static function setHistory($subDeviceId){
$history = SubDeviceManager::getSubDevice($subDeviceId)['history'];
if ($history > 0) self::clean(-abs($history));
}
}
?>

View File

@@ -19,6 +19,12 @@ class RoomManager{
return $allRoom;
}
public static function getRoomName ($room_id) {
//TODO: ignore Widgets withoud data
$allRoom = Db::loadAlone ("SELECT name FROM rooms WHERE room_id=?", array ($room_id));
return $allRoom;
}
public static function create ($name) {
$room = array (
'name' => $name,

View File

@@ -14,6 +14,7 @@ class SettingsManager{
}
public static function create ($name, $value, $type = '') {
if (!self::getByName($name)){
$setting = array (
'name' => $name,
'value' => $value,
@@ -26,9 +27,10 @@ class SettingsManager{
die();
}
}
}
public static function update ($name, $value, $type = '') {
if (self::getByName($name)){
if (!self::getByName($name)){
self::create($name, $value, $type);
} else {
try {

View File

@@ -50,7 +50,7 @@ class SubDeviceManager
}
//check if dubdevice exist
//Add History to be set in Creation
public static function create($deviceId, $type, $unit)
{
$record = array(
@@ -66,6 +66,10 @@ class SubDeviceManager
}
}
public static function editSubDevicesByDevice ($deviceId, $subDeviceParameters) {
DB::edit('subdevices', $subDeviceParameters, 'WHERE device_id=?', array ($deviceId));
}
public static function remove($subDeviceId)
{
RecordManager::cleanSubdeviceRecords($subDeviceId);

View File

@@ -22,7 +22,7 @@ class AirQuality extends VirtualDeviceManager
$finalUrl = sprintf($this->api_uri, $this->city_sluig, $this->app_id);
$json = json_decode(Utilities::CallAPI('GET', $finalUrl, ''), true);
RecordManager::create($deviceId, $this->subdevice_type, $json['data']['aqi']);
RecordManager::create($deviceId, $this->subdevice_type, $json['data']['aqi'], 'plugin');
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, 'senzore-virtual');
DeviceManager::approved($this->virtual_device_name);

View File

@@ -9,6 +9,14 @@ class AirQuality extends VirtualDeviceManager
function make()
{
//Register the settings
$settingMng = new SettingsManager();
if (!($settingField = $settingMng->getByName("airquality"))) {
$settingMng->create("token", "", "airquality");
} else {
$app_id = $settingField['value'];
}
try {
if (DeviceManager::registeret($this->virtual_device_name)) {
$deviceId = DeviceManager::getDeviceByToken($this->virtual_device_name)['device_id'];
@@ -22,7 +30,7 @@ class AirQuality extends VirtualDeviceManager
$finalUrl = sprintf($this->api_uri, $this->city_sluig, $this->app_id);
$json = json_decode(Utilities::CallAPI('GET', $finalUrl, ''), true);
RecordManager::create($deviceId, $this->subdevice_type, $json['data']['aqi']);
RecordManager::create($deviceId, $this->subdevice_type, $json['data']['aqi'], 'plugin');
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, 'senzore-virtual');
DeviceManager::approved($this->virtual_device_name);

View File

@@ -31,7 +31,7 @@ class CovidV2 extends VirtualDeviceManager
$json = json_decode(Utilities::CallAPI('GET', $finalUrl, ''), true)['data'];
foreach ($dataItems as $dataItem) {
RecordManager::create($deviceId, strtolower($dataItem), end($json)[$this->name_index[$dataItem]]);
RecordManager::create($deviceId, strtolower($dataItem), end($json)[$this->name_index[$dataItem]], 'plugin');
}
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, strtolower($this->virtual_device_name));

85
app/plugins/DameJidlo.php Normal file
View File

@@ -0,0 +1,85 @@
<?php
class DameJidlo extends VirtualDeviceManager
{
private $virtual_device_name = "Dáme Jídlo";
private $device_type = "virtual-device";
private $subdevice_type = "dame-jidlo";
public function deliveryTime($token)
{
// Generated by curl-to-PHP: http://incarnate.github.io/curl-to-php/
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://cz.fd-api.com/api/v5/tracking/active-orders?time_variation=Variation2');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_ENCODING, 'gzip, deflate');
$headers = array();
$headers[] = 'Authority: cz.fd-api.com';
$headers[] = 'Sec-Ch-Ua: \"Chromium\";v=\"88\", \"Google Chrome\";v=\"88\", \";Not A Brand\";v=\"99\"';
$headers[] = 'Accept: application/json, text/plain, */*';
$headers[] = 'Authorization: Bearer ' . $token;
$headers[] = 'X-Pd-Language-Id: 2';
$headers[] = 'Sec-Ch-Ua-Mobile: ?0';
$headers[] = 'X-Fp-Api-Key: volo';
$headers[] = 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.146 Safari/537.36';
$headers[] = 'Origin: https://www.damejidlo.cz';
$headers[] = 'Sec-Fetch-Site: cross-site';
$headers[] = 'Sec-Fetch-Mode: cors';
$headers[] = 'Sec-Fetch-Dest: empty';
$headers[] = 'Referer: https://www.damejidlo.cz/';
$headers[] = 'Accept-Language: en-US,en;q=0.9,cs-CZ;q=0.8,cs;q=0.7';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
var_dump(isset(json_decode($result, true)['data']['active_orders'][0]['delivery']['time']['eta']) ? json_decode($result, true)['data']['active_orders'][0]['delivery']['time']['eta'] : 0);
return (isset(json_decode($result, true)['data']['active_orders'][0]['delivery']['time']['eta']) ? json_decode($result, true)['data']['active_orders'][0]['delivery']['time']['eta'] : 0);
}
function make()
{
//Register the settings
$settingMng = new SettingsManager();
if (!($settingField = $settingMng->getByName("damejidlo_token","damejidlo"))) {
$settingMng->create("damejidlo_token", "", "damejidlo");
} else {
$bearer = $settingField['value'];
}
try {
if (DeviceManager::registeret($this->virtual_device_name)) {
$deviceId = DeviceManager::getDeviceByToken($this->virtual_device_name)['device_id'];
if (!$subDevice = SubDeviceManager::getSubDeviceByMaster($deviceId, $this->subdevice_type)) {
SubDeviceManager::create($deviceId, $this->subdevice_type, '');
sleep(1);
$subDevice = SubDeviceManager::getSubDeviceByMaster($deviceId, strtolower($this->subdevice_type));
}
//if (!$this->fetchEnabled($deviceId,$subDevice['subdevice_id'])) die();
RecordManager::create($deviceId, $this->subdevice_type, $this->deliveryTime($bearer), 'plugin');
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, 'senzore-virtual');
DeviceManager::approved($this->virtual_device_name);
}
return 'sucessful';
} catch (Exception $e) {
return 'exception: ' . $e->getMessage();
}
}
function translate($value){
if ($value == 0) {
return " Delivered";
} else if ($value <= 1) {
return "less " . $value;
}
return $value;
}
}

View File

@@ -3,30 +3,45 @@ class DatabaseBackup
{
public function make()
{
//Register the settings
$time = '00:00';
$settingMng = new SettingsManager();
if (!($settingField = $settingMng->getByName("backup_time","db_backup"))) {
$settingMng->create("backup_time", $time, "db_backup");
} else {
$time = $settingField['value'];
}
//Time to Backup ?
if (date("H:i",time()) != $time)
return 'pending';
try {
$filenames = [];
$backupWorker = new DatabaseBackup;
$filenames[] = $backupWorker->scheme(); //Backup Database scheme
$filenames[] = $backupWorker->data(); //Backup Database Data
//$filenames[] = $_SERVER['DOCUMENT_ROOT'] . '/config/config.php'; //Backup Configuration File
$backupWorker->compress($_SERVER['DOCUMENT_ROOT'] . BASEDIR . 'backup/' . date("Y-m-d", time()) . '.zip', $filenames);
$backupWorker->compress($_SERVER['DOCUMENT_ROOT'] . BASEDIR . '/backup/' . date("Y-m-d", time()) . '.zip', $filenames);
return 'sucessful';
} catch (Exception $e) {
return 'exception: ' . $e->getMessage();
}
}
private function scheme()
private function data()
{
$backupfile = $_SERVER['DOCUMENT_ROOT'] . BASEDIR . "backup/" . DBNAME . '_scheme_' . date("Y-m-d", time()) . '.sql';
$backupfile = $_SERVER['DOCUMENT_ROOT'] . BASEDIR . "/backup/" . DBNAME . '_data_' . date("Y-m-d", time()) . '.sql';
if (file_exists($backupfile)) return null;
$command = "mysqldump --skip-comments --no-create-info -h localhost -u " . DBUSER . " -p" . DBPASS . " " . DBNAME . " -r $backupfile 2>&1";
$this->executeCommand($command);
return $backupfile;
}
private function data()
private function scheme()
{
$backupfile = $_SERVER['DOCUMENT_ROOT'] . BASEDIR . "backup/" . DBNAME . '_data_' . date("Y-m-d", time()) . '.sql';
$backupfile = $_SERVER['DOCUMENT_ROOT'] . BASEDIR . "/backup/" . DBNAME . '_scheme_' . date("Y-m-d", time()) . '.sql';
if (file_exists($backupfile)) return null;
$command = "mysqldump --skip-comments --no-data -h localhost -u " . DBUSER . " -p" . DBPASS . " " . DBNAME . " -r $backupfile 2>&1";
$this->executeCommand($command);
return $backupfile;
@@ -43,9 +58,7 @@ class DatabaseBackup
$zip = new ZipArchive();
if ($zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE)) {
foreach ($files as $file) {
$filename = explode('/', $file);
$filename = end($filename);
$zip->addFile($file, $filename);
$zip->addFile($file);
}
$zip->close();
foreach ($files as $file) {

View File

@@ -29,7 +29,7 @@ class N7Day extends VirtualDeviceManager
$datediff = $now - $your_date;
$daysUntilN7Day = round($datediff / (60 * 60 * 24));
RecordManager::create($deviceId, $this->subdevice_type, $daysUntilN7Day);
RecordManager::create($deviceId, $this->subdevice_type, $daysUntilN7Day, 'plugin');
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, $this->device_type);
DeviceManager::approved($this->virtual_device_name);

View File

@@ -23,7 +23,39 @@ class OpenWeatherMap extends VirtualDeviceManager
$finalUrl = sprintf($this->api_uri, $this->city_sluig, $this->app_id);
$json = json_decode(Utilities::CallAPI('GET', $finalUrl, ''), true);
RecordManager::create($deviceId, $this->subdevice_type, $json['weather'][0]['id']);
//Notification data setup
$notificationMng = new NotificationManager;
if ($json['weather'][0]['id'] >= 500 && $json['weather'][0]['id'] < 600) {
// $notificationData = [
// 'title' => 'Weather',
// 'body' => 'It Will be rainy outhere, Take Umbrela :)',
// 'icon' => 'http://dev.steelants.cz/projekty/simplehome-client/img/icons/favicon-16x16.png',
// ];
// //Notification for newly added Device
// if ($notificationData != []) {
// $subscribers = $notificationMng::getSubscription();
// foreach ($subscribers as $key => $subscriber) {
// $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
// }
// }
} else if ($json['weather'][0]['id'] >= 600 && $json['weather'][0]['id'] < 700) {
// $notificationData = [
// 'title' => 'Weather',
// 'body' => 'It is white out there :)',
// 'icon' => 'http://dev.steelants.cz/projekty/simplehome-client/img/icons/favicon-16x16.png',
// ];
// //Notification for newly added Device
// if ($notificationData != []) {
// $subscribers = $notificationMng::getSubscription();
// foreach ($subscribers as $key => $subscriber) {
// $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
// }
// }
}
RecordManager::create($deviceId, $this->subdevice_type, $json['weather'][0]['id'], 'plugin');
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, 'senzore-virtual');
DeviceManager::approved($this->virtual_device_name);
@@ -33,4 +65,8 @@ class OpenWeatherMap extends VirtualDeviceManager
return 'exception: ' . $e->getMessage();
}
}
function enable(){
(new SettingsManager)->create('open_weather_api_token', '', 'open_weather');
}
}

View File

@@ -52,7 +52,7 @@ class UsaElection extends VirtualDeviceManager
$OnePercent = ($Trump + $Biden + $Unknown) / 100;
foreach ($dataItems as $Category) {
RecordManager::create($deviceId, strtolower($Category), round(($$Category / $OnePercent)));
RecordManager::create($deviceId, strtolower($Category), round(($$Category / $OnePercent)), 'plugin');
}
} else {
DeviceManager::create($this->virtual_device_name, $this->virtual_device_name, 'senzore-virtual');

View File

@@ -5,6 +5,21 @@ class Device extends Template
{
function __construct($sortBy = null, $sortType = null)
{
// //Notification data setup
// $notificationMng = new NotificationManager;
// $notificationData = [
// 'title' => 'Info',
// 'body' => 'New device Detected Found',
// 'icon' => 'http://dev.steelants.cz/projekty/simplehome-client/img/icons/favicon-16x16.png',
// ];
// //Notification for newly added Device
// if ($notificationData != []) {
// $subscribers = $notificationMng::getSubscription();
// foreach ($subscribers as $key => $subscriber) {
// $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
// }
// }
$userManager = new UserManager();
$deviceManager = new DeviceManager();
$subDeviceManager = new SubDeviceManager();
@@ -28,7 +43,8 @@ class Device extends Template
"token" => "token",
"signal" => "signal",
"firmware" => "firmware_hash",
"icon" => "icon"
"icon" => "icon",
"history" => "history",
];
$sortIcons = [
@@ -47,12 +63,17 @@ class Device extends Template
$sortBy = "id";
$sortType = "DESC";
}
$template->prepare('sortIcon', [$sortBy => $sortIcons[$sortType]]);
foreach ($devices as $key => $device) {
//Signal Stenght
$subdevice = $subDeviceManager->getSubDeviceByMasterAndType($device['device_id'], "wifi");
$subdeviceLocal = $subDeviceManager->getSubDeviceByMaster($device['device_id']);
if (!empty($subdeviceLocal)) {
$devices[$key]['history'] = (!empty($subdeviceLocal['history']) ? $subdeviceLocal['history'] : 0);
} else {
$devices[$key]['history'] = "null";
}
$devices[$key]['signal'] = "";
if (!empty($subdevice['subdevice_id'])) {
$record = $recordManager->getLastRecord($subdevice['subdevice_id']);

View File

@@ -70,6 +70,8 @@ class Setting extends Template
$result = $settingsManager->getSettingGroup($plugins[$key]['slug']);
if (count ($result) > 0) {
$plugins[$key]['settings'] = $result;
} else {
unset($plugins[$key]);
}
}
}

View File

@@ -36,6 +36,7 @@
<a href="device/mac/<?php echo $SORTTYPE; ?>">(Mac)</a><i class="fa"><?php echo (!empty($SORTICON['mac']) ? $SORTICON['mac'] : ""); ?></i><br>
<a href="device/token/<?php echo $SORTTYPE; ?>">Token</a><i class="fa"><?php echo (!empty($SORTICON['token']) ? $SORTICON['token'] : ""); ?></i>
</th>
<th><a href="device/history/<?php echo $SORTTYPE; ?>">Historie</a><i class="fa"><?php echo (!empty($SORTICON['history']) ? $SORTICON['history'] : ""); ?></i></th>
<th>Action
<form method="post" action="">
<button class="fa custom-file-input" type="submit" name="deviceCommand" value="reset" title="Reset All"><b>&#xf01e;</b></button>
@@ -100,6 +101,14 @@
<td><?php echo (!empty($device['mac']) ? $device['mac'] : ""); ?><br>
<?php echo (!empty($device['ip_address']) ? $device['ip_address'] : ""); ?><br>
<?php echo (!empty($device['token']) ? $device['token'] : ""); ?></td>
<td>
<?php if (isset($device['history']) && $device['history'] != "null"): ?>
<form method="post" action="">
<input type="hidden" name="deviceId" value="<?php echo (!empty($device['device_id']) ? $device['device_id'] : ""); ?>">
<input class="input" type="number" onchange="this.form.submit();" name="deviceHistory" value="<?php echo (!empty($device['history']) ? $device['history'] : 0); ?>">
</form>
<?php endif; ?>
</td>
<td>
<?php if (!empty($device['mac'])) : ?>
<form method="post" action="">
@@ -122,12 +131,6 @@
$partial->render();
//TODO js do main.js
?>
<script>
$(function() {
$("#sortable").sortable();
$("#sortable").disableSelection();
});
</script>
</body>
</html>

View File

@@ -202,7 +202,23 @@ $partial = new Partial('head');
</form>
</div>
<!--Plugins Settings-->
<?php foreach ($PLUGINSSETTINGS as $key => $pluginSeting) { ?>
<div class="col-12 col-sm-9 mx-auto mt-4">
<h4 class="mb-4"><?php echo $pluginSeting['name'] ?></h4>
<form method="post">
<?php foreach ($pluginSeting['settings'] as $key => $pluginSetingField) { ?>
<div class="field">
<div class="label"><?php echo $pluginSetingField['name'] ?>:</div>
<input type="text" class="input" name="<?php echo $pluginSetingField['name'] ?>" value="<?php echo $pluginSetingField['value'] ?>">
</div>
<?php } ?>
<div class="field">
<input type="submit" name="submitPlugins<?php echo $pluginSeting['name'] ?>Settings" class="button" value="<?php $LANGMNG->echo('b_save') ?>">
</div>
</form>
</div>
<?php } ?>
</div>

View File

@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $this->title ?></title>
<title><?php echo $this->title; ?></title>
</head>
<body>
<?php echo $this->content(); ?>

View File

@@ -60,7 +60,6 @@ const UNITS = [
//Notifications
define('SERVERKEY','');
define('SERVERVAIPKEY','');
//TODO: Po registraci vzít výchozí hodnoty
//Default network Setting

View File

@@ -1,24 +0,0 @@
<?php
namespace Core\Configuration;
class ConfigurationLoader
{
private const CONFIGURATIONS_DIRECTORY = __DIR__ . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR
. '..' . DIRECTORY_SEPARATOR . 'config'
. DIRECTORY_SEPARATOR;
public function load(): array
{
return [];
}
/**
* Concerns
* -> Loading configuration files
* - Scan directory for files.
* - Filtering none config / php files.
* - Creating assoc array.
*/
}

View File

@@ -8,18 +8,4 @@ namespace Core\Configuration;
* @author Romano Schoonheim https://github.com/romano1996
*/
class Configurations
{
/** @var array */
private $configurations;
public function __construct(ConfigurationLoader $configurationLoader)
{
// Concern: Storing assoc array to this object.
$this->configurations = $configurationLoader->load();
}
public function get(string $path)
{
// Concern: Accessing configurations based on "paths" application.something For example.
}
}
{}

2
git-stats.ps1 Normal file
View File

@@ -0,0 +1,2 @@
$lines = (ls -r|sls '^\s*(#|$)' -a -n).Count
write-host $lines" of code"

View File

@@ -2660,19 +2660,19 @@ html {
@font-face {
font-family: 'Metropolis';
src: url("../fonts/Metropolis-Regular.ttf");
/*src: url("../fonts/Metropolis-Regular.ttf");*/
font-weight: 400;
}
@font-face {
font-family: 'Metropolis';
src: url("../fonts/Metropolis-Medium.ttf");
/*src: url("../fonts/Metropolis-Medium.ttf");*/
font-weight: 500;
}
@font-face {
font-family: 'Metropolis';
src: url("../fonts/Metropolis-SemiBold.ttf");
/*src: url("../fonts/Metropolis-SemiBold.ttf");*/
font-weight: 600;
}