Source of file api.generators.php
Size: 64,963 Bytes - Last Modified: 2026-06-05T10:00:07+03:00
/tmp/current_snapshot/api/libs/api.generators.php
| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723 | <?php/** * Electrical generators management and accounting */class Generators { /** * Contains system alter.ini config as key=>value * * @var array */protected $altCfg = array(); /** * System message helper object placeholder * * @var object */protected $messages = ''; /** * Contains devices database abstraction layer * * @var object */protected $devicesDb = ''; /** * Contains services database abstraction layer * * @var object */protected $servicesDb = ''; /** * Contains events database abstraction layer * * @var object */protected $eventsDb = ''; /** * Contains refuels database abstraction layer * * @var object */protected $refuelsDb = ''; /** * OnePunch object placeholder * * @var object */protected $onePunch = ''; /** * Contains available fuel types * * @var array */protected $fuelTypes = array(); /** * Contains all generator devices as id=>data * * @var array */protected $allDevices = array(); /** * Contains all generator services * * @var array */protected $allServices = array(); /** * Contains all generator events * * @var array */protected $allEvents = array(); /** * Contains all generator refuels * * @var array */protected $allRefuels = array(); /** * Contains filtered OnePunch punch scripts for generators state monitoring as alias=>name * * @var array */protected $availScripts = array(); // some predefined stuff here const TABLE_DEVICES = 'gen_devices'; const TABLE_SERVICE_TYPES = 'gen_service_types'; const TABLE_SERVICES = 'gen_services'; const TABLE_EVENTS = 'gen_events'; const TABLE_REFUELS = 'gen_refuels'; //get routes here const URL_ME = '?module=generators'; const ROUTE_DEVICES = 'devices'; const ROUTE_DELETE_DEVICE = 'deletedeviceid'; const ROUTE_START_DEVICE = 'startdeviceid'; const ROUTE_STOP_DEVICE = 'stopdeviceid'; const ROUTE_VIEW_EVENTS = 'viewevents'; const ROUTE_VIEW_EVENTS_ALL = 'eventsall'; const ROUTE_VIEW_SERVICES_ALL='servicesall'; const ROUTE_EDIT_SERVICE = 'editserviceid'; const ROUTE_VIEW_REFUELS_ALL='refuelsall'; const ROUTE_EDIT_REFUEL = 'editrefuelid'; const ROUTE_VIEW_MAP='rendermap'; //some form routes here const PROUTE_NEW_DEVICE = 'createdevice'; const PROUTE_EDIT_DEVICE = 'editdeviceid'; const PROUTE_DEV_MODEL = 'devmodel'; const PROUTE_DEV_FUEL_TYPE = 'devfueltype'; const PROUTE_DEV_TANK_VOLUME = 'devtankvolume'; const PROUTE_DEV_FUEL_CONSUMPTION = 'devfuelconsumption'; const PROUTE_DEV_ADDRESS = 'devaddress'; const PROUTE_DEV_GEO = 'devgeo'; const PROUTE_DEV_MOTO_HOURS = 'devmotohours'; const PROUTE_DEV_SERVICE_INTERVAL = 'devserviceinterval'; const PROUTE_DEV_OP_ALIAS = 'devopalias'; const PROUTE_REFUEL_DEVICE = 'refueldevice'; const PROUTE_REFUEL_LITERS = 'refuelliters'; const PROUTE_REFUEL_PRICE = 'refuelprice'; const PROUTE_EDIT_REFUEL = 'editrefuel'; const PROUTE_SERVICE_DEVICE = 'servicedevice'; const PROUTE_SERVICE_MOTO_HOURS = 'servicemotohours'; const PROUTE_SERVICE_NOTES = 'servicenotes'; const PROUTE_SERVICE_DATE = 'servicedate'; const PROUTE_SERVICE_TIME = 'servicetime'; const PROUTE_EDIT_SERVICE = 'editservice'; //other stuff const WATCHER_PID='GENERATORS'; const OP_MON_MARK='$generatorState'; //// .----------.// | ~ON~ |// | ____ |// | |.--.| |// | || || |// | ||__|| |// | ||\ \| |// | |\ \_\ |// | |_\[_] |// | |// | ~OFF~ |// '----------'///** * Creates new Generators instance * * @return void */public function __construct() { $this->loadConfig(); $this->initMessages(); $this->setFuelTypes(); $this->initDb(); $this->initOnePunch(); $this->loadOnePunchScripts(); $this->loadDevices(); $this->loadServices(); $this->loadEvents(); $this->loadRefuels(); } /** * Loads system alter.ini config * * @return void */protected function loadConfig() { global $ubillingConfig; $this->altCfg = $ubillingConfig->getAlter(); } /** * Initializes message helper instance * * @return void */protected function initMessages() { $this->messages = new UbillingMessageHelper(); } /** * Initializes onepunch object * * @return void */protected function initOnePunch() { $this->onePunch = new OnePunch(); } /** * Preloads all one punch scripts and filters them for generators state monitoring * * @return void */protected function loadOnePunchScripts() { $allScripts= $this->onePunch->getAllScripts(); if (!empty($allScripts)) { foreach ($allScripts as $io => $each) { if (ispos($each['content'], self::OP_MON_MARK)) { $this->availScripts[$each['alias']] = $each['name']; } } } } /** * Initializes database abstraction layers * * @return void */protected function initDb() { $this->devicesDb = new NyanORM(self::TABLE_DEVICES); $this->servicesDb = new NyanORM(self::TABLE_SERVICES); $this->eventsDb = new NyanORM(self::TABLE_EVENTS); $this->refuelsDb = new NyanORM(self::TABLE_REFUELS); } /** * Sets available fuel types * * @return void */protected function setFuelTypes() { $this->fuelTypes = array( 'diesel' => __('Diesel'), 'petrol' => __('Petrol'), 'lpg' => __('Liquefied petroleum gas'), 'wood' => __('On the wood'), 'other' => __('Other') ); } /** * Loads all generator devices from database * * @return void */protected function loadDevices() { $this->allDevices = $this->devicesDb->getAll('id'); } /** * Loads all services from database * * @return void */protected function loadServices() { $this->allServices = $this->servicesDb->getAll('id'); } /** * Loads all events from database * * @return void */protected function loadEvents() { $this->allEvents = $this->eventsDb->getAll('id'); } /** * Loads all refuels from database * * @return void */protected function loadRefuels() { $this->allRefuels = $this->refuelsDb->getAll('id'); } /** * Gets events count for device * * @param int $deviceId * * @return int */protected function getDeviceEventsCount($deviceId) { $result = 0; if (!empty($this->allEvents)) { foreach ($this->allEvents as $io => $event) { if ($event['genid'] == $deviceId) { $result++; } } } return ($result); } /** * Gets next maintenance date in motohours remaining * * @param int $deviceId * @param int $runningSeconds * * @return string */protected function getNextMaintenanceDate($deviceId, $runningSeconds = 0) { $result = '-'; $deviceId = ubRouting::filters($deviceId, 'int'); $runningSeconds = ubRouting::filters($runningSeconds, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $serviceInterval = $device['serviceinterval']; $currentMotohours = $device['motohours']; if ($runningSeconds > 0) { $currentMotohours += $runningSeconds / 3600; } if ($serviceInterval > 0) { $lastServiceMotohours = 0; if (!empty($this->allServices)) { foreach ($this->allServices as $io => $service) { if ($service['genid'] == $deviceId) { if ($service['motohours'] > $lastServiceMotohours) { $lastServiceMotohours = $service['motohours']; } } } } $nextMaintenanceMotohours = $lastServiceMotohours + $serviceInterval; $remainingMotohours = $nextMaintenanceMotohours - $currentMotohours; if ($remainingMotohours > 0) { $result = round($remainingMotohours, 2) . ' ' . __('hours'); } else { $result = __('Overdue') . '! (' . round(abs($remainingMotohours), 2) . ' ' . __('hours') . ')'; } } } return ($result); } /** * Creates service record for device * * @param int $deviceId * * @return string */public function createService($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $requiredFields = array(self::PROUTE_SERVICE_DEVICE, self::PROUTE_SERVICE_MOTO_HOURS); if (ubRouting::checkPost($requiredFields)) { $motohours = ubRouting::post(self::PROUTE_SERVICE_MOTO_HOURS, 'float'); $notes = ubRouting::post(self::PROUTE_SERVICE_NOTES, 'safe'); $notes= ubRouting::filters($notes, 'mres'); $serviceDate = ubRouting::post(self::PROUTE_SERVICE_DATE, 'mres'); $serviceTime = ubRouting::post(self::PROUTE_SERVICE_TIME, 'mres'); if ($motohours >= 0) { $serviceDateTime = curdatetime(); if (!empty($serviceDate) AND !empty($serviceTime)) { $serviceDateTime = $serviceDate . ' ' . $serviceTime . ':00'; } elseif (!empty($serviceDate)) { $serviceDateTime = $serviceDate . ' ' . date('H:i:s'); } $this->servicesDb->data('genid', $deviceId); $this->servicesDb->data('date', $serviceDateTime); $this->servicesDb->data('motohours', $motohours); $this->servicesDb->data('notes', $notes); $this->servicesDb->create(); $this->loadServices(); log_register('GENERATORS DEVICE MAINTENANCE [' . $deviceId . '] MOTOHOURS `' . $motohours . '`'); } else { $result = __('Invalid motohours value'); } } } else { $result = __('Something went wrong') . ': [' . $deviceId . '] ' . __('Not exists'); } return ($result); } /** * Calculates fuel consumption for device during working time * * @param int $deviceId * @param int $seconds * * @return float */public function calculateFuelConsumption($deviceId, $seconds) { $result = 0; $deviceId = ubRouting::filters($deviceId, 'int'); $seconds = ubRouting::filters($seconds, 'int'); if (isset($this->allDevices[$deviceId]) AND $seconds > 0) { $consumption = $this->allDevices[$deviceId]['consumption']; $hours = $seconds / 3600; $result = $consumption * $hours; } return ($result); } /** * Gets running time for device since last start event in seconds * * @param int $deviceId * * @return int */protected function getDeviceRunningTime($deviceId) { $result = 0; $lastStartTime = 0; if (!empty($this->allEvents)) { foreach ($this->allEvents as $io => $event) { if ($event['genid'] == $deviceId AND $event['event'] == 'start') { $eventTime = strtotime($event['date']); if ($eventTime > $lastStartTime) { $lastStartTime = $eventTime; } } } } if ($lastStartTime > 0) { $currentTime = strtotime(curdatetime()); $result = $currentTime - $lastStartTime; if ($result < 0) { $result = 0; } } return ($result); } /** * Renders navigation controls * * @return string */public function renderControls() { $result = ''; $devicesUrl = self::URL_ME . '&' . self::ROUTE_DEVICES . '=true'; $result .= wf_Link($devicesUrl, wf_img('skins/icon_generators.png') . ' ' . __('Devices'), false, 'ubButton') . ' '; $eventsAllUrl = self::URL_ME . '&' . self::ROUTE_VIEW_EVENTS_ALL . '=true'; $result .= wf_Link($eventsAllUrl, wf_img('skins/log_icon_small.png') . ' ' . __('Events'), false, 'ubButton') . ' '; $servicesUrl = self::URL_ME . '&' . self::ROUTE_VIEW_SERVICES_ALL . '=true'; $result .= wf_Link($servicesUrl, wf_img('skins/icon_repair.gif') . ' ' . __('Maintenance'), false, 'ubButton') . ' '; $refuelsUrl = self::URL_ME . '&' . self::ROUTE_VIEW_REFUELS_ALL . '=true'; $result .= wf_Link($refuelsUrl, wf_img('skins/icon_fuel.png') . ' ' . __('Refuels'), false, 'ubButton') . ' '; $mapUrl = self::URL_ME . '&' . self::ROUTE_VIEW_MAP . '=true'; $result .= wf_Link($mapUrl, wf_img('skins/icon_map_small.png') . ' ' . __('Map'), false, 'ubButton') . ' '; return ($result); } /** * Renders device start stop dialog * * @param int $deviceId * * @return string */protected function renderDeviceStartStopDialog($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $cancelUrl=self::URL_ME.'&'.self::ROUTE_DEVICES.'=true'; if ($device['running']) { $stopUrl = self::URL_ME . '&' . self::ROUTE_STOP_DEVICE . '=' . $device['id']; $shutdownText=__('Stop').' '.__('generator').': '.$device['address'].'?'; $result.=wf_ConfirmDialog($stopUrl, wf_img('skins/pause.png',__('Stop')), $shutdownText, '', $cancelUrl, __('Stop').'?'); } else { $startUrl = self::URL_ME . '&' . self::ROUTE_START_DEVICE . '=' . $device['id']; $startText=__('Start').' '.__('generator').': '.$device['address'].'?'; $result.=wf_ConfirmDialog($startUrl, wf_img('skins/play.png',__('Start')), $startText, '', $cancelUrl, __('Start').'?'); } } return ($result); } /** * Renders generator devices list with actions * * @return string */public function renderDevicesList() { $result = ''; $anyActionsAvailable = false; if (cfr('GENERATORSMGMT') or cfr('GENERATORSREFUEL') or cfr('GENERATORSSERVICE') or cfr('GENERATORSRUN')) { $anyActionsAvailable = true; } if (!empty($this->allDevices)) { $cells = wf_TableCell(__('Model')); $cells .= wf_TableCell(__('Address')); $cells.= wf_TableCell(__('Running')); $cells .= wf_TableCell(__('Motohours')); $cells .= wf_TableCell(__('In tank')); $cells .= wf_TableCell(__('Fuel level')); // in percent $cells .= wf_TableCell(__('Next maintenance')); $cells.= wf_TableCell(__('Events')); if ($anyActionsAvailable) { $cells .= wf_TableCell(__('Actions')); } $rows = wf_TableRow($cells, 'row1'); foreach ($this->allDevices as $io=>$device) { $cells = wf_TableCell($device['model']); $cells .= wf_TableCell($device['address']); $runningDisplay = web_bool_led($device['running']); $fuelConsumed=0; $deviceMotohours=$device['motohours']; $runningSeconds=0; if ($device['running']) { $runningSeconds = $this->getDeviceRunningTime($device['id']); if ($runningSeconds > 0) { $fuelConsumption = $this->calculateFuelConsumption($device['id'], $runningSeconds); $fuelConsumed += $fuelConsumption; $runningDisplay .= ' ('; $runningDisplay .= zb_formatTime($runningSeconds); $runningDisplay .= ', ' . round($fuelConsumption, 2) . ' ' . __('litre'); $runningDisplay .= ')'; $deviceMotohours += $runningSeconds / 3600; } } $cells .= wf_TableCell($runningDisplay); $cells .= wf_TableCell(round($deviceMotohours, 2)); $cells .= wf_TableCell(round($device['intank']-$fuelConsumed, 2) . ' ' . __('litre')); $cells .= wf_TableCell(round($this->calculateInTankPercent($device['id']),2). '%'); $nextMaintenanceDate=$this->getNextMaintenanceDate($device['id'], $runningSeconds); $cells .= wf_TableCell($nextMaintenanceDate); $eventsCount = $this->getDeviceEventsCount($device['id']); $eventsUrl = self::URL_ME . '&' . self::ROUTE_VIEW_EVENTS . '=' . $device['id']; $eventsLink = wf_Link($eventsUrl, $eventsCount, false, ''); $cells .= wf_TableCell($eventsLink); $deviceControls=''; if ($anyActionsAvailable) { if (cfr('GENERATORSMGMT')) { $deletionUrl = self::URL_ME . '&' . self::ROUTE_DELETE_DEVICE . '=' . $device['id']; $cancelUrl=self::URL_ME . '&' . self::ROUTE_DEVICES . '=true'; $deletionDialog=wf_ConfirmDialog($deletionUrl, web_delete_icon(), $this->messages->getDeleteAlert(), '', $cancelUrl, __('Delete').'?'); $deviceControls .= $deletionDialog; $editTitle = __('Edit').' ID:' . $device['id'] . ', '.$device['address']; $editDialog = wf_modalAuto(web_edit_icon(), $editTitle, $this->renderDeviceEditForm($device['id'])); $deviceControls .= $editDialog; } if (cfr('GENERATORSRUN')) { $deviceControls .= $this->renderDeviceStartStopDialog($device['id']); } if (cfr('GENERATORSSERVICE')) { $serviceForm = $this->renderServiceForm($device['id']); $deviceControls .= $serviceForm; } if (cfr('GENERATORSREFUEL')) { $refuelForm=$this->renderRefuelForm($device['id']); $deviceControls .= $refuelForm; } $cells .= wf_TableCell($deviceControls); } $rows .= wf_TableRow($cells, 'row5'); } $result .= wf_TableBody($rows, '100%', 0, 'sortable'); } else { $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning'); } return ($result); } /** * Renders service form for device * * @param int $deviceId * * @return string */protected function renderServiceForm($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $deviceMotohours = $device['motohours']; if ($device['running']) { $runningSeconds = $this->getDeviceRunningTime($deviceId); if ($runningSeconds > 0) { $deviceMotohours += $runningSeconds / 3600; } } $currentDate = date('Y-m-d'); $currentTime = date('H:i'); $inputs = wf_HiddenInput(self::PROUTE_SERVICE_DEVICE, $deviceId); $inputs .= wf_TextInput(self::PROUTE_SERVICE_MOTO_HOURS, __('Motohours'), round($deviceMotohours, 2), false, 8, 'float').' '; $inputs .= wf_DatePickerPreset(self::PROUTE_SERVICE_DATE, $currentDate, true); $inputs .= wf_tag('label') . __('Date') . wf_tag('label', true).' '; $inputs .= wf_TimePickerPreset(self::PROUTE_SERVICE_TIME, $currentTime, __('Time'), true).' '; $inputs .= wf_TextArea(self::PROUTE_SERVICE_NOTES, '', '', true, '50x5'); $inputs .= wf_Submit(__('Create'). ' '.__('maintenance')); $form = wf_Form('', 'POST', $inputs, 'glamour'); $result = wf_modalAuto(wf_img('skins/icon_repair.gif',__('Maintenance')), __('Maintenance'), $form, ''); } return ($result); } /** * Renders refuel form for device * * @param int $deviceId * * @return string */protected function renderRefuelForm($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $latestResuelPrice=$this->getLatestRefuelPrice($deviceId); $inputs = wf_HiddenInput(self::PROUTE_REFUEL_DEVICE, $deviceId); $inputs .= wf_TextInput(self::PROUTE_REFUEL_LITERS, __('Litre'), '', true, 6, 'float'); $inputs .= wf_TextInput(self::PROUTE_REFUEL_PRICE, __('Price'), $latestResuelPrice, true, 4, 'finance'); $inputs .= wf_Submit(__('Refuel')); $form = wf_Form('', 'POST', $inputs, 'glamour'); $result = wf_modalAuto(wf_img('skins/icon_fuel.png',__('Refuel')), __('Refuel'), $form, ''); } return ($result); } /** * Gets latest refuel price for device * * @param int $deviceId * * @return float */protected function getLatestRefuelPrice($deviceId) { $result = 0; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allRefuels[$deviceId])) { foreach ($this->allRefuels as $io => $refuel) { if ($refuel['genid'] == $deviceId) { $result = $refuel['price']; } } } return ($result); } /** * Creates refuel record and updates device intank * * @param int $deviceId * * @return string */public function createRefuel($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $requiredFields = array(self::PROUTE_REFUEL_DEVICE, self::PROUTE_REFUEL_LITERS); if (ubRouting::checkPost($requiredFields)) { $liters = ubRouting::post(self::PROUTE_REFUEL_LITERS, 'float'); $price = ubRouting::post(self::PROUTE_REFUEL_PRICE, 'float'); if ($liters > 0) { $currentIntank = $this->allDevices[$deviceId]['intank']; $tankVolume = $this->allDevices[$deviceId]['tankvolume']; $newIntank = $currentIntank + $liters; if ($newIntank <= $tankVolume) { $this->refuelsDb->data('genid', $deviceId); $this->refuelsDb->data('date', curdatetime()); $this->refuelsDb->data('liters', $liters); $this->refuelsDb->data('price', $price); $this->refuelsDb->create(); $this->setDeviceIntank($deviceId, $newIntank); $this->loadDevices(); log_register('GENERATORS DEVICE REFUEL [' . $deviceId . '] LITERS `' . $liters . '` PRICE `' . $price . '`'); } else { $result = __('Tank overflow') . ': ' . __('Maximum') . ' ' . $tankVolume . ' ' . __('litre'); } } else { $result = __('Invalid values'); } } } else { $result = __('Something went wrong') . ': [' . $deviceId . '] ' . __('Not exists'); } return ($result); } /** * Sets device intank value * * @param int $deviceId * @param float $liters * * @return void */protected function setDeviceIntank($deviceId, $liters) { $deviceId = ubRouting::filters($deviceId, 'int'); $liters = ubRouting::filters($liters, 'float'); if (isset($this->allDevices[$deviceId])) { $this->devicesDb->where('id', '=', $deviceId); $this->devicesDb->data('intank', $liters); $this->devicesDb->save(); } } /** * Renders device creation form * * @return string */public function renderDeviceCreateForm() { $result = ''; $sup=wf_tag('sup') . '*' . wf_tag('sup', true); $inputs = wf_HiddenInput(self::PROUTE_NEW_DEVICE, 'true'); $inputs .= wf_TextInput(self::PROUTE_DEV_MODEL, __('Model') . $sup, '', true, 20); $inputs .= wf_TextInput(self::PROUTE_DEV_ADDRESS, __('Address') . $sup, '', true, 30); $inputs .= wf_TextInput(self::PROUTE_DEV_GEO, __('Location'), '', true, 20, 'geo'); $inputs .= wf_Selector(self::PROUTE_DEV_FUEL_TYPE, $this->fuelTypes, __('Fuel type') . $sup, '', true); $inputs .= wf_TextInput(self::PROUTE_DEV_TANK_VOLUME, __('Tank volume'), '', true, 4, 'digits'); $inputs .= wf_TextInput(self::PROUTE_DEV_FUEL_CONSUMPTION, __('Fuel consumption'), '', true, 4, 'float'); $inputs .= wf_TextInput(self::PROUTE_DEV_MOTO_HOURS, __('Motohours'), '', true, 8, 'float'); $inputs .= wf_TextInput(self::PROUTE_DEV_SERVICE_INTERVAL, __('Service interval'), '', true, 4, 'digits'); $availScripts=array(''=>'-'); $availScripts=array_merge($availScripts, $this->availScripts); $inputs .= wf_Selector(self::PROUTE_DEV_OP_ALIAS, $availScripts, __('One-punch').' '.__('script'), '', true); $inputs .= wf_Submit(__('Create')); $result .= wf_Form('', 'POST', $inputs, 'glamour'); return ($result); } /** * Creates new generator device * * @return void */public function createDevice() { $requiredFields = array(self::PROUTE_NEW_DEVICE, self::PROUTE_DEV_MODEL, self::PROUTE_DEV_ADDRESS, self::PROUTE_DEV_FUEL_TYPE); if (ubRouting::checkPost($requiredFields)) { $newModel = ubRouting::post(self::PROUTE_DEV_MODEL, 'safe'); $newAddress = ubRouting::post(self::PROUTE_DEV_ADDRESS, 'safe'); $newGeo = ubRouting::post(self::PROUTE_DEV_GEO, 'mres'); $newFuelType = ubRouting::post(self::PROUTE_DEV_FUEL_TYPE, 'gigasafe'); $newTankVolume = ubRouting::post(self::PROUTE_DEV_TANK_VOLUME, 'int'); $newFuelConsumption = ubRouting::post(self::PROUTE_DEV_FUEL_CONSUMPTION, 'float'); $newMotohours = ubRouting::post(self::PROUTE_DEV_MOTO_HOURS, 'float'); $newServiceInterval = ubRouting::post(self::PROUTE_DEV_SERVICE_INTERVAL, 'int'); $newOpAlias = ubRouting::post(self::PROUTE_DEV_OP_ALIAS, 'mres'); if (!empty($newModel) AND !empty($newAddress) AND !empty($newFuelType)) { $this->devicesDb->data('model', $newModel); $this->devicesDb->data('address', $newAddress); $this->devicesDb->data('geo', $newGeo); $this->devicesDb->data('fuel', $newFuelType); $this->devicesDb->data('tankvolume', $newTankVolume); $this->devicesDb->data('consumption', $newFuelConsumption); $this->devicesDb->data('motohours', $newMotohours); $this->devicesDb->data('serviceinterval', $newServiceInterval); $this->devicesDb->data('opalias', $newOpAlias); $this->devicesDb->data('running', 0); //default running state is off $this->devicesDb->create(); $newDeviceId = $this->devicesDb->getLastId(); log_register('GENERATORS DEVICE CREATE [' . $newDeviceId . ']'); } } } /** * Deletes generator device * * @param int $deviceId * * @return string */public function deleteDevice($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $this->eventsDb->where('genid', '=', $deviceId); $this->eventsDb->delete(); $this->servicesDb->where('genid', '=', $deviceId); $this->servicesDb->delete(); $this->refuelsDb->where('genid', '=', $deviceId); $this->refuelsDb->delete(); $this->devicesDb->where('id','=',$deviceId); $this->devicesDb->delete(); log_register('GENERATORS DEVICE DELETE [' . $deviceId . ']'); } else { $result = __('Something went wrong') . ': [' . $deviceId . '] ' . __('Not exists'); } return ($result); } /** * Renders device edit form * * @param int $deviceId * * @return string */public function renderDeviceEditForm($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $sup=wf_tag('sup') . '*' . wf_tag('sup', true); $inputs = wf_HiddenInput(self::PROUTE_EDIT_DEVICE, $deviceId); $inputs .= wf_TextInput(self::PROUTE_DEV_MODEL, __('Model') . $sup, $device['model'], true, 20); $inputs .= wf_TextInput(self::PROUTE_DEV_ADDRESS, __('Address') . $sup, $device['address'], true, 30); $inputs .= wf_TextInput(self::PROUTE_DEV_GEO, __('Location'), $device['geo'], true, 20, 'geo'); $inputs .= wf_Selector(self::PROUTE_DEV_FUEL_TYPE, $this->fuelTypes, __('Fuel type') . $sup, $device['fuel'], true); $inputs .= wf_TextInput(self::PROUTE_DEV_TANK_VOLUME, __('Tank volume'), $device['tankvolume'], true, 4, 'digits'); $inputs .= wf_TextInput(self::PROUTE_DEV_FUEL_CONSUMPTION, __('Fuel consumption'), $device['consumption'], true, 4, 'float'); $inputs .= wf_TextInput(self::PROUTE_DEV_MOTO_HOURS, __('Motohours'), $device['motohours'], true, 8, 'float'); $inputs .= wf_TextInput(self::PROUTE_DEV_SERVICE_INTERVAL, __('Service interval'), $device['serviceinterval'], true, 4, 'digits'); $availScripts=array(''=>'-'); $availScripts=array_merge($availScripts, $this->availScripts); $inputs .= wf_Selector(self::PROUTE_DEV_OP_ALIAS, $availScripts, __('One-punch').' '.__('script'), $device['opalias'], true); $inputs .= wf_Submit(__('Save')); $result .= wf_Form('', 'POST', $inputs, 'glamour'); } else { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('Not exists'), 'error'); } return ($result); } /** * Updates generator device data * * @param int $deviceId * * @return string */public function updateDevice($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $requiredFields = array(self::PROUTE_EDIT_DEVICE, self::PROUTE_DEV_MODEL, self::PROUTE_DEV_ADDRESS, self::PROUTE_DEV_FUEL_TYPE); if (ubRouting::checkPost($requiredFields)) { $newModel = ubRouting::post(self::PROUTE_DEV_MODEL, 'safe'); $newAddress = ubRouting::post(self::PROUTE_DEV_ADDRESS, 'safe'); $newGeo = ubRouting::post(self::PROUTE_DEV_GEO, 'mres'); $newFuelType = ubRouting::post(self::PROUTE_DEV_FUEL_TYPE, 'gigasafe'); $newTankVolume = ubRouting::post(self::PROUTE_DEV_TANK_VOLUME, 'int'); $newFuelConsumption = ubRouting::post(self::PROUTE_DEV_FUEL_CONSUMPTION, 'float'); $newMotohours = ubRouting::post(self::PROUTE_DEV_MOTO_HOURS, 'float'); $newServiceInterval = ubRouting::post(self::PROUTE_DEV_SERVICE_INTERVAL, 'int'); $newOpAlias = ubRouting::post(self::PROUTE_DEV_OP_ALIAS, 'mres'); if (!empty($newModel) AND !empty($newAddress) AND !empty($newFuelType)) { $this->devicesDb->where('id', '=', $deviceId); $this->devicesDb->data('model', $newModel); $this->devicesDb->data('address', $newAddress); $this->devicesDb->data('geo', $newGeo); $this->devicesDb->data('fuel', $newFuelType); $this->devicesDb->data('tankvolume', $newTankVolume); $this->devicesDb->data('consumption', $newFuelConsumption); $this->devicesDb->data('motohours', $newMotohours); $this->devicesDb->data('serviceinterval', $newServiceInterval); $this->devicesDb->data('opalias', $newOpAlias); $this->devicesDb->save(); $this->loadDevices(); log_register('GENERATORS DEVICE EDIT [' . $deviceId . ']'); } } } else { $result = __('Something went wrong') . ': [' . $deviceId . '] ' . __('Not exists'); } return ($result); } /** * Starts generator device * * @param int $deviceId * * @return string */public function startDevice($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { if (!$this->allDevices[$deviceId]['running']) { $this->devicesDb->where('id', '=', $deviceId); $this->devicesDb->data('running', 1); $this->devicesDb->save(); $this->eventsDb->data('genid', $deviceId); $this->eventsDb->data('event', 'start'); $this->eventsDb->data('date', curdatetime()); $this->eventsDb->create(); $this->loadDevices(); log_register('GENERATORS DEVICE START [' . $deviceId . ']'); } else { $result = __('Generator is already running'); } } else { $result = __('Something went wrong') . ': [' . $deviceId . '] ' . __('Not exists'); } return ($result); } /** * Updates device motohours based on last start event * * @param int $deviceId * * @return int */protected function updateDeviceMotohours($deviceId) { $result = 0; $lastStartTime = 0; if (!empty($this->allEvents)) { foreach ($this->allEvents as $io => $event) { if ($event['genid'] == $deviceId AND $event['event'] == 'start') { $eventTime = strtotime($event['date']); if ($eventTime > $lastStartTime) { $lastStartTime = $eventTime; } } } } if ($lastStartTime > 0) { $stopTime = strtotime(curdatetime()); $secondsDiff = $stopTime - $lastStartTime; if ($secondsDiff > 0) { $result = $secondsDiff; $hoursDiff = $secondsDiff / 3600; $currentMotohours = $this->allDevices[$deviceId]['motohours']; $newMotohours = $currentMotohours + $hoursDiff; $this->devicesDb->where('id', '=', $deviceId); $this->devicesDb->data('motohours', $newMotohours); $this->devicesDb->save(); } } return ($result); } /** * Updates device fuel lefts counter * * @param int $deviceId * @param int $timePassed * * @return int */protected function updateDeviceIntank($deviceId, $timePassed) { $result = 0; $deviceId = ubRouting::filters($deviceId, 'int'); $timePassed = ubRouting::filters($timePassed, 'int'); if (isset($this->allDevices[$deviceId])) { $fuelConsumption = $this->calculateFuelConsumption($deviceId, $timePassed); $newIntank = $this->allDevices[$deviceId]['intank'] - $fuelConsumption; $this->devicesDb->where('id', '=', $deviceId); $this->devicesDb->data('intank', $newIntank); $this->devicesDb->save(); $result = $newIntank; } return ($result); } /** * Stops generator device * * @param int $deviceId * * @return string */public function stopDevice($deviceId) { $result = ''; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { if ($this->allDevices[$deviceId]['running']) { $this->devicesDb->where('id', '=', $deviceId); $this->devicesDb->data('running', 0); $this->devicesDb->save(); $this->eventsDb->data('genid', $deviceId); $this->eventsDb->data('event', 'stop'); $this->eventsDb->data('date', curdatetime()); $this->eventsDb->create(); $this->loadDevices(); //updating device motorhours counter $timePassed=$this->updateDeviceMotohours($deviceId); //updating device fuel lefts counter $this->updateDeviceIntank($deviceId, $timePassed); log_register('GENERATORS DEVICE STOP [' . $deviceId . '] AFTER `' . $timePassed . '` SEC'); } else { $result = __('Generator is already stopped'); } } else { $result = __('Something went wrong') . ': [' . $deviceId . '] ' . __('Not exists'); } return ($result); } /** * Gets device info by ID * * @param int $deviceId * * @return array */public function getDeviceInfo($deviceId) { $result = array(); $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $result = $this->allDevices[$deviceId]; } return ($result); } /** * Renders device events like start or stop * * @param int|null $deviceId optional device ID filter * * @return string */public function renderDeviceEvents($deviceId = null) { $result = ''; $deviceId = ($deviceId !== null) ? ubRouting::filters($deviceId, 'int') : null; if ($deviceId !== null and !isset($this->allDevices[$deviceId])) { $result .= $this->messages->getStyledMessage(__('Something went wrong') . ': ' . __('Not exists'), 'error'); } else { $eventsToShow = array(); if (!empty($this->allEvents)) { foreach ($this->allEvents as $io => $event) { if ($deviceId === null or $event['genid'] == $deviceId) { $eventsToShow[] = $event; } } } if (empty($eventsToShow)) { $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning'); $backUrl = self::URL_ME . '&' . self::ROUTE_DEVICES . '=true'; $result .= wf_delimiter(); $result .= wf_BackLink($backUrl); } else { usort($eventsToShow, function ($a, $b) { return strtotime($b['date']) - strtotime($a['date']); }); $eventsByDevice = array(); foreach ($eventsToShow as $event) { $genid = $event['genid']; if (!isset($eventsByDevice[$genid])) { $eventsByDevice[$genid] = array(); } $eventsByDevice[$genid][] = $event; } foreach ($eventsByDevice as $genid => $list) { usort($eventsByDevice[$genid], function ($a, $b) { return strtotime($b['date']) - strtotime($a['date']); }); } $columns = array( __('Date'), __('Device'), __('Event'), __('Duration'), __('Fuel consumption') ); $data = array(); $currentTime = strtotime(curdatetime()); foreach ($eventsToShow as $event) { $genid = $event['genid']; $deviceEvents = $eventsByDevice[$genid]; $deviceRunning = isset($this->allDevices[$genid]) and $this->allDevices[$genid]['running']; $deviceName = __('Unknown'); if (isset($this->allDevices[$genid])) { $device = $this->allDevices[$genid]; $deviceName = $device['model'] . ' - ' . $device['address']; } $timeDisplay = '-'; $fuelDisplay = '-'; $eventTime = strtotime($event['date']); if ($event['event'] == 'stop') { $startTime = 0; foreach ($deviceEvents as $prevEvent) { $prevTime = strtotime($prevEvent['date']); if ($prevEvent['event'] == 'start' and $prevTime < $eventTime and $prevTime > $startTime) { $startTime = $prevTime; } } if ($startTime > 0) { $seconds = $eventTime - $startTime; $timeDisplay = zb_formatTime($seconds); $fuelConsumption = $this->calculateFuelConsumption($genid, $seconds); $fuelDisplay = round($fuelConsumption, 2) . ' ' . __('litre'); } } else { if ($event['event'] == 'start') { $stopTime = 0; foreach ($deviceEvents as $nextEvent) { $nextTime = strtotime($nextEvent['date']); if ($nextEvent['event'] == 'stop' and $nextTime > $eventTime and ($stopTime == 0 or $nextTime < $stopTime)) { $stopTime = $nextTime; } } if ($stopTime > 0) { $seconds = $stopTime - $eventTime; $timeDisplay = zb_formatTime($seconds); } else { if ($deviceRunning) { $seconds = $currentTime - $eventTime; $timeDisplay = zb_formatTime($seconds); } } } } $data[] = array( $event['date'], $deviceName, $event['event'], $timeDisplay, $fuelDisplay ); } $opts = 'order: [[ 0, "desc" ]], "dom": \'<"F"lfB>rti<"F"ps>\', buttons: [\'csv\', \'excel\', \'pdf\', \'print\']'; $result .= wf_JqDtEmbed($columns, $data, false, __('Events'), 50, $opts); $backUrl = self::URL_ME . '&' . self::ROUTE_DEVICES . '=true'; $result .= wf_delimiter(); $result .= wf_BackLink($backUrl); } } return ($result); } /** * Renders all maintenances report for all devices * * @return string */public function renderAllServices() { $result = ''; if (!empty($this->allServices)) { usort($this->allServices, function($a, $b) { return strtotime($b['date']) - strtotime($a['date']); }); $columns=array( __('Date'), __('Device'), __('Motohours'), __('Notes') ); if (cfr('GENERATORSMGMT')) { $columns[] = __('Actions'); } $data=array(); foreach ($this->allServices as $io => $service) { $deviceId = $service['genid']; $deviceName = __('Unknown'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $deviceName = $device['model'] . ' - ' . $device['address']; } $cells = wf_TableCell($service['date']); $cells .= wf_TableCell($deviceName); $cells .= wf_TableCell(round($service['motohours'], 2)); $cells .= wf_TableCell($service['notes']); if (cfr('GENERATORSMGMT')) { } $dataRow=array($service['date'], $deviceName, round($service['motohours'], 2), $service['notes'], ); if (cfr('GENERATORSMGMT')) { $editDialog = wf_modalAuto(web_edit_icon(), __('Edit'), $this->renderServiceEditForm($service['id'])); array_push($dataRow, $editDialog); } $data[]=$dataRow; } $opts='order: [[ 0, "desc" ]], "dom": \'<"F"lfB>rti<"F"ps>\', buttons: [\'csv\', \'excel\', \'pdf\', \'print\']'; $result=wf_JqDtEmbed($columns, $data, false, __('Maintenance'),50, $opts); } else { $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning'); } $backUrl = self::URL_ME . '&' . self::ROUTE_DEVICES . '=true'; $result .= wf_delimiter(); $result .= wf_BackLink($backUrl); return ($result); } /** * Renders service edit form * * @param int $serviceId * * @return string */protected function renderServiceEditForm($serviceId) { $result = ''; $serviceId = ubRouting::filters($serviceId, 'int'); $service = null; if (!empty($this->allServices)) { foreach ($this->allServices as $io => $svc) { if ($svc['id'] == $serviceId) { $service = $svc; break; } } } if ($service) { $serviceDate = date('Y-m-d', strtotime($service['date'])); $serviceTime = date('H:i', strtotime($service['date'])); $inputs = wf_HiddenInput(self::PROUTE_EDIT_SERVICE, $serviceId); $inputs .= wf_TextInput(self::PROUTE_SERVICE_MOTO_HOURS, __('Motohours'), round($service['motohours'], 2), false, 8, 'float') . ' '; $inputs .= wf_DatePickerPreset(self::PROUTE_SERVICE_DATE, $serviceDate, true); $inputs .= wf_tag('label') . __('Date') . wf_tag('label', true) . ' '; $inputs .= wf_TimePickerPreset(self::PROUTE_SERVICE_TIME, $serviceTime, __('Time'), true) . ' '; $inputs .= wf_TextArea(self::PROUTE_SERVICE_NOTES, '', $service['notes'], true, '50x5'); $inputs .= wf_Submit(__('Save')); $result = wf_Form('', 'POST', $inputs, 'glamour'); } return ($result); } /** * Updates service record * * @param int $serviceId * * @return string */public function updateService($serviceId) { $result = ''; $serviceId = ubRouting::filters($serviceId, 'int'); $service = null; if (!empty($this->allServices)) { foreach ($this->allServices as $io => $svc) { if ($svc['id'] == $serviceId) { $service = $svc; break; } } } if ($service) { $requiredFields = array(self::PROUTE_EDIT_SERVICE, self::PROUTE_SERVICE_MOTO_HOURS); if (ubRouting::checkPost($requiredFields)) { $motohours = ubRouting::post(self::PROUTE_SERVICE_MOTO_HOURS, 'float'); $notes = ubRouting::post(self::PROUTE_SERVICE_NOTES, 'safe'); $notes = ubRouting::filters($notes, 'mres'); $serviceDate = ubRouting::post(self::PROUTE_SERVICE_DATE, 'mres'); $serviceTime = ubRouting::post(self::PROUTE_SERVICE_TIME, 'mres'); if ($motohours >= 0) { $serviceDateTime = $service['date']; if (!empty($serviceDate) AND !empty($serviceTime)) { $serviceDateTime = $serviceDate . ' ' . $serviceTime . ':00'; } elseif (!empty($serviceDate)) { $serviceDateTime = $serviceDate . ' ' . date('H:i:s'); } $this->servicesDb->where('id', '=', $serviceId); $this->servicesDb->data('date', $serviceDateTime); $this->servicesDb->data('motohours', $motohours); $this->servicesDb->data('notes', $notes); $this->servicesDb->save(); $this->loadServices(); log_register('GENERATORS DEVICE MAINTENANCE UPDATE [' . $service['genid'] . '] SERVICE [' . $serviceId . '] MOTOHOURS `' . $motohours . '`'); } else { $result = __('Invalid motohours value'); } } } else { $result = __('Something went wrong') . ': [' . $serviceId . '] ' . __('Not exists'); } return ($result); } /** * Runs generators watcher scripts for all devices * * @return void */public function runGeneratorsWatcher() { $result = ''; if (!empty($this->allDevices)) { foreach ($this->allDevices as $io=>$device) { if (!empty($device['opalias'])) { $scriptContent=$this->onePunch->getScriptContent($device['opalias']); if (!empty($scriptContent)) { $currentGeneratorStatus=$device['running']; eval($scriptContent); if (isset($generatorState)) { if ($generatorState == 1 or $generatorState == 0) { if ($generatorState != $currentGeneratorStatus) { if ($generatorState) { $this->startDevice($device['id']); } else { $this->stopDevice($device['id']); } } } else { log_register('GENERATORS WATCHER ['.$device['id'].'] FAIL OPSCRIPT `' . $device['opalias'] . '` GENERATOR STATE WRONG FORMAT'); } //cleanup generator state variable unset($generatorState); } else { log_register('GENERATORS WATCHER ['.$device['id'].'] FAIL OPSCRIPT `' . $device['opalias'] . '` NOT SET GENERATOR STATE'); } } else { log_register('GENERATORS WATCHER ['.$device['id'].'] FAIL OPSCRIPT `' . $device['opalias'] . '` NOT FOUND'); } } } } return ($result); } /** * Renders all refuels report for all devices * * @return string */public function renderAllRefuels() { $result = ''; if (!empty($this->allRefuels)) { usort($this->allRefuels, function($a, $b) { return strtotime($b['date']) - strtotime($a['date']); }); $columns=array( __('Date'), __('Device'), __('Liters'), __('Price'), __('Total') ); if (cfr('GENERATORSMGMT')) { $columns[] = __('Actions'); } $data=array(); foreach ($this->allRefuels as $io => $refuel) { $deviceId = $refuel['genid']; $deviceName = __('Unknown'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $deviceName = $device['model'] . ' - ' . $device['address']; } $editDialog=''; $dataRow=array($refuel['date'], $deviceName, round($refuel['liters'], 2) . ' ' . __('litre'), round($refuel['price'], 2), round($refuel['liters'] * $refuel['price'], 2) ); if (cfr('GENERATORSMGMT')) { $editDialog = wf_modalAuto(web_edit_icon(), __('Edit'), $this->renderRefuelEditForm($refuel['id'])); array_push($dataRow, $editDialog); } $data[]=$dataRow; } $opts='"order": [[ 0, "desc" ]], "dom": \'<"F"lfB>rti<"F"ps>\', buttons: [\'csv\', \'excel\', \'pdf\', \'print\']'; $result=wf_JqDtEmbed($columns, $data, false, __('Refuels'),50, $opts); } else { $result .= $this->messages->getStyledMessage(__('Nothing to show'), 'warning'); } $backUrl = self::URL_ME . '&' . self::ROUTE_DEVICES . '=true'; $result .= wf_delimiter(); $result .= wf_BackLink($backUrl); return ($result); } /** * Renders refuel edit form * * @param int $refuelId * * @return string */protected function renderRefuelEditForm($refuelId) { $result = ''; $refuelId = ubRouting::filters($refuelId, 'int'); $refuel = null; if (!empty($this->allRefuels)) { foreach ($this->allRefuels as $io => $rf) { if ($rf['id'] == $refuelId) { $refuel = $rf; break; } } } if ($refuel) { $refuelDate = date('Y-m-d', strtotime($refuel['date'])); $refuelTime = date('H:i', strtotime($refuel['date'])); $inputs = wf_HiddenInput(self::PROUTE_EDIT_REFUEL, $refuelId); $inputs .= wf_TextInput(self::PROUTE_REFUEL_LITERS, __('Litre'), round($refuel['liters'], 2), false, 6, 'float') . ' '; $inputs .= wf_TextInput(self::PROUTE_REFUEL_PRICE, __('Price'), round($refuel['price'], 2), false, 4, 'finance') . ' '; $inputs .= wf_DatePickerPreset('refueldate', $refuelDate, true); $inputs .= wf_tag('label') . __('Date') . wf_tag('label', true) . ' '; $inputs .= wf_TimePickerPreset('refueltime', $refuelTime, __('Time'), false) . ' '; $inputs .= wf_Submit(__('Save')); $result = wf_Form('', 'POST', $inputs, 'glamour'); } return ($result); } /** * Updates refuel record * * @param int $refuelId * * @return string */public function updateRefuel($refuelId) { $result = ''; $refuelId = ubRouting::filters($refuelId, 'int'); $refuel = null; if (!empty($this->allRefuels)) { foreach ($this->allRefuels as $io => $rf) { if ($rf['id'] == $refuelId) { $refuel = $rf; break; } } } if ($refuel) { $requiredFields = array(self::PROUTE_EDIT_REFUEL, self::PROUTE_REFUEL_LITERS); if (ubRouting::checkPost($requiredFields)) { $liters = ubRouting::post(self::PROUTE_REFUEL_LITERS, 'float'); $price = ubRouting::post(self::PROUTE_REFUEL_PRICE, 'float'); $refuelDate = ubRouting::post('refueldate', 'mres'); $refuelTime = ubRouting::post('refueltime', 'mres'); if ($liters > 0) { $refuelDateTime = $refuel['date']; if (!empty($refuelDate) AND !empty($refuelTime)) { $refuelDateTime = $refuelDate . ' ' . $refuelTime . ':00'; } elseif (!empty($refuelDate)) { $refuelDateTime = $refuelDate . ' ' . date('H:i:s'); } $deviceId = $refuel['genid']; $oldLiters = $refuel['liters']; $litersDiff = $liters - $oldLiters; if (isset($this->allDevices[$deviceId])) { $currentIntank = $this->allDevices[$deviceId]['intank']; $tankVolume = $this->allDevices[$deviceId]['tankvolume']; $newIntank = $currentIntank + $litersDiff; if ($newIntank >= 0 AND $newIntank <= $tankVolume) { $this->refuelsDb->where('id', '=', $refuelId); $this->refuelsDb->data('date', $refuelDateTime); $this->refuelsDb->data('liters', $liters); $this->refuelsDb->data('price', $price); $this->refuelsDb->save(); $this->setDeviceIntank($deviceId, $newIntank); $this->loadDevices(); $this->loadRefuels(); log_register('GENERATORS DEVICE REFUEL UPDATE [' . $deviceId . '] REFUEL [' . $refuelId . '] LITERS `' . $liters . '` PRICE `' . $price . '`'); } else { $result = __('Invalid tank level') . ': ' . __('Minimum') . ' 0, ' . __('Maximum') . ' ' . $tankVolume . ' ' . __('litre'); } } else { $result = __('Device not found'); } } else { $result = __('Invalid values'); } } } else { $result = __('Something went wrong') . ': [' . $refuelId . '] ' . __('Not exists'); } return ($result); } /** * Renders devices map * * @return string */public function renderDevicesMap() { $result = ''; global $ubillingConfig; $mapsCfg = $ubillingConfig->getYmaps(); $mapCenter = $mapsCfg['CENTER']; $mapZoom = $mapsCfg['ZOOM']; $generatorsMap=new MapCore('generators'); $generatorsMap->setCenter($mapCenter); $generatorsMap->setZoom($mapZoom); $generatorsMap->setType($mapsCfg['TYPE']); $result.= $generatorsMap->renderContainer('100%', '600px'); if (!empty($this->allDevices)) { foreach ($this->allDevices as $io => $device) { if (!empty($device['geo'])) { $deviceLabel=$device['model'] . ' - ' . $device['address']; $deviceIcon = ($device['running']) ? 'marker.green' : 'marker.red'; $deviceState=($device['running']) ? __('Running') : __('Stopped'); $deviceInTankPercent=__('In tank').': '.$this->calculateInTankPercent($device['id']).'%'; $options=array( 'popupFooter' => $deviceState .', '. $deviceInTankPercent, 'tooltip' => $deviceState .', '. $deviceInTankPercent, 'icon' => $deviceIcon ); $generatorsMap->addMarker($device['geo'], $deviceLabel, $options); } } } $result .= $generatorsMap->render(); $result.= wf_delimiter(); $result.= wf_BackLink(self::URL_ME.'&'.self::ROUTE_DEVICES.'=true'); return ($result); } /** * Calculates in tank percent for device (in percent) * * @param int $deviceId * * @return float */public function calculateInTankPercent($deviceId) { $result = 0; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $runningSeconds=0; $fuelConsumed=0; if ($device['running']) { $runningSeconds = $this->getDeviceRunningTime($device['id']); if ($runningSeconds > 0) { $fuelConsumption = $this->calculateFuelConsumption($device['id'], $runningSeconds); $fuelConsumed += $fuelConsumption; } } $inTankPercent = (($device['intank']-$fuelConsumed) / $device['tankvolume']) * 100; $result = round($inTankPercent, 2); } return ($result); } /** * Calculates in tank level for device (in liters) * * @param int $deviceId * * @return float */public function calculateInTankLevel($deviceId) { $result = 0; $deviceId = ubRouting::filters($deviceId, 'int'); if (isset($this->allDevices[$deviceId])) { $device = $this->allDevices[$deviceId]; $fuelConsumed = 0; if ($device['running']) { $fuelConsumed += $this->calculateFuelConsumption($device['id'], $this->getDeviceRunningTime($device['id'])); } $result=$device['intank'] - $fuelConsumed; } return ($result); } /** * Returns all devices as id=>deviceData * * @return array */public function getAllDevices() { return ($this->allDevices); } /** * Returns all devices fuel levels as id=>fuelLevel (in percent) * * @return array */public function getAllDevicesFuelPercent() { $result = array(); if (!empty($this->allDevices)) { foreach ($this->allDevices as $io => $device) { $result[$device['id']] = $this->calculateInTankPercent($device['id']); } } return ($result); } /** * Returns all devices fuel levels as id=>fuelLevel (in liters) * * @return array */public function getAllDevicesFuelLevel() { $result = array(); if (!empty($this->allDevices)) { foreach ($this->allDevices as $io => $device) { $result[$device['id']] = $this->calculateInTankLevel($device['id']); } } return ($result); } } |