public function testGetMessageWithTime_TwoSameCalls() { $log = new ListenerLog(); StubFactory::clear(); StubFactory::stubFunction('ListenerLog->find', array('return' => $log)); $message1 = ListenerLog::getMessageWithTime(1, '12345', '423'); $message2 = ListenerLog::getMessageWithTime(1, '12345', '423'); $this->assertSame($log, $message1); $this->assertSame($log, $message2); $this->assertEquals(1, StubFactory::getStubCallCount('ListenerLog->find')); }
protected function pollDataFromStation($station) { $this->_logger->log(__METHOD__, array('station' => $station->station_id_code)); $matches = array(); $source = $station->communication_esp_ip . ':' . $station->communication_esp_port; // Check IP_ADDRESS|DOMAIN_NAME:PORT pattern if (preg_match('/^([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}|[a-zA-Z0-9\\-\\.]+\\.[a-zA-Z]+)\\:([0-9]{1,5})$/', $source, $matches)) { $this->_logger->log(__METHOD__ . ': Matched.'); $message = $this->pollData($matches[1], $matches[2], $this->generatePollCommand($station)); if ($message != false) { ListenerLog::addNew($message, null, false, 'poller', $station->station_id); } } }
protected function getData() { $this->_logger->log(__METHOD__ . ' $this->start_time: ' . print_r($this->start_time, 1)); $this->_logger->log(__METHOD__ . ' $this->end_time: ' . print_r($this->end_time, 1)); $result = ListenerLog::model()->getAllDataInType($this->station_type, $this->start_time, $this->end_time); $this->_logger->log(__METHOD__ . ' $result COUNT: ' . print_r(COUNT($result), 1)); if (!is_null($result)) { // $this->schedule_type_report->updateLastReportedMessageData($result[0]->created); $this->data = $result; return true; } else { $this->data = array(); // $this->schedule_type_report->updateLastReportedMessageData($this->end_time); return false; } }
function actionIndex() { ini_set('memory_limit', '-1'); print 'Checking `listener_log` table upgrade....<br/>'; $sql = "SHOW COLUMNS FROM `" . ListenerLog::model()->tableName() . "` LIKE 'is_last'"; $res = Yii::app()->db->createCommand($sql)->queryAll(); if (!$res) { print '<br/><br/>Checked - requires update.<br/><br/>Attention! Script going to make small update to your database.... Please, be patient, don\'t use system before script is completed.'; $sql = "ALTER TABLE `" . ListenerLog::model()->tableName() . "` ADD `is_last` tinyint(1) NOT NULL DEFAULT '0' AFTER `is_processed`"; Yii::app()->db->createCommand($sql)->query(); $sql = "SELECT * FROM `" . Station::model()->tableName() . "`"; $stations = Yii::app()->db->createCommand($sql)->queryAll(); if ($stations) { foreach ($stations as $key => $value) { ListenerLog::updateIsLastForStation($value['station_id']); } } print '<br><br>.....<br><br>Done!. <br/><br/>You can continue work with <a href="' . It::baseUrl() . '">Delairco</a>'; } else { print '<br/>Checked - doesn\'t require update. <br/><br/>You can continue work with <a href="' . It::baseUrl() . '">Delairco</a>'; } }
public static function getHistory($schedule_id, $page_size = 15) { if ($page_size) { $sql = "SELECT COUNT(t1.schedule_processed_id)\n FROM `" . ScheduleReportProcessed::model()->tableName() . "` t1\n WHERE `t1`.`schedule_id` = '" . $schedule_id . "'"; $total = Yii::app()->db->createCommand($sql)->queryScalar(); } if ($total || !$page_size) { if ($page_size) { $pages = new CPagination($total); $pages->pageSize = $page_size; } $sql = "SELECT \n\t\t\t\t\t\tt1.*, t2.message, t2.measuring_timestamp, t3.report_type \n FROM \n\t\t\t\t\t\t`" . ScheduleReportProcessed::model()->tableName() . "` t1\n LEFT JOIN \n\t\t\t\t\t\t`" . ListenerLog::model()->tableName() . "` t2 ON t2.log_id = t1.listener_log_id\n LEFT JOIN \n\t\t\t\t\t\t`" . ScheduleReport::model()->tableName() . "` t3 ON t3.schedule_id = t1.schedule_id\n WHERE \n\t\t\t\t\t\t`t1`.`schedule_id` = '" . $schedule_id . "'\n ORDER BY \n\t\t\t\t\t\t`t1`.`created` DESC"; if ($page_size) { $sql .= " LIMIT " . $pages->currentPage * $pages->pageSize . ", " . $pages->pageSize; } $res = Yii::app()->db->createCommand($sql)->queryAll(); if ($res) { $files_path = dirname(Yii::app()->request->scriptFile) . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR . "schedule_reports"; foreach ($res as $key => $value) { if ($value['serialized_report_errors']) { $res[$key]['report_errors'] = unserialize($value['serialized_report_errors']); } if ($value['serialized_report_explanations']) { $res[$key]['report_explanations'] = unserialize($value['serialized_report_explanations']); } if (in_array($value['report_type'], array('synop', 'metar', 'speci')) && file_exists($files_path . DIRECTORY_SEPARATOR . $value['schedule_processed_id'])) { $res[$key]['report_string_initial'] = file_get_contents($files_path . DIRECTORY_SEPARATOR . $value['schedule_processed_id']); } if ($value['listener_log_ids']) { $sql = "SELECT t2.log_id, t2.message, t2.measuring_timestamp \n FROM `" . ListenerLog::model()->tableName() . "` t2\n WHERE t2.log_id IN (" . $value['listener_log_ids'] . ")\n ORDER BY `t2`.`measuring_timestamp` DESC"; $res[$key]['logs'] = Yii::app()->db->createCommand($sql)->queryAll(); } } } } return array('list' => $res, 'pages' => $pages); }
public function getCalculatedValue($station_id, $last_logs) { $last_logs_ids = array(); if (is_array($last_logs)) { foreach ($last_logs as $value) { if (count($value) > 0) { $last_logs_ids[] = $value->log_id; } } } $last_logs_ids[] = 0; $sql = "SELECT t1.listener_log_id, t1.value\n FROM `" . StationCalculationData::model()->tableName() . "` `t1`\n LEFT JOIN `" . StationCalculation::model()->tableName() . "` t2 ON t2.calculation_id = t1.calculation_id\n LEFT JOIN `" . CalculationDBHandler::model()->tableName() . "` t3 ON t3.handler_id = t2.handler_id\n LEFT JOIN `" . ListenerLog::model()->tableName() . "` t4 ON t4.log_id = t1.listener_log_id\n WHERE `t3`.handler_id_code = ? AND t2.station_id = ? AND t1.listener_log_id IN (" . implode(',', $last_logs_ids) . ")\n ORDER BY t4.measuring_timestamp DESC\n LIMIT 2 "; $res = Yii::app()->db->createCommand($sql)->queryAll(true, array($this->handler_id_code, $station_id)); $return = array('last' => '-', 'change' => 'no', 'metric_html_code' => $this->metric_html_code, 'display_name' => $this->display_name); if (!$res) { return $return; } if ($res[0]['listener_log_id'] && $res[0]['listener_log_id'] == $last_logs_ids[0]) { $return['last'] = number_format(round($res[0]['value'], 1), 1); if ($res[1]['listener_log_id']) { if ($res[0]['value'] > $res[1]['value']) { $return['change'] = 'up'; } else { if ($res[0]['value'] < $res[1]['value']) { $return['change'] = 'down'; } } } } return $return; }
public function prepareSection4() { $this->_logger->log(__METHOD__); $s = 4; $i = 0; $measuring_timestamp = strtotime($this->listener_log_info->measuring_timestamp); // $measuring_year = date('Y', $measuring_timestamp); // $measuring_month = date('m', $measuring_timestamp); // $measuring_day = date('d', $measuring_timestamp); // $measuring_hour = date('H', $measuring_timestamp); // $measuring_minute = date('i', $measuring_timestamp); // $measuring_second = date('s', $measuring_timestamp); $script_runtime = strtotime($this->schedule_process_info->check_period_end); $script_runtime_year = date('Y', $script_runtime); $script_runtime_month = date('m', $script_runtime); $script_runtime_day = date('d', $script_runtime); $script_runtime_hour = date('H', $script_runtime); $script_runtime_minute = date('i', $script_runtime); $script_runtime_second = date('s', $script_runtime); $sensors_3hr_ago = array(); $sensors_24hr_ago = array(); $x_hr_ago_1 = date('Y-m-d H:i:s', mktime($script_runtime_hour - 3, $script_runtime_minute, $script_runtime_second, $script_runtime_month, $script_runtime_day, $script_runtime_year)); $x_hr_ago_2 = date('Y-m-d H:i:s', mktime($script_runtime_hour - 4, $script_runtime_minute, $script_runtime_second, $script_runtime_month, $script_runtime_day, $script_runtime_year)); $log_3_hr_ago = ListenerLog::getMessageWithTime($this->station_info->station_id, $x_hr_ago_1, $x_hr_ago_2); if (!is_null($log_3_hr_ago)) { $sensors_3hr_ago = $this->prepareSensorsInfo($log_3_hr_ago->log_id); } $x_hr_ago_1 = date('Y-m-d H:i:s', mktime($script_runtime_hour, $script_runtime_minute, $script_runtime_second, $script_runtime_month, $script_runtime_day - 1, $script_runtime_year)); $x_hr_ago_2 = date('Y-m-d H:i:s', mktime($script_runtime_hour - 1, $script_runtime_minute, $script_runtime_second, $script_runtime_month, $script_runtime_day - 1, $script_runtime_year)); $log_24_hr_ago = ListenerLog::getMessageWithTime($this->station_info->station_id, $x_hr_ago_1, $x_hr_ago_2); if (!is_null($log_24_hr_ago)) { $sensors_24hr_ago = $this->prepareSensorsInfo($log_24_hr_ago->log_id); } /// ??? RECALCULATE !!!! $this->report_parts[$s][$i] = $this->prepare_binary_value(0, 24); $this->explanations[$s][$i][] = 'Octets 1-3: <span>' . $this->report_parts[$s][$i] . '</span> => <span></span> (length of section4 in octets)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value(0, 8); $this->explanations[$s][$i][] = 'Octets 4: <span>' . $this->report_parts[$s][$i] . '</span> reserved'; $i++; //3 01 090: Fixed surface station identification, time, horizontal and vertical coordinates $this->report_parts[$s][$i] = $this->prepare_binary_value($this->station_info->wmo_block_number, 7); $this->explanations[$s][$i][] = '301090 -> 301004 -> 001001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $this->station_info->wmo_block_number . '</span> (WMO Block #, 7 bits)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value($this->station_info->station_number, 10); $this->explanations[$s][$i][] = '301090 -> 301004 -> 001002: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $this->station_info->station_number . '</span> (station number, 10 bits)'; $i++; $station_display_name = substr($this->station_info->display_name, 0, 20); $tmp_str = ''; $tmp_str_2 = ''; for ($j = 0; $j < strlen($station_display_name); $j++) { $tmp = $this->prepare_binary_value(ord($station_display_name[$j]), 8); $tmp_str .= $tmp; $tmp_str_2 .= ' ' . $tmp; } $this->report_parts[$s][$i] = str_pad($tmp_str, 160, '0', STR_PAD_RIGHT); $this->explanations[$s][$i][] = '301090 -> 301004 -> 001015: <span>' . str_pad($tmp_str_2, 160 + strlen($station_display_name), '0', STR_PAD_RIGHT) . '</span> => <span>' . $station_display_name . '</span> (station code, 160 bits. Each letter incoded into 7bits binary with and padded with left 0 to 8bits. Then joined string is right-padded with 0 to fit 160bits length)'; $i++; $this->report_parts[$s][$i] = '00'; $this->explanations[$s][$i][] = '301090 -> 301004 -> 002001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>0</span> (Type of station, 2 bits)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value($script_runtime_year, 12); $this->explanations[$s][$i][] = '301090 -> 301011 -> 00 4001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $script_runtime_year . '</span> (Year, 12 bits)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value($script_runtime_month, 4); $this->explanations[$s][$i][] = '301090 -> 301011 -> 004002: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $script_runtime_month . '</span> (Month, 4 bits)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value($script_runtime_day, 6); $this->explanations[$s][$i][] = '301090 -> 301011 -> 004003: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $script_runtime_day . '</span> (Day, 6 bits)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value($script_runtime_hour, 5); $this->explanations[$s][$i][] = '301090 -> 301012 -> 004004: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $script_runtime_hour . '</span> (Hour, 5 bits)'; $i++; $this->report_parts[$s][$i] = $this->prepare_binary_value($script_runtime_minute, 6); $this->explanations[$s][$i][] = '301090 -> 301012 -> 004005: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $script_runtime_minute . '</span> (Minute, 6 bits)'; $i++; // 301090 -> 301021 -> 005001 => Latitude // 25 bits. Metric = degree. Scale = 5. Reference = –9000000 $tmp = round($this->station_info->lat, 5) * 100000 + 9000000; $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 25); $this->explanations[$s][$i][] = '301090 -> 301021 -> 005001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>round(' . $this->station_info->lat . ', 5) * 10^5 -(-9000000) = ' . $tmp . '</span> (Latitude, 25 bits)'; $i++; // 301090 -> 301021 -> 006001 => Longitude. // 26 bits. Metric = degree. Scale = 5. Ref value = -18000000 $tmp = round($this->station_info->lng, 5) * 100000 + 18000000; $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 26); $this->explanations[$s][$i][] = '301090 -> 301021 -> 006001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>round(' . $this->station_info->lng . ', 5) * 10^5 -(-18000000) = ' . $tmp . '</span> (Longitude, 26 bits)'; $i++; // 301090 -> 007030 => Altitude, Height of station ground above mean sea level. // 17 bits. Metric = m, Scale = 1, Ref = 4000 $tmp = round($this->station_info->altitude, 1) * 10 + 4000; $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 17); $this->explanations[$s][$i][] = '301090 -> 007030: <span>' . $this->report_parts[$s][$i] . '</span> => <span>round(' . $this->station_info->altitude . ', 1) * 10^1 -(-4000) = ' . $tmp . '</span> (Altitude, 17 bits)'; $i++; // 301090 -> 007031: Barometer Height. // 17 bits. Metric = m, Scale = 1, Ref = 4000 $expl_val = ''; if (isset($this->sensors['pressure'])) { $tmp = It::convertMetric($this->sensors['pressure_height']['height'], $this->sensors['pressure_height']['height_metric_code'], 'meter'); $str_tmp = round($tmp + $this->station_info->altitude, 1) * 10 + 4000; $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 17); $expl_val = $this->sensors['pressure_height']['height'] . ' ' . $this->sensors['pressure_height']['height_metric_code']; if ($this->sensors['pressure_height']['height_metric_code'] != 'meter') { $expl_val .= ' = ' . $tmp . ' meter'; } $expl_val .= ' ~ round( (' . $tmp . ' + ' . $this->station_info->altitude . '), 1)*10^1 -(-4000) = ' . $str_tmp; } else { $this->report_parts[$s][$i] = '11111111111111111'; $expl_val = 'No Pressure sensor'; } $this->explanations[$s][$i][] = '301090 -> 007031: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Barometer Height, m, 17 bits)'; $i++; // 3 02 031: Pressure. // 302031 -> 302001 -> 010004: Pressure data // Metric = Pa. Scale = –1. Reference value = 0. Size = 14 bits if (isset($this->sensors['pressure'])) { if ($this->sensors['pressure']['is_m']) { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = 'Data from Pressure sensor is unavailable'; } else { $tmp = It::convertMetric($this->sensors['pressure']['sensor_feature_value'], $this->sensors['pressure']['metric_code'], 'pascal'); $str_tmp = round($tmp / 10, 0); $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 14); $expl_val = $this->sensors['pressure']['sensor_feature_value'] . ' ' . $this->sensors['pressure']['metric_code']; if ($this->sensors['pressure']['metric_code'] != 'pascal') { $expl_val .= ' = ' . $tmp . ' pascal'; } $expl_val .= ' ~ round(' . $tmp . ' * 10^(-1), 0) - 0 = ' . $str_tmp; } } else { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = 'No Pressure sensor'; } $this->explanations[$s][$i][] = '302031 -> 302001 -> 010004: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Barometer Pressure, Pa, 14 bits)'; $i++; // 302031 -> 302001 -> 010051: Pressure reduced to mean sea level // 14 bits. Metric = Pa. Scale = –1. Ref = 0. if (isset($this->calculations['PressureSeaLevel'])) { $tmp = It::convertMetric($this->calculations['PressureSeaLevel']['value'], 'hpascal', 'pascal'); $str_tmp = round($tmp / 10, 0); $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 14); $expl_val = $this->calculations['PressureSeaLevel']['value'] . ' hPa = ' . $tmp . ' Pa ~ round(' . $tmp . ' * 10^(-1), 0) - 0 = ' . $str_tmp . '</span>'; } else { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = 'No Pressure MSL Calculation'; } $this->explanations[$s][$i][] = '302031 -> 302001 -> 010051: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Pressure MSL, Pa, 14bits)'; $i++; // 302031 -> 302001 -> 010061: 3-hour pressure change // 10 bits. Metric = Pa. Scale = -1. Ref = -500 // AND // 302031 -> 302001 -> 010063: Characteristic of pressure tendency // 4 bits. Code table value. Scale = 0. Ref = 0 if (isset($this->sensors['pressure']) && isset($sensors_3hr_ago['pressure'])) { if ($this->sensors['pressure']['is_m']) { $this->report_parts[$s][$i] = '1111111111'; $this->explanations[$s][$i][] = '302031 -> 302001 -> 010061: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Last data from Pressure sensor is unavailable</span> (3h Pressure change, 10 bits)'; $i++; $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '302031 -> 302001 -> 010063: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Last data from Pressure sensor is unavailable</span> (3h Pressure change Tendency, 4bits)'; } else { if ($sensors_3hr_ago['pressure']['is_m']) { $this->report_parts[$s][$i] = '1111111111'; $this->explanations[$s][$i][] = '302031 -> 302001 -> 010061: <span>' . $this->report_parts[$s][$i] . '</span> => <span>3h ago data from Pressure sensor is unavailable</span> (3h Pressure change, 10 bits)'; $i++; $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '302031 -> 302001 -> 010063: <span>' . $this->report_parts[$s][$i] . '</span> => <span>3h ago data from Pressure sensor is unavailable</span> (3h Pressure change Tendency, 4bits)'; } else { $pressure_3hr = $sensors_3hr_ago['pressure']['sensor_feature_value']; $pressure_3hr_metric = $sensors_3hr_ago['pressure']['metric_code']; $pressure_3hr = It::convertMetric($pressure_3hr, $pressure_3hr_metric, 'pascal'); $pressure_now = $this->sensors['pressure']['sensor_feature_value']; $pressure_now_metric = $this->sensors['pressure']['metric_code']; $pressure_now = It::convertMetric($pressure_now, $pressure_now_metric, 'pascal'); $tmp3 = round(($pressure_now - $pressure_3hr) / 10, 0); $str_tmp = abs($tmp3) + 500; $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 10); $expl_val = '302031 -> 302001 -> 010061: <span>' . $this->report_parts[$s][$i] . '</span> => '; $expl_val .= '<span>~ round(' . $pressure_now . ' - ' . $pressure_3hr . ') * 10^(-1), 0) Pa = ' . $tmp3 . ' Pa ~ |' . $tmp3 . '| -(-500) = ' . $str_tmp . ' </span> (3h Pressure change, Pa, 10bits)'; $this->explanations[$s][$i][] = $expl_val; $i++; if ($pressure_now > $pressure_3hr) { $this->report_parts[$s][$i] = '0010'; $expl_val = '<span>2 = Increased</span>'; } else { if ($pressure_now < $pressure_3hr) { $this->report_parts[$s][$i] = '0111'; $expl_val = '<span>7 = Decreased</span>'; } else { $this->report_parts[$s][$i] = '0000'; $expl_val = '<span>4 = Stable</span>'; } } $this->explanations[$s][$i][] = '302031 -> 302001 -> 010063: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (3h Pressure change Tendency, 4bits)'; } } } else { $this->report_parts[$s][$i] = '1111111111'; $this->explanations[$s][$i][] = '302031 -> 302001 -> 010061: <span>' . $this->report_parts[$s][$i] . '</span> => <span>No pressure sensor</span> (3h Pressure change, 10 bits)'; $i++; $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '302031 -> 302001 -> 010063: <span>' . $this->report_parts[$s][$i] . '</span> => <span>No pressure sensor</span> (3h Pressure change Tendency, 4bits)'; } $i++; // 302031 -> 010062: 24-hour pressure change // 11 bits. Metric = Pa. Scale = -1. Ref = -1000 if (isset($this->sensors['pressure']) && isset($sensors_24hr_ago['pressure'])) { if ($this->sensors['pressure']['is_m']) { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>Last data from Pressure sensor is unavailable</span>'; } else { if ($sensors_24hr_ago['pressure']['is_m']) { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>24h ago data from Pressure sensor is unavailable</span>'; } else { $pressure_24hr = It::convertMetric($sensors_24hr_ago['pressure']['sensor_feature_value'], $sensors_24hr_ago['pressure']['metric_code'], 'pascal'); $pressure_now = It::convertMetric($this->sensors['pressure']['sensor_feature_value'], $this->sensors['pressure']['metric_code'], 'pascal'); $tmp3 = round(($pressure_now - $pressure_24hr) / 10, 0); $str_tmp = abs($tmp3) + 1000; $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 11); $expl_val = '<span>~ round((' . $pressure_now . ' - ' . $pressure_24hr . ') * 10^(-1), 0) Pa = ' . $tmp3 . ' Pa ~ |' . $tmp3 . '| -(-1000) = ' . $str_tmp . '</span>'; } } } else { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>No pressure sensor</span>'; } $this->explanations[$s][$i][] = '302031 -> 010062: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (24h Pressure change, Pa, 11bits)'; $i++; // 302031 -> 007004: Pressure // 14 bits. Metric = Pa. Scale = -1. Ref = 0 $this->report_parts[$s][$i] = '11111111111111'; $this->explanations[$s][$i][] = '302031 -> 007004: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Pressure, Pa, 14bits)'; $i++; //302031 -> 010009: Geopotential height // 17 bits. Metric = gpm. Scale = 0. Ref = -1000. $this->report_parts[$s][$i] = '11111111111111111'; $this->explanations[$s][$i][] = '302031 -> 010009: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (GEOPOTENTIAL HEIGHT, GPM, 17bits)'; $i++; //3 02 035: Basic synoptic “instantaneous” data //3 02 035 -> 3 02 032: Temperature and Humidity data. // // 302035 -> 302032 -> 012101: Height of temperature sensor above local ground // Metric = m. Scale = 2. Ref = 0. 16 bits $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302035 -> 302032 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of temperature/humidity sensors, 16bits)'; $i++; // 302035 -> 302032 -> 012101: Temperature/dry-bulb temperature // 16 bits. Metric = K. Scale = 2. Ref = 0. if (isset($this->sensors['temperature'])) { if ($this->sensors['temperature']['is_m']) { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = '<span>Last data from Temperature sensor is unavailable</span>'; } else { $tmp = It::convertMetric($this->sensors['temperature']['sensor_feature_value'], $this->sensors['temperature']['metric_code'], 'kelvin'); $str_tmp = round($tmp * 100); $this->report_parts[$s][$i] = ($tmp > 0 ? '0' : '1') . $this->prepare_binary_value(abs($str_tmp), 15); $expl_val = '<span>' . $this->sensors['temperature']['sensor_feature_value'] . ' ' . $this->sensors['temperature']['metric_code']; if ($this->sensors['temperature']['metric_code'] != 'kelvin') { $expl_val .= ' = ' . $tmp . ' kelvin'; } $expl_val .= ' ~ |round(' . $tmp . ' * 10^2 - 0)| = ' . round($tmp * 100) . ' (+left bit = ' . ($tmp > 0 ? '0' : '1') . ' because ' . ($tmp > 0 ? 'positive' : 'negative') . ') '; $expl_val .= '</span>'; } } else { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = '<span>No temperature sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302032 -> 012101: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Temperature, kelvin degree, 16bits)'; $i++; // 302035 -> 302032 -> 012103: Dew-point temperature // 16 bits. Metric = K. Scale = 2. Ref = 0. if (isset($this->calculations['DewPoint'])) { $tmp = It::convertMetric($this->calculations['DewPoint']['value'], 'celsius', 'kelvin'); $str_tmp = round($tmp * 100); $this->report_parts[$s][$i] = ($tmp > 0 ? '0' : '1') . $this->prepare_binary_value(abs($str_tmp), 15); $expl_val = '<span>' . $this->calculations['DewPoint']['value'] . ' celsius'; $expl_val .= ' = ' . $tmp . ' kelvin'; $expl_val .= ' ~ |round(' . $tmp . ' * 10^2 - 0)| = ' . $str_tmp . ' (+left bit = ' . ($tmp > 0 ? '0' : '1') . ' because ' . ($tmp > 0 ? 'positive' : 'negative') . ')'; $expl_val .= '</span>'; } else { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = '<span>No calculation</span>'; } $this->explanations[$s][$i][] = '302035 -> 302032 -> 012103: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (DewPoint, kelvin, 16bits)'; $i++; // 302035 -> 302032 -> 013003: Relative humidity // 7 bits. Metric = %. Scale = 0. Ref = 0. if (isset($this->sensors['humidity'])) { if ($this->sensors['humidity']['is_m']) { $this->report_parts[$s][$i] = '1111111'; $expl_val = '<span>Last data from Humidity sensor is unavailable</span>'; } else { $str_tmp = round($this->sensors['humidity']['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 7); $expl_val = '<span>round(' . $this->sensors['humidity']['sensor_feature_value'] . ')</span>'; } } else { $this->report_parts[$s][$i] = '1111111'; $expl_val = '<span>No humidity sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302032 -> 013003:<span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (RELATIVE HUMIDITY, %, 7bits)'; $i++; // 302035 -> 302033 -> 007032: Height of visibility sensor above local ground // 16 bits. Metric = m. Scale = 2. Ref = 0 $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302035 -> 302033 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Hight of visibility sensor, 16bits)'; $i++; // 302035 -> 302033 -> 020001: Horizontal Visibility // 13 bits. Metric = m. Scale = -1. Ref = 0 if (isset($this->sensors['visibility_1'])) { if ($this->sensors['visibility_1']['is_m']) { $this->report_parts[$s][$i] = '1111111111111'; $expl_val = '<span>Last data from Visibility sensor is unavailable</span>'; } else { $tmp = It::convertMetric($this->sensors['visibility_1']['sensor_feature_value'], $this->sensors['visibility_1']['metric_code'], 'meter'); $str_tmp = round($tmp / 10, 0); $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 13); $expl_val = '<span>' . $this->sensors['visibility_1']['sensor_feature_value'] . ' ' . $this->sensors['visibility_1']['metric_code'] . ' = ' . $tmp . ' meter. Apply scale=-1 => ' . $str_tmp . ' </span>'; } } else { $this->report_parts[$s][$i] = '1111111111111'; $expl_val = '<span>No Visibility sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302033 -> 020001: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Horizontal Visibility, 13bits)'; $i++; // 302035 -> 302034 -> 007032: Height of Rain sensor // 16 bits. Metric = m. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302035 -> 302034 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of Rain sensor, 16bits)'; $i++; // 302035 -> 302034 -> 013023: Total precipitation past 24 hours, kg/m2 // 14 bits. Metric = kg/m2. Scale = 1. Ref = -1. if (isset($this->sensors['rain_in_period'])) { if ($this->sensors['rain_in_period']['is_m']) { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = '<span>Last data from Rain sensor is unavailable</span>'; } else { $handler_obj = SensorHandler::create($this->sensors['rain_in_period']['handler_id_code']); $rain_last_24_hr = $handler_obj->getTotalInLastXHr($this->sensors['rain_in_period']['sensor_feature_id'], $measuring_timestamp, 24, false)['total']; $tmp = It::convertMetric($rain_last_24_hr, $this->sensors['rain_in_period']['metric_code'], 'millimeter'); $tmp_str = round($tmp, 1) * 10 - -1; $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp_str, 14); $expl_val = '<span>' . $rain_last_24_hr . ' ' . $this->sensors['rain_in_period']['metric_code']; if ($this->sensors['rain_in_period']['metric_code'] != 'millimeter') { $expl_val .= ' = ' . $tmp . ' millimeter'; } $expl_val .= ' ~ round(' . $tmp . ', 1) * 10^1 -(-1) = ' . $tmp_str . '</span>'; } } else { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = '<span>No rain sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302034 -> 013023: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . '(Total precipitation past 24 hours, kg/m2, 14bits)'; $i++; // 302035 -> 007032: Height of Rain sensor // 16bits. Metric = m. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302035 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of Rain sensor, 16bits)'; $i++; // -- 3 02 035 -> 3 02 004: Cloud Data -- // 302035 -> 302004 -> 020010: Cloud cover // 7 bits. Metric = %. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111111'; $this->explanations[$s][$i][] = '302035 -> 302004 -> 020010: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud cover, %, 7bits)'; // 7bits $i++; // 302035 -> 302004 -> 008002: Vertical Significance // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = ' 302035 -> 302004 -> 008002: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Vertical Significance, 6 bits)'; $i++; // 302035 -> 302004 -> 020011: Cloud Amount // 4 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; // if (isset($this->sensors['cloud_amount_amount_total'])) // { // if ($this->sensors['cloud_amount_amount_total']['is_m']) // { // $this->report_parts[$s][$i] = '1111'; // $expl_val = 'Last data about Cloud Amount is unavailable'; // } // else // { // $tmp1 = $this->_get_cloud_cover_code(round($this->sensors['cloud_amount_amount_total']['sensor_feature_value'], 1)); // // $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 4); // $expl_val = $tmp1 .' ('. round($this->sensors['cloud_amount_amount_total']['sensor_feature_value']) .'/8)'; // } // } // else // { // $this->report_parts[$s][$i] = '1111'; // $expl_val = 'No Cloud Amount sensor'; // } // $this->explanations[$s][$i][] = '302035 -> 302004 -> 020011: <span>'.$this->report_parts[$s][$i].'</span> => <span>'. $expl_val .'</span> (Cloud Amount, 4bits)'; $this->explanations[$s][$i][] = '302035 -> 302004 -> 020011: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud Amount, 4bits)'; $i++; // 302035 -> 302004 -> 020013: Height of base cloud // 11 bits. Metric = m. Scale = -1. Ref = -40. $this->report_parts[$s][$i] = '11111111111'; $this->explanations[$s][$i][] = '302035 -> 302004 -> 020013: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of base cloud, 11bits)'; $i++; // 302035 -> 302004 -> 020012: Cloud Type of low clouds // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302035 -> 302004 -> 020012: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud Type of low clouds, 6bits)'; $i++; // 302035 -> 302004 -> 020012: Cloud Type of middle clouds // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302035 -> 302004 -> 020012: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud Type of middle clouds, 6bits)'; $i++; // 302035 -> 302004 -> 020012: Cloud Type of high clouds // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302035 -> 302004 -> 020012: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud Type of high clouds, 6bits)'; $i++; // 307080 -> 302035 -> 031001: 3 repetitions for Cloud Layers. // 8 bits // number of repetitions should be there. // As far as we have 3 layers of clouds – this value is fixed to 3. $this->report_parts[$s][$i] = $this->prepare_binary_value(3, 8); $this->explanations[$s][$i][] = '307080 -> 302035 -> 031001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>3</span> repetitions for 3 Cloud Layers.(Decide here how much repetition we need, 8bits)'; $i++; // Repetition #1 $cloudAmountSensor = isset($this->sensors['cloud_amount_amount_1']) ? $this->sensors['cloud_amount_amount_1'] : null; // 302035 -> 302005 -> 008002 (Repetition #1): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. if (isset($cloudAmountSensor)) { if ($cloudAmountSensor['is_m']) { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>Missing</span>'; } else { $tmp1 = $this->getVerticalSignificance(1, $cloudAmountSensor['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 6); $expl_val = '<span>' . $tmp1 . ' (' . $cloudAmountSensor['sensor_feature_value'] . '/8)</span>'; } } else { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>Missing (No such measurement)</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 008002 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Vertical significance (surface observations), 6bits)'; $i++; // 302035 -> 302005 -> 020011 (Repetition #1): Cloud amount // 4 bits. Metric = code table. Scale = 0. Ref = 0. if (isset($cloudAmountSensor)) { if ($cloudAmountSensor['is_m']) { $this->report_parts[$s][$i] = '1111'; $expl_val = '<span>Last data about Cloud Amount is unavailable</span>'; } else { $tmp1 = $this->_get_cloud_cover_code($cloudAmountSensor['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 4); $expl_val = '<span>' . $tmp1 . ' (' . $cloudAmountSensor['sensor_feature_value'] . '/8)</span>'; } } else { $this->report_parts[$s][$i] = '1111'; $expl_val = '<span>No Cloud Amount sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 020011 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Cloud amount, 4bits)'; $i++; // 302035 -> 302005 -> 020012 (Repetition #1): Cloud Type // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302035 -> 302005 -> 020012 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing (No such measurement)</span> (Cloud Type, 6bits)'; $i++; $cloudHeightSensor = isset($this->sensors['cloud_amount_height_1']) ? $this->sensors['cloud_amount_height_1'] : (isset($this->sensors['cloud_height_height_1']) ? $this->sensors['cloud_height_height_1'] : null); // 302035 -> 302005 -> 020013 (Repetition #1): Height of Base Cloud // 11 bits. Metric = m. Scale = -1. Ref = -40. if (isset($cloudHeightSensor)) { if ($cloudHeightSensor['is_m']) { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>Last data about Cloud Height is unavailable</span>'; } else { $tmp1 = It::convertMetric($cloudHeightSensor['sensor_feature_value'], $cloudHeightSensor['metric_code'], 'meter'); $tmp2 = round($tmp1 / 10 + 40); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp2, 11); $expl_val = '<span>' . round($cloudHeightSensor['sensor_feature_value']) . ' ' . $cloudHeightSensor['metric_code'] . ' = ' . round($tmp1, 1) . ' meter.</span> With scale=-1 and ref=40: <span>' . $tmp2 . '</span>'; } } else { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>No Cloud Height sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 020013 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Height of Base Cloud, 11bits)'; $i++; // Repetition #2 $cloudAmountSensor = isset($this->sensors['cloud_amount_amount_2']) ? $this->sensors['cloud_amount_amount_2'] : null; // 302035 -> 302005 -> 008002 (Repetition #2): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. if (isset($cloudAmountSensor)) { if ($cloudAmountSensor['is_m']) { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>Missing</span>'; } else { $tmp1 = $this->getVerticalSignificance(2, $cloudAmountSensor['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 6); $expl_val = '<span>' . $tmp1 . ' (' . $cloudAmountSensor['sensor_feature_value'] . '/8)</span>'; } } else { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>Missing (No such measurement)</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 008002 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Vertical significance (surface observations), 6bits)'; $i++; // 302035 -> 302005 -> 020011 (Repetition #2): Cloud amount // 4 bits. Metric = code table. Scale = 0. Ref = 0. if (isset($cloudAmountSensor)) { if ($cloudAmountSensor['is_m']) { $this->report_parts[$s][$i] = '1111'; $expl_val = '<span>Last data about Cloud Amount is unavailable</span>'; } else { $tmp1 = $this->_get_cloud_cover_code($cloudAmountSensor['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 4); $expl_val = '<span>' . $tmp1 . ' (' . $cloudAmountSensor['sensor_feature_value'] . '/8)</span>'; } } else { $this->report_parts[$s][$i] = '1111'; $expl_val = '<span>No Cloud Amount sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 020011 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Cloud amount, 4bits)'; $i++; // 302035 -> 302005 -> 020012 (Repetition #2): Cloud Type // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302035 -> 302005 -> 020012 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing (No such measurement)</span> (Cloud Type, 6bits)'; $i++; $cloudHeightSensor = isset($this->sensors['cloud_amount_height_2']) ? $this->sensors['cloud_amount_height_2'] : (isset($this->sensors['cloud_height_height_2']) ? $this->sensors['cloud_height_height_2'] : null); // 302035 -> 302005 -> 020013 (Repetition #2): Height of Base Cloud // 11 bits. Metric = m. Scale = -1. Ref = -40. if (isset($cloudHeightSensor)) { if ($cloudHeightSensor['is_m']) { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>Last data about Cloud Height is unavailable</span>'; } else { $tmp1 = It::convertMetric($cloudHeightSensor['sensor_feature_value'], $cloudHeightSensor['metric_code'], 'meter'); $tmp2 = round($tmp1 / 10 + 40); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp2, 11); $expl_val = '<span>' . round($cloudHeightSensor['sensor_feature_value']) . ' ' . $cloudHeightSensor['metric_code'] . ' = ' . round($tmp1, 1) . ' meter.</span> With scale=-1 and ref=40: <span>' . $tmp2 . '</span>'; } } else { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>No Cloud Height sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 020013 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Height of Base Cloud, 11bits)'; $i++; // Repetition #3 // if layer 3 is missing then check layer 4. $cloudAmountSensor = isset($this->sensors['cloud_amount_amount_3']) && $this->sensors['cloud_amount_amount_3']['is_m'] != 1 ? $this->sensors['cloud_amount_amount_3'] : (isset($this->sensors['cloud_amount_amount_4']) ? $this->sensors['cloud_amount_amount_4'] : null); $group = isset($this->sensors['cloud_amount_amount_3']) && $this->sensors['cloud_amount_amount_3']['is_m'] != 1 ? 3 : (isset($this->sensors['cloud_amount_amount_4']) ? 4 : null); // 302035 -> 302005 -> 008002 (Repetition #3): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. if (isset($cloudAmountSensor)) { if ($cloudAmountSensor['is_m']) { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>Missing</span>'; } else { $tmp1 = $this->getVerticalSignificance($group, $cloudAmountSensor['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 6); $expl_val = '<span>' . $tmp1 . ' (' . $cloudAmountSensor['sensor_feature_value'] . '/8)</span>'; } } else { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>Missing (No such measurement)</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 008002 (Repetition #3): <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Vertical significance (surface observations), 6bits)'; $i++; // 302035 -> 302005 -> 020011 (Repetition #3): Cloud amount // 4 bits. Metric = code table. Scale = 0. Ref = 0. if (isset($cloudAmountSensor)) { if ($cloudAmountSensor['is_m']) { $this->report_parts[$s][$i] = '1111'; $expl_val = '<span>Last data about Cloud Amount is unavailable</span>'; } else { $tmp1 = $this->_get_cloud_cover_code($cloudAmountSensor['sensor_feature_value']); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp1, 4); $expl_val = '<span>' . $tmp1 . ' (' . $cloudAmountSensor['sensor_feature_value'] . '/8)</span>'; } } else { $this->report_parts[$s][$i] = '1111'; $expl_val = '<span>No Cloud Amount sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 020011 (Repetition #3): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Cloud amount, 4bits)'; $i++; // 302035 -> 302005 -> 020012 (Repetition #3): Cloud Type // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302035 -> 302005 -> 020012 (Repetition #3): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing (No such measurement)</span> (Cloud Type, 6bits)'; $i++; $cloudHeightSensor = isset($this->sensors['cloud_amount_height_3']) ? $this->sensors['cloud_amount_height_3'] : (isset($this->sensors['cloud_height_height_3']) ? $this->sensors['cloud_height_height_3'] : null); // 302035 -> 302005 -> 020013 (Repetition #3): Height of Base Cloud // 11 bits. Metric = m. Scale = -1. Ref = -40. if (isset($cloudHeightSensor)) { if ($cloudHeightSensor['is_m']) { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>Last data about Cloud Height is unavailable</span>'; } else { $tmp1 = It::convertMetric($cloudHeightSensor['sensor_feature_value'], $cloudHeightSensor['metric_code'], 'meter'); $tmp2 = round($tmp1 / 10 + 40); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp2, 11); $expl_val = '<span>' . round($cloudHeightSensor['sensor_feature_value']) . ' ' . $cloudHeightSensor['metric_code'] . ' = ' . round($tmp1, 1) . ' meter.</span> With scale=-1 and ref=40: <span>' . $tmp2 . '</span>'; } } else { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>No Cloud Height sensor</span>'; } $this->explanations[$s][$i][] = '302035 -> 302005 -> 020013 (Repetition #3): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Height of Base Cloud, 11bits)'; $i++; // 3 02 036: Clouds with bases below station level // 302036 -> 031001: 1 repetition // 8 bits // 1 repetition only, so 1 is fixed $this->report_parts[$s][$i] = $this->prepare_binary_value(1, 8); $this->explanations[$s][$i][] = '302036 -> 031001 (Decide here how much repetition we need): <span>' . $this->report_parts[$s][$i] . '</span> => <span>1</span>'; $i++; // 302036 -> 008002 (Repetition #1): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302036 -> 008002 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Vertical significance (surface observations), 6bits)'; $i++; // 302036 -> 020011 (Repetition #1): Cloud amount // 4 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '302036 -> 020011 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud amount, 4bits)'; $i++; // 302036 -> 020012 (Repetition #1): Cloud Type // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302036 -> 020012 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud Type, 6bits)'; $i++; // 302036 -> 020014 (Repetition #1): Height of top of cloud // 11 bits. Metric = m. Scale = -1. Ref = -40; $this->report_parts[$s][$i] = '11111111111'; $this->explanations[$s][$i][] = '302036 -> 020014 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of top of cloud, 11bits)'; $i++; // 302036 -> 020017 (Repetition #1): Cloud top description // 4 bits. Metric = code table. Scale = 0. Ref = 0; $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '302036 -> 020017 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud top description, 4bits)'; $i++; // 3 02 047: Direction of cloud drift // 302047 -> 008002 (Repetition #1): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302047 -> 008002 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Vertical significance (surface observations), 6bits)'; $i++; // 302047 -> 020054 (Repetition #1): True direction // 9 bits. Metric = degree true. Scale = 0. Ref = 9 $this->report_parts[$s][$i] = '111111111'; $this->explanations[$s][$i][] = '302047 -> 020054 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (True direction from which clouds are moving, 9bits)'; $i++; // 302047 -> 008002 (Repetition #2): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302047 -> 008002 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Vertical significance (surface observations), 6bits)'; $i++; // 302047 -> 020054 (Repetition #2): True direction // 9 bits. Metric = degree true. Scale = 0. Ref = 9 $this->report_parts[$s][$i] = '111111111'; $this->explanations[$s][$i][] = '302047 -> 020054 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (True direction from which clouds are moving, 9bits)'; $i++; // 302047 -> 008002 (Repetition #3): Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0 $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302047 -> 008002 (Repetition #3): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Vertical significance (surface observations), 6bits)'; $i++; // 302047 -> 020054 (Repetition #3): True direction // 9 bits. Metric = degree true. Scale = 0. Ref = 9 $this->report_parts[$s][$i] = '111111111'; $this->explanations[$s][$i][] = '302047 -> 020054 (Repetition #3): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (True direction from which clouds are moving, 9bits)'; $i++; // 008002: Vertical significance (surface observations) // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '008002: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Vertical significance, 6bits)'; $i++; // 3 02 048: Direction and elevation of cloud // 302048 -> 005021: Bearing of azimuth // 16 bits. Metric = degree. Scale = 2. Ref = 0 $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302048 -> 005021: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Bearing of azimuth, 16bits)'; $i++; // 302048 -> 007021: Elevation // 15 bits. Metric = Degree. Scale = 2. Ref = -9000. $this->report_parts[$s][$i] = '111111111111111'; $this->explanations[$s][$i][] = '302048 -> 007021: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Elevation, 15bits)'; $i++; // 302048 -> 020012: Cloud type // 6 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111'; $this->explanations[$s][$i][] = '302048 -> 020012: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Cloud type, 6bits)'; $i++; // 302048 -> 005021: Bearing of azimuth // 16 bits. Metric = degree. Scale = 2. Ref = 0 $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302048 -> 005021: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Bearing of azimuth, 16bits)'; $i++; // 302048 -> 007021: Elevation // 15 bits. Metric = Degree. Scale = 2. Ref = -9000. $this->report_parts[$s][$i] = '111111111111111'; $this->explanations[$s][$i][] = '302048 -> 007021: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Elevation, 15bits)'; $i++; // 3 02 037: State of ground, snow depth, ground minimum temperature // 302037 -> 020062: State of the ground // 5 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '11111'; // 31 - missing value from "State of ground" code table. $this->explanations[$s][$i][] = '302037 -> 020062: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (State of the ground, 5bits)'; $i++; // 302037 -> 013013: Total snow depth // 16 bits. Metric = m. Scale = 2. Ref = -2. if (isset($this->sensors['snow_depth'])) { if ($this->sensors['snow_depth']['is_m']) { $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302037 -> 013013: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Last data about Snow Depth is unavailable</span> (Total snow depth, 16bits)'; } else { $value = round($this->sensors['snow_depth']['sensor_feature_value'] * 100) + 2; $this->report_parts[$s][$i] = $this->prepare_binary_value($value, 16); $this->explanations[$s][$i][] = '302037 -> 013013: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $value . '</span> (Total snow depth, 16bits)'; } } else { $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302037 -> 013013: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Total snow depth, 16bits)'; } $i++; // 302037 -> 012113: Ground minimum temperature // 16 bits. Metric = K. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302037 -> 012113: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Ground minimum temperature, 16bits)'; $i++; // 0 12 122: Ground minimum temperature of the preceding night // 16 bits. Metric = K. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '0 12 122: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Ground minimum temperature of the preceding night, 16bits)'; $i++; // 0 13 056: Character and intensity of precipitation // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 13 056: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Character and intensity of precipitation, 4bits)'; $i++; // 0 13 057: Time of beginning or end of precipitation // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 13 057: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time of beginning or end of precipitation, 4bits)'; $i++; // -- Locust data -- // 0 20 101: Locust (acridian) name // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 101: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Locust (acridian) name, 4bits)'; $i++; // 0 20 102: Locust (maturity) colour // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 102: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Locust (maturity) colour, 4bits)'; $i++; // 0 20 103: Stage of development of locusts // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 103: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Stage of development of locusts, 4bits)'; $i++; // 0 20 104: Organization state of swarm or band of locusts // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 104: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Organization state of swarm or band of locusts, 4bits)'; $i++; // 0 20 105: Size of swarm or band of locusts and duration of passage of swarm // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 105: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Size of swarm or band of locusts and duration of passage of swarm, 4bits)'; $i++; // 0 20 106: Locust population density // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 106: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Locust population density , 4bits)'; $i++; // 0 20 107: Direction of movements of locust swarm // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 107: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Direction of movements of locust swarm, 4bits)'; $i++; // 0 20 108: Extent of vegetation // 4 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '0 20 108: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Extent of vegetation, 4bits)'; $i++; // -- End of Locust data -- // 3 02 043: Basic synoptic “Period” data // 3 02 043 → 3 02 038: Present and past weather. // 302043 -> 302038 -> 020003: Present weather // 9 bits. Metric = Code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111111'; $this->explanations[$s][$i][] = '302043 -> 302038 -> 020003: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> Present weather, 9bits)'; $i++; // SEE NOTE 1! // 302043 -> 302038 -> 004024: Time period of displacement // 12 bits. Metric = Hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302038 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time period of displacement, 12bits)'; $i++; // 302043 -> 302038 -> 020004: Past Weather 1 // 5 bits. Metric = -. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '11111'; $this->explanations[$s][$i][] = '302043 -> 302038 -> 020004: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Past Weather 1, 5bits)'; $i++; // SEE NOTE 2! // 302043 -> 302038 -> 020005: Past Weather 2 // 5 bits. Metric = Code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '11111'; $this->explanations[$s][$i][] = '302043 -> 302038 -> 020005: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Past Weather 2, 5bits)'; $i++; // SEE NOTE 3! // 3 02 043 → 3 02 039: Sunshine data (from 1 hour and 24 hour period) // 302043 -> 302039 -> 004024 (Repetition #1): Time period of sunshine measuring // 12 bits. Metric = Hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = $this->prepare_binary_value(2047, 12); $this->explanations[$s][$i][] = '302043 -> 302039 -> 004024 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>-1 - (-2048) = 2047</span> (Time period of sunshine measuring, hours, 12 bits)'; $i++; // 302043 -> 302039 -> 014031 (Repetition #1): Total Sunshine // 11 bits. Metric = minute. Scale = 0. Ref = 0. if (isset($this->sensors['sun_duration_in_period']) && $this->sensors['sun_duration_in_period']['sensor_feature_period']) { if ($this->sensors['sun_duration_in_period']['is_m']) { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>Last data about Sunshine is unavailable</span>'; } else { // get object of SunDuration handler $handler_obj = SensorHandler::create($this->sensors['sun_duration_in_period']['handler_id_code']); // get total sunshine in last 1 hour $last_1_hr = $handler_obj->getTotalInLastXHr($this->sensors['sun_duration_in_period']['sensor_feature_id'], $script_runtime, 1, false)['total']; // round to get integer $str_tmp = round($last_1_hr); $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 11); $expl_val = '<span>' . $str_tmp . ' (during last hour)</span>'; } } else { $this->report_parts[$s][$i] = '11111111111'; $expl_val = '<span>No sunshine sensor</span>'; } $this->explanations[$s][$i][] = '302043 -> 302039 -> 014031 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Total Sunshine, minutes, 11bits)'; $i++; // 302043 -> 302039 -> 004024 (Repetition #2): Time period of sunshine measuring // 12 bits. Metric = hour. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = '100000011000'; $this->explanations[$s][$i][] = '302043 -> 302039 -> 004024 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>24 - (-2048) = 2072</span> (Time period of sunshine measuring, hrs, 12bits)'; $i++; // 302043 -> 302039 -> 014031 (Repetition #2): Total Sunshine // 11 bits. Metric = minute. Scale = 0. Ref = 0. if (isset($this->sensors['sun_duration_in_period']) && $this->sensors['sun_duration_in_period']['sensor_feature_period']) { $handler_obj = SensorHandler::create($this->sensors['sun_duration_in_period']['handler_id_code']); $last_24_hr = $handler_obj->getTotalInLastXHr($this->sensors['sun_duration_in_period']['sensor_feature_id'], $measuring_timestamp, 24, false)['total']; $str_tmp = round($last_24_hr); $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 11); $expl_val = '<span>' . $str_tmp . '</span>'; } else { $this->report_parts[$s][$i] = '11111111111'; $this->explanations[$s][$i][] = '<span>No sunshine sensor</span>'; } $this->explanations[$s][$i][] = '302043 -> 302039 -> 014031 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Total Sunshine, minutes, 11bits)'; $i++; // 3 02 043 → 3 02 040: Precipitation measurement // 302043 -> 302040 -> 007032: Height of rain sensor // 16 bits. Metric = m. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302043 -> 302040 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of rain sensor, 16bits)'; $i++; // 302043 -> 302040 -> 004024 (Repetition #1): Time period or displacement // 12 bits. Metric = hour. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = $this->prepare_binary_value(2047, 12); $this->explanations[$s][$i][] = '302043 -> 302040 -> 004024 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>-1 - (-2048) = 2049</span> (Time period or displacemnt, Hours, 12bits)'; $i++; // 302043 -> 302040 -> 013011 (Repetition #1): Total rain for 1 hour // 14 bits. Metric = kg/m2. Scale = 1. Ref = -1. if (isset($this->sensors['rain_in_period']) && $this->sensors['rain_in_period']['sensor_feature_period']) { if ($this->sensors['rain_in_period']['is_m']) { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = '<span>last data from Rain sensor is unavalable.</span>'; } else { // create object of Rain handler $handler_obj = SensorHandler::create($this->sensors['rain_in_period']['handler_id_code']); // get total rain in last 1 hour $last_1_hr = $handler_obj->getTotalInLastXHr($this->sensors['rain_in_period']['sensor_feature_id'], $script_runtime, 1, false)['total']; $tmp1 = It::convertMetric($last_1_hr, $this->sensors['rain_in_period']['metric_code'], 'millimeter'); // 1. apply scale = -2 (value * 10^1 ) // 2. round to get integer // 3. apply ref = -1 $tmp = round($tmp1 * 10) - -1; $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 14); $expl_val = '<span>' . $last_1_hr . ' ' . $this->sensors['rain_in_period']['metric_code'] . ' (during 60 min)'; if ($this->sensors['rain_in_period']['metric_code'] != 'millimeter') { $expl_val .= ' = ' . $tmp1 . ' mm '; } $expl_val .= ' ~ round(' . $tmp1 . ' * 10^1) -(-1) = ' . $tmp . '</span>'; } } else { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = '<span>No rain sensor</span>'; } $this->explanations[$s][$i][] = '302043 -> 302040 -> 013011 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . '(Total rain for 1 hour, 14bits)'; $i++; // The following descriptors about rain depend on script run timestamp. // At 00:00 report shows total rain for last 24 hours. // At 06:00, 12:00, 18:00 report shows total rain for last 6 hours. // For any other timestamp report shows missed value (111...) $rain_total_hours = 0; if ($script_runtime_minute == '00' && $script_runtime_hour == '00') { $rain_total_hours = 24; } else { if ($script_runtime_minute == '00' && in_array($script_runtime_hour, array('06', '12', '18'))) { $rain_total_hours = 6; } } // 302043 -> 302040 -> 004024 (Repetition #2): Time period of precipitation measuring // 12 bits. Metric = hour. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = $rain_total_hours ? $this->prepare_binary_value(2048 - $rain_total_hours, 12) : '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302040 -> 004024 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . ($rain_total_hours ? '-' . $rain_total_hours . ' - (-2048)' : 'This is not 00, 06, 12 or 18 hr') . '</span> (Time period of precipitation measuring, hrs, 12bits)'; $i++; // 302043 -> 302040 -> 013011 (Repetition #2): Total precipitation in last 24 or 6 hours // 14bits. Metric = kg/m2. Scale = 1. Ref = -1. if (isset($this->sensors['rain_in_period'])) { if ($rain_total_hours === 0) { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = '<span>Total rain can be calculated only at 00, 06, 12 or 18 hr</span>'; } else { // create object of rain Handler $handler_obj = SensorHandler::create($this->sensors['rain_in_period']['handler_id_code']); $rain_last_24_hr = $handler_obj->getTotalInLastXHr($this->sensors['rain_in_period']['sensor_feature_id'], $script_runtime, $rain_total_hours, false)['total']; $tmp = It::convertMetric($rain_last_24_hr, $this->sensors['rain_in_period']['metric_code'], 'millimeter'); // 1. apply scale = -2 (value * 10^1 ) // 2. round to get integer // 3. apply ref = -1 $tmp_str = round($tmp * 10) - -1; $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp_str, 14); $expl_val = '<span>'; $expl_val .= $rain_last_24_hr . ' ' . $this->sensors['rain_in_period']['metric_code']; if ($this->sensors['rain_in_period']['metric_code'] != 'millimeter') { $expl_val .= ' = ' . $tmp . ' mm'; } $expl_val .= '~ round(' . $tmp . ' * 10^1) -(-1) = ' . $tmp_str . '</span>'; } } else { $this->report_parts[$s][$i] = '11111111111111'; $expl_val = '<span>No rain sensor</span>'; } $this->explanations[$s][$i][] = '302043 -> 302040 -> 013011 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Total precipitation past ' . $rain_total_hours . ' hours, kg/m2, 14bits)'; $i++; // 3 02 043 -> 3 02 041: Extreme temperature data // 302043 -> 302041 -> 007032: Height of temperature sensor // 16 bits. Metric = m. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302043 -> 302041 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of temperature sensor, 16bits)'; $i++; // prepare temperature extremums if (isset($this->sensors['temperature'])) { $handler_obj = SensorHandler::create($this->sensors['temperature']['handler_id_code']); if ($script_runtime_hour == '06') { // get temperature extremums in period [21:00 of day before previous day; 21:00 of previous day) $tmp_measuring_timestamp = mktime(20, 59, 59, $script_runtime_month, $script_runtime_day - 1, $script_runtime_year); $temperature_extr = $handler_obj->getMaxMinFromHour($this->sensors['temperature']['sensor_feature_id'], $tmp_measuring_timestamp, 21, false); } else { if ($script_runtime_hour == '00') { // get temperature extremums in period [09:00 of previous day; 09:00 of this day) $tmp_measuring_timestamp = mktime(8, 59, 59, $script_runtime_month, $script_runtime_day - 1, $script_runtime_year); $temperature_extr = $handler_obj->getMaxMinFromHour($this->sensors['temperature']['sensor_feature_id'], $tmp_measuring_timestamp, 9, false); } } } // Max tempr // 302043 -> 302041 -> 004024: Time period of temperature measuring // 12 bits. Metric = hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = $script_runtime_hour == '06' && $script_runtime_minute == '00' ? '011111100100' : '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302041 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>24 * 10^0 - (-2048) = 2072</span> (Time period of temperature measuring, hours, 12bits)'; $i++; // 302043 -> 302041 -> 004024: Time period of temperature measuring // 12 bits. Metric = hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = $script_runtime_hour == '06' && $script_runtime_minute == '00' ? '011111111100' : '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302041 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time period or replacement, 12bits)'; $i++; // 302043 -> 302041 -> 012111: Maximum temperature, at height and over period specified // 16 bits. Metric = K. Scale = 2. Ref = 0. if (isset($this->sensors['temperature'])) { if ($script_runtime_hour == '06' && $script_runtime_minute == '00') { $tmp1 = It::convertMetric($temperature_extr['max'] ? $temperature_extr['max'] : 0, $this->sensors['temperature']['metric_code'], 'kelvin'); // 1. apply scale = 2 (value * 10^2) // 2. round to get integer $tmp = round($tmp1 * 100); $this->report_parts[$s][$i] = ($tmp > 0 ? '0' : '1') . $this->prepare_binary_value(abs($tmp), 15); $expl_val = $temperature_extr['max'] . ' ' . $this->sensors['temperature']['metric_code']; if ($this->sensors['temperature']['metric_code'] != 'kelvin') { $expl_val .= ' = ' . $tmp1 . ' kelvin'; } $expl_val .= ' ~ |round(' . $tmp1 . ' * 10^2) - 0| = ' . $tmp . '(+left bit = ' . ($tmp > 0 ? '0' : '1') . ' because ' . ($tmp > 0 ? 'positive' : 'negative') . ') '; } else { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = 'MAX tempr can be calculated only at 06UTC'; } } else { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = 'No temperature sensor'; } $this->explanations[$s][$i][] = '302043 -> 302041 -> 012111: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Maximum temperature, K, 16bits)'; $i++; // Min tempr // 302043 -> 302041 -> 004024: Time period of temperature measuring $this->report_parts[$s][$i] = $script_runtime_hour == '06' && $script_runtime_minute == '00' ? '011111100100' : '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302041 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . ($script_runtime_hour == '06' && $script_runtime_minute == '00' ? '-28 - (-2048) = 2020' : 'Missed because it is not at 00 UTC') . '</span> (Time period of temperature measuring, 12bits)'; $i++; // 302043 -> 302041 -> 004024: Time period of temperature measuring // 12 bits. Metric = hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = $script_runtime_hour == '06' && $script_runtime_minute == '00' ? '011111111100' : '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302041 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . ($script_runtime_hour == '06' && $script_runtime_minute == '00' ? '-4 - (-2048) = 2044' : 'Missed because it is not at 00 UTC') . '</span> (Time period or displacement, 12bits)'; $i++; // 302043 -> 302041 -> 012112: Minimum temperature, at height and over period specified // 16 bits. Metric = K. Scale = 2. Ref = 0. if (isset($this->sensors['temperature'])) { if ($script_runtime_hour == '06' && $script_runtime_minute == '00') { $tmp1 = It::convertMetric($temperature_extr['min'] ? $temperature_extr['min'] : 0, $this->sensors['temperature']['metric_code'], 'kelvin'); // 1. apply scale = 2 (value * 10^2) // 2. round to get integer $tmp = round($tmp1 * 100); $this->report_parts[$s][$i] = ($tmp > 0 ? '0' : '1') . $this->prepare_binary_value(abs($tmp), 15); $expl_val = $temperature_extr['min'] . ' ' . $this->sensors['temperature']['metric_code']; if ($this->sensors['temperature']['metric_code'] != 'kelvin') { $expl_val .= ' = ' . $tmp1 . ' kelvin'; } $expl_val .= ' ~ |round(' . $tmp1 . ' * 10^2) - 0| = ' . abs($tmp) . ' (+left bit = ' . ($tmp > 0 ? '0' : '1') . ' because ' . ($tmp > 0 ? 'positive' : 'negative') . ')'; } else { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = 'MIN tempr can be calculated only at 00UTC'; } } else { $this->report_parts[$s][$i] = '1111111111111111'; $expl_val = 'No temperature sensor'; } $this->explanations[$s][$i][] = '302043 -> 302041 -> 012112: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Minimum temperature, K, 16bits)'; $i++; // 3 02 043 -> 3 02 042: Wind data // 302043 -> 302042 -> 007032: Height of wind sensor // 16 bits. Metric = m. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of wind sensor, 16bits)'; $i++; // 302043 -> 302042 -> 002002: Type of instrumentation for wind measurement // 4 bits. Metric = Flag table. Scale = 0. Ref = 0 $this->report_parts[$s][$i] = $this->prepare_binary_value(8, 4); $this->explanations[$s][$i][] = '302043 -> 302042 -> 002002: <span>' . $this->report_parts[$s][$i] . '</span> => <span>8</span> (Type of instrumentation for wind measurement, 4 bits)'; $i++; // 302043 -> 302042 -> 008021: Time significance // 5 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = $this->prepare_binary_value(2, 5); $this->explanations[$s][$i][] = '302043 -> 302042 -> 008021: <span>' . $this->report_parts[$s][$i] . '</span> => <span>2=time averaged</span> (Time significance, 5 bits)'; $i++; // 302043 -> 302042 -> 004025: Time period or displacement // 12 bits. Metric = minute. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = $this->prepare_binary_value(2038, 12); $this->explanations[$s][$i][] = '302043 -> 302042 -> 004025: <span>' . $this->report_parts[$s][$i] . '</span> => <span>-10 - (-2048) = 2038</span> (Time period or displacement, min, 12bits)'; $i++; // 302043 -> 302042 -> 011001: Wind direction // 9 bits. Metric = degree. Scale = 0. Ref = 0. if (isset($this->sensors['wind_direction_10'])) { if ($this->sensors['wind_direction_10']['is_m']) { $this->report_parts[$s][$i] = '111111111'; $expl_val = 'Last data about Wind Direction is unavailable'; } else { // create object of wind direction handler $handler_obj = SensorHandler::create($this->sensors['wind_direction_10']['handler_id_code']); // apply magnetic north offset $tmp = $handler_obj->applyOffset($this->sensors['wind_direction_10']['sensor_feature_value'], $this->station_info->magnetic_north_offset); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 9); $expl_val = $this->sensors['wind_direction_10']['sensor_feature_value']; } } else { $this->report_parts[$s][$i] = '111111111'; $expl_val = 'No Wind Direction sensor'; } $this->explanations[$s][$i][] = '302043 -> 302042 -> 011001: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Wind direction, degree, 9 bits)'; $i++; // 302043 -> 302042 -> 011002: Wind speed // 12 bits. Metric = m/s. Scale = 1. Ref = 0. if (isset($this->sensors['wind_speed_10'])) { if ($this->sensors['wind_speed_10']['is_m']) { $this->report_parts[$s][$i] = '111111111111'; $expl_val = 'Last data about Wind Speed is unavailable'; } else { $tmp1 = It::convertMetric($this->sensors['wind_speed_10']['sensor_feature_value'], $this->sensors['wind_speed_10']['metric_code'], 'meter_per_second'); // 1. apply scale = 1 (value * 10) // 2. round to get integer $tmp = round($tmp1 * 10); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 12); $expl_val = $this->sensors['wind_speed_10']['sensor_feature_value'] . ' ' . $this->sensors['wind_speed_10']['metric_code']; if ($this->sensors['wind_speed_10']['metric_code'] != 'meter_per_second') { $expl_val .= ' = ' . $tmp1 . ' meter_per_second'; } $expl_val .= ' ~ round(' . $tmp1 . ' * 10^1) = ' . $tmp; } } else { $this->report_parts[$s][$i] = '111111111111'; $expl_val = 'No Wind Speed sensor'; } $this->explanations[$s][$i][] = '302043 -> 302042 -> 011002: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Wind speed, m/s, 12bits)'; $i++; // 302043 -> 302042 -> 008021: Time significance // 5 bits. Metric = code table. Scale = 0. Ref =0 . $this->report_parts[$s][$i] = '11111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 008021: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time significance, 5bits)'; $i++; // 302043 -> 302042 -> 004025 (Repetition #1): Time of preiod or displacement // 12 bits. Metric = minute. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 004025 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time of preiod or displacement, min, 12 bits)'; $i++; // 302043 -> 302042 -> 011043 (Repetition #1): Maximum wind gust direction // 9 bits. Metric = degree. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 011043 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Maximum wind gust direction, degree, 9 bits)'; $i++; // 302043 -> 302042 -> 011041 (Repetition #1): Maximum wind gust speed // 12 bits. Metric = m/s. Scale = 1. Ref = 0. $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 011041 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Maximum wind gust speed, 12 bits)'; $i++; // 302043 -> 302042 -> 004025 (Repetition #2): Time of preiod or displacement // 12 bits. Metric = minute. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 004025 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time of preiod or displacement, min, 12 bits)'; $i++; // 302043 -> 302042 -> 011043 (Repetition #2): Maximum wind gust direction // 9 bits. Metric = degree. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 011043 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Maximum wind gust direction, degree, 9 bits)'; $i++; // 302043 -> 302042 -> 011041 (Repetition #2): Maximum wind gust speed // 12 bits. Metric = m/s. Scale = 1. Ref = 0. $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302043 -> 302042 -> 011041 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Maximum wind gust speed, 12 bits)'; $i++; // ADDED BLOCK! // 302043 -> 007032: Height of sensor above local ground // 16 bits. Metric = m. Scale = 2. Ref = 0. $this->report_parts[$s][$i] = '1111111111111111'; $this->explanations[$s][$i][] = '302043 -> 007032: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Height of sensor above local ground (or deck of marine platform, 16 bits)'; $i++; // END OF ADDED BLOCK! // 3 02 044: Evaporation data // 302044 -> 004024: Time period or displacement // 12 bits. Metric = hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302044 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time period or displacement, Hour, 12 bits)'; $i++; // 302044 -> 002004: Type of instrumentation for evaporation measurement or type of crop for which evapotranspiration is reported // 4 bits. Metric = code table. Scale = 0. Ref = 0. $this->report_parts[$s][$i] = '1111'; $this->explanations[$s][$i][] = '302044 -> 002004: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Type of ..., 4bits)'; $i++; // 302044 -> 013033: Evaporation/evapotranspiration // 10 bits. Metric = kg/m2. Scale = 1. Ref = 0. $this->report_parts[$s][$i] = '1111111111'; $this->explanations[$s][$i][] = '302044 -> 013033: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing (Evaporation/evapotranspiration, 10bits)</span>'; $i++; // 3 02 045: Radiation data (from 1 hour and 24 hour period) // 302045 -> 004024 (Repetition #1): Time period or displacement // 12 bits. Metric = hour. Scale = 0. Ref = 2048. $this->report_parts[$s][$i] = $this->prepare_binary_value(2047, 12); $this->explanations[$s][$i][] = '302045 -> 004024 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>-1 - (-2048) = 2047</span> (Time period or displacement, Hour, 12 bits)'; $i++; // 302045 -> 014002 (Repetition #1): Long-wave radiation // 17 bits. Metric: J/m2. Scale = -3. Ref = -65536. $this->report_parts[$s][$i] = '11111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014002 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Long-wave radiation, 17 bits)'; $i++; // 302045 -> 014004 (Repetition #1): Short-wave radiation // 17 bits. Metric: J/m2. Scale = -3. Ref = -65536. $this->report_parts[$s][$i] = '11111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014004 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Short-wave radiation, 17 bits)'; $i++; // 302045 -> 014016 (Repetition #1): Net radiation // 15 bits. Metric: J/m2. Scale = -4. Ref = -16384 $this->report_parts[$s][$i] = '111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014016 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Net radiation, 15 bits)'; $i++; // 302045 -> 014028 (Repetition #1): Global solar radiation // 20 bits. Metric = J/m2. Scale = -2. Ref = 0. if (isset($this->sensors['solar_radiation_in_period']) && $this->sensors['solar_radiation_in_period']['sensor_feature_period']) { if ($this->sensors['solar_radiation_in_period']['is_m']) { $this->report_parts[$s][$i] = '11111111111111111111'; $expl_val = 'Last data about Sun Radiation is unavailable'; } else { // create object of Solar Radiation Handler $handler_obj = SensorHandler::create($this->sensors['solar_radiation_in_period']['handler_id_code']); // get total radiation in last 1 hr $last_1_hr = $handler_obj->getTotalInLastXHr($this->sensors['solar_radiation_in_period']['sensor_feature_id'], $script_runtime, 1, false)['total']; $tmp1 = It::convertMetric($last_1_hr, $this->sensors['solar_radiation_in_period']['metric_code'], 'joule_per_sq_meter'); $tmp = round($tmp1 / 100); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 20); $expl_val = $tmp1 . ' ' . $this->sensors['solar_radiation_in_period']['metric_code'] . ' (during 60 min)'; if ($this->sensors['solar_radiation_in_period']['metric_code'] != 'joule_per_sq_meter') { $expl_val .= ' = ' . $tmp1 . ' joule_per_sq_meter (during 60 min)'; } $expl_val .= ' ~ round(' . $tmp1 . ' * 10^(-2)) = ' . $tmp; } } else { $this->report_parts[$s][$i] = '11111111111111111111'; $expl_val = 'No Sun Radiation sensor'; } $this->explanations[$s][$i][] = '302045 -> 014028 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (Global solar radiation, J/m2, 20 bits)'; $i++; // 302045 -> 014029 (Repetition #1): Diffuse solar radiation // 20 bits. Metric = J/m2. Scale = -2. Ref = 0. $this->report_parts[$s][$i] = '11111111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014029 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Diffuse solar radiation, 20 bits)'; $i++; // 302045 -> 014030 (Repetition #1): Direct solar radiation // 20 bits. Metric = J/m2. Scale = -2. Ref = 0. $this->report_parts[$s][$i] = '11111111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014030 (Repetition #1): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Direct solar radiation, 20 bits)'; $i++; // 302045 -> 004024 (Repetition #2): Time period or displacement (24 hr only for report at 00:00. Miss for other times) // 12 bits. Metric = hour. Scale = 0. Ref = -2048 $this->report_parts[$s][$i] = $script_runtime_hour == '06' && $script_runtime_minute == '00' ? '011111101000' : '111111111111'; $this->explanations[$s][$i][] = '302045 -> 004024 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . ($script_runtime_hour == '06' && $script_runtime_minute == '00' ? '(-24) - (-2048) = 2024' : 'Missing, It is not 06UTC') . '</span> (Time period or displacement, Hour, 12 bits)'; $i++; // 302045 -> 014002 (Repetition #2): Long-wave radiation // 17 bits. Metric: J/m2. Scale = -3. Ref = -65536. $this->report_parts[$s][$i] = '11111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014002 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Long-wave radiation, 17 bits)'; $i++; // 302045 -> 014004 (Repetition #2): Short-wave radiation // 17 bits. Metric: J/m2. Scale = -3. Ref = -65536. $this->report_parts[$s][$i] = '11111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014004 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Short-wave radiation, 17 bits)'; $i++; // 302045 -> 014016 (Repetition #2): Net radiation // 15 bits. Metric: J/m2. Scale = -4. Ref = -16384 $this->report_parts[$s][$i] = '111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014016 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Net radiation, 15 bits)'; $i++; // 302045 -> 014028 (Repetition #2): GLOBAL SOLAR RADIATION // 20 bits. Metric = J/m2. Scale = -2. Ref = 0. if (isset($this->sensors['solar_radiation_in_period'])) { if ($script_runtime_hour == '06' && $script_runtime_minute == '00') { // create object of Solar Radiation Handler $handler_obj = SensorHandler::create($this->sensors['solar_radiation_in_period']['handler_id_code']); // get total radiation in last 24 hr $last_24_hr = $handler_obj->getTotalInLastXHr($this->sensors['solar_radiation_in_period']['sensor_feature_id'], $script_runtime, 24, false)['total']; $tmp1 = It::convertMetric($last_24_hr, $this->sensors['solar_radiation_in_period']['metric_code'], 'joule_per_sq_meter'); $tmp = round($tmp1 / 100); $this->report_parts[$s][$i] = $this->prepare_binary_value($tmp, 20); $expl_val = $last_24_hr . ' ' . $this->sensors['solar_radiation_in_period']['metric_code']; if ($this->sensors['solar_radiation_in_period']['metric_code'] != 'joule_per_sq_meter') { $expl_val .= ' = ' . $tmp1 . ' joule_per_sq_meter'; } $expl_val .= ' ~ round(' . $tmp1 . ' * 10^(-2)) = ' . $tmp; } else { $this->report_parts[$s][$i] = '11111111111111111111'; $expl_val = '24hr radiation can be calculated only at 06UTC'; } } else { $this->report_parts[$s][$i] = '11111111111111111111'; $expl_val = 'No Sun Radiation sensor'; } $this->explanations[$s][$i][] = '302045 -> 014028 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $expl_val . '</span> (GLOBAL SOLAR RADIATION, J/m2, 20 bits)'; $i++; // 302045 -> 014029 (Repetition #2): Diffuse solar radiation // 20 bits. Metric = J/m2. Scale = -2. Ref = 0. $this->report_parts[$s][$i] = '11111111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014029 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Diffuse solar radiation, 20 bits)'; $i++; // 302045 -> 014030 (Repetition #2): Direct solar radiation // 20 bits. Metric = J/m2. Scale = -2. Ref = 0. $this->report_parts[$s][$i] = '11111111111111111111'; $this->explanations[$s][$i][] = '302045 -> 014030 (Repetition #2): <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Direct solar radiation, 20 bits)'; $i++; // 3 02 046: Temperature change // 302046 -> 004024: Time period or displacement // 12 bits. Metric = hour. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302046 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time period or displacement, Hour, 12 bits)'; $i++; // 302046 -> 004024: Time period or displacement // 12 bits. Metric = hour. Scale = 0. Ref = -2048. $this->report_parts[$s][$i] = '111111111111'; $this->explanations[$s][$i][] = '302046 -> 004024: <span>' . $this->report_parts[$s][$i] . '</span> => <span>Missing</span> (Time period or displacement, Hour, 12 bits)'; $i++; // 302046 -> 012049: Temperature change over period specified // 6 bits. Metric = K. Scale = 0. Ref = -30. if (isset($this->sensors['temperature']) && isset($sensors_24hr_ago['temperature'])) { if ($script_runtime_minute == '00' && in_array($script_runtime_hour, array('00', '03', '06', '09', '12', '15', '18', '21'))) { if ($this->sensors['temperature']['is_m']) { $this->report_parts[$s][$i] = '111111'; $expl_val = 'Data about last Temperature is unavailable'; } else { if ($sensors_24hr_ago['temperature']['is_m']) { $this->report_parts[$s][$i] = '111111'; $expl_val = 'Data about 24h ago Temperature is unavailable'; } else { $tmp1 = It::convertMetric($this->sensors['temperature']['sensor_feature_value'], $this->sensors['temperature']['metric_code'], 'kelvin'); $tmp2 = It::convertMetric($sensors_24hr_ago['temperature']['sensor_feature_value'], $sensors_24hr_ago['temperature']['metric_code'], 'kelvin'); $str_tmp = abs(round($tmp1 - $tmp2)) + 30; $this->report_parts[$s][$i] = $this->prepare_binary_value($str_tmp, 6); $expl_val = 'Last Tempr = ' . round($this->sensors['temperature']['sensor_feature_value'], 1) . ' ' . $this->sensors['temperature']['metric_code'] . ' (' . round($tmp1, 1) . ' kelvin)'; $expl_val .= '; 24h ago Tempr = ' . round($sensors_24hr_ago['temperature']['sensor_feature_value'], 1) . ' ' . $sensors_24hr_ago['temperature']['metric_code'] . ' (' . round($tmp2, 1) . ' kelvin)'; $expl_val .= '; |Last - 24h| = |' . ($tmp1 - $tmp2) . '| ~ ' . abs(round($tmp1 - $tmp2)); $expl_val .= '; Apply ref.value -30: <span>' . (abs(round($tmp1 - $tmp2)) + 30) . '</span>'; } } } else { $this->report_parts[$s][$i] = '111111'; $expl_val = '<span>It is not 06UTC. Total 24h Sunshine is calculated only at 06:00UTC</span>'; } } else { $this->report_parts[$s][$i] = '111111'; $expl_val = 'No Temperature sensor'; } $this->explanations[$s][$i][] = '302046 -> 012049: <span>' . $this->report_parts[$s][$i] . '</span> => ' . $expl_val . ' (Temperature change over period specified, K, 6 bits)'; $i++; $concatenated = implode('', $this->report_parts[$s]); $reminder = fmod(strlen($concatenated), 8); $this->report_parts[$s][$i] = str_pad('0', 8 - $reminder, '0', STR_PAD_LEFT); $this->explanations[$s][$i][] = 'Extra <span>' . (8 - $reminder) . '</span> bits to make int count of octets in section 4: <span>' . $this->report_parts[$s][$i] . '</span>'; $s = 4; $i = 0; $concatenated = implode('', $this->report_parts[$s]); $total = strlen($concatenated) / 8; /// ??? RECALCULATE !!!! $this->report_parts[$s][$i] = $this->prepare_binary_value($total, 24); $this->explanations[$s][$i][0] = 'Octets 1-3: <span>' . $this->report_parts[$s][$i] . '</span> => <span>' . $total . '</span> (length of section4 in octets)'; $i++; }
protected function _prepareListenerLogInfo() { $this->_logger->log(__METHOD__); if (!is_null($this->schedule_process_info)) { $criteria = new CDbCriteria(); $criteria->compare('station_id', $this->schedule_info->station_id); $criteria->compare('failed', '0'); $criteria->compare('measuring_timestamp', '>=' . $this->schedule_process_info->check_period_start); $criteria->compare('measuring_timestamp', '<=' . $this->schedule_process_info->check_period_end); $criteria->order = 'measuring_timestamp desc, log_id desc'; $this->_logger->log(__METHOD__ . 'measuring_timestamp' . '>=' . $this->schedule_process_info->check_period_start); $this->_logger->log(__METHOD__ . 'measuring_timestamp' . '<=' . $this->schedule_process_info->check_period_end); if (in_array($this->schedule_info->report_type, array('bufr', 'synop', 'metar', 'speci'))) { $criteria->limit = '1'; $logRecord = ListenerLog::model()->find($criteria); // $this->schedule_process_info->listener_log_id = is_null($logRecord) ? 0 : $logRecord->log_id; // $this->schedule_process_info->save(); $this->listener_log_info = $logRecord; $this->_logger->log(__METHOD__ . ' $this->listener_log_info' . print_r($this->listener_log_info, 1)); if (is_null($this->listener_log_info)) { $this->errors[] = 'Listener log info (#' . $this->schedule_process_info->listener_log_id . ') can not be found'; return false; } } else { $logRecords = ListenerLog::model()->findAll($criteria); if (count($logRecords) > 0) { $logIds = array(); foreach ($logRecords as $logRecord) { $logIds[] = $logRecord->log_id; } $this->listener_log_info = $logRecords; $this->schedule_process_info->listener_log_ids = implode(',', $logIds); $this->schedule_process_info->save(); } else { $this->listener_log_info = null; $this->schedule_process_info->listener_log_ids = ''; $this->schedule_process_info->save(); $this->errors[] = 'Listener log info (#' . $this->schedule_process_info->listener_log_id . ') can not be found'; return false; } } } return true; }
public function prepareList($page_size = 10) { $stations = $this->getAllStations(); if ($stations) { $sql_where = array(); //---------------- Start groupping $use_field = ''; if ($this->rate_volume == 1) { $use_field = 'sensor_value'; } else { if ($this->rate_volume == 5) { $use_field = '5min_sum'; $tmp = array('00', '05', '10', '15', '20', '25', '30', '35', '40', '45', '50', '55'); } else { if ($this->rate_volume == 10) { $use_field = '10min_sum'; $tmp = array('00', '10', '20', '30', '40', '50'); } else { if ($this->rate_volume == 20) { $use_field = '20min_sum'; $tmp = array('00', '20', '40'); } else { if ($this->rate_volume == 30) { $use_field = '30min_sum'; $tmp = array('00', '30'); } else { if ($this->rate_volume == 60) { $use_field = '60min_sum'; $tmp = array('00'); } } } } } $sql_where[] = "DATE_FORMAT(`sd`.`measuring_timestamp`, '%i') IN ('" . implode("','", $tmp) . "')"; } $sql_where[] = "`sd`.`" . $use_field . "` > 0"; //---------------- End groupping //---------------- Start date filter if ($this->date_from) { $sql_where[] = "`sd`.`measuring_timestamp` >= '" . date('Y-m-d H:i:s', strtotime($this->date_from . ' ' . $this->time_from)) . "'"; } if ($this->date_to) { $sql_where[] = "`sd`.`measuring_timestamp` <= '" . date('Y-m-d H:i:s', strtotime($this->date_to . ' ' . $this->time_to)) . "'"; } //---------------- End date filter //---------------- Start Station filter if ($this->station_id) { $sql_where[] = "`sd`.`station_id` = '" . $this->station_id . "'"; } else { $sql_groupped_table = "SELECT `sensor_id`, MAX(`measuring_timestamp`) AS `MaxDateTime` FROM `" . SensorDataMinute::model()->tableName() . "` WHERE `" . $use_field . "` > 0 "; if ($this->date_from) { $sql_groupped_table .= " AND `measuring_timestamp` >= '" . date('Y-m-d H:i:s', strtotime($this->date_from . ' ' . $this->time_from)) . "' "; } if ($this->date_to) { $sql_groupped_table .= " AND `measuring_timestamp` <= '" . date('Y-m-d H:i:s', strtotime($this->date_to . ' ' . $this->time_to)) . "' "; } $sql_groupped_table .= " GROUP BY `sensor_id` "; $sql = "SELECT `tt`.`sensor_data_id`\n FROM `" . SensorDataMinute::model()->tableName() . "` `tt`\n INNER JOIN ( {$sql_groupped_table} ) `groupedtt` ON `tt`.`sensor_id` = `groupedtt`.`sensor_id` AND `tt`.`measuring_timestamp` = `groupedtt`.`MaxDateTime`"; $last_values = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryColumn(); if (!$last_values) { $last_values = array(0); } $sql_where[] = "`sd`.`station_id` IN (" . implode(',', array_keys($stations)) . ") AND `sd`.`sensor_data_id` IN (" . implode(',', $last_values) . ")"; } //---------------- End Station filter if ($page_size > 0) { $sql = "SELECT COUNT(*)\n FROM `" . SensorDataMinute::model()->tableName() . "` `sd`\n WHERE " . implode(' AND ', $sql_where); $total = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryScalar(); $pages = new CPagination($total); $pages->pageSize = $page_size; //$pages->applyLimit($criteria); } if ($this->order_field == 'date') { $sql_order = "`sd`.`measuring_timestamp` " . $this->order_direction; } elseif ($this->order_field == 'name') { $sql_order = "`st`.`display_name` " . $this->order_direction; } elseif ($this->order_field == 'lasttx') { $sql_order = "`sd`.`" . $use_field . "` " . $this->order_direction; } elseif ($this->order_field == 'lasthr') { $sql_order = "`sd`.`60min_sum` " . $this->order_direction; } elseif ($this->order_field == 'last24hr') { $sql_order = "`sd`.`1day_sum` " . $this->order_direction; } $sql = "SELECT `st`.`display_name`,\n `st`.`station_id_code`,\n `st`.`station_id`,\n\n `ll`.`message`,\n `ll`.`log_id`,\n\n `sd`.`sensor_data_id`,\n `sd`.`battery_voltage`,\n `sd`.`sensor_id`,\n `sd`.`measuring_timestamp`,\n DATE_FORMAT(`sd`.`measuring_timestamp`, '%m/%d/%Y') AS `tx_date_formatted`,\n DATE_FORMAT(`sd`.`measuring_timestamp`, '%H:%i') AS `tx_time_formatted`,\n `sd`.`sensor_value`,\n `sd`.`5min_sum`,\n `sd`.`10min_sum`,\n `sd`.`20min_sum`,\n `sd`.`30min_sum`,\n `sd`.`60min_sum`,\n `sd`.`1day_sum`,\n\n `sd`.`bucket_size`,\n `sd`.`1day_sum` AS `day_value_mm`,\n `sd`.`60min_sum` AS `hour_value_mm`\n\n FROM `" . SensorDataMinute::model()->tableName() . "` `sd`\n LEFT JOIN `" . ListenerLog::model()->tableName() . "` `ll` ON `sd`.`listener_log_id` = `ll`.`log_id`\n LEFT JOIN `" . Station::model()->tableName() . "` `st` ON `st`.`station_id` = `sd`.`station_id`\n\n WHERE " . implode(' AND ', $sql_where) . "\n ORDER BY {$sql_order} "; if ($page_size) { $sql .= " LIMIT " . $pages->currentPage * $pages->pageSize . ", " . $pages->pageSize; } $res = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); if ($res) { $total_found = count($res); foreach ($res as $key => $value) { $res[$key]['battery_voltage_formatted'] = $value['battery_voltage'] / 10; $res[$key]['tx_value_mm'] = $value[$use_field] * $value['bucket_size']; $res[$key]['tx_value_rate_mm'] = $value[$use_field] * $value['bucket_size'] * 60 / $this->rate_volume; $res[$key]['day_value_mm'] = $value['day_value_mm'] * $value['bucket_size']; $res[$key]['hour_value_mm'] = $value['hour_value_mm'] * $value['bucket_size']; $res[$key]['period'] = $this->rate_volume; $hour_value_id = date('YmdH', strtotime($value['measuring_timestamp'])); $res[$key]['hour_value_id'] = $hour_value_id; $res[$key]['hour_value_rate_mm'] = 0; if ($stations[$value['station_id']]['filter_limit_max'] > 0) { if ($res[$key]['tx_value_mm'] >= $stations[$value['station_id']]['filter_limit_max']) { $res[$key]['filter_errors'][] = "R >= <b>" . $stations[$value['station_id']]['filter_limit_max'] . "</b> "; } } if ($stations[$value['station_id']]['filter_limit_min'] > 0) { if ($res[$key]['tx_value_mm'] <= $stations[$value['station_id']]['filter_limit_min']) { $res[$key]['filter_errors'][] = "R <= <b>" . $stations[$value['station_id']]['filter_limit_min'] . "</b> "; } } if ($stations[$value['station_id']]['filter_limit_diff'] > 0) { if ($key != 0 && abs($res[$key]['tx_value_mm'] - $res[$key - 1]['tx_value_mm']) >= $stations[$value['station_id']]['filter_limit_diff']) { $res[$key]['filter_errors'][] = "|R - R0| >= <b>" . $stations[$value['station_id']]['filter_limit_diff'] . "</b> "; } } } foreach ($res as $key => $value) { if ($key != 0 && $res[$key]['hour_value_id'] != $res[$key - 1]['hour_value_id']) { $res[$key - 1]['hour_value_rate_mm'] = $res[$key - 1]['hour_value_mm']; } elseif ($key == $total_found - 1) { $res[$key]['hour_value_rate_mm'] = $res[$key]['hour_value_mm']; } } } } return array('list' => $res, 'pages' => $pages); }
public function actionScheduleStationHistory() { $station_to_report_id = isset($_REQUEST['station_to_report_id']) ? intval($_REQUEST['station_to_report_id']) : null; if (!$station_to_report_id) { $this->redirect($this->createUrl('site/schedule')); } $criteria = new CDbCriteria(); $criteria->condition = 'sr_to_s_id = :sr_to_s_id'; $criteria->params = array(':sr_to_s_id' => $station_to_report_id); $criteria->order = 'schedule_processed_id DESC'; $count = ScheduleReportProcessed::model()->count($criteria); $pages = new CPagination($count); $pages->pageSize = 15; $pages->applyLimit($criteria); $scheduleProcessed = ScheduleReportProcessed::model()->with('listenerLog', 'ScheduleReportToStation.schedule_report', 'ScheduleReportToStation.realStation')->findAll($criteria); $files_path = dirname(Yii::app()->request->scriptFile) . DIRECTORY_SEPARATOR . "files" . DIRECTORY_SEPARATOR . "schedule_reports"; $scheduleProcessedFormatted = array(); foreach ($scheduleProcessed as $key => $value) { $scheduleProcessedFormatted[$key] = $value->attributes; $scheduleProcessedFormatted[$key]['report_type'] = $value->ScheduleReportToStation['schedule_report']['report_type']; $scheduleProcessedFormatted[$key]['report_format'] = $value->ScheduleReportToStation['schedule_report']['report_format']; $scheduleProcessedFormatted[$key]['station_id'] = $value->ScheduleReportToStation->station_id; $scheduleProcessedFormatted[$key]['measuring_timestamp'] = $value->listenerLog['measuring_timestamp']; $scheduleProcessedFormatted[$key]['message'] = $value->listenerLog->message; if ($scheduleProcessedFormatted[$key]['serialized_report_errors']) { $scheduleProcessedFormatted[$key]['report_errors'] = unserialize($scheduleProcessedFormatted[$key]['serialized_report_errors']); } if ($scheduleProcessedFormatted[$key]['serialized_report_explanations']) { $scheduleProcessedFormatted[$key]['report_explanations'] = unserialize($scheduleProcessedFormatted[$key]['serialized_report_explanations']); } if (in_array($value->ScheduleReportToStation['schedule_report']['report_type'], array('synop', 'metar', 'speci')) && file_exists($files_path . DIRECTORY_SEPARATOR . $scheduleProcessedFormatted[$key]['schedule_processed_id'])) { $scheduleProcessedFormatted[$key]['report_string_initial'] = file_get_contents($files_path . DIRECTORY_SEPARATOR . $scheduleProcessedFormatted[$key]['schedule_processed_id']); } if ($scheduleProcessedFormatted[$key]['listener_log_ids']) { $sql = "SELECT t2.log_id, t2.message, t2.measuring_timestamp\n FROM `" . ListenerLog::model()->tableName() . "` t2\n WHERE t2.log_id IN (" . $scheduleProcessedFormatted[$key]['listener_log_ids'] . ")\n ORDER BY `t2`.`measuring_timestamp` DESC"; $scheduleProcessedFormatted[$key]['logs'] = Yii::app()->db->createCommand($sql)->queryAll(); } } $reportInfo = $scheduleProcessed[0]->ScheduleReportToStation['schedule_report']->attributes; $stationInfo = $scheduleProcessed[0]->ScheduleReportToStation->realStation->attributes; $this->render('schedule_report_history', array('scheduleProcessed' => $scheduleProcessedFormatted, 'stationInfo' => $stationInfo, 'reportInfo' => $reportInfo, 'pages' => $pages)); }
protected function listenDLTorrent($cycle = 1) { $this->_logger->log(__METHOD__, array('cycle' => $cycle)); $this->_connector->setParams(array('timeout' => 60)); ListenerProcess::addComment($this->listener->listener_id, 'comment', 'Opening COM connection'); $messages = null; $process = $this; $logger = $process->_logger; $this->_connector->onReceiveMessage = function ($message) use(&$process, &$logger) { $logger->log(__METHOD__ . ' New message', array('message' => $message, 'listener_id' => $process->listener->listener_id, 'overwrite' => $process->settings->overwrite_data_on_listening)); $messageId = ListenerLog::addNew($message, $process->listener->listener_id, $process->settings->overwrite_data_on_listening, 'datalogger'); ListenerProcess::addComment($process->listener->listener_id, 'comment', 'got msg #' . $messageId); }; $result = $this->_connector->readData($messages); $this->_logger->log(__METHOD__ . ' Complete listen datalogger.', array('cycle' => $cycle, 'result' => $result)); }
/** * parses message and adds parsed values to database */ function logMessage() { $this->_logger->log(__METHOD__); if ($this->_station->timezone_id) { TimezoneWork::set($this->_station->timezone_id); // TimezoneWork::setReverse($this->_station->timezone_id); } // saves measuring timestamp $measuring_timestamp = mktime(substr($this->_tx_time, 0, 2), substr($this->_tx_time, 2, 2), 0, substr($this->_tx_date, 2, 2), substr($this->_tx_date, 4, 2), substr($this->_tx_date, 0, 2)); // if ($this->_station->timezone_id){ // $measuring_timestamp = TimezoneWork::setTimeByLocalTz($this->_station->timezone_id,$measuring_timestamp); // } $this->message_obj->measuring_timestamp = date('Y-m-d H:i:s', $measuring_timestamp); $this->_logger->log(__METHOD__ . " measuring_timestamp: " . $measuring_timestamp); $this->_logger->log(__METHOD__ . " date: " . $this->message_obj->measuring_timestamp); $this->message_obj->save(); // there are different ways to parse LOG message and REGULAR message if ($this->_message_type === 'rg_log') { // LOG provides us with info from only 1 sensor (however RG station can have more sensors) $sensor_info = $this->getFirstRGSensor(); if ($sensor_info !== false) { $save_data_params = array('listener_log_id' => $this->message_obj->log_id, 'rewrite_prev_values' => $this->message_obj->rewrite_prev_values, 'battery_voltage' => $this->rg_battery_voltage, 'sensor' => $sensor_info['sensor'], 'sensor_features' => $sensor_info['features']); // create object of sensor handler $handler_obj = SensorHandler::create('RainRgLog'); // parse part of message which is going just after sensor ID. // prepare data pairs basing on this string $res = $handler_obj->prepareDataPairs($this->_body, $measuring_timestamp, $sensor_info['features']); if ($res === false) { $this->pushWarning('incorrect_sensor_value_format', 'Handler ' . $sensor_info['sensor']->sensor_id_code . ' can not get data from "' . $this->_body . '"'); //continue; } // save prepared sensor's data $handler_obj->saveDataPairs($save_data_params); } } else { // parse body into pairs SensorId::DataString $message_sensors_strings = $this->parseSensorsValues($this->_body); if (is_array($message_sensors_strings) && count($message_sensors_strings) > 0) { $save_data_params = array('listener_log_id' => $this->message_obj->log_id, 'rewrite_prev_values' => $this->message_obj->rewrite_prev_values, 'battery_voltage' => $this->rg_battery_voltage); foreach ($message_sensors_strings as $message_sensor_string) { // get sensor's info by sensor ID code $sensor_info = $this->getSensorInfo($message_sensor_string[0]); if (!is_null($sensor_info)) { $save_data_params['sensor'] = $sensor_info['sensor']; $save_data_params['sensor_features'] = $sensor_info['features']; // create object of sensor handler $handler_obj = SensorHandler::create($sensor_info['sensor']->handler->handler_id_code); $handler_obj->loadAWSFormat($this->_station->aws_format); // parse string coming after sensor ID into data pairs (feature:value) $res = $handler_obj->prepareDataPairs($message_sensor_string[1], $measuring_timestamp, $sensor_info['features']); if ($res === false) { $this->pushWarning('incorrect_sensor_value_format', 'Handler ' . $message_sensor_string[0] . ' can not get data from "' . $message_sensor_string[1] . '"'); continue; } // save features values $handler_obj->saveDataPairs($save_data_params); // some actions can be done after data is saved (depends on handler) $handler_obj->afterDataPairsSaved($save_data_params); } } } } }
private function prepareListenerLogInserts($limit_timestamp) { $result_sql = ""; $sql = "SELECT * \n FROM `" . ListenerLog::model()->tableName() . "`\n WHERE `created` <= '" . $limit_timestamp . "' \n LIMIT 0, 50"; $res = Yii::app()->db->createCommand($sql)->queryAll(); $total = count($res); $ids = array(); if ($res) { $fields = array(); foreach ($res[0] as $key2 => $value2) { $fields[] = $key2; } $sql_header = "INSERT IGNORE INTO `" . ListenerLog::model()->tableName() . "` (`" . implode('`,`', $fields) . "`) VALUES "; $result_sql = $sql_header; foreach ($res as $key => $value) { $ids[] = $value['log_id']; $result_sql .= "('" . implode("','", $value) . "')"; if ($key + 1 < $total) { $result_sql .= ", "; } } $this->addBackupLog(count($ids) . " inserts for ListenerLog"); } return array($ids, $result_sql); }
public function m_0_4_1() { @apache_setenv('no-gzip', 1); @ini_set('zlib.output_compression', 0); @ini_set('implicit_flush', 1); ini_set('memory_limit', '-1'); //ob_start(); $this->flushNotification('...Please wait... Updating is going on... DO NOT LEAVE THIS PAGE!'); $this->flushNotification('<br/>...Going to add "is_last" fields to `listener_log` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . ListenerLog::model()->tableName() . "` LIKE 'is_last'")->queryAll(); if (!$res) { Yii::app()->db->createCommand("ALTER TABLE `" . ListenerLog::model()->tableName() . "` ADD `is_last` tinyint(1) NOT NULL DEFAULT '0' AFTER `is_processed`")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $stations = Yii::app()->db->createCommand("SELECT * FROM `" . Station::model()->tableName() . "`")->queryAll(); if ($stations) { foreach ($stations as $key => $value) { ListenerLog::updateIsLastForStation($value['station_id']); } } $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... not need'); } $this->flushNotification('<br/>...Going to add "is_processing" column to `listener_log` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . ListenerLog::model()->tableName() . "` LIKE 'is_processing'")->queryAll(); if (!$res) { Yii::app()->db->createCommand("ALTER TABLE `" . ListenerLog::model()->tableName() . "` ADD `is_processing` TINYINT(1) NOT NULL DEFAULT '0' AFTER `is_processed`")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... not need'); } // station $this->flushNotification('<br/><br/>Station table:'); $this->flushNotification('<br/>...Going to update "national_aws_number" field at `station` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . Station::model()->tableName() . "` LIKE 'national_aws_number'")->queryAll(); if ($res[0]['Null'] == 'NO') { Yii::app()->db->createCommand("ALTER TABLE `station` CHANGE `national_aws_number` `national_aws_number` int(11) DEFAULT '0'")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... not need'); } $this->flushNotification('<br/>...Going to add new column "country_id" to `station` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . Station::model()->tableName() . "` LIKE 'country_id'")->queryAll(); if (!$res) { Yii::app()->db->createCommand("ALTER TABLE `station` ADD `country_id` int(11) NOT NULL DEFAULT '0' AFTER `magnetic_north_offset`")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } $this->flushNotification('<br/>...Going to add new column "city_id" to `station` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . Station::model()->tableName() . "` LIKE 'city_id'")->queryAll(); if (!$res) { Yii::app()->db->createCommand("ALTER TABLE `station` ADD `city_id` int(11) NOT NULL DEFAULT '0' AFTER `country_id`")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } $this->flushNotification('<br/>...Going to add new column "timezone_offset" to `station` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . Station::model()->tableName() . "` LIKE 'timezone_offset'")->queryAll(); if (!$res) { Yii::app()->db->createCommand("ALTER TABLE `station` ADD `timezone_offset` varchar(20) NOT NULL AFTER `timezone_id`")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } $this->flushNotification('<br/>...Going to update "timezone_offset" data in `station` table...'); $sql = "SELECT `station_id`, `timezone_id` FROM `" . Station::model()->tableName() . "` WHERE `timezone_offset` = ''"; $res = Yii::app()->db->createCommand($sql)->queryAll(); if ($res) { foreach ($res as $key => $value) { $sql = "UPDATE `" . Station::model()->tableName() . "` SET `timezone_offset` = '" . TimezoneWork::getOffsetFromUTC($value['timezone_id'], 1) . "' WHERE `station_id` = '" . $value['station_id'] . "'"; Yii::app()->db->createCommand($sql)->query(); } Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... not need'); } $this->flushNotification('<br/>...Going to add new column "awos_msg_source_folder" to `station` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `" . Station::model()->tableName() . "` LIKE 'awos_msg_source_folder'")->queryAll(); if (!$res) { Yii::app()->db->createCommand("ALTER TABLE `station` ADD `awos_msg_source_folder` TEXT CHARACTER SET ucs2 COLLATE ucs2_general_ci NOT NULL AFTER `city_id`")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } // Sensor Data $this->flushNotification('<br/>...Going to update `sensor_data` table\'s data...'); Yii::app()->db->createCommand("UPDATE `sensor_data` SET `period` = 1440 WHERE `period` = 86400")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); //Schedule report $this->flushNotification('<br/>...Going to create `schedule_report` table...'); $tables = array(); $res = Yii::app()->db->createCommand("SHOW TABLES")->queryAll(); if ($res) { foreach ($res as $key => $value) { foreach ($value as $k1 => $v1) { $tables[] = $v1; } } } if (!in_array('schedule_report', $tables)) { $sql = "CREATE TABLE `schedule_report` (\n `schedule_id` int(11) NOT NULL AUTO_INCREMENT,\n `report_type` varchar(50) NOT NULL DEFAULT 'synop' COMMENT 'synop, bufr',\n `station_id` int(11) NOT NULL,\n `period` int(11) NOT NULL DEFAULT '60' COMMENT 'in minutes',\n `method` varchar(20) NOT NULL DEFAULT 'email' COMMENT 'email, ftp',\n `destination_email` varchar(255) NOT NULL,\n `destination_ip` varchar(15) NOT NULL,\n `destination_ip_port` int(5) NOT NULL DEFAULT '21',\n `destination_ip_folder` varchar(255) NOT NULL DEFAULT '/',\n `destination_ip_user` varchar(255) NOT NULL,\n `destination_ip_password` varchar(255) NOT NULL,\n `report_format` varchar(20) NOT NULL DEFAULT 'csv' COMMENT 'txt, csv',\n `last_scheduled_run_fact` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n `last_scheduled_run_planned` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n `created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n PRIMARY KEY (`schedule_id`)\n ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"; Yii::app()->db->createCommand($sql)->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } $this->flushNotification('<br/>...Going to create `schedule_report_processed` table...'); if (!in_array('schedule_report_processed', $tables)) { $sql = "CREATE TABLE `schedule_report_processed` (\n `schedule_processed_id` int(11) NOT NULL AUTO_INCREMENT,\n `schedule_id` int(11) NOT NULL,\n `listener_log_id` int(11) NOT NULL,\n `is_processed` tinyint(1) NOT NULL DEFAULT '0',\n `report_string_initial` text NOT NULL,\n `report_string_changed` text NOT NULL,\n `serialized_report_problems` text NOT NULL,\n `serialized_report_errors` text NOT NULL,\n `serialized_report_explanations` text NOT NULL,\n `is_last` tinyint(1) NOT NULL DEFAULT '0',\n `created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n `updated` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n PRIMARY KEY (`schedule_processed_id`),\n KEY `schedule_id` (`schedule_id`),\n KEY `listener_log_id` (`listener_log_id`),\n CONSTRAINT `schedule_report_processed_fk` FOREIGN KEY (`schedule_id`) REFERENCES `schedule_report` (`schedule_id`) ON DELETE CASCADE ON UPDATE NO ACTION,\n CONSTRAINT `schedule_report_processed_ibfk_1` FOREIGN KEY (`listener_log_id`) REFERENCES `listener_log` (`log_id`) ON DELETE CASCADE ON UPDATE NO ACTION\n ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"; Yii::app()->db->createCommand($sql)->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } // metrics $this->flushNotification('<br/><br/>New Metrics:'); $this->flushNotification('<br/>...Going to add new metric "kJ/sq.m" ...'); Yii::app()->db->createCommand("INSERT INTO `refbook_metric` (`metric_id`, `html_code`, `short_name`, `full_name`, `code`) VALUES ('21', 'kJ/sq.m', 'kJ/sq.m', 'Kilo Joule per square meter', 'kjoule_per_sq_meter')")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new metric "feet"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_metric` (`metric_id`, `html_code`, `short_name`, `full_name`, `code`) VALUES ('22', 'ft', 'ft', 'Feet', 'feet')")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new metric "km"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_metric` (`metric_id`,`html_code`,`short_name`,`full_name`,`code`) VALUES (23 , 'km', 'km', 'Kilometer', 'kilometer')")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new relation between "solar radiation" and "kj/sq.m"...'); RefbookMeasurementTypeMetric::model()->deleteByPk(23); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES ('23', '9', '21', '0')")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new measuring type "Cloud Vertical Visibility"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type` (`measurement_type_id`, `display_name`, `code`, `ord`) VALUES (16 ,'Cloud Vertical Visibility', 'cloud_vertical_visibility', '14')")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new measuring type "Cloud Height" ...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type` (`measurement_type_id`, `display_name`, `code`, `ord`) VALUES (17, 'Cloud Height', 'cloud_height', 15)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new measuring type "Sea Level" ...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type` (`measurement_type_id`, `display_name`, `code`, `ord`) VALUES (18 , 'Sea Level (Mean, Sigma, Wave Hight)', 'sea_level', '16')")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add relation between "Cloud Vertical Visibility" and "ft" ...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES (24,16,22,1)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new relation between "Cloud Vertical Visibility" and "meter"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES (25,16,11,0)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new relation between "Cloud Height" and "ft"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES (26,17,22,1)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new relation between "Cloud Height" and "meter"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES (27,17,11,0)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new relation between "Visibility" and "meter"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES (28, 11, 11, 1)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to add new relation between "Sea Level" and "meter"...'); Yii::app()->db->createCommand("INSERT INTO `refbook_measurement_type_metric` (`measurement_type_metric_id`, `measurement_type_id`, `metric_id`, `is_main`) VALUES (29, 18, 11, 1)")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); // sensor handler $this->flushNotification('<br/>...Going to add new column "awos_station_uses" to `sensor_handler` table...'); $res = Yii::app()->db->createCommand("SHOW COLUMNS FROM `sensor_handler` LIKE 'awos_station_uses'")->queryAll(); if (!$res) { $res = Yii::app()->db->createCommand("ALTER TABLE `sensor_handler` ADD `awos_station_uses` TINYINT( 1 ) NOT NULL DEFAULT '0'")->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); } else { $this->flushNotification(' ... already exists'); } $this->flushNotification('<br/>...Going to update `sensor_handler` table...'); $sql = "UPDATE `sensor_handler` SET \n `handler_id_code` = 'SeaLevelAWS',\n `display_name` = 'Sea Level and Tide Data',\n `description` = 'Handler \"Sea Level and Tide Data\" : Processes string like \"SL1XXXXYYYYZZZZ\", where <br/>SL1 - device Id; <br/>XXXX - Mean value;<br/>YYYY - Sigma value; <br/>ZZZZ - Wave Height <br/>Example: SL1179017900140 = SL1 sensor sent data: Mean value = 1.79, Sigma value = 1.79, Wave height = 140m.',\n `default_prefix` = 'SL',\n `aws_station_uses` = 1,\n `rain_station_uses` = 0,\n `awos_station_uses` = 0,\n `aws_single_group` = 'sea_level'\n WHERE `handler_id` = 13"; Yii::app()->db->createCommand($sql)->query(); Yii::app()->db->createCommand("COMMIT")->query(); $sql = "UPDATE `sensor_handler` SET \n `handler_id_code` = 'VisibilityAWS',\n `display_name` = 'Visibility',\n `description` = 'Handler \"Visibility\"',\n `default_prefix` = 'VI',\n `aws_station_uses` = 1,\n `rain_station_uses` = 0,\n `awos_station_uses` = 0,\n `aws_single_group` = 'visibility'\n WHERE `handler_id` = 14"; Yii::app()->db->createCommand($sql)->query(); Yii::app()->db->createCommand("COMMIT")->query(); $sql = "UPDATE `sensor_handler` SET `handler_id_code` = 'CloudHeightAWS',\n `display_name` = 'Cloud Height',\n `description` = 'Handler \"Cloud Height\"',\n `default_prefix` = 'CH',\n `aws_station_uses` = 1,\n `rain_station_uses` = 0,\n `awos_station_uses` = 0,\n `aws_single_group` = 'clouds'\n WHERE `handler_id` = 15"; Yii::app()->db->createCommand($sql)->query(); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $this->flushNotification('<br/>...Going to update calculation_handler table...'); $res = Yii::app()->db->createCommand("UPDATE `calculation_handler` SET `display_name` = 'Pressure Adjusted to MSL' WHERE `handler_id` = 2"); Yii::app()->db->createCommand("COMMIT")->query(); $this->flushNotification(' ... done'); $bat_path = dirname(Yii::app()->request->scriptFile) . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . 'at' . DIRECTORY_SEPARATOR . 'schedule.bat'; $schedule_bat_content = getConfigValue('php_exe_path') . " -f " . dirname(Yii::app()->request->scriptFile) . DIRECTORY_SEPARATOR . "console.php schedule"; file_put_contents($bat_path, $schedule_bat_content); exec('schtasks /create /sc minute /mo 1 /F /ru "SYSTEM" /tn delaircoScheduleScript /tr ' . $bat_path, $output); $values = getConfigValue('schedule'); $values['each_minute_process_id'] = 'delaircoScheduleScript'; InstallConfig::setConfigSection('schedule', $values); $values = getConfigValue('path'); $values['site_url_for_console'] = It::baseUrl(); InstallConfig::setConfigSection('path', $values); It::memStatus('update__success'); $this->flushNotification('<script type="text/javascript"> setTimeout(function(){document.location.href="' . Yii::app()->controller->createUrl('update/index') . '"}, 10000)</script>'); }
public function process($path) { if (!file_exists($path)) { throw new Exception('Can\'t find file ' . $path); } $pathinfo = pathinfo($path); $base_filename = $pathinfo['basename']; $xml_content = file_get_contents($path); if (!strlen($xml_content)) { throw new Exception($base_filename . " is empty"); } libxml_use_internal_errors(true); $sxe = simplexml_load_string($xml_content); $error_str = ""; if ($sxe === false) { foreach (libxml_get_errors() as $error) { $error_str .= "\n" . $error->message; } throw new Exception($error_str); } // XML must contain 1 RUNWAY tag if (count($sxe->RUNWAY) > 1) { throw new Exception('XML ' . $base_filename . ' contains ' . count($sxe->RUNWAY) . ' RUNWAY tags'); } if (count($sxe->RUNWAY) == 0) { throw new Exception('XML ' . $base_filename . ' doesn\'t contain RUNWAY tags'); } // RUNWAY's "NAME" attribute must be "08/26" if ($sxe->RUNWAY['NAME'] != '08/26') { throw new Exception('XML ' . $base_filename . ' RUNWAY name = "' . $sxe->RUNWAY['NAME'] . '", "08/26" was expected'); } // RUNWAY must contain at least 1 ZONE tag if (count($sxe->RUNWAY->ZONE) == 0) { throw new Exception('XML ' . $base_filename . ' doesn\'t contain ZONE tags'); } // XML must contain "UNITS" tag if (!isset($sxe->UNITS)) { throw new Exception('XML ' . $base_filename . ' doesn\'t contain UNITS section'); } $str = ''; $possible_units = array('WIND' => 'kt', 'VISBILITY' => 'meters', 'RVR' => 'meters', 'ALTIMETER' => 'hpa'); foreach ($possible_units as $key => $value) { if (!isset($sxe->UNITS->{$key})) { $str .= ($str ? '; ' : '') . ' UNITS[' . $key . '] is missed'; } else { if ($sxe->UNITS->{$key} != $value) { $str .= ($str ? '; ' : '') . ' unknown metric "' . $sxe->UNITS->{$key} . '" in UNITS[' . $key . ']'; } } } if ($str) { throw new Exception($str); } $result = array(); $messages = array(); for ($key = 0; $key < count($sxe->RUNWAY->ZONE); $key++) { // Get's Station ID if ($sxe->RUNWAY->ZONE[$key]['NAME'] == '08') { $messages[$key]['station_id_code'] = 'AWS08'; } else { if ($sxe->RUNWAY->ZONE[$key]['NAME'] == '26') { $messages[$key]['station_id_code'] = 'AWS26'; } else { continue; } } //Gets sensor's data from tags: // WIND SPEED if (isset($sxe->RUNWAY->ZONE[$key]->WSPD_5SEC)) { $messages[$key]['sensors']['WindSpeed'][0]['wind_speed_1'] = (string) $sxe->RUNWAY->ZONE[$key]->WSPD_5SEC; } if (isset($sxe->RUNWAY->ZONE[$key]->WSPD_2MIN)) { $messages[$key]['sensors']['WindSpeed'][0]['wind_speed_2'] = (string) $sxe->RUNWAY->ZONE[$key]->WSPD_2MIN; } // WIND DIRECTION if (isset($sxe->RUNWAY->ZONE[$key]->WDIR_5SEC)) { $messages[$key]['sensors']['WindDirection'][0]['wind_direction_1'] = (string) $sxe->RUNWAY->ZONE[$key]->WDIR_5SEC; } if (isset($sxe->RUNWAY->ZONE[$key]->WDIR_2MIN)) { $messages[$key]['sensors']['WindDirection'][0]['wind_direction_2'] = (string) $sxe->RUNWAY->ZONE[$key]->WDIR_2MIN; } // TEMPERATURE if (isset($sxe->RUNWAY->ZONE[$key]->TEMP_5MIN)) { $messages[$key]['sensors']['Temperature'][0]['temperature'] = (string) $sxe->RUNWAY->ZONE[$key]->TEMP_5MIN; } // HUMIDITY if (isset($sxe->RUNWAY->ZONE[$key]->HUM_5MIN)) { $messages[$key]['sensors']['Humidity'][0]['humidity'] = (string) $sxe->RUNWAY->ZONE[$key]->HUM_5MIN; } // PRESSURE if (isset($sxe->RUNWAY->ZONE[$key]->PRESSURE1)) { $messages[$key]['sensors']['Pressure'][0]['pressure'] = (string) $sxe->RUNWAY->ZONE[$key]->PRESSURE1; } if (isset($sxe->RUNWAY->ZONE[$key]->PRESSURE2)) { $messages[$key]['sensors']['Pressure'][1]['pressure'] = (string) $sxe->RUNWAY->ZONE[$key]->PRESSURE2; } if (isset($sxe->RUNWAY->ZONE[$key]->PRESSURE3)) { $messages[$key]['sensors']['Pressure'][2]['pressure'] = (string) $sxe->RUNWAY->ZONE[$key]->PRESSURE3; } // CLOUD if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDRANGE)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_measuring_range'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDRANGE; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDVV)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_vertical_visibility'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDVV; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDH1)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_height_height_1'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDH1; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDH2)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_height_height_2'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDH2; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDH3)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_height_height_3'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDH3; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDD1)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_height_depth_1'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDD1; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDD2)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_height_depth_2'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDD2; } if (isset($sxe->RUNWAY->ZONE[$key]->CLOUDD3)) { $messages[$key]['sensors']['CloudHeightAWS'][0]['cloud_height_depth_3'] = (string) $sxe->RUNWAY->ZONE[$key]->CLOUDD3; } // VISIBILITY $vis = (string) $sxe->RUNWAY->ZONE[$key]->EXC; if (isset($sxe->RUNWAY->ZONE[$key]->EXC) && is_numeric($vis) && $vis != 0) { //P = (1/σ) x ln (1/0.05) //where ln is the log to base e or the natural logarithm. σ is the extinction cooefficient. //This number will be in km, so we will need to multiply by 1000. $messages[$key]['sensors']['VisibilityAWS'][0]['visibility_1'] = 1 / $vis * log(20) * 1000; } // SOLAR if (isset($sxe->RUNWAY->ZONE[$key]->SOLAR_1MIN)) { $messages[$key]['sensors']['SolarRadiation'][0]['solar_radiation_in_period'] = (string) $sxe->RUNWAY->ZONE[$key]->SOLAR_1MIN; } // Rain fall if (isset($sxe->RUNWAY->ZONE[$key]->PRECIP_ACCUM)) { $messages[$key]['sensors']['RainAws'][0]['period'] = 5; $messages[$key]['sensors']['RainAws'][0]['rain_in_period'] = (string) $sxe->RUNWAY->ZONE[$key]->PRECIP_ACCUM; } // Sunshine duration if (isset($sxe->RUNWAY->ZONE[$key]->SUN_ACCUM)) { $messages[$key]['sensors']['SunshineDuration'][0]['period'] = 5; $messages[$key]['sensors']['SunshineDuration'][0]['sun_duration_in_period'] = (string) $sxe->RUNWAY->ZONE[$key]->SUN_ACCUM; } } if (!$messages) { $result[] = $base_filename . " : No datasets found"; return implode("\n", $result); } $result[] = $base_filename . " : " . count($messages) . ' datasets were found'; $sql = "SELECT * \n FROM `" . Station::model()->tableName() . "` `t1`\n WHERE `t1`.`station_id_code` IN ('AWS08', 'AWS26')"; $res = Yii::app()->db->createCommand($sql)->queryAll(); if (!$res) { $result[] = "AWS08 and AWS26 are not exist in database, no sense to convert XML into messages"; return implode("\n", $result); } // for each stationID looks for sensors and features of this station $stations = array(); foreach ($res as $key => $value) { $stations[$value['station_id_code']] = $value; $sql = "SELECT `t1`.`sensor_id_code`,\n `t1`.`station_id`,\n `t2`.`feature_code`,\n `t3`.`code` AS `metric_code`,\n `t4`.`handler_id_code`\n FROM `" . StationSensor::model()->tableName() . "` `t1`\n LEFT JOIN `" . StationSensorFeature::model()->tableName() . "` `t2` ON `t1`.`station_sensor_id` = `t2`.`sensor_id`\n LEFT JOIN `" . RefbookMetric::model()->tableName() . "` `t3` ON `t3`.`metric_id` = `t2`.`metric_id`\n LEFT JOIN `" . SensorDBHandler::model()->tableName() . "` `t4` ON `t4`.`handler_id` = `t1`.`handler_id`\n WHERE `t1`.`station_id` = '" . $value['station_id'] . "'\n ORDER BY `t4`.`handler_id_code` ASC, `t1`.`sensor_id_code` ASC"; $res2 = Yii::app()->db->createCommand($sql)->queryAll(); if ($res2) { $tmp = array(); foreach ($res2 as $value2) { $tmp[$value2['handler_id_code']][$value2['sensor_id_code']][$value2['feature_code']] = $value2['metric_code']; } foreach ($tmp as $key_handler => $value_sensors) { foreach ($value_sensors as $key_sensor => $value_features) { $stations[$value['station_id_code']]['sensors'][$key_handler][] = array('sensor_id_code' => $key_sensor, 'features' => $value_features); } } } } $date_parsed = date_parse_from_format("D, j M Y H:i:s", $sxe->DATE); $date_prepared = mktime($date_parsed['hour'], $date_parsed['minute'], $date_parsed['second'], $date_parsed['month'], $date_parsed['day'], $date_parsed['year']); // convert parsed XML data into regular message // for this kind of messages we have an agreement to put X instead of D at the beginning of message. foreach ($messages as $key => $value) { if (!$stations[$value['station_id_code']]) { $result[] = $value['station_id_code'] . " station is not exists in database, no sense to convert RNWY part into message"; continue; } $result_message_body = 'X' . $value['station_id_code']; $result_message_body .= date('ymdHi', $date_prepared); $result_message_body .= '00'; // we need last_log for this satation to calculate period of measurement (some sensors' strings should contain this period $last_logs = ListenerLog::getLast2Messages($stations[$value['station_id_code']]['station_id']); if (isset($value['sensors'])) { foreach ($value['sensors'] as $key_handler => $value_sensors) { if ($value_sensors) { foreach ($value_sensors as $key_sensor => $value2) { if (isset($stations[$value['station_id_code']]['sensors'][$key_handler][$key_sensor])) { // create handler for each sensor (we parsed new data for) $handler = SensorHandler::create($key_handler); if ($key_handler == 'SolarRadiation' && $last_logs[0]['log_id']) { if ($last_logs[0]['log_id']) { $total_minutes = round(abs($date_prepared - strtotime($last_logs[0]['measuring_timestamp'])) / 60); $value2['period'] = $total_minutes; } else { $value2['period'] = 1; } if ($value2['solar_radiation_in_period'][0] != 'M') { $value2['solar_radiation_in_period'] = $value2['solar_radiation_in_period'] * $value2['period'] * 60; } } // each handler has it's own implementation of preparing sensors string for message basing on XML data $res = $handler->prepareXMLValue($value2, $stations[$value['station_id_code']]['sensors'][$key_handler][$key_sensor]['features']); $result_message_body .= $stations[$value['station_id_code']]['sensors'][$key_handler][$key_sensor]['sensor_id_code'] . $res; } } } } $result_message_body .= It::prepareCRC($result_message_body); $result_message_body = '@' . $result_message_body . '$'; // add new message into database. It will be processed later as all newcame messages $log_id = ListenerLog::addNew($result_message_body, 0, 1); $result[] = $base_filename . " : New message #" . $log_id . " was added"; } } // return some comments created during convertation return implode("\n", $result); }
protected function listen() { $this->_logger->log(__CLASS__ . ' ' . __METHOD__ . ' Start listen.', array('source' => $this->source)); $messages = null; $process = $this; $logger = $process->_logger; $this->_connector->onReceiveMessage = function ($message, $station_id, $source_info) use(&$process, &$logger) { $logger->log(__CLASS__ . ' ' . __METHOD__ . ' New message', array('message' => $message, 'listener_id' => $process->listener->listener_id, 'overwrite' => $process->settings->overwrite_data_on_listening)); $messageId = ListenerLog::addNew($message, $process->listener->listener_id, $process->settings->overwrite_data_on_listening, 'server', 0, $source_info); ListenerProcess::addComment($process->listener->listener_id, 'comment', 'got msg #' . $messageId); }; $this->_connector->readData($messages); $this->_logger->log(__CLASS__ . ' ' . __METHOD__ . ' Complete listen.', array('source' => $this->source)); }
public function actionSetup() { $criteria = new CDbCriteria(); $criteria->condition = "ord > 0"; $criteria->order = "ord ASC"; $meas_types = RefbookMeasurementType::model()->findAll($criteria); if ($meas_types) { foreach ($meas_types as $key => $value) { $sql = "SELECT `t1`.`metric_id`, CONCAT(`t2`.`html_code`, ' (', `t2`.`full_name`, ')') AS `name`, `t1`.`is_main`, `t1`.`measurement_type_metric_id`\n FROM `" . RefbookMeasurementTypeMetric::model()->tableName() . "` `t1`\n LEFT JOIN `" . RefbookMetric::model()->tableName() . "` `t2` ON `t2`.`metric_id` = `t1`.`metric_id`\n WHERE `t1`.`measurement_type_id` = '" . $value->measurement_type_id . "'"; $meas_types[$key]->metrics_list = Yii::app()->db->createCommand($sql)->queryAll(); } } if (Yii::app()->request->isPostRequest && isset($_POST['main_metric'])) { foreach ($_POST['main_metric'] as $key => $value) { if ($meas_types[$key]->metrics_list) { foreach ($meas_types[$key]->metrics_list as $v1) { $update = array('is_main' => $v1['metric_id'] == $value ? 1 : 0); RefbookMeasurementTypeMetric::model()->updateByPk($v1['measurement_type_metric_id'], $update); } } } StationSensorFeature::updateMetric(); $DB = array('db' => CStubActiveRecord::getDbConnect(), 'db_long' => CStubActiveRecord::getDbConnect(true)); foreach ($DB as $db) { $db->createCommand("DELETE FROM `" . ScheduleReportProcessed::model()->tableName() . "`")->query(); $db->createCommand("DELETE FROM `" . ForwardedMessage::model()->tableName() . "`")->query(); $db->createCommand("DELETE FROM `" . StationCalculationData::model()->tableName() . "`")->query(); $db->createCommand("DELETE FROM `" . SeaLevelTrend::model()->tableName() . "`")->query(); $db->createCommand("DELETE FROM `" . SensorDataMinute::model()->tableName() . "`")->query(); $db->createCommand("DELETE FROM `" . SensorData::model()->tableName() . "`")->query(); $db->createCommand("DELETE FROM `" . ListenerLog::model()->tableName() . "`")->query(); } It::memStatus('admin_metrics_saved'); $this->redirect($this->createUrl('admin/setup')); } $this->render('setup', array('meas_types' => $meas_types)); }
protected function listenESPTorrent($attempt = 0) { $this->_logger->log(__CLASS__ . ' ' . __METHOD__, array('attempt' => $attempt)); $timeout = 10; if ($attempt == 0) { ListenerProcess::addComment($this->listener->listener_id, 'comment', 'trying to connect with ' . $this->source); } else { ListenerProcess::addComment($this->listener->listener_id, 'comment', 'Trying to reconnect with ' . $this->source . '; attempt #' . $attempt . '/3'); } $source_parts = explode(':', $this->source); // creates socket connection with IP:port $fp = @fsockopen($source_parts[0], $source_parts[1], $errno, $errstr, $timeout); if ($fp !== false) { $attempt = 0; ListenerProcess::addComment($this->listener->listener_id, 'connected', 'successfully'); $message = ''; while (!feof($fp)) { $res = fwrite($fp, ' ', 2); //print "\n try write: ".$res; $line = fread($fp, 8192); $line = trim($line); $occurances_dl = strpos($line, '$'); if ($line != '') { $message .= $line; if ($occurances_dl !== false) { if ($this->synchronization->isMaster()) { $res = ListenerLog::addNew($message, $this->listener->listener_id, $this->settings->overwrite_data_on_listening, 'datalogger'); } else { // slave //$res = ListenerLog::addNew($message, $this->listener->listener_id, $this->settings->overwrite_data_on_listening, 'datalogger'); } ListenerProcess::addComment($this->listener->listener_id, 'comment', 'got msg #' . $res); $message = ''; } } } ListenerProcess::addComment($this->listener->listener_id, 'stopped', 'can not receive data anymore - ESP is unreachable'); fclose($fp); } else { ListenerProcess::addComment($this->listener->listener_id, 'cannot_connect', '[' . $errno . '] ' . $errstr); } if ($attempt < 3) { $attempt++; sleep(3); } else { ListenerProcess::addComment($this->listener->listener_id, 'comment', 'Three attempts to reconnect failed. Waiting for 2 minutes before trying to reconnect.'); sleep(120); $attempt = 0; } return $this->listenESPTorrent($attempt); }
public static function lastMsgIds($station_ids, &$stations = null) { $lastMessages = ListenerLog::getAllLast2Messages($station_ids); $lastMessageIds = array(); foreach ($lastMessages as $key => $stationMessages) { //station last message if (isset($stations[$key])) { $next_expected = strtotime($stationMessages[0]->measuring_timestamp) + $stations[$key]->event_message_period * 60 + 300; $stations[$key]->nextMessageIsLates = $next_expected < time() ? 1 : 0; $stations[$key]->lastMessage = $stationMessages[0]; } //log id foreach ($stationMessages as $message) { $lastMessageIds[] = $message->log_id; } } return $lastMessageIds; }
public function prepareList($station_id = 0) { if ($this->hasErrors()) { return ['prepared_header' => [], 'prepared_data' => []]; } $prepared_header = array(); $prepared_data = array(); $sensor_feature_code = $this->getSensorFeatureCode(); $handler_code = array_keys($this->getSelectedGroupSensorFeatureCode()); $search_features = array(); $search_calcs = array(); foreach ($sensor_feature_code as $key) { if (in_array($key, array_keys($this->calc_handlers))) { $search_calcs[] = $this->calc_handlers[$key]; } else { $search_features[] = $key; } } if (count($this->station_id) > 1) { $sql_part = "`t2`.`station_id` IN (" . implode(',', $this->station_id) . ") "; } else { $sql_part = "`t2`.`station_id` = '" . $this->station_id[0] . "' "; } // 1.a) GET FEATURES if (count($search_features) > 0) { $sql = "SELECT `t1`.`sensor_feature_id`,\n `t1`.`feature_code`,\n `t1`.`sensor_id`,\n `t3`.`station_id_code`,\n `t2`.`sensor_id_code`,\n `t2`.`station_id`,\n `t4`.`handler_id_code`,\n `t3`.`magnetic_north_offset`\n FROM `" . StationSensorFeature::model()->tableName() . "` `t1`\n LEFT JOIN `" . StationSensor::model()->tableName() . "` `t2` ON `t1`.`sensor_id` = `t2`.`station_sensor_id`\n LEFT JOIN `" . SensorDBHandler::model()->tableName() . "` `t4` ON `t4`.`handler_id` = `t2`.`handler_id`\n LEFT JOIN `" . Station::model()->tableName() . "` `t3` ON `t3`.`station_id` = `t2`.`station_id`\n WHERE " . $sql_part . " AND `t1`.`feature_code` IN ('" . implode("','", $search_features) . "') AND `t4`.`handler_id_code` IN ('" . implode("','", $handler_code) . "')\n ORDER BY `t1`.`feature_code`, `t3`.`station_id_code`, `t2`.`sensor_id_code`"; $found_sensors = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); $total_found_sensors = count($found_sensors); } // 1.b) GET CALCS if (count($search_calcs) > 0) { $sql = "SELECT `t1`.`calculation_id`,\n `t1`.`handler_id`,\n `t2`.`station_id_code`,\n `t2`.`station_id`,\n IF(`t1`.`handler_id` = 1, 'DP', 'MSL') AS `sensor_id_code`,\n IF(`t1`.`handler_id` = 1, 'Dew Point', 'Pressure MSL') AS `feature_code`,\n IF(`t1`.`handler_id` = 1, 'DewPoint', 'PressureSeaLevel') AS `handler_id_code`\n FROM `" . StationCalculation::model()->tableName() . "` `t1`\n LEFT JOIN `" . Station::model()->tableName() . "` `t2` ON `t2`.`station_id` = `t1`.`station_id`\n WHERE " . $sql_part . " AND `t1`.`handler_id` IN (" . implode(',', $search_calcs) . ")\n ORDER BY `t1`.`handler_id`, `t2`.`station_id_code`"; $found_calcs = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); $total_found_calcs = count($found_calcs); } $start_datetime = strtotime($this->date_from . ' ' . $this->time_from); $end_datetime = strtotime($this->date_to . ' ' . $this->time_to); $features_set = array(); // 2.a) PREPARE HEADER if (is_array($found_sensors) && $total_found_sensors > 0) { $sensor_feature_ids = array(); for ($i = 0; $i < $total_found_sensors; $i++) { $key = $found_sensors[$i]['handler_id_code'] . $found_sensors[$i]['feature_code']; if (!isset($prepared_header[$key])) { $prepared_header[$key] = array('sensor_feature_code' => $found_sensors[$i]['feature_code'], 'handler_id_code' => $found_sensors[$i]['handler_id_code'], 'sensors' => array(), 'station_sensors' => array()); } $sensor_feature_ids[] = $found_sensors[$i]['sensor_feature_id']; $prepared_header[$key]['sensors'][] = array('station_id' => $found_sensors[$i]['station_id'], 'sensor_id_code' => $found_sensors[$i]['sensor_id_code']); if (isset($prepared_header[$key]['station_sensors'][$found_sensors[$i]['station_id']])) { $prepared_header[$key]['station_sensors'][$found_sensors[$i]['station_id']]++; } else { $prepared_header[$key]['station_sensors'][$found_sensors[$i]['station_id']] = 1; } $features_set[$found_sensors[$i]['sensor_feature_id']] = array('station_id' => $found_sensors[$i]['station_id'], 'station_id_code' => $found_sensors[$i]['station_id_code'], 'value' => '-', 'sensor_id' => $found_sensors[$i]['sensor_id'], 'sensor_id_code' => $found_sensors[$i]['sensor_id_code'], 'sensor_feature_code' => $found_sensors[$i]['feature_code'], 'handler_id_code' => $found_sensors[$i]['handler_id_code'], 'magnetic_north_offset' => $found_sensors[$i]['magnetic_north_offset']); } } // 2.b) PREPARE HEADER if (count($search_calcs) > 0) { $sql = "SELECT `t1`.`calculation_id`,\n `t1`.`handler_id`,\n `t2`.`station_id_code`,\n `t2`.`station_id`,\n IF(`t1`.`handler_id` = 1, 'DP', 'MSL') AS `sensor_id_code`,\n IF(`t1`.`handler_id` = 1, 'Dew Point', 'Pressure MSL') AS `feature_code`,\n IF(`t1`.`handler_id` = 1, 'DewPoint', 'PressureSeaLevel') AS `handler_id_code`\n FROM `" . StationCalculation::model()->tableName() . "` `t1`\n LEFT JOIN `" . Station::model()->tableName() . "` `t2` ON `t2`.`station_id` = `t1`.`station_id`\n WHERE " . $sql_part . " AND `t1`.`handler_id` IN (" . implode(',', $search_calcs) . ")\n ORDER BY `t1`.`handler_id`, `t2`.`station_id`"; $found_calcs = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); if (is_array($found_calcs) && count($found_calcs) > 0) { $calculation_ids = array(); for ($i = 0; $i < count($found_calcs); $i++) { $key = 'calc_' . $found_calcs[$i]['handler_id']; if (!isset($prepared_header[$key])) { $prepared_header[$key] = array('sensor_feature_code' => $key, 'sensors' => array(), 'station_sensors' => array()); } $calculation_ids[] = $found_calcs[$i]['calculation_id']; $prepared_header[$key]['sensors'][] = array('station_id' => $found_calcs[$i]['station_id'], 'sensor_id_code' => $found_calcs[$i]['sensor_id_code']); if (isset($prepared_header[$key]['station_sensors'][$found_calcs[$i]['station_id']])) { $prepared_header[$key]['station_sensors'][$found_calcs[$i]['station_id']]++; } else { $prepared_header[$key]['station_sensors'][$found_calcs[$i]['station_id']] = 1; } $features_set['calc_' . $found_calcs[$i]['calculation_id']] = array('station_id' => $found_calcs[$i]['station_id'], 'station_id_code' => $found_calcs[$i]['station_id_code'], 'value' => '-', 'calculation_id' => $found_calcs[$i]['calculation_id'], 'sensor_id_code' => $found_calcs[$i]['sensor_id_code'], 'sensor_feature_code' => $found_calcs[$i]['feature_code'], 'handler_id_code' => $found_calcs[$i]['handler_id_code']); } } } // 3.a) PREPARE DATA if (is_array($found_sensors) && $total_found_sensors) { $qb = new CDbCriteria(); $qb->select = ['sensor_data_id', 'station_id', 'sensor_id', 'sensor_feature_id', 'sensor_feature_normalized_value', 'is_m', 'measuring_timestamp']; $qb->addInCondition('sensor_feature_id', $sensor_feature_ids); $qb->addBetweenCondition('measuring_timestamp', date('Y-m-d H:i:s', $start_datetime), date('Y-m-d H:i:s', $end_datetime)); $qb->order = 'measuring_timestamp DESC'; $found_values = SensorData::model()->long()->findAll($qb); $total_found_values = count($found_values); if (is_array($found_values) && $total_found_values > 0) { if ($this->accumulation_period == 0) { for ($j = 0; $j < $total_found_values; $j++) { $f_id = $found_values[$j]['sensor_feature_id']; $f_time = $found_values[$j]['measuring_timestamp']; $f_code = $features_set[$f_id]['sensor_feature_code']; $magnetic_north_offset = $features_set[$f_id]['magnetic_north_offset']; $st_id = $found_values[$j]['station_id']; if (!isset($prepared_data[$f_time])) { $prepared_data[$f_time] = array(); $prepared_data[$f_time]['stations'] = array(); } if (!isset($prepared_data[$f_time]['data'])) { $prepared_data[$f_time]['data'] = $features_set; } $handler_obj = SensorHandler::create($features_set[$f_id]['handler_id_code']); if ($found_values[$j]['is_m'] == 1) { $prepared_data[$f_time]['data'][$f_id]['value'] = '-'; } else { $found_values[$j]['sensor_feature_normalized_value'] = $handler_obj->applyOffset($found_values[$j]['sensor_feature_normalized_value'], $magnetic_north_offset); $prepared_data[$f_time]['data'][$f_id]['value'] = $handler_obj->formatValue($found_values[$j]['sensor_feature_normalized_value'], $f_code); } if (!in_array($st_id, $prepared_data[$f_time]['stations'])) { $prepared_data[$f_time]['stations'][] = $st_id; } } } else { for ($j = 0; $j < $total_found_values; $j++) { $f_id = $found_values[$j]['sensor_feature_id']; $f_time = $found_values[$j]['measuring_timestamp']; $f_code = $features_set[$f_id]['sensor_feature_code']; $magnetic_north_offset = $features_set[$f_id]['magnetic_north_offset']; $st_id = $found_values[$j]['station_id']; $period = $start_datetime + (intval((strtotime($f_time) - $start_datetime) / ($this->accumulation_period * 60)) + 1) * $this->accumulation_period * 60; $period = $period > $end_datetime ? $end_datetime : $period; $period = date('Y-m-d H:i:s', $period); if (!isset($prepared_data[$period])) { $prepared_data[$period] = array(); $prepared_data[$period]['stations'] = array(); } if (!isset($prepared_data[$period]['data'])) { $prepared_data[$period]['data'] = $features_set; } $handler_obj = SensorHandler::create($features_set[$f_id]['handler_id_code']); if ($found_values[$j]['is_m'] == 1) { $prepared_data[$period]['data'][$f_id]['value'] = '-'; } else { $found_values[$j]['sensor_feature_normalized_value'] = $handler_obj->applyOffset($found_values[$j]['sensor_feature_normalized_value'], $magnetic_north_offset); $prepared_data[$period]['data'][$f_id]['value'] = ($prepared_data[$period]['data'][$f_id]['value'] ? $prepared_data[$period]['data'][$f_id]['value'] : 0) + $handler_obj->formatValue($found_values[$j]['sensor_feature_normalized_value'], $f_code); } if (!in_array($st_id, $prepared_data[$period]['stations'])) { $prepared_data[$period]['stations'][] = $st_id; } } } } } // 3.b) PREPARE DATA if (is_array($found_calcs) && $total_found_calcs > 0) { $sql = "SELECT `t2`.`station_id`,\n `t1`.`calculation_id`,\n `t1`.`value`,\n `t2`.`measuring_timestamp`\n FROM `" . StationCalculationData::model()->tableName() . "` `t1`\n LEFT JOIN `" . ListenerLog::model()->tableName() . "` `t2` ON `t2`.`log_id` = `t1`.`listener_log_id`\n WHERE `t1`.`calculation_id` IN (" . implode(',', $calculation_ids) . ")\n AND `t2`.`measuring_timestamp` >= '" . date('Y-m-d H:i:s', $start_datetime) . "'\n AND `t2`.`measuring_timestamp` <= '" . date('Y-m-d H:i:s', $end_datetime) . "'\n ORDER BY `t2`.`measuring_timestamp` DESC"; $found_values = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); $total_found_values = count($found_values); if (is_array($found_values) && $total_found_values) { for ($j = 0; $j < $total_found_values; $j++) { $f_id = 'calc_' . $found_values[$j]['calculation_id']; $f_time = $found_values[$j]['measuring_timestamp']; $st_id = $found_values[$j]['station_id']; if (!$prepared_data[$f_time]) { $prepared_data[$f_time] = array(); $prepared_data[$f_time]['stations'] = array(); } if (!$prepared_data[$f_time]['data']) { $prepared_data[$f_time]['data'] = $features_set; } $prepared_data[$f_time]['data'][$f_id]['value'] = CalculationHandler::formatValue($found_values[$j]['value']); $prepared_data[$f_time]['data'][$f_id]['station_id'] = $st_id; if (!in_array($st_id, $prepared_data[$f_time]['stations'])) { $prepared_data[$f_time]['stations'][] = $st_id; } } } } //need sort krsort($prepared_data); //print_r(array( // 'prepared_header' => $prepared_header, // 'prepared_data' => $prepared_data, // ));exit; return array('prepared_header' => $prepared_header, 'prepared_data' => $prepared_data); }
public function run($args) { if (!Yii::app()->mutex->lock('ScheduleCommand', 3600)) { Yii::app()->end(); } $synchronization = new Synchronization(); if (!$synchronization->isMaster() and $synchronization->isProcessed()) { return; } $generationTime = time(); $proper_periods = ScheduleCommand::getProperPeriods($generationTime); if (count($proper_periods) === 0) { self::$_logger->log(__METHOD__ . ' Exiting. No proper periods found.' . "\n\n"); // Yii::app()->mutex->unlock(); // Yii::app()->end(); } $criteria = new CDbCriteria(); $criteria->select = array('schedule_id', 'report_type', 'station_id', 'report_format', 'period', 'last_scheduled_run_planned', 'last_scheduled_run_fact', '(`last_scheduled_run_planned` + INTERVAL `period` MINUTE) AS nextScheduleTime', 'UNIX_TIMESTAMP(`last_scheduled_run_planned` + INTERVAL `period` MINUTE) AS nextScheduleUnixTime'); $criteria->with = array('station'); $criteria->compare('period', '>0'); $criteria->compare('period', $proper_periods); $criteria->addCondition('(UNIX_TIMESTAMP(`last_scheduled_run_planned` + INTERVAL `period` MINUTE) <= UNIX_TIMESTAMP() OR `last_scheduled_run_planned` = "0000-00-00 00:00:00")'); /** @var array|ScheduleReport[] $scheduledReports */ $scheduledReports = ScheduleReport::model()->findAll($criteria); if (count($scheduledReports) === 0) { self::$_logger->log(__METHOD__ . ' Exiting. No proper reports found.' . "\n\n"); Yii::app()->mutex->unlock(); Yii::app()->end(); } self::$_logger->log(__METHOD__ . ' New scheduled reports', array('report count' => count($scheduledReports))); $reportProcesses = array(); foreach ($scheduledReports as $scheduledReport) { self::$_logger->log("\n"); self::$_logger->log(__METHOD__ . ' Check scheduled report', array('schedule_id' => $scheduledReport->schedule_id)); $check_period = ScheduleCommand::getCheckPeriod($generationTime, $scheduledReport->period); if ($scheduledReport->report_type === 'data_export') { self::$_logger->log(__METHOD__ . ' scheduledReport->report_type = data_export'); // add record about schedule running to process afterwards for ($i = 0; $i < count($scheduledReport->station); $i++) { $schedule_report_process = new ScheduleReportProcessed(); $schedule_report_process->sr_to_s_id = $scheduledReport->station[$i]->id; $schedule_report_process->check_period_start = $check_period[3]; $schedule_report_process->check_period_end = $check_period[4]; $schedule_report_process->save(); $scheduledReport->last_scheduled_run_fact = $check_period[1]; $scheduledReport->last_scheduled_run_planned = $check_period[2]; if ($scheduledReport->validate()) { $scheduledReport->save(false); } else { self::$_logger->log(__METHOD__ . ' Schedule report not saved ', array('schedule_error' => $scheduledReport->getErrors())); } $reportProcesses[$scheduledReport->station[$i]->id] = array('schedule_id' => $scheduledReport->schedule_id, 'schedule_processed_id' => $schedule_report_process->schedule_processed_id, 'schedule_info' => $scheduledReport, 'check_period_start' => $check_period[3], 'check_period_end' => $check_period[4]); } } else { $logRecords = array(); foreach ($scheduledReport->station as $station) { $criteria = new CDbCriteria(); $criteria->compare('station_id', $station->station_id); $criteria->compare('failed', '0'); $criteria->compare('measuring_timestamp', '>' . $check_period[0]); $criteria->compare('measuring_timestamp', '<=' . $check_period[1]); $criteria->order = 'measuring_timestamp desc, log_id desc'; $criteria->limit = '1'; $logRecord = ListenerLog::model()->find($criteria); if (!is_null($logRecord)) { $logRecords[] = $logRecord; } } // add record about schedule running to process afterwards (only in case system received base message) if (count($logRecords) > 0) { for ($i = 0; $i < count($scheduledReport->station); $i++) { $schedule_report_process = new ScheduleReportProcessed(); $continue = false; foreach ($logRecords as $logRecord) { if ($logRecord->station_id == $scheduledReport->station[$i]->station_id) { $schedule_report_process->listener_log_id = $logRecord->log_id; $listener_log_id = $logRecord->log_id; $continue = false; break; } else { $continue = true; } } if ($continue) { continue; } $schedule_report_process->sr_to_s_id = $scheduledReport->station[$i]->id; $schedule_report_process->check_period_start = $check_period[3]; $schedule_report_process->check_period_end = $check_period[4]; $schedule_report_process->save(); $scheduledReport->last_scheduled_run_fact = $check_period[1]; $scheduledReport->last_scheduled_run_planned = $check_period[2]; if ($scheduledReport->validate()) { $scheduledReport->save(false); } else { self::$_logger->log(__METHOD__ . ' Schedule report not saved ', array('schedule_error' => $scheduledReport->getErrors())); } $reportProcesses[$scheduledReport->station[$i]->id] = array('log_id' => $listener_log_id, 'schedule_id' => $scheduledReport->schedule_id, 'schedule_processed_id' => $schedule_report_process->schedule_processed_id, 'schedule_info' => $scheduledReport, 'check_period_start' => $check_period[3], 'check_period_end' => $check_period[4]); } } } } if (count($reportProcesses) > 0) { $total = count($reportProcesses); $i = 1; foreach ($reportProcesses as $reportProcess) { $weatherReport = null; switch (strtolower($reportProcess['schedule_info']->report_type)) { case 'synop': $weatherReport = WeatherReport::create('Synop', self::$_logger); break; case 'bufr': $weatherReport = WeatherReport::create('Bufr', self::$_logger); break; case 'metar': $weatherReport = WeatherReport::create('Metar', self::$_logger); break; case 'odss': $weatherReport = WeatherReport::create('ODSS', self::$_logger); break; default: $weatherReport = WeatherReport::create('Export', self::$_logger); break; } try { $weatherReport->load($reportProcess['schedule_processed_id']); $weatherReport->generate(); $weatherReport->saveProcess(); $weatherReport->deliverReport(); } catch (Exteption $e) { self::$_logger->log(__METHOD__ . ' Error ', array('err' => $e->getMessage())); } self::$_logger->log(__METHOD__ . ' Completed', array('num' => $i++, 'total' => $total)); } } //send report from sttions together $scheduleProcessedIdArray_schedule_id = array(); foreach ($reportProcesses as $reportProcess) { $scheduleProcessedIdArray_schedule_id[$reportProcess['schedule_id']][] = $reportProcess['schedule_processed_id']; } foreach ($scheduleProcessedIdArray_schedule_id as $scheduleProcessedIdArray) { new WeatherReportMailSender($scheduleProcessedIdArray); } self::$_logger->log(__METHOD__ . ' Schedule report completed' . "\n\n\n\n\n\n\n\n\n"); Yii::app()->mutex->unlock(); }
public function prepareList($page_size = 50) { $sql_where_str = $this->_prepareSqlCondition(); $sql_order_str = $this->_prepareSqlOrder(); if ($page_size) { $total = $this->total; } if ($total || !$page_size) { if ($page_size) { $pages = new CPagination($total); $pages->pageSize = $page_size; } $sql = "SELECT `t1`.`log_id`, `t1`.`updated`,`t1`.`measuring_timestamp`, `t1`.`created`, `t1`.`message`, `t1`.`fail_description`, t3.station_id_code, t3.display_name, t3.station_type, `t2`.`process_error_id`, `t1`.`is_processed`\n FROM `" . ListenerLog::model()->tableName() . "` t1\n LEFT JOIN `" . ListenerLogProcessError::model()->tableName() . "` `t2` ON `t2`.`log_id` = `t1`.`log_id`\n LEFT JOIN `" . Station::model()->tableName() . "` `t3` ON `t3`.`station_id` = `t1`.`station_id`\n {$sql_where_str}\n GROUP BY `t1`.`log_id`\n {$sql_order_str}"; if ($page_size) { $sql .= " LIMIT " . $pages->currentPage * $pages->pageSize . ", " . $pages->pageSize; } $res = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); if ($res) { $ids = array(); foreach ($res as $key => $value) { $ids[] = $value['log_id']; if ($value['fail_description']) { $value['errors'] = explode(',', $value['fail_description']); } $list[$value['log_id']] = $value; } $sql = "SELECT * FROM `" . ListenerLogProcessError::model()->tableName() . "` WHERE `log_id` IN (" . implode(',', $ids) . ")"; $res2 = CStubActiveRecord::getDbConnect(true)->createCommand($sql)->queryAll(); if ($res2) { foreach ($res2 as $key => $value) { if ($value['type'] == 'error') { $list[$value['log_id']]['errors'][] = $value['description']; } else { if ($value['type'] == 'warning') { $list[$value['log_id']]['warnings'][] = $value['description']; } } } } } } return array('list' => $list, 'pages' => $pages); }