db = new MySQL(DB_HOST, DB_PORT, DB_USER, DB_PASS, DB_NAME); } // Allows us to connect or not public function SelectConected($idTag) { if(isset($idTag) && $idTag != NULL) { $res = $this->db->row("SELECT * FROM my_charger WHERE idTag = '{$idTag}' "); if($res != NULL && $res['id'] > 0 ) { $this->idTag = $res['idTag']; $this->name = $res['name']; return true; } } else return false; } //Ping the base my_set_command and if the commands are sent to the station and the command itself is deleted public function SetCommand($idTag) { $res = $this->db->row("SELECT * FROM my_set_command WHERE idTag = '{$idTag}' order by id DESC "); if($res != false) { $us = $this->db->row("SELECT * FROM `my_user` WHERE `mobile` = '{$res['user_id']}' "); $res['user_id'] = $us['id']; $this->db->query("DELETE FROM `my_set_command` WHERE id = '".$res['id']."'; "); return $res; } else {return false;} } //We write to the temporary base which connector was launched public function UpConnectorCommand($idTag, $connector_id = 0) { $heartbeat = time(); $this->db->query( "DELETE FROM `my_set_command_connector` WHERE idTag = '{$idTag}' " ); $this->db->query( "INSERT INTO `my_set_command_connector` (`idTag`, `connectorId`, `heartbeat`) VALUES ('{$idTag}', '{$connector_id}', '{$heartbeat}')" ); } //Write to the temporary base who launched the command public function UpUserCommand($idTag, $user_id = 0) { $heartbeat = time(); if($user_id > 0) { $res = $this->db->row("SELECT * FROM my_set_command_buffer WHERE idTag = '{$idTag}' "); if($res) { $id = $res['id']; $this->db->query( "UPDATE `my_set_command_buffer` SET `user_id` = '{$user_id}' WHERE id = '{$id}'; " ); } else { $this->db->query( "INSERT INTO `my_set_command_buffer` (`idTag`, `user_id`, `heartbeat`) VALUES ('{$idTag}', '{$user_id}', '{$heartbeat}')" ); } } } //Get the user id who last ran the command on the current station public function UserID($idTag) { $res = $this->db->row("SELECT user_id FROM my_set_command_buffer WHERE idTag = '{$idTag}' "); if($res['user_id'] > 0) { return $res['user_id']; } else { return 1; } } //Get the connector id who last ran the command on the current station public function ConnectorSID($idTag) { $res = $this->db->row("SELECT connectorId FROM my_set_command_connector WHERE idTag = '{$idTag}' "); return $res['connectorId']; } //Write the history of commands sent by handles to the database public function up_command($data, $idTag) { $type = json_decode($data); $heartbeat = time(); if(isset($type[2]) && $type[0] == 2) { $SetType = $this->SetType($type[2]); $this->db->query( "INSERT INTO `my_set_history` (`idTag`, `type`, `typeText`, `text`, `heartbeat`) VALUES ('{$idTag}', '{$SetType}', '{$type[2]}', '{$data}', '{$heartbeat}')" ); } if($type[0] == 3) { $search = '[2,"'.$type[1]; $res = $this->db->row(" SELECT * FROM `my_set_history` WHERE `text` LIKE '%{$search}%' AND idTag = '{$idTag}' ORDER BY `id` DESC "); if($res) { $this->type = $res['typeText']; } $SetType = $this->SetType($this->type); $this->db->query( "INSERT INTO `my_set_history` (`idTag`, `type`, `typeText`, `text`, `heartbeat`) VALUES ('{$idTag}', '{$SetType}', '{$this->type}', '{$data}', '{$heartbeat}')" ); } //If the command is to start a transaction, then assign a connector number if($type['2'] == 'RemoteStartTransaction') { $this->UpConnectorCommand($idTag, $type[3]->connectorId); } } //We receive some data from the station and process them through switch - we answer public function Status($data, $idTag = '') { $this->idTag = $idTag; $t = explode(" ",microtime()); $currentTime = date("Y-m-d\TH:i:s",time()).substr((string)$t[0],1,4).'Z'; if(!is_object($data[2])) { $this->type = $data[2]; } switch ($data[2]) { case 'BootNotification': $boot = new \stdClass(); $this->SetBootNotification($data); $boot->currentTime = $currentTime; $boot->interval = 60; $boot->status = 'Accepted'; $BootNotification = json_encode( array(0 =>3,1 => $data[1], $boot )); return $BootNotification; break; case 'StatusNotification': $this->SetStatus($data); $StatusNotification = json_encode( array(0 =>3,1 => $data[1], new \stdClass() )); return $StatusNotification; break; case 'Heartbeat': $head = new \stdClass(); $head->currentTime = $currentTime; $Heartbeat = json_encode( array(0 =>3,1 => $data[1], $head )); $this->SetHeartbeat($idTag, $data); return $Heartbeat; break; case 'StartTransaction': //Создаем номер транзакции из случайного числа $rand = rand(1, 999999999); $set = new \stdClass(); $set->parentIdTag = ''; $set->status = $this->StartTransactionStatus($idTag, $data); $StartTransaction = json_encode( array(0 => 3, 1 => $data[1], array('idTagInfo' => $set, 'transactionId' => $rand ) )); $times = time(); $user_id = $this->UserID($idTag); if($set->status == 'Accepted') { //Записываем в базу my_user_start_transaction кто и когда запустил транзакцию $this->db->query("INSERT INTO `my_user_start_transaction` (`user_id`, `transactionId`, `TimeCompletion`) VALUES ('{$user_id}', '{$rand}', '{$times}')"); //Записываем фальший 0, MeterValues, а так же далее шлем уведомление $this->SetFalseMeterValues($idTag, $user_id, $rand); return $StartTransaction; } else { $StopTransaction = json_encode( array(0 => 2, 1 => ''.rand(1000000,9999999).'', 2 => 'RemoteStopTransaction', array('transactionId' => $rand) )); $times = time(); $this->db->row("INSERT INTO `my_set_command` (`idTag`, `user_id`, `type`, `text`, `heartbeat`) VALUES ('{$idTag}', '{$user_id}', 'RemoteStopTransaction', '{$StopTransaction}', '{$times}')"); } break; case 'MeterValues': $this->MeterValues($idTag, $data); $this->SetHeartbeat($idTag, $data); $MeterValues = json_encode( array(0 => 3, 1 => $data[1], new \stdClass() )); return $MeterValues; break; case 'StopTransaction': $set = new \stdClass(); $set->parentIdTag = ''; $set->status = 'Accepted'; $StopTransaction = json_encode( array(0 => 3, 1 => $data[1], array('idTagInfo' => $set) )); $this->user_id = 1; return $StopTransaction; break; case 'Authorize': $Auth = new \stdClass(); $Auth->status = $this->AuthorizeStatus($idTag, $data);; $Authorize = json_encode( array(0 => 3, 1 => $data[1], array('idTagInfo' => $Auth ) )); return $Authorize; break; default: //print_r($data); break; } } public function StartTransactionStatus($idTag, $data) { $res = $this->db->row("SELECT * FROM `my_charger` WHERE idTag = '".$data[3]->idTag."' "); if($res) { return 'Accepted'; } else { return 'Blocked'; } } public function AuthorizeStatus($idTag, $data) { $res = $this->db->row("SELECT * FROM `my_charger_authorize` WHERE idTag = '{$idTag}' AND idTag_Authorize = '".$data[3]->idTag."' "); if($res) { return 'Accepted'; } else { return 'Blocked'; } } //Write the firmware version public function SetBootNotification($data) { $this->db->query("UPDATE my_charger SET firmwareVersion = '{$data[3]->firmwareVersion}' WHERE idTag = '{$this->idTag}'; "); } //Record heartbeat time public function SetHeartbeat($idTag, $data) { $time = time(); $this->db->row("UPDATE `my_charger` SET `heartbeat` = '{$time}' WHERE idTag = '{$idTag}'; "); } //Write the status of the stations in the StatusNotification method public function SetStatus($data) { //Проверяем базу если такие конектора $res = $this->db->row("SELECT * FROM `my_charger_connectorId` WHERE `idTag` LIKE '{$this->idTag}' "); if($res == false) { $this->connectorId($data); } else { $osp = $this->db->row("SELECT * FROM `my_charger_connectorId` WHERE `idTag` LIKE '{$this->idTag}' AND connectorId = '{$data[3]->connectorId}' "); if($osp == false) { $this->connectorId($data); } else { $this->db->query("UPDATE my_charger_connectorId SET status = '{$data[3]->status}', errorCode = '{$data[3]->errorCode}' WHERE idTag = '{$this->idTag}' AND connectorId = '{$data[3]->connectorId}' ; "); } } } //Write a fake 0, MeterValues public function SetFalseMeterValues($idTag, $user_id, $rand) { $times = time(); $user_id = $this->UserID($idTag); $connector_id = $this->ConnectorSID($idTag); $this->db->query( "INSERT INTO `my_charger_meter` (`userId`, `idTag`, `connectorId`, `transactionId`, `timestamp`) VALUES ('{$user_id}', '{$idTag}', '{$connector_id}', '{$rand}', '{$times}' )" ); $parentId = $this->db->lastInsertId(); $this->db->query( "INSERT INTO `my_charger_meter_type` (`idTag`, `transactionId`, `parentId`, `value`, `measurand`, `phase`, `unit`) VALUES ('{$idTag}', '{$rand}', '{$parentId}', 0, 'Energy.Active.Import.Register', NULL, 'Wh')" ); } //Updating information about the connector public function connectorId($data) { $this->db->query( "INSERT INTO `my_charger_connectorId` (`idTag`, `connectorId`, `status`, `errorCode`) VALUES ('{$this->idTag}', '{$data[3]->connectorId}', '{$data[3]->status}', '{$data[3]->errorCode}')" ); } //Get the id of the user who started the transaction public function UserTransactionId($transaction = 0) { if($transaction > 0) { $user = $this->db->row(" SELECT user_id FROM `my_user_start_transaction` WHERE `transactionId` = '{$transaction}' "); if($user['user_id'] > 0) { return $user['user_id']; } else { return $user['user_id']; } } else { return 1; } } public function MeterStartZero($idTag, $transactionId) { $zero_2 = $this->db->row("SELECT text FROM my_set_history WHERE idTag = '".$idTag."' AND type = 4 AND `text` LIKE '%[3%' AND text LIKE '%".$transactionId."%' order by id DESC "); $type = json_decode($zero_2['text']); $zero_3 = $this->db->row("SELECT text FROM my_set_history WHERE idTag = '".$idTag."' AND type = 4 AND `text` LIKE '%[2%' AND text LIKE '%".$type[1]."%' order by id DESC "); $Rtype = json_decode($zero_3['text']); return $Rtype[3]->meterStart; } //write data from counters public function MeterValues($idTag, $data) { if($data[2] == 'MeterValues') { if($data[3]->transactionId > 0) { $zero = $this->MeterStartZero($idTag, $data[3]->transactionId); if($zero > 0) { $this->NotStandardAlgorithm($data, $idTag, $zero); } else { $this->StandardAlgorithm($data, $idTag); } } //Stop charging function if the user's balance is less than 0 $transaction_user = $this->db->row("SELECT user_id FROM `my_user_start_transaction` WHERE transactionId = '{$data[3]->transactionId}' "); $user = $this->db->row("SELECT * FROM `my_user` WHERE id = '".$transaction_user['user_id']."' AND stop = 0 "); if($user) { if($user['balanse'] <= 0) { //If there is no stop command in the database, write the stop command to the database :) $row = $this->db->row("SELECT * FROM `my_set_command` WHERE idTag = '".$idTag."' AND type = 'RemoteStopTransaction' "); if($row === false) { $StopTransaction = json_encode( array(0 => 2, 1 => ''.rand(1000000,9999999).'', 2 => 'RemoteStopTransaction', array('transactionId' => $data[3]->transactionId) )); $mobile = $user['mobile']; $times = time(); $this->db->row("INSERT INTO `my_set_command` (`idTag`, `user_id`, `type`, `text`, `heartbeat`) VALUES ('{$idTag}', '{$mobile}', 'RemoteStopTransaction', '{$StopTransaction}', '{$times}')"); } } }//if($user) } } public function NotStandardAlgorithm($data, $idTag, $zero) { //Первым делом удаляем фальшивый MeterValues $this->db->query(" DELETE FROM `my_charger_meter_type` WHERE idTag ='".$idTag."' AND `transactionId` LIKE '".$data[3]->transactionId."' AND value = '0.00' AND `measurand` LIKE 'Energy.Active.Import.Register'; "); //Первым делом удоляем фальшивый MeterValues $times = time(); //Определяем кому принадлежит сессия $user = $this->UserTransactionId($data[3]->transactionId); $this->db->query( "INSERT INTO `my_charger_meter` (`userId`, `idTag`, `connectorId`, `transactionId`, `timestamp`) VALUES ('{$user}', '{$idTag}', '{$data[3]->connectorId}', '{$data[3]->transactionId}', '{$times}')" ); $parentId = $this->db->lastInsertId(); $eair = $this->searchForId('Energy.Active.Import.Register', $data[3]->meterValue[0]->sampledValue); if($eair === NULL) { //Шнайдер if(count($data[3]->meterValue[0]->sampledValue) == 1) { foreach ($data[3]->meterValue[0]->sampledValue as $key => $value) { $measurandS = 'Energy.Active.Import.Register'; $unitS = 'Wh'; $value = $value->value; $this->db->query( "INSERT INTO `my_charger_meter_type`(`idTag`,`transactionId`, `parentId`, `value`, `measurand`, `unit`) VALUES ('{$idTag}', '{$data[3]->transactionId}', '{$parentId}', '{$value}', '{$measurandS}', '{$unitS}')" ); $this->SetMoney($this->db->lastInsertId()); } }//Похожие станции с отсутствующим значением measurand = Energy.Active.Import.Register в масииве sampledValue else { foreach ($data[3]->meterValue[0]->sampledValue as $key => $value) { if(isset($value->phase)) {$phase = $value->phase;} else { $phase = NULL;} if(isset($value->unit)) {$unit = $value->unit;} else { $unit = NULL;} if(isset($value->measurand)) { $measurand = $value->measurand; $value = $value->value; } else { $measurand = 'Energy.Active.Import.Register'; $unit = 'Wh'; $value = $value->value - $zero; } $this->db->query( "INSERT INTO `my_charger_meter_type`(`idTag`,`transactionId`, `parentId`, `value`, `measurand`, `phase`, `unit`) VALUES ('{$idTag}', '{$data[3]->transactionId}', '{$parentId}', '{$value}', '{$measurand}', '{$phase}', '{$unit}')" ); $this->SetMoney($this->db->lastInsertId()); } } } else { //Все остальные станции foreach ($data[3]->meterValue[0]->sampledValue as $key => $value) { if(isset($value->phase)) {$phase = $value->phase;} else { $phase = NULL;} if(isset($value->unit)) {$unit = $value->unit;} else { $unit = NULL;} if(isset($value->measurand)) { if($value->measurand == 'Energy.Active.Import.Register') { $measurand = $value->measurand; $value = $value->value - $zero; } else { $measurand = $value->measurand; $value = $value->value; } } else { $measurand = NULL; $value = $value->value;} $this->db->query( "INSERT INTO `my_charger_meter_type`(`idTag`,`transactionId`, `parentId`, `value`, `measurand`, `phase`, `unit`) VALUES ('{$idTag}', '{$data[3]->transactionId}', '{$parentId}', '{$value}', '{$measurand}', '{$phase}', '{$unit}')" ); $this->SetMoney($this->db->lastInsertId()); } } } public function StandardAlgorithm($data, $idTag) { $times = time(); //Определяем кому принадлежит сессия $user = $this->UserTransactionId($data[3]->transactionId); $this->db->query( "INSERT INTO `my_charger_meter` (`userId`, `idTag`, `connectorId`, `transactionId`, `timestamp`) VALUES ('{$user}', '{$idTag}', '{$data[3]->connectorId}', '{$data[3]->transactionId}', '{$times}')" ); $parentId = $this->db->lastInsertId(); $eair = $this->searchForId('Energy.Active.Import.Register', $data[3]->meterValue[0]->sampledValue); if($eair === NULL) { //Шнайдер foreach ($data[3]->meterValue[0]->sampledValue as $key => $value) { $measurandS = 'Energy.Active.Import.Register'; $unitS = 'Wh'; $value = $value->value; $this->db->query( "INSERT INTO `my_charger_meter_type`(`idTag`,`transactionId`, `parentId`, `value`, `measurand`, `unit`) VALUES ('{$idTag}', '{$data[3]->transactionId}', '{$parentId}', '{$value}', '{$measurandS}', '{$unitS}')" ); $this->SetMoney($this->db->lastInsertId()); } } else { //Все остальные станции foreach ($data[3]->meterValue[0]->sampledValue as $key => $value) { if(isset($value->phase)) {$phase = $value->phase;} else { $phase = NULL;} if(isset($value->unit)) {$unit = $value->unit;} else { $unit = NULL;} if(isset($value->measurand)) {$measurand = $value->measurand;} else { $measurand = NULL;} if(isset($value->value)) {$value = $value->value;} else { $value = NULL;} $this->db->query( "INSERT INTO `my_charger_meter_type`(`idTag`,`transactionId`, `parentId`, `value`, `measurand`, `phase`, `unit`) VALUES ('{$idTag}', '{$data[3]->transactionId}', '{$parentId}', '{$value}', '{$measurand}', '{$phase}', '{$unit}')" ); $this->SetMoney($this->db->lastInsertId()); } } } // Ticketing public function SetMoney($parent_id) { //Если где то сработал MeterValues if($parent_id > 0) { //Получаем информаци о текщей операции $res = $this->db->row("SELECT * FROM `my_charger_meter_type` WHERE id = '{$parent_id}' "); //Если в масиве есть значение Energy.Active.Import.Register if($res['measurand'] == 'Energy.Active.Import.Register') { $times = time(); $parentId = $res['parentId']; //Получаем информацию о текущей операции $parent_id = $this->db->row("SELECT * FROM `my_charger_meter` WHERE id = '{$parentId}' "); //Устанавливаем переменные $transactionId = $parent_id['transactionId']; $idTag = $parent_id['idTag']; $connectorId = $parent_id['connectorId']; //Получаем предыдущию информацию о значения счетчика $old_t = $this->db->row("SELECT * FROM `my_charger_meter_type` WHERE transactionId = '{$transactionId}' AND idTag = '{$idTag}' AND measurand = 'Energy.Active.Import.Register' ORDER BY id DESC LIMIT 1, 1; "); //Переопределяем юзера - берем с текщей сесии $user_id = $this->UserTransactionId($transactionId); //Что бы узнать за сколько ватт снимать деньги, от текущей операции отнимаем значение предыдущей операции (значения счетчика) $wh = $res['value'] - $old_t['value']; $special = $this->SpecialMoney($idTag, $connectorId, $user_id); if($special > 0) { $price_c = $special/1000; } else { //Получаем стандартную стоимость 1Квт на текущем конекторе $connector = $this->db->row("SELECT * FROM `my_charger_connectorId` WHERE idTag = '{$idTag}' AND connectorId = '{$connectorId}' ; "); //Переводим Квт В Ватты $price_c = $connector['price']/1000; } //Сумма за затраченную энергию в текущем состоянии $price_m = $wh*$price_c; //Записываем значения в базу my_user_operations о затраченой энергии и денег $this->db->query( "INSERT INTO `my_user_operations`(`user_id`,`transactionId`, `operationTime`, `MeterValues`, `money`) VALUES ('{$user_id}', '{$transactionId}', '{$times}', '{$wh}', '{$price_m}')" ); $parentId = $this->db->lastInsertId(); //Полученную сумму отнимает от основного счета $sum_user = $this->db->row("SELECT * FROM `my_user` WHERE id = '{$user_id}' AND visible = '1' ; "); $bals_user = $sum_user['balanse'] - $price_m; //Обновляем баланс юзера $this->db->row("UPDATE `my_user` SET `balanse` = '{$bals_user}' WHERE id = '{$user_id}'; "); //Записываем остаток баланса $this->db->row("UPDATE `my_user_operations` SET `user_balanse` = '{$bals_user}' WHERE id = '{$parentId}'; "); } } } // Special price for some users public function SpecialMoney($idTag, $connectorId, $user_id) { //Получаем номер пользователя, он же логин $mobile = $this->db->row("SELECT mobile FROM `my_user` WHERE id = '{$user_id}'; "); //Проверяем если спец цена для юзера на этой станции и конекторе $connector = $this->db->row("SELECT * FROM `my_charger_connectorId_special` WHERE idTag = '{$idTag}' AND connectorId = '{$connectorId}' AND user_id = '".$mobile['mobile']."' AND endcdate > '".time()."' ; "); if($connector) { return $connector['price']; } } //What type is this number public function SetType($type) { switch ($type) { case 'Heartbeat': $int = 1; break; case 'BootNotification': $int = 2; break; case 'StatusNotification': $int = 3; break; case 'StartTransaction': $int = 4; break; case 'StopTransaction': $int = 5; break; case 'RemoteStartTransaction': $int = 6; break; case 'RemoteStopTransaction': $int = 7; break; case 'MeterValues': $int = 8; break; case 'Authorize': $int = 9; break; case 'Reset': $int = 10; break; case 'UpdateFirmware': $int = 11; break; case 'GetDiagnostics': $int = 12; break; case 'DiagnosticsStatusNotification': $int = 13; break; case 'FirmwareStatusNotification': $int = 14; break; case 'TriggerMessage': $int = 15; break; case 'ChangeConfiguration': $int = 16; break; case 'GetConfiguration': $int = 17; break; case 'ClearCache': $int = 18; break; case 'ReserveNow': $int = 19; break; case 'CancelReservation': $int = 20; break; case 'UnlockConnector': $int = 21; break; case 'DataTransfer': $int = 22; break; default: continue; break; } return $int; } //Search for the Energy.Active.Import.Register value in the array public function searchForId($id, $array) { foreach ($array as $key => $val) { if(isset($val->measurand)) { if ($val->measurand === $id) { return $key; } } } return null; } }