Host = $host;
$this->Port = $port;
$this->Key = $APIKey;
$this->Pass = $Password;
Global $System;
/** @var System $System */
$Cache = $System->getCache();
if (!$Cache->exists('FindBoxCoreSystem')) {
$URI = '/1.0.0/index.php/getstatus/1.0.0/';
$ret = $this->CallAPI($URI, "");
if ($ret['err'] != 0)
throw new Exception("Can't connect to FindBox server:
{$ret['value']}");
if ($ret['err'] == 0 && $ret['value']['code'] == 0) {
$details = $ret['value']['value'];
$this->coreDetails = array_filter_keys($details, ['core.box_id', 'core.version']);
}
$Cache->set('FindBoxCoreSystem', $this->coreDetails, 3600);
} else {
$this->coreDetails = $Cache->get('FindBoxCoreSystem');
}
}
/**
* CallGetAPI make HTTP GET requests
* @param string $URI full path of api url, for example "/1.0.0/index.php/smartesl.blink_special/1.0.0/"
* @param string $Parameters
* @param bool $skipResponse for faster communications, if response not need, you can skip this step
* @return array converted from JSON response of request if present
*/
public function CallAPI(string $URI, string $Parameters, bool $skipResponse = false): array
{
$bodyJSON = null;
$auth = "Authorization: Basic " . base64_encode("{$this->Key}:{$this->Pass}") . "\r\n";
$streamfbOS = @stream_socket_client("tcp://{$this->Host}:{$this->Port}", $errno, $errstr, 1);
if (!$streamfbOS) {
return $this->returnCode($errno, $errstr);
} else {
//$requestText = "{$method} {$URI}{$Parameters} HTTP/1.0\r\nHost: {$this->Host}\r\n{$auth}Accept: */*\r\nConnection: close\r\n\r\n";
$requestBodyLength = strlen($Parameters);
$requestText = "POST {$URI} HTTP/1.0\r\nHost: {$this->Host}\r\n{$auth}Accept: */*\r\nContent-Type: application/json\r\nContent-Length: {$requestBodyLength}\r\n\r\n{$Parameters}\r\n";
//file_put_contents("request.txt", $requestText);
fwrite($streamfbOS, $requestText);
if (!$skipResponse) {
$r = stream_get_contents($streamfbOS);
list(, $bodyJSON) = explode("\r\n\r\n", $r, 2);
}
fclose($streamfbOS);
}
$bodyJSON = ($bodyJSON == null) ? "{}" : $bodyJSON;
return $this->returnCode(0, $bodyJSON);
}
/**
* Helper for make JSON return code
*
* @param int $errorCode
* @param string $value
* @return array
*/
private function returnCode(int $errorCode, string $value): array
{
$val = json_decode($value, true) ?? $value;
return array(
"err" => $errorCode,
"value" => $val);
}
public function BlinkUnassigned()
{
$URI = "/1.0.0/index.php/smartesl.blink_unassigned/2.0.0/";
$this->CallAPI($URI, "", true);
}
/**
* Save products into findbus database
* @param string $barcode
* @param string $name
* @param array $dataFields Custom fields
* @return array
*/
public function SaveProducts(string $barcode, string $name, array $dataFields): array
{
$product = json_encode([[[
"barcode" => $barcode,
"name1" => $name,
"datafields" => $dataFields
]]]);
$URI = "/1.0.0/index.php/saveproducts/1.2.0/";
return $this->CallAPI($URI, $product);
}
/**
* Add label into findbox system and Bind it with a barcode
*
* @param string $labelId
* @param string $barcode
* @return array
*/
public function Bind(string $labelId, string $barcode): array
{
$URI = "/1.0.0/index.php/smartesl.bind/1.1.0/";
return $this->CallAPI($URI, "[\"{$labelId}\",\"{$barcode}\"]");
}
/**
* Remove label from findbox system
*
* @param string $labelId
* @return array
*/
public function UnBind(string $labelId): array
{
// Retrieve barcode associated to the label
$labelDetails = $this->CallAPI("/1.0.0/index.php/smartesl.getstatus/3.1.0/", "[[\"{$labelId}\"]]");
// If RSSI exist, label it is binded to system
if (isset($labelDetails['value']['value'][$labelId]['rssi'])) {
$barcode = $labelDetails['value']['value'][$labelId]['data']['barcode'];
$ret = $this->CallAPI("/1.0.0/index.php/smartesl.unbind/1.0.0/", "[\"{$labelId}\"]");
if ($ret['err'] != 0)
return $this->returnCode(1, 'Error on unbind');
$ret = $this->CallAPI("/1.0.0/index.php/deleteproducts/1.0.0/", "[\"{$barcode}\"]");
if ($ret['err'] != 0)
return $this->returnCode(1, 'Error on deleteproducts');
// All ok
return $this->returnCode(0, '');
} else
return $this->returnCode(1, 'No label exist on Findbox');
}
/**
* Check the response of FindBoxOS, return an array if no error, else NULL
*
* @param array $fbOS_Response
* @return NULL|array
*/
public function getLabelsFromResponse(array $fbOS_Response): ?array
{
// Check if response have field 'value' that is an array
$haveArray = isset($fbOS_Response['value']['value']) && is_array($fbOS_Response['value']['value']);
if (!$haveArray)
return NULL;
return $fbOS_Response['value']['value'];
}
/**
* Request all label status to FindBox core.
* If request is forced may require large amount of time to retrieve status directly from labels
*
* @param bool $force true = ask status directly to ESL and not from FindBox Core Cache
*
* @return null|array return array with labelID => status_struct
*/
public function GetAllESLStatus($force = false): ?array
{
// Retrieve all labels
$URI = '/1.0.0/index.php/smartesl.getstatus/4.0.0/[[],false]';
$ret = $this->CallAPI($URI, "");
if ($ret['err'] != 0)
return null;
$fbOSResponse = $this->getLabelsFromResponse($ret);
if (!$fbOSResponse) {
$this->log->write('GetAllESLStatus: ' . $ret['value']['value'], 'd/m/Y H:i:s');
return null;
}
$labels = $fbOSResponse;
$this->setTemplatesName($labels);
if (!$force)
return $labels;
// Request status directly to ESL
$eslStatus = [];
foreach($labels as $labelID => $status) {
// Filter for ONLINE labels only
$labelStatus = strtoupper($status['data']['esl_state']);
if ($force && in_array($labelStatus, ['OFFLINE', 'BLOCKED,FC']))
continue;
// Request status to ESL
$URI = "/1.0.0/index.php/smartesl.getstatus/4.0.0/[[\"{$labelID}\"],true]";
$fbOSResponse = $this->getLabelsFromResponse($this->CallAPI($URI, ""));
if ($fbOSResponse != null) {
$eslStatus = array_merge($eslStatus, $fbOSResponse);
}
}
return $eslStatus;
}
/**
* Add 'data.template_name' to the structure returned by GetStatus
*
* @param array $status
*/
private function setTemplatesName(&$status)
{
$tplNameList = [];
$fb_template = $this->CallAPI('/1.0.0/index.php/smartesl.gettemplates/1.0.0/', '[]');
$templates = $this->getLabelsFromResponse($fb_template);
if ($templates != null) {
foreach($templates as $item) {
$tplNameList[$item['template_id']] = $item['name'];
}
}
foreach($status as &$esl) {
if (count($tplNameList) == 0) {
$esl['data']['template_name'] = '';
continue;
}
$tplName = $tplNameList[$esl['data']['template_id']];
$esl['data']['template_name'] = $tplName ?? '{NO_NAME}';
}
}
}