-
Roberto Milton Scheffel authoredRoberto Milton Scheffel authored
SmartAPI.php 18.88 KiB
<?php
namespace SmartData\SmartAPI
{
require_once( __DIR__ . '/Config.php');
require_once( __DIR__ . '/Logger.php');
require_once( __DIR__ . '/Backend.php');
require_once( __DIR__ . '/Packer.php');
require_once( __DIR__ . '/Description.php');
require_once( __DIR__ . '/MultiSmartData.php');
require_once( __DIR__ . '/Unit.php');
use SmartData\SmartAPI\Internals\{JsonAPI, BinaryAPI};
use SmartData\Exception\{BadRequestException, RequestFailedException, InsertionFailedException, CreationFailedException};
use SmartData\{Series, SmartData, Backend, Credentials, Logger, MultiSmartData, Unit, Config_Common};
use SmartData\Description;
use SmartData\Utility\{Pack,Unpack};
function health_check()
{
return Backend::health_check();
}
function search($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() === JSON_ERROR_NONE) {
list($credentials,$series,$parameter) = JsonAPI::parse_search($json);
if ($series instanceof Series) { // is this verification required?
$backend = new Backend($credentials);
switch($series->version) {
case SmartData::STATIC_VERSION:
case SmartData::MOBILE_VERSION:
$return = $backend->search($series,$parameter);
break;
default:
throw new \Exception("Unsupported SmartData version [{$ver}]");
return null;
}
if($return != NULL){
$return = json_encode($return);
$return = preg_replace('/:"([0-9]*)"/',':$1',$return);
} else {
throw new RequestFailedException("Error processing request: null return");
}
}
} else {
throw new BadRequestException("Error parsing content request: invalid series");
}
return $return;
}
function get($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() === JSON_ERROR_NONE)
list($credentials,$series,$aggregator,$options) = JsonAPI::parse_get($json);
else
list($credentials,$series,$aggregator,$options) = BinaryAPI::parse_get($content);
if ($series instanceof Series) {
$backend = new Backend($credentials);
switch($series->version) {
case SmartData::STATIC_VERSION:
if ($series->dev== -999999)
$return = $backend->get_activity($series,$aggregator,$options);
else
$return = $backend->query($series,$aggregator,$options);
break;
case SmartData::MOBILE_VERSION:
$return = $backend->track($series,$aggregator,$options);
break;
default:
throw new \Exception("Unsupported SmartData version [{$ver}]");
return null;
}
if($return != NULL) {
$pos = 0;
foreach ( $return['series'] as $key => $sd ) {
if (array_key_exists("SmartData", $sd)) {
} else if (array_key_exists('value', $sd)) {
$u = Unit::interpret( $sd['unit'] );
if ( $u->is_digital() && ( $sd['unit'] & 0x0FFF0000 ) == 0x02230000 ) {
$aux = base64_encode($sd['value']);
$return['series'][$pos]['value'] = $aux;
}
}
$pos = $pos + 1;
}
$return = json_encode($return);
$return = preg_replace('/:"([0-9]*)"/',':$1',$return);
} else {
throw new RequestFailedException("Error processing request: null return");
}
} else {
throw new BadRequestException("Error parsing content request: invalid series");
}
return $return;
}
function put($content)
{
$values = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() === JSON_ERROR_NONE) {
if (property_exists( $values, "credentials") ) {
$credentials = Credentials::fromJson( $values->credentials );
$backend = new Backend($credentials);
} else {
$backend = new Backend();
}
if (property_exists( $values, "MultiValueSmartData")) {
$data = MultiSmartData::multi_values($values);
if (!$backend->insert_multiple(...$data)) {
throw new InsertionFailedException("JSON MultiValue SmartData Insertion Failed");
}
} else if (property_exists( $values, "MultiDeviceSmartData")) {
$data = MultiSmartData::multi_devices($values);
if (!$backend->insert_multiple(...$data)) {
throw new InsertionFailedException("JSON MultiDevice SmartData Insertion Failed");
}
} else if (property_exists( $values, "MultiUnitSmartData")) {
$data = MultiSmartData::multi_units($values);
$keys = array_keys($data);
foreach ($keys as $k) {
$lst = $data[$k];
if (!$backend->insert_multiple(...$lst)) {
throw new InsertionFailedException("MultiUnit SmartData Insertion Failed");
}
}
} else if ( property_exists($values,"smartdata" ) ) {
list($credentials,$smartdata_array,$params) = JsonAPI::parse_put($values);
foreach($smartdata_array as $smartdata) {
$u = Unit::interpret($smartdata->unit);
if ( $u->is_digital() && ( $smartdata->unit & 0x0FFF0000 ) == 0x02230000 ) {
$wav_name = Config_Common::TEMP_DIR . "/arq". mt_rand(100000000000, 999999999999) . ".wav";
$flac_name = Config_Common::TEMP_DIR . "/arq". mt_rand(100000000000, 999999999999) . ".flac";
$arq = fopen($wav_name,"wb");
fwrite($arq, $smartdata->value);
fclose($arq);
$ret = shell_exec("ffmpeg -v 0 -loglevel 0 -y -i " . $wav_name . " -af aformat=s16 " . $flac_name);
$arq = fopen($flac_name,"rb");
$aux = fread($arq, filesize($flac_name));
$smartdata->value = $aux;
fclose($arq);
try { unlink($wav_name); } finally { }
try { unlink($flac_name); } finally { }
}
if(!$backend->insert($smartdata, ...$params)) {
throw new InsertionFailedException("Insertion Failed");
}
}
} else {
throw new InsertionFailedException("SmartData type not identified...");
}
} else {
// Is Binary
$backend = new Backend();
list($credentials,$smartdata_array,$params) = BinaryAPI::parse_put($content);
foreach($smartdata_array as $smartdata) {
if(!$backend->insert($smartdata, ...$params)) {
throw new InsertionFailedException("Insertion Failed");
}
}
}
}
function finish($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
$last_error = json_last_error();
if ($last_error === JSON_ERROR_NONE) {
list($credentials,$series,$params) = JsonAPI::parse_create($json);
} else {
list($credentials,$series,$params) = BinaryAPI::parse_create($content);
}
if ($series instanceof Series) {
$backend = new Backend($credentials);
if(!$backend->finish($series, ...$params)) {
throw new CreationFailedException("Finish Failed");
}
} else {
throw new BadRequestException("Error parsing content request: invalid series");
}
}
function create($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
$last_error = json_last_error();
if ($last_error === JSON_ERROR_NONE) {
list($credentials,$series,$params) = JsonAPI::parse_create($json);
} else {
list($credentials,$series,$params) = BinaryAPI::parse_create($content);
}
if ($series instanceof Series) {
$backend = new Backend($credentials);
if(!$backend->create($series, ...$params)) {
throw new CreationFailedException("Creation Failed");
}
} else {
throw new BadRequestException("Error parsing content request: invalid series");
}
}
function attach($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() === JSON_ERROR_NONE)
list($credentials,$series,$params) = JsonAPI::parse_attach($json);
else
list($credentials,$series,$params) = BinaryAPI::parse_attach($content);
if ($series instanceof Series) {
$backend = new Backend($credentials);
if(!$backend->attach($series, ...$params)){
throw new CreationFailedException("Attachment Failed");
}
} else {
throw new BadRequestException("Error parsing content request: invalid series");
}
}
function batch($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() === JSON_ERROR_NONE)
throw new Exception\NotImplementedException("JSON-based import in batch has not been implemented yet");
else{
//list($credentials,$smartdata_array,$params) = BinaryAPI::parse_put($content);
$binary = $content;
$credentials = null;
if(!REQUEST_CERT) {
$credentials = Credentials::unpack($binary);
if(!$credentials){
throw new BadRequestException("!CERT > Credentials cannot be null");
}
}
$series = Series::unpack($binary);
$csdf = array();
$smartdata_array = array();
while($binary) {
$smartdata = SmartData::unpack($binary, $csdf);
if($smartdata instanceof SmartData)
array_push($smartdata_array, $smartdata);
}
$params = array();
$backend = new Backend($credentials);
if(!$backend->insertBatch($series, ...$smartdata_array)) {
throw new Exception\InsertionFailedException("Insertion Failed");
}
}
}
function describe($content)
{
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() !== JSON_ERROR_NONE)
throw new Exception\InvalidJSONException("JSON description is incorrect");
else{
list($credentials, $description) = JsonAPI::parse_description($json);
$backend = new Backend($credentials);
if(!$backend->describe($description)) {
throw new Exception\InsertionFailedException("Description insertion failed");
}
}
}
function list_devices($content) {
Logger::debug($content);
$json = json_decode($content, false, 512, JSON_BIGINT_AS_STRING);
if (json_last_error() !== JSON_ERROR_NONE)
throw new Exception\InvalidJSONException("JSON series for listing is incorrect");
else{
list($credentials, $series) = JsonAPI::parse_get($json, false);
$backend = new Backend($credentials);
$descs = $backend->list_devices($series);
return json_encode($descs);
}
}
}
namespace SmartData\SmartAPI\Internals
{
use SmartData\{Series,SmartData,Credentials,Logger,Description};
trait JsonAPI
{
public function parse_description($json)
{
$credentials = null;
$description = null;
if (isset($json->credentials))
$credentials = Credentials::fromJson($json->credentials);
if (isset($json->series_descriptions)) {
$description = array();
foreach ($json->series_descriptions as $d) {
$d = Description::fromJson($d);
array_push($description, $d);
}
}
if (isset($json->series_description)) {
$d = Description::fromJson($json->series_description);
$description = array();
array_push($description, $d);
}
return array($credentials, $description);
}
public function parse_get($json, $verify = true)
{
$credentials = null;
if(isset($json->credentials))
$credentials = Credentials::fromJson($json->credentials);
$series = Series::fromJsonNew($json->series, $verify);
$aggregator = $json->aggregator ?? null;
$options = $json->options?? null;
return array($credentials, $series, $aggregator, $options);
}
public function parse_put($json)
{
$credentials = null;
$params = $smartdata_array = array();
if(isset($json->credentials))
$credentials = Credentials::fromJson($json->credentials);
$smartdata_set = $json->smartdata;
foreach($smartdata_set as $smartdata_fields) {
$smartdata = SmartData::fromJson($smartdata_fields);
if($smartdata instanceof SmartData)
array_push($smartdata_array, $smartdata);
}
return array($credentials, $smartdata_array, $params);
}
public function parse_create($json)
{
$credentials = null;
$params = array();
if(isset($json->credentials))
$credentials = Credentials::fromJson($json->credentials);
if (isset($json->series->type)) {
$series = Series::fromJsonNew($json->series);
} else {
$series = Series::fromJson($json->series);
}
$aggregator = array($json->aggregator??null);
return array($credentials, $series, $params);
}
public function parse_attach($json)
{
$credentials = null;
$params = array();
if(isset($json->credentials))
$credentials = Credentials::fromJson($json->credentials);
$series = Series::fromJson($json->series);
$aggregator = array($json->aggregator??null);
return array($credentials, $series, $params);
}
public function parse_search($json)
{
$credentials = null;
if(isset($json->credentials))
$credentials = Credentials::fromJson($json->credentials);
$series = Series::fromJson($json->series);
$parameter = $json->parameter ?? null;
return array($credentials, $series, $parameter);
}
}
}
namespace SmartData\SmartAPI\Internals
{
use SmartData\Exception\{BadRequestException};
use SmartData\{Series,SmartData,Credentials,Logger};
use SmartData\Utility\{Unpack};
trait BinaryAPI
{
public function parse_get($binary)
{
$credentials = null;
$series = Series::unpack($binary);
$params = array();
$options = array();
return array($credentials, $series, $params, $options);
}
public function parse_put($binary)
{
$credentials = null;
if(!REQUEST_CERT){
$credentials = Credentials::unpack($binary);
if(!$credentials){
throw new BadRequestException("!CERT > Credentials cannot be null");
}
}
// Common SmartData Fields Bitmap
// ------7-----------6-----------5-----------4-----------3-----------2-----------1-----------0-------
// | version | unit | error | confidence | x | y | z | dev |
// --< 1 bit >---< 1 bit >---< 1 bit >---< 1 bit >---< 1 bit >---< 1 bit >---< 1 bit >---< 1 bit >---
$csdf = array();
if(isset($_GET['csdf'])){
$csdf_bitmap = intval($_GET['csdf']);
if(($csdf_bitmap & (0b1 << 7)) != 0) $csdf = array_merge($csdf, array('version' => Unpack::uInt8($binary, true)));
if(($csdf_bitmap & (0b1 << 6)) != 0) $csdf = array_merge($csdf, array('unit' => Unpack::uInt32($binary, true)));
if(($csdf_bitmap & (0b1 << 5)) != 0) $csdf = array_merge($csdf, array('error' => Unpack::uInt8($binary, true)));
if(($csdf_bitmap & (0b1 << 4)) != 0) $csdf = array_merge($csdf, array('confidence' => Unpack::uInt8($binary, true)));
if(($csdf_bitmap & (0b1 << 3)) != 0) $csdf = array_merge($csdf, array('x' => Unpack::int32($binary, true)));
if(($csdf_bitmap & (0b1 << 2)) != 0) $csdf = array_merge($csdf, array('y' => Unpack::int32($binary, true)));
if(($csdf_bitmap & (0b1 << 1)) != 0) $csdf = array_merge($csdf, array('z' => Unpack::int32($binary, true)));
if(($csdf_bitmap & (0b1 << 0)) != 0) $csdf = array_merge($csdf, array('dev' => Unpack::uint32($binary, true)));
}
$smartdata_array = array();
while($binary) {
$smartdata = SmartData::unpack($binary, $csdf);
if($smartdata instanceof SmartData)
array_push($smartdata_array, $smartdata);
}
$params = array();
return array($credentials, $smartdata_array, $params);
}
public function parse_create($binary)
{
$credentials = null;
if(!REQUEST_CERT){
$credentials = Credentials::unpack($binary);
if(!$credentials){
throw new BadRequestException("!CERT > Credentials cannot be null");
}
}
$series = Series::unpack($binary);
$params = array();
return array($credentials, $series, $params);
}
public function parse_attach($binary)
{
$credentials = null;
if(!REQUEST_CERT){
$credentials = Credentials::unpack($binary);
if(!$credentials){
throw new BadRequestException("!CERT > Credentials cannot be null");
}
}
$series = Series::unpack($binary);
$params = array();
return array($credentials, $series, $params);
}
}
}