Firmware Updater (Backend + GUI)

This commit is contained in:
JonatanRek 2020-03-11 12:22:44 +01:00
parent 0d076eb67c
commit 44c4c84292
6 changed files with 110 additions and 94 deletions

1
.gitignore vendored
View File

@ -6,5 +6,6 @@ _nemazat/css/main.css.map
_nemazat/css/main.css _nemazat/css/main.css
_nemazat/css/font-awesome.min.css _nemazat/css/font-awesome.min.css
app/logs/*.log app/logs/*.log
.vscode/
.vscode/sftp.json .vscode/sftp.json
app/updater/*.bin app/updater/*.bin

96
api.php
View File

@ -38,8 +38,9 @@ Db::connect (DBHOST, DBUSER, DBPASS, DBNAME);
//Read API data //Read API data
$json = file_get_contents('php://input'); $json = file_get_contents('php://input');
$obj = json_decode($json, true); $obj = json_decode($json, true);
if (defined(DEBUGMOD) && DEBUGMOD == 1) { if (defined(DEBUGMOD) && DEBUGMOD == 1) {
$logManager->write("[API] Rest API request body -> decodet to json \n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO); $logManager->write("[API] request body\n" . json_encode($obj, JSON_PRETTY_PRINT), LogRecordType::INFO);
} }
//zabespecit proti Ddosu //zabespecit proti Ddosu
@ -52,7 +53,7 @@ if (isset($obj['user']) && $obj['user'] != ''){
UserManager::atHome($userId, $atHome); UserManager::atHome($userId, $atHome);
$logManager->write("[Record] user " . $userId . " changet his home state to " . $atHome . " " . RECORDTIMOUT , LogRecordType::INFO); $logManager->write("[Record] user " . $userId . " changet his home state to " . $atHome . " " . RECORDTIMOUT , LogRecordType::INFO);
echo 'Saved: ' . $atHome; echo 'Saved: ' . $atHome;
header("HTTP/1.1 200 OK"); header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
die(); die();
} }
} }
@ -64,7 +65,7 @@ if (DEBUGMOD != 1) {
'state' => 'unsuccess', 'state' => 'unsuccess',
'errorMSG' => "Using API from your IP insnt alowed!", 'errorMSG' => "Using API from your IP insnt alowed!",
)); ));
header("HTTP/1.1 401 Unauthorized"); header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
$logManager->write("[API] acces denied from " . $_SERVER['REMOTE_ADDR'], LogRecordType::WARNING); $logManager->write("[API] acces denied from " . $_SERVER['REMOTE_ADDR'], LogRecordType::WARNING);
exit(); exit();
} }
@ -90,18 +91,23 @@ try {
//Variables //Variables
$token = $obj['token']; $token = $obj['token'];
$values = null; $values = null;
$settings = null;
if (isset($obj['values'])) { if (isset($obj['values'])) {
$values = $obj['values']; $values = $obj['values'];
} }
if (isset($obj['settings'])) {
$settings = $obj['settings'];
}
//Checks //Checks
if ($token == null || $token == "") { if ($token == null || $token == "") {
echo json_encode(array( echo json_encode(array(
'state' => 'unsuccess', 'state' => 'unsuccess',
'errorMSG' => "Missing Value Token in JSON payload", 'errorMSG' => "Missing Value Token in JSON payload",
)); ));
header("HTTP/1.1 401 Unauthorized"); header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
die(); die();
} }
@ -119,24 +125,24 @@ if (!DeviceManager::registeret($token)) {
if (!SubDeviceManager::getSubDeviceByMaster($deviceId, $key)) { if (!SubDeviceManager::getSubDeviceByMaster($deviceId, $key)) {
SubDeviceManager::create($deviceId, $key, UNITS[$key]); SubDeviceManager::create($deviceId, $key, UNITS[$key]);
} }
if ($notificationData != []) { if ($notificationData != []) {
$subscribers = $notificationMng::getSubscription(); $subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) { foreach ($subscribers as $key => $subscriber) {
$logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " "); $logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " ", LogRecordType::INFO);
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData); $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
} }
} }
} }
//Notification for newly added Device //Notification for newly added Device
$subscribers = $notificationMng::getSubscription(); $subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) { foreach ($subscribers as $key => $subscriber) {
$logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " "); $logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " ", LogRecordType::INFO);
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData); $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
} }
header("HTTP/1.1 401 Unauthorized"); header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
echo json_encode(array( echo json_encode(array(
'state' => 'unsuccess', 'state' => 'unsuccess',
'errorMSG' => "Device not registeret", 'errorMSG' => "Device not registeret",
@ -146,7 +152,7 @@ if (!DeviceManager::registeret($token)) {
} }
if (!DeviceManager::approved($token)) { if (!DeviceManager::approved($token)) {
header("HTTP/1.1 401 Unauthorized"); header($_SERVER["SERVER_PROTOCOL"]." 401 Unauthorized");
echo json_encode(array( echo json_encode(array(
'state' => 'unsuccess', 'state' => 'unsuccess',
'errorMSG' => "Unaproved Device", 'errorMSG' => "Unaproved Device",
@ -154,9 +160,14 @@ if (!DeviceManager::approved($token)) {
exit(); exit();
} }
// Diagnostic Data Write to DB
if (isset($settings)){
DeviceManager::editByToken($token, ['mac' => $settings["network"]["mac"], 'ip_address' => $settings["network"]["ip"]]);
}
// Subdevices first data! // Subdevices first data!
if ($values != null || $values != "") { if ($values != null || $values != "") {
//ZAPIS //ZAPIS
$device = DeviceManager::getDeviceByToken($token); $device = DeviceManager::getDeviceByToken($token);
$deviceId = $device['device_id']; $deviceId = $device['device_id'];
@ -166,40 +177,40 @@ if ($values != null || $values != "") {
} }
RecordManager::create($deviceId, $key, round($value['value'],3)); RecordManager::create($deviceId, $key, round($value['value'],3));
$logManager->write("[API] Device_ID " . $deviceId . " writed value " . $key . ' ' . $value['value'], LogRecordType::INFO); $logManager->write("[API] Device_ID " . $deviceId . " writed value " . $key . ' ' . $value['value'], LogRecordType::INFO);
//notification //notification
if ($key == 'door' || $key == 'water') { if ($key == 'door' || $key == 'water') {
$notificationMng = new NotificationManager; $notificationMng = new NotificationManager;
$notificationData = []; $notificationData = [];
switch ($key) { switch ($key) {
case 'door': case 'door':
$notificationData = [ $notificationData = [
'title' => 'Info', 'title' => 'Info',
'body' => 'Someone just open up '.$device['name'], 'body' => 'Someone just open up '.$device['name'],
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png', 'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
]; ];
break; break;
case 'water': case 'water':
$notificationData = [ $notificationData = [
'title' => 'Alert', 'title' => 'Alert',
'body' => 'Wather leak detected by '.$device['name'], 'body' => 'Wather leak detected by '.$device['name'],
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png', 'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
]; ];
break; break;
} }
if (DEBUGMOD) $notificationData['body'] .= ' value='.$value['value']; if (DEBUGMOD) $notificationData['body'] .= ' value='.$value['value'];
if ($notificationData != []) { if ($notificationData != []) {
$subscribers = $notificationMng::getSubscription(); $subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) { foreach ($subscribers as $key => $subscriber) {
$logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " "); $logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " ", LogRecordType::INFO);
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData); $notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
} }
} }
} }
} }
$hostname = strtolower($device['name']); $hostname = strtolower($device['name']);
$hostname = str_replace(' ', '_', $hostname); $hostname = str_replace(' ', '_', $hostname);
$jsonAnswer = [ $jsonAnswer = [
@ -211,46 +222,45 @@ if ($values != null || $values != "") {
], ],
'state' => 'succes', 'state' => 'succes',
]; ];
$subDevicesTypeList = SubDeviceManager::getSubDeviceSTypeForMater($deviceId); $subDevicesTypeList = SubDeviceManager::getSubDeviceSTypeForMater($deviceId);
if (!in_array($subDevicesTypeList, ['on/off', 'door', 'water'])) { if (!in_array($subDevicesTypeList, ['on/off', 'door', 'water'])) {
$jsonAnswer['device']['sleepTime'] = $device['sleep_time']; $jsonAnswer['device']['sleepTime'] = $device['sleep_time'];
} }
echo json_encode($jsonAnswer); echo json_encode($jsonAnswer);
header("HTTP/1.1 200 OK"); header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
} else { } else {
//Vypis //Vypis
//TODO: doděla uložení výpisu jinými slovy zda li byl comman vykonán
$device = DeviceManager::getDeviceByToken($token); $device = DeviceManager::getDeviceByToken($token);
$deviceId = $device['device_id']; $deviceId = $device['device_id'];
if (count(SubDeviceManager::getAllSubDevices($deviceId)) == 0) { if (count(SubDeviceManager::getAllSubDevices($deviceId)) == 0) {
SubDeviceManager::create($deviceId, 'on/off', UNITS[$key]); SubDeviceManager::create($deviceId, 'on/off', UNITS[$key]);
//RecordManager::create($deviceId, 'on/off', 0); //RecordManager::create($deviceId, 'on/off', 0);
} }
$subDeviceId = SubDeviceManager::getAllSubDevices($deviceId)[0]['subdevice_id']; $subDeviceId = SubDeviceManager::getAllSubDevices($deviceId)[0]['subdevice_id'];
$subDeviceLastReord = RecordManager::getLastRecord($subDeviceId); $subDeviceLastReord = RecordManager::getLastRecord($subDeviceId);
$subDeviceLastReordValue = $subDeviceLastReord['value']; $subDeviceLastReordValue = $subDeviceLastReord['value'];
if ($subDeviceLastReord['execuded'] == 0){ if ($subDeviceLastReord['execuded'] == 0){
$logManager->write("[API] subDevice id ".$subDeviceId . " executed comand with value " .$subDeviceLastReordValue . " record id " . $subDeviceLastReord['record_id'] . " executed " . $subDeviceLastReord['execuded']); $logManager->write("[API] subDevice id ".$subDeviceId . " executed comand with value " .$subDeviceLastReordValue . " record id " . $subDeviceLastReord['record_id'] . " executed " . $subDeviceLastReord['execuded']);
RecordManager::setExecuted($subDeviceLastReord['record_id']); RecordManager::setExecuted($subDeviceLastReord['record_id']);
} }
echo json_encode(array( echo json_encode(array(
'device' => [ 'device' => [
'hostname' => $device['name'], 'hostname' => $device['name'],
'ipAddress' => $device['ip_address'], 'ipAddress' => $device['ip_address'],
'subnet' => $device['subnet'], 'subnet' => $device['subnet'],
'gateway' => $device['gateway'], 'gateway' => $device['gateway'],
], ],
'state' => 'succes', 'state' => 'succes',
'value' => $subDeviceLastReordValue 'value' => $subDeviceLastReordValue
)); ));
header("HTTP/1.1 200 OK"); header($_SERVER["SERVER_PROTOCOL"]." 200 OK");
} }
unset($logManager); unset($logManager);
Db::disconect(); Db::disconect();
die(); die();

View File

@ -47,6 +47,15 @@ class DeviceManager{
} }
} }
public function editByToken ($token, $values = []) {
try {
Db::edit ('devices', $values, 'WHERE token = ?', array($deviceId));
} catch(PDOException $error) {
echo $error->getMessage();
die();
}
}
/** /**
* [assignRoom Přiřazení zařízení do třídy] * [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] $roomId [číslo místnosti do kter se zařízení přiřadit]

View File

@ -67,6 +67,10 @@
<div class="label">Type:</div> <div class="label">Type:</div>
<input class="input" type="text" name="deviceToken" value="<?php echo $DEVICE['type']; ?>" disabled> <input class="input" type="text" name="deviceToken" value="<?php echo $DEVICE['type']; ?>" disabled>
</div> </div>
<div class="field">
<div class="label">Mac Address:</div>
<input class="input" type="text" name="deviceToken" value="<?php echo $DEVICE['mac']; ?>" disabled>
</div>
<div class="field"> <div class="field">
<div class="label">IP:</div> <div class="label">IP:</div>
<input class="input" type="text" name="deviceIp" value="<?php echo $DEVICE['ip']; ?>" minlength="7" maxlength="15" size="15" pattern="^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$" disabled> <input class="input" type="text" name="deviceIp" value="<?php echo $DEVICE['ip']; ?>" minlength="7" maxlength="15" size="15" pattern="^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$" disabled>
@ -85,6 +89,13 @@
<div class="label">DNS:</div> <div class="label">DNS:</div>
<input class="input" type="text" name="deviceDns" value="<?php echo $DEVICE['dns']; ?>" minlength="7" maxlength="15" size="15" pattern="^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$" disabled> <input class="input" type="text" name="deviceDns" value="<?php echo $DEVICE['dns']; ?>" minlength="7" maxlength="15" size="15" pattern="^((\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$" disabled>
</div> </div>
<h4 class="mb-4"><?php $LANGMNG->echo('t_deviceVersion'); ?></h4>
<div class="field">
<div class="label"><?php $LANGMNG->echo('l_uploadFirmware'); ?></div>
<input class="input" type="file" name="deviceFirmware" value="">
</div>
<?php if ($DEVICE['userIsAdmin']) { ?> <?php if ($DEVICE['userIsAdmin']) { ?>
<?php if (!in_array($SUBDEVICE['type'], ['on/off', 'door', 'water'])) { ?> <?php if (!in_array($SUBDEVICE['type'], ['on/off', 'door', 'water'])) { ?>
<div class="field"> <div class="field">

View File

@ -161,6 +161,7 @@ class Home extends Template
'room' => $deviceData['room_id'], 'room' => $deviceData['room_id'],
'token' => $deviceData['token'], 'token' => $deviceData['token'],
'type' => $deviceData['type'], 'type' => $deviceData['type'],
'mac' => $deviceData['mac'],
'ip' => $deviceData['ip_address'], 'ip' => $deviceData['ip_address'],
'subnet' => $deviceData['subnet'], 'subnet' => $deviceData['subnet'],
'gateway' => $deviceData['gateway'], 'gateway' => $deviceData['gateway'],

View File

@ -23,65 +23,49 @@ foreach($files as $file) {
include './app/class/'. $file; include './app/class/'. $file;
} }
$logManager = new LogManager(); $logManager = new LogManager();
header('Content-type: text/plain; charset=utf8', true);
/* header('Content-type: text/plain; charset=utf8', true);
function check_header($name, $value = false)
{
if (!isset($_SERVER[$name])) {
return false;
}
if ($value && $_SERVER[$name] != $value) {
return false;
}
return true;
}*/
function sendFile($path) function sendFile($path)
{ {
header($_SERVER["SERVER_PROTOCOL"] . ' 200 OK', true, 200); header($_SERVER["SERVER_PROTOCOL"] . ' 200 OK', true, 200);
header('Content-Type: application/octet-stream', true); header('Content-Type: application/octet-stream', true);
header('Content-Disposition: attachment; filename=' . basename($path)); header('Content-Disposition: attachment; filename=' . basename($path));
header('Content-Length: ' . filesize($path), true); header('Content-Length: ' . filesize($path), true);
header('x-MD5: ' . md5_file($path), true); header('x-MD5: ' . md5_file($path), true);
readfile($path); readfile($path);
} }
/*if (!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden', true, 403);
echo "only for ESP8266 updater!\n";
exit();
}
if (
!check_header('HTTP_X_ESP8266_STA_MAC') ||
!check_header('HTTP_X_ESP8266_AP_MAC') ||
!check_header('HTTP_X_ESP8266_FREE_SPACE') ||
!check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
!check_header('HTTP_X_ESP8266_SKETCH_MD5') ||
!check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
!check_header('HTTP_X_ESP8266_SDK_VERSION')
) {
header($_SERVER["SERVER_PROTOCOL"] . ' 403 Forbidden', true, 403);
echo "only for ESP8266 updater! (header)\n";
exit();
}*/
$localBinary = "./app/updater/" . str_replace(':', '', $_SERVER['HTTP_X_ESP8266_STA_MAC']) . ".bin"; $localBinary = "./app/updater/" . str_replace(':', '', $_SERVER['HTTP_X_ESP8266_STA_MAC']) . ".bin";
$logManager->write("[Update] url: " . $localBinary, LogRecordType::INFO); $logManager->write("[Updater] url: " . $localBinary, LogRecordType::INFO);
$logManager->write("[Update] version: " . $_SERVER['HTTP_X_ESP8266_SKETCH_MD5'], LogRecordType::INFO); $logManager->write("[Updater] version: " . $_SERVER['HTTP_X_ESP8266_SKETCH_MD5'], LogRecordType::INFO);
if (file_exists($localBinary)) { if (file_exists($localBinary)) {
$logManager->write("[Update] version PHP: " . md5_file($localBinary), LogRecordType::INFO); $logManager->write("[Updater] version PHP: " . md5_file($localBinary), LogRecordType::INFO);
if ($_SERVER['HTTP_X_ESP8266_SKETCH_MD5'] != md5_file($localBinary)) { if ($_SERVER['HTTP_X_ESP8266_SKETCH_MD5'] != md5_file($localBinary)) {
sendFile($localBinary); sendFile($localBinary);
//notification
$notificationMng = new NotificationManager;
$notificationData = [
'title' => 'Info',
'body' => 'Someone device was just updated to new version',
'icon' => BASEDIR . '/app/templates/images/icon-192x192.png',
];
if ($notificationData != []) {
$subscribers = $notificationMng::getSubscription();
foreach ($subscribers as $key => $subscriber) {
$logManager->write("[NOTIFICATION] SENDING TO" . $subscriber['id'] . " ", LogRecordType::INFO);
$notificationMng::sendSimpleNotification(SERVERKEY, $subscriber['token'], $notificationData);
}
}
} else {
header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
}
} else { } else {
header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304); header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
} }
} else { header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);
header("HTTP/1.1 404 Not Found"); die();
}
die();