Пример #1
0
 /**
  * @param \App\Repository\Entity\Station   $station
  * @param \App\Repository\Entity\Component $component
  * @param \DateTime                        $start
  * @param \DateTime|null                   $to
  *
  * @return float|null
  */
 public function getStationAverageForTimeAndComponent(Station $station, Component $component, \DateTime $start, \DateTime $to = null)
 {
     $query = $this->queryBuilder->from(self::$tableName);
     $query->where('station_id', $station->getId());
     $query->where('component_id', $component->getId());
     $query->where('measure_timestamp >= "' . $start->format("Y-m-d H:i:s") . '"');
     if (isset($to)) {
         $query->where('measure_timestamp <= "' . $to->format("Y-m-d H:i:s") . '"');
     }
     $query->select('AVG(value) AS average');
     $result = $query->fetch('average');
     return !empty($result) ? floatval($result) : null;
 }
Пример #2
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function handle()
 {
     // Get all stations
     $stationRepository = StationRepository::getInstance();
     $measurementRepository = MeasurementRepository::getInstance();
     $stations = $stationRepository->getAll();
     Component::initializeCoefficients();
     // calculate for last 30 days
     $start = new \DateTime();
     $end = clone $start;
     $start->sub(new \DateInterval("PT1H"));
     //        $totalSteps = 7 * 24;
     //        for ($i = 1; $i <= $totalSteps; $i++) {
     //            $end = $end->add(new \DateInterval("PT1H"));
     /** @var Station $station */
     foreach ($stations as $station) {
         $indexes = [];
         $dailyAverages = [];
         $stationCaqi = null;
         echo "[" . date("Y-m-d H:i:s") . "] Calculating AQI for station " . $station->getEoiCode() . " for interval " . $start->format("Y-m-d H:i:s") . " - " . $end->format("Y-m-d H:i:s") . PHP_EOL;
         // get all measurements in the last hour
         $hourlyMeasurements = $measurementRepository->getLatestForStationAndTime($station, $start, $end);
         if (!empty($hourlyMeasurements)) {
             echo "[" . date("Y-m-d H:i:s") . "] Fetched measurements total " . count($hourlyMeasurements) . " for CAQI." . PHP_EOL;
             // Calculate CAQI index for each of the components/indices
             /** @var Measurement $hourlyMeasurement */
             foreach ($hourlyMeasurements as $hourlyMeasurement) {
                 // Skip CO since we use 8 hour average here.
                 if ($hourlyMeasurement->getComponent()->getSepaId() === Component::COMPONENT_CO) {
                     continue;
                 }
                 echo "[" . date("Y-m-d H:i:s") . "] Calculating CAQI for component " . $hourlyMeasurement->getComponent()->getName() . "." . PHP_EOL;
                 $component = $hourlyMeasurement->getComponent();
                 // Get coefficients
                 $coeff = isset(Component::$coefficients[$station->getType()][$component->getSepaId()]) ? Component::$coefficients[$station->getType()][$component->getSepaId()] : false;
                 // If coeff is not defined than it's not included in CAQI calculation.
                 if (!$coeff) {
                     echo "[" . date("Y-m-d H:i:s") . "] " . $hourlyMeasurement->getComponent()->getName() . " not CAQI component." . PHP_EOL;
                     continue;
                 }
                 $coeffValue = null;
                 if ($component->getSepaId() === Component::COMPONENT_PM2P5 || $component->getSepaId() === Component::COMPONENT_PM10) {
                     $coeff = $coeff['hourly'];
                 }
                 // Find coeff according to the value
                 foreach ($coeff as $limit => $value) {
                     if ($hourlyMeasurement->getValue() < $limit) {
                         $coeffValue = $value;
                         break;
                     }
                 }
                 if ($component->getSepaId() === Component::COMPONENT_CO) {
                     $hourlyMeasurement->setValue($hourlyMeasurement->getValue() * 1000);
                 }
                 if (isset($coeffValue)) {
                     // Calculate CAQI for component
                     $caqi = $coeffValue * $hourlyMeasurement->getValue();
                     $indexes[$hourlyMeasurement->getComponent()->getSepaId()] = round($caqi);
                 } else {
                     $indexes[$hourlyMeasurement->getComponent()->getSepaId()] = 101;
                 }
                 echo "[" . date("Y-m-d H:i:s") . "] CAQI for " . $hourlyMeasurement->getComponent()->getName() . " is " . $indexes[$hourlyMeasurement->getComponent()->getSepaId()] . " calculated for value " . $hourlyMeasurement->getValue() . "." . PHP_EOL;
                 if (!isset($stationCaqi) || $stationCaqi < $indexes[$hourlyMeasurement->getComponent()->getSepaId()]) {
                     $stationCaqi = $indexes[$hourlyMeasurement->getComponent()->getSepaId()];
                 }
             }
         }
         // Daily / 8 hours average.
         $dailyStart = clone $end;
         $dailyStart->sub(new \DateInterval("P1D"));
         $componentRepository = ComponentRepository::getInstance();
         $pm10Component = $componentRepository->getBySepaId(Component::COMPONENT_PM10);
         $pm10dailyAverage = $measurementRepository->getStationAverageForTimeAndComponent($station, $pm10Component, $dailyStart, $end);
         if (isset($pm10dailyAverage)) {
             $coefs = Component::$coefficients[$station->getType()][Component::COMPONENT_PM10]['daily'];
             $coeffValue = null;
             // Find coeff according to the value
             foreach ($coefs as $limit => $value) {
                 if ($pm10dailyAverage < $limit) {
                     $coeffValue = $value;
                     break;
                 }
             }
             if (isset($coeffValue)) {
                 $dailyAverages[Component::COMPONENT_PM10] = $coeffValue * $pm10dailyAverage;
             } else {
                 $dailyAverages[Component::COMPONENT_PM10] = 101;
             }
             if (!isset($stationCaqi) || $stationCaqi < $dailyAverages[Component::COMPONENT_PM10]) {
                 $stationCaqi = $dailyAverages[Component::COMPONENT_PM10];
             }
         }
         $pm25Component = $componentRepository->getBySepaId(Component::COMPONENT_PM2P5);
         $pm25dailyAverage = $measurementRepository->getStationAverageForTimeAndComponent($station, $pm25Component, $dailyStart);
         if (isset($pm25dailyAverage)) {
             $coefs = Component::$coefficients[$station->getType()][Component::COMPONENT_PM2P5]['daily'];
             $coeffValue = null;
             // Find coeff according to the value
             foreach ($coefs as $limit => $value) {
                 if ($pm25dailyAverage < $limit) {
                     $coeffValue = $value;
                     break;
                 }
             }
             if (isset($coeffValue)) {
                 $dailyAverages[Component::COMPONENT_PM2P5] = $coeffValue * $pm25dailyAverage;
             } else {
                 $dailyAverages[Component::COMPONENT_PM2P5] = 101;
             }
             if (!isset($stationCaqi) || $stationCaqi < $dailyAverages[Component::COMPONENT_PM2P5]) {
                 $stationCaqi = $dailyAverages[Component::COMPONENT_PM2P5];
             }
         }
         // CO 8-hour moving average
         $coComponent = $componentRepository->getBySepaId(Component::COMPONENT_CO);
         $avgStart = clone $end;
         $avgStart->sub(new \DateInterval("PT8H"));
         $coAverage = $measurementRepository->getStationAverageForTimeAndComponent($station, $coComponent, $avgStart, $end);
         if (isset($coAverage)) {
             $coefs = Component::$coefficients[$station->getType()][Component::COMPONENT_CO];
             $coeffValue = null;
             // Find coeff according to the value
             foreach ($coefs as $limit => $value) {
                 if ($coAverage < $limit) {
                     $coeffValue = $value;
                     break;
                 }
             }
             if (isset($coeffValue)) {
                 $indexes[Component::COMPONENT_CO] = $coeffValue * $coAverage;
             } else {
                 $indexes[Component::COMPONENT_CO] = 101;
             }
             if (!isset($stationCaqi) || $stationCaqi < $indexes[Component::COMPONENT_CO]) {
                 $stationCaqi = $indexes[Component::COMPONENT_CO];
             }
         }
         $historyTimestamp = $start->format("Y-m-d H:i:s");
         if (isset($stationCaqi)) {
             $station->setAqiValue($stationCaqi);
             $station->setAqiTimestamp($historyTimestamp);
             $station->save();
             $historyItem = new StationAqiHistoryItem();
             $historyItem->setStationId($station->getId());
             foreach ($indexes as $sepaKey => $value) {
                 $historyItem->setIndex($sepaKey, $value);
             }
             foreach ($dailyAverages as $sepaKey => $value) {
                 $historyItem->setIndex($sepaKey, $value, 'daily');
             }
             $historyItem->setTimestamp($historyTimestamp);
             $historyItem->save();
         }
     }
     //            $start = clone $end;
     //        }
 }
Пример #3
0
<?php

require_once 'bootstrap.php';
use Importers\ImportComponents;
use App\Repository\Entity\Component;
use App\Repository\Exceptions\QueryException;
use GuzzleHttp\Exception\ConnectException;
$importer = new ImportComponents();
try {
    $components = $importer->doImport();
} catch (ConnectException $e) {
    echo $e->getMessage() . PHP_EOL;
    die;
}
foreach ($components as $c) {
    try {
        $component = new Component($c);
        $component->save();
    } catch (QueryException $e) {
        echo $c['name'] . ' skipped because SEPA_ID ' . $c['sepa_id'] . ' most likely already exists' . PHP_EOL;
        echo $e->getMessage() . PHP_EOL;
    }
}
echo 'All components saved' . PHP_EOL . PHP_EOL;