restructured api internally
This commit is contained in:
parent
0b53a08123
commit
e14321af8b
4 changed files with 296 additions and 137 deletions
|
@ -5,13 +5,15 @@ A (hopefully soon) fully featured selft-hosted web interface and server-backend
|
||||||
# State of development
|
# State of development
|
||||||
|
|
||||||
- interface and backend planned
|
- interface and backend planned
|
||||||
|
- readonly dashboard is working
|
||||||
|
|
||||||
# API docs
|
# API docs
|
||||||
|
|
||||||
## get locations
|
## get locations
|
||||||
triggered by setting no GET parameter at all
|
triggered by setting no GET parameter at all
|
||||||
### Parameters
|
### Parameters
|
||||||
<no>
|
no parameters
|
||||||
|
|
||||||
### Tags
|
### Tags
|
||||||
- id
|
- id
|
||||||
- locationname
|
- locationname
|
||||||
|
@ -59,3 +61,5 @@ triggered by setting GET parameter 'locId' to a vaild location id
|
||||||
- range (actual range of present measvalues)
|
- range (actual range of present measvalues)
|
||||||
- from
|
- from
|
||||||
- to
|
- to
|
||||||
|
|
||||||
|
|
||||||
|
|
268
api/blueweather.php
Normal file
268
api/blueweather.php
Normal file
|
@ -0,0 +1,268 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BlueWeather
|
||||||
|
*
|
||||||
|
* PHP version 7.2
|
||||||
|
*
|
||||||
|
* @category Tools
|
||||||
|
* @package BlueWeather
|
||||||
|
* @author Dorian Zedler <dorian@itsblue.de>
|
||||||
|
* @license GPLV3 gpl.com
|
||||||
|
* @link itsblue.de
|
||||||
|
*/
|
||||||
|
|
||||||
|
class BlueWeather
|
||||||
|
{
|
||||||
|
private $_config;
|
||||||
|
private $_con;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param mixed $_config config array containing some stuff
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct($_config)
|
||||||
|
{
|
||||||
|
$this->_config = $_config;
|
||||||
|
$this->_con = mysqli_connect(
|
||||||
|
$_config['dbhost'],
|
||||||
|
$_config['dbuser'],
|
||||||
|
$_config['dbpassword'],
|
||||||
|
$_config['dbname']
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!$this->_con) {
|
||||||
|
echo "Error connecting to database: " . mysqli_connect_error();
|
||||||
|
http_response_code(500);
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to login users
|
||||||
|
*
|
||||||
|
* @param string $username username
|
||||||
|
* @param string $password passowrd
|
||||||
|
*
|
||||||
|
* @return string '' or session token
|
||||||
|
*/
|
||||||
|
public function loginUser($username, $password)
|
||||||
|
{
|
||||||
|
$sql = "SELECT * FROM `users`
|
||||||
|
WHERE`username`=\"".$this->_con->real_escape_string($username)."\"";
|
||||||
|
$result = $this->_con->query($sql);
|
||||||
|
|
||||||
|
// only one row will be returned
|
||||||
|
$data = $result->fetch_assoc();
|
||||||
|
|
||||||
|
if (!password_verify($password, $data['password'])) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
//generate random token
|
||||||
|
$length = 10;
|
||||||
|
$str = "";
|
||||||
|
$characters = array_merge(range('A', 'Z'), range('a', 'z'), range('0', '9'));
|
||||||
|
$max = count($characters) - 1;
|
||||||
|
for ($i = 0; $i < $length; $i++) {
|
||||||
|
$rand = mt_rand(0, $max);
|
||||||
|
$str .= $characters[$rand];
|
||||||
|
}
|
||||||
|
$token_hash = password_hash($str, PASSWORD_DEFAULT);
|
||||||
|
|
||||||
|
$sql = 'INSERT INTO `sessions` (userId, session)
|
||||||
|
VALUES ("'. $data['id'] .'", "'. $token_hash .'")';
|
||||||
|
|
||||||
|
if (!$this->_con->query($sql)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $token_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
// - getter functions -
|
||||||
|
// --------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get all locations from the database
|
||||||
|
*
|
||||||
|
* @return mixed (array with all locations)
|
||||||
|
*/
|
||||||
|
public function getAllLocations()
|
||||||
|
{
|
||||||
|
// get all locations
|
||||||
|
$sql = "SELECT * FROM `locations`";
|
||||||
|
$result = $this->_con->query($sql);
|
||||||
|
|
||||||
|
//loop through the returned data
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
$locations[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to get the data of a specific location
|
||||||
|
*
|
||||||
|
* @param int $locId id of the location to return data of
|
||||||
|
* @param mixed $range contains 'from' and 'to' as unix timestamps
|
||||||
|
* @param int $maxVals maximum measvals to be transmitted; if more are
|
||||||
|
* present in the timespan, the avarage will be calculated
|
||||||
|
*
|
||||||
|
* @return mixed object with all information about the location (see docs)
|
||||||
|
*/
|
||||||
|
function getLocationData($locId, $range, $maxVals)
|
||||||
|
{
|
||||||
|
$sql = "SELECT * FROM `locations`
|
||||||
|
WHERE`id`=$locId";
|
||||||
|
$result = $this->_con->query($sql);
|
||||||
|
|
||||||
|
// only one row will be returned
|
||||||
|
$data = $result->fetch_assoc();
|
||||||
|
|
||||||
|
if (!isset($range['from']) || $range['from'] === "") {
|
||||||
|
$range['from'] = time() - 24 * 60 * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($range['to']) || $range['to'] === "") {
|
||||||
|
$range['to'] = time();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all measvalues of given location
|
||||||
|
$sql = "SELECT M.measvalue,M.sensorid,M.timestamp FROM measvalues M
|
||||||
|
JOIN sensors S ON M.sensorid = S.id
|
||||||
|
JOIN locations L ON S.locationid=L.id
|
||||||
|
WHERE L.id=$locId AND M.timestamp > " . $range['from'] .
|
||||||
|
"AND M.timestamp < " . $range['to'] . "
|
||||||
|
ORDER BY timestamp ASC";
|
||||||
|
|
||||||
|
$result = $this->_con->query($sql);
|
||||||
|
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
$measvalues[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all sensors of given location
|
||||||
|
$sql = "SELECT * FROM `sensors`
|
||||||
|
WHERE `locationid` = $locId";
|
||||||
|
|
||||||
|
$result = $this->_con->query($sql);
|
||||||
|
|
||||||
|
//loop through the returned data
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
unset($row['locationid']); // remove locId as it is redundant
|
||||||
|
$sensors[] = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get all value types
|
||||||
|
$sql = "SELECT * FROM `valuetypes`";
|
||||||
|
|
||||||
|
$result = $this->_con->query($sql);
|
||||||
|
|
||||||
|
//loop through the returned data
|
||||||
|
while ($row = $result->fetch_assoc()) {
|
||||||
|
foreach ($sensors as $sensor) {
|
||||||
|
if ($sensor['valuetypeid'] == $row['id']) {
|
||||||
|
$valuetypes[] = $row;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($maxVals) && $maxVals > 0 && count($measvalues) > $maxVals) {
|
||||||
|
// build the new measvalues array with respect to maxVals for each sensor
|
||||||
|
|
||||||
|
$finalMeasvals = array();
|
||||||
|
|
||||||
|
foreach ($sensors as $sensor) {
|
||||||
|
|
||||||
|
// get all measvalues of the current sensor
|
||||||
|
$rawMeasvalsOfThisSensor = array();
|
||||||
|
$finalMeasvalsOfThisSensor = array();
|
||||||
|
|
||||||
|
foreach ($measvalues as $measvalue) {
|
||||||
|
if ($measvalue["sensorid"] === $sensor["id"]) {
|
||||||
|
array_push($rawMeasvalsOfThisSensor, $measvalue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// always sum up the same amount of values to get a new array
|
||||||
|
// which doesn't have more than $maxVals values
|
||||||
|
$countOfValuesForAvarage = intval(
|
||||||
|
round(count($rawMeasvalsOfThisSensor) / $maxVals, 0)
|
||||||
|
);
|
||||||
|
|
||||||
|
$takenValuesForNextSum = 0;
|
||||||
|
$tmpMeasvalueSum = 0;
|
||||||
|
$tmpTimestampSum = 0;
|
||||||
|
|
||||||
|
for ($i = 0; $i < count($rawMeasvalsOfThisSensor); $i++) {
|
||||||
|
// loop through all measvals of the sensor
|
||||||
|
$measvalue = $rawMeasvalsOfThisSensor[$i];
|
||||||
|
|
||||||
|
if ($measvalue["sensorid"] === $sensor["id"]) {
|
||||||
|
$tmpMeasvalueSum += $measvalue["measvalue"];
|
||||||
|
$tmpTimestampSum += $measvalue["timestamp"];
|
||||||
|
$takenValuesForNextSum += 1;
|
||||||
|
}
|
||||||
|
if ($takenValuesForNextSum === $countOfValuesForAvarage || $i === count($rawMeasvalsOfThisSensor) - 1) {
|
||||||
|
array_push(
|
||||||
|
$finalMeasvalsOfThisSensor,
|
||||||
|
array(
|
||||||
|
"measvalue" => round(
|
||||||
|
$tmpMeasvalueSum / $takenValuesForNextSum, 2
|
||||||
|
),
|
||||||
|
"timestamp" => round(
|
||||||
|
$tmpTimestampSum / $takenValuesForNextSum, 0
|
||||||
|
),
|
||||||
|
"sensorid" => $sensor["id"]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$takenValuesForNextSum = 0;
|
||||||
|
$tmpMeasvalueSum = 0;
|
||||||
|
$tmpTimestampSum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert the new vals of this sensor into the global new vals
|
||||||
|
$finalMeasvals = array_merge(
|
||||||
|
$finalMeasvals, $finalMeasvalsOfThisSensor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$measvalues = $finalMeasvals;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find actual range
|
||||||
|
$min = null;
|
||||||
|
$max = null;
|
||||||
|
|
||||||
|
foreach ($measvalues as $value) {
|
||||||
|
if ($value['timestamp'] < $min || !isset($min)) {
|
||||||
|
$min = $value['timestamp'];
|
||||||
|
} else if ($value['timestamp'] > $max || !isset($max)) {
|
||||||
|
$max = $value['timestamp'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add sensors and value types to data object
|
||||||
|
$data['measvalues'] = $measvalues;
|
||||||
|
$data['sensors'] = $sensors;
|
||||||
|
$data['valuetypes'] = $valuetypes;
|
||||||
|
$data['range'] = array('from' => $min, 'to' => $max);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
19
api/example.config.php
Normal file
19
api/example.config.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* BlueWeather
|
||||||
|
*
|
||||||
|
* PHP version 7.2
|
||||||
|
*
|
||||||
|
* @category Tools
|
||||||
|
* @package BlueWeather
|
||||||
|
* @author Dorian Zedler <dorian@itsblue.de>
|
||||||
|
* @license GPLV3 gpl.com
|
||||||
|
* @link itsblue.de
|
||||||
|
*/
|
||||||
|
|
||||||
|
$config['dbhost'] = '<yourdbhost>';
|
||||||
|
$config['dbname'] = '<yourdbname>';
|
||||||
|
$config['dbuser'] = '<yourusername>';
|
||||||
|
$config['dbpassword'] = '<yourpassword>';
|
||||||
|
|
||||||
|
?>
|
140
api/json.php
140
api/json.php
|
@ -17,19 +17,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once './config.php';
|
require_once './config.php';
|
||||||
|
require_once './blueweather.php';
|
||||||
|
|
||||||
|
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json');
|
||||||
header('Access-Control-Allow-Origin: *');
|
header('Access-Control-Allow-Origin: *');
|
||||||
|
|
||||||
$con = mysqli_connect($config['dbhost'], $config['dbuser'], $config['dbpassword'], $config['dbname']);
|
$blueweather = new BlueWeather($config);
|
||||||
if (!$con) {
|
|
||||||
echo "<h1>Fatal internal Error! :-/</h1>";
|
|
||||||
echo "Error connecting to database: " . mysqli_connect_error();
|
|
||||||
http_response_code(500);
|
|
||||||
exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_GET['locId'])) {
|
if (isset($_GET['locId'])) {
|
||||||
// get data of given location
|
// get data of given location
|
||||||
|
@ -38,134 +31,9 @@ if (isset($_GET['locId'])) {
|
||||||
$range['to'] = $con->real_escape_string($_GET['range']['to']);
|
$range['to'] = $con->real_escape_string($_GET['range']['to']);
|
||||||
$maxVals = $con->real_escape_string($_GET['maxVals']);
|
$maxVals = $con->real_escape_string($_GET['maxVals']);
|
||||||
|
|
||||||
$sql = "SELECT * FROM `locations`
|
$data = getLocationData($locId, $range, $maxVals);
|
||||||
WHERE`id`=$locId";
|
|
||||||
$result = $con->query($sql);
|
|
||||||
|
|
||||||
// only one row will be returned
|
|
||||||
$data = $result->fetch_assoc();
|
|
||||||
|
|
||||||
if (!isset($range['from']) || $range['from'] === "") {
|
|
||||||
$range['from'] = time() - 24 * 60 * 60;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($range['to']) || $range['to'] === "") {
|
|
||||||
$range['to'] = time();
|
|
||||||
}
|
|
||||||
|
|
||||||
// get all measvalues of given location
|
|
||||||
$sql = "SELECT M.measvalue,M.sensorid,M.timestamp FROM measvalues M
|
|
||||||
JOIN sensors S ON M.sensorid = S.id
|
|
||||||
JOIN locations L ON S.locationid=L.id
|
|
||||||
WHERE L.id=$locId AND M.timestamp > " . $range['from'] . " AND M.timestamp < " . $range['to'] . "
|
|
||||||
ORDER BY timestamp ASC";
|
|
||||||
|
|
||||||
$result = $con->query($sql);
|
|
||||||
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
$measvalues[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get all sensors of given location
|
|
||||||
$sql = "SELECT * FROM `sensors`
|
|
||||||
WHERE `locationid` = $locId";
|
|
||||||
|
|
||||||
$result = $con->query($sql);
|
|
||||||
|
|
||||||
//loop through the returned data
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
unset($row['locationid']); // remove locId as it is redundant
|
|
||||||
$sensors[] = $row;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get all value types
|
|
||||||
$sql = "SELECT * FROM `valuetypes`";
|
|
||||||
|
|
||||||
$result = $con->query($sql);
|
|
||||||
|
|
||||||
//loop through the returned data
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
foreach ($sensors as $sensor) {
|
|
||||||
if ($sensor['valuetypeid'] == $row['id']) {
|
|
||||||
$valuetypes[] = $row;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($maxVals) && $maxVals > 0 && count($measvalues) > $maxVals) {
|
|
||||||
// build the new measvalues array with respect to maxVals for each sensor
|
|
||||||
|
|
||||||
$finalMeasvals = array();
|
|
||||||
|
|
||||||
foreach ($sensors as $sensor) {
|
|
||||||
|
|
||||||
|
|
||||||
$rawMeasvalsOfThisSensor = array();
|
|
||||||
$finalMeasvalsOfThisSensor = array();
|
|
||||||
|
|
||||||
foreach ($measvalues as $measvalue) {
|
|
||||||
if ($measvalue["sensorid"] === $sensor["id"]) {
|
|
||||||
array_push($rawMeasvalsOfThisSensor, $measvalue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$countOfValuesForAvarage = intval(round(count($rawMeasvalsOfThisSensor) / $maxVals, 0));
|
|
||||||
|
|
||||||
$takenValuesForNextSum = 0;
|
|
||||||
$tmpMeasvalueSum = 0;
|
|
||||||
$tmpTimestampSum = 0;
|
|
||||||
|
|
||||||
for ($i = 0; $i < count($rawMeasvalsOfThisSensor); $i++) {
|
|
||||||
$measvalue = $rawMeasvalsOfThisSensor[$i];
|
|
||||||
if ($measvalue["sensorid"] === $sensor["id"]) {
|
|
||||||
$tmpMeasvalueSum += $measvalue["measvalue"];
|
|
||||||
$tmpTimestampSum += $measvalue["timestamp"];
|
|
||||||
$takenValuesForNextSum += 1;
|
|
||||||
}
|
|
||||||
if ($takenValuesForNextSum === $countOfValuesForAvarage || $i === count($rawMeasvalsOfThisSensor) - 1) {
|
|
||||||
array_push($finalMeasvalsOfThisSensor, array("measvalue" => round($tmpMeasvalueSum / $takenValuesForNextSum, 2), "timestamp" => round($tmpTimestampSum / $takenValuesForNextSum, 0), "sensorid" => $sensor["id"]));
|
|
||||||
|
|
||||||
$takenValuesForNextSum = 0;
|
|
||||||
$tmpMeasvalueSum = 0;
|
|
||||||
$tmpTimestampSum = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//print_r($finalMeasvalsOfThisSensor);
|
|
||||||
|
|
||||||
$finalMeasvals = array_merge($finalMeasvals, $finalMeasvalsOfThisSensor);
|
|
||||||
}
|
|
||||||
|
|
||||||
$measvalues = $finalMeasvals;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find actual range
|
|
||||||
$min;
|
|
||||||
$max;
|
|
||||||
foreach ($measvalues as $value) {
|
|
||||||
if ($value['timestamp'] < $min || !isset($min)) {
|
|
||||||
$min = $value['timestamp'];
|
|
||||||
} else if ($value['timestamp'] > $max || !isset($max)) {
|
|
||||||
$max = $value['timestamp'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// add sensors and value types to data object
|
|
||||||
$data['measvalues'] = $measvalues;
|
|
||||||
$data['sensors'] = $sensors;
|
|
||||||
$data['valuetypes'] = $valuetypes;
|
|
||||||
$data['range'] = array('from' => $min, 'to' => $max);
|
|
||||||
} else {
|
} else {
|
||||||
// get all locations
|
$data = $blueweather->getAllLocations();
|
||||||
$sql = "SELECT * FROM `locations`";
|
|
||||||
$result = $con->query($sql);
|
|
||||||
|
|
||||||
//loop through the returned data
|
|
||||||
while ($row = $result->fetch_assoc()) {
|
|
||||||
$data[] = $row;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
http_response_code(200);
|
http_response_code(200);
|
||||||
|
|
Loading…
Reference in a new issue