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}'; } } }