diff --git a/htdocs/includes/models/model.class.php b/htdocs/includes/models/model.class.php new file mode 100644 index 0000000..4c3b9de --- /dev/null +++ b/htdocs/includes/models/model.class.php @@ -0,0 +1,116 @@ +_id = $id; + } + + /** + * Returns id of the object + * + * @return int + */ + public function getId() + { + return $this->_id; + } + + /** + * Returns true if object exists in database + * + * @return boolean + */ + public function isExistingObject() + { + if ($this->_id != null) { + return true; + } + return false; + } + + /** + * Makes it possible to get $object->field + * + * @param string $key + */ + public function __get($key) + { + $key = $this->_camelize($key); + + if (isset($this->_values[$key])) { + return $this->_values[$key]; + } else { + return null; + } + } + + + /** + * Makes it possible to set $object->field + * + * @param string $key + * @param mixed + */ + public function __set($key, $value) + { + $this->_values[$this->_camelize($key)] = $value; + } + + + /** + * Makes it possible to check if $object->field is set + * + * @param string $key + */ + public function __isset($key) + { + if (isset($this->_values[$key])) { + return true; + } else { + return false; + } + } + + /** + * Makes it possible to unset $object->field + * + * @param string $key + */ + public function __unset($key) + { + if (isset($this->_values[$key])) { + unset($this->_values[$key]); + } + } + + /** + * Update object from array, usually a db record + * column-names with underscores will be converted to camelcase + * + * @param array $array + */ + public function updateObjectFromArray($array) + { + foreach ($array as $column => $value) { + $this->_values[$this->_camelize($column)] = $value; + } + } + + /** + * Convert underscore separated variables to camelcaps + * (for some reason I prefer underscore in db-columns but I prefer camelCaps in code...) + * + * @param string $input + * @return string + */ + private function _camelize($input) + { + return lcfirst(str_replace('_', '', ucwords($input, '_'))); + } +} diff --git a/htdocs/includes/models/packet.class.php b/htdocs/includes/models/packet.class.php new file mode 100644 index 0000000..3d14372 --- /dev/null +++ b/htdocs/includes/models/packet.class.php @@ -0,0 +1,375 @@ +symbol) >= 1 && strlen($this->symbolTable) >= 1) { + $symbolAsciiValue = ord(substr($this->symbol, 0, 1)); + $symbolTableAsciiValue = ord(substr($this->symbolTable, 0, 1)); + } else { + // Default values + $symbolAsciiValue = 125; + $symbolTableAsciiValue = 47; + } + + $scaleStrValue = ''; + if ($scaleWidth !== null && $scaleHeight !== null) { + $scaleStrValue = '-scale' . $scaleWidth . 'x' . $scaleHeight; + } + + return '/symbols/symbol-' . $symbolAsciiValue . '-' . $symbolTableAsciiValue . $scaleStrValue . '.png'; + } + + /** + * Get PGH range in meters + * + * @return float + */ + public function getPHGRange() + { + if ($this->getPhg() != null) { + $p = $this->getPhgPower(); + $h = $this->getPhgHaat(false); + $g = $this->getPhgGain(); + + $gain = pow(10, ($g/10)); //converts from DB to decimal + $range = sqrt(2 * $h * sqrt(($p / 10) * ($gain / 2))); + return $range / 0.000621371192; // convert to m and return + } + return null; + } + + /** + * Get PGH description + * + * @return String + */ + public function getPHGDescription() + { + if ($this->getPhg() != null) { + $power = $this->getPhgPower(); + $haat = $this->getPhgHaat(); + $gain = $this->getPhgGain(); + $direction = $this->getPhgDirection(); + $range = $this->getPHGRange(); + + $description = ''; + if ($power !== null) { + $description .= 'Power ' . $power . ' W'; + } + + if ($haat !== null) { + + if (strlen($description) > 0) { + $description .= ', '; + } + + if (isImperialUnitUser()) { + $description .= 'Height ' . round(convertMeterToFeet($haat), 0) . ' ft'; + } else { + $description .= 'Height ' . $haat . ' m'; + } + } + + if ($gain !== null && $direction !== null) { + if (strlen($description) > 0) { + $description .= ', '; + } + $description .= 'Gain ' . $gain . ' dB ' . $direction; + } + + return $description; + } + return null; + } + + /** + * Get PGH string + * + * @return string + */ + public function getPhg() + { + if ($this->phg != null) { + if ($this->phg == 0) { + return null; // 0000 is considered not to be used (power == 0!) + } else if ($this->phg < 10) { + return '000' + strval($this->phg); + } else if ($this->phg < 100) { + return '00' + strval($this->phg); + } else if ($this->phg < 1000) { + return '0' + strval($this->phg); + } else { + return strval($this->phg); + } + } + return null; + } + + /** + * Get PGH power + * + * @return int + */ + public function getPhgPower() + { + if ($this->getPhg() != null) { + return pow(intval(substr($this->getPhg(), 0, 1)), 2); + } + return null; + } + + /** + * Get PGH hight (above averange terrain) + * + * @param boolean $inMeters + * @return int + */ + public function getPhgHaat($inMeters = true) + { + if ($this->getPhg() != null) { + $value = intval(substr($this->getPhg(), 1, 1)); + + $haat = 0; + if ($value != 0) { + $haat = 10 * pow(2, $value); + } + + if ($inMeters) { + return intval(round($haat * 0.3048)); + } else { + return $haat; + } + + } + return null; + } + + /** + * Get PGH Gain + * + * @return int + */ + public function getPhgGain() + { + if ($this->getPhg() != null) { + return intval(substr($this->getPhg(), 2, 1)); + } + return null; + } + + /** + * Get PGH Direction + * + * @return String + */ + public function getPhgDirection() + { + if ($this->getPhg() != null) { + + switch (substr($this->getPhg(), 3, 1)) { + case 0: + return 'omni'; + break; + case 1: + return 'North East'; + break; + case 2: + return 'East'; + break; + case 3: + return 'South East'; + break; + case 4: + return 'South'; + break; + case 5: + return 'South West'; + break; + case 6: + return 'West'; + break; + case 7: + return 'North West'; + break; + case 8: + return 'North'; + break; + case 9: + return null; + break; + } + } + return null; + } + + /** + * Get PGH Direction Degree + * + * @return int + */ + public function getPhgDirectionDegree() + { + if ($this->getPhg() != null) { + + switch (substr($this->getPhg(), 3, 1)) { + case 0: + return null; + break; + case 1: + return 45; + break; + case 2: + return 90; + break; + case 3: + return 135; + break; + case 4: + return 180; + break; + case 5: + return 225; + break; + case 6: + return 270; + break; + case 7: + return 315; + break; + case 8: + return 360; + break; + case 9: + return null; + break; + } + } + return null; + } + + /** + * Get RNG + * + * @return float + */ + public function getRng() + { + if ($this->rng != null) { + return $this->rng; + } + return null; + } + + /** + * Get packet type description + * + * @return Station + */ + public function getPacketTypeName() + { + switch ($this->packetTypeId) { + case 1: + return 'Position'; + break; + case 2: + return 'Direction'; + break; + case 3: + return 'Weather'; + break; + case 4: + return 'Object'; + break; + case 5: + return 'Item'; + break; + case 6: + return 'Telemetry'; + break; + case 7: + return 'Message'; + break; + case 8: + return 'Query'; + break; + case 9: + return 'Response'; + break; + case 10: + return 'Status'; + break; + case 11: + return 'Other'; + break; + default: + return 'Unknown'; + break; + } + } + + /** + * Get releted packet weather + * @return PacketWeather + */ + public function getPacketWeather() { + return PacketWeatherRepository::getInstance()->getObjectByPacketId($this->id, $this->timestamp); + } + + /** + * Get releted packet telemetry + * @return PacketTelemetry + */ + public function getPacketTelemetry() { + return PacketTelemetryRepository::getInstance()->getObjectByPacketId($this->id, $this->timestamp); + } + + /** + * Returns OGN part of packet + * + * @return PacketOgn + */ + public function getPacketOgn() + { + static $cache = array(); + $key = $this->id; + if (!isset($cache[$key])) { + if ($this->sourceId == 5) { + $cache[$key] = PacketOgnRepository::getInstance()->getObjectByPacketId($this->id); + } else { + $cache[$key] = new PacketOgn(null); + } + } + return $cache[$key]; + } + + /** + * Get Station + * @return Station + */ + public function getStationObject() { + return StationRepository::getInstance()->getObjectById($this->stationId); + } + + /** + * Get Sender + * @return Sender + */ + public function getSenderObject() { + return SenderRepository::getInstance()->getObjectById($this->senderId); + } +} diff --git a/htdocs/includes/models/packetogn.class.php b/htdocs/includes/models/packetogn.class.php new file mode 100644 index 0000000..5150d13 --- /dev/null +++ b/htdocs/includes/models/packetogn.class.php @@ -0,0 +1,10 @@ +_stationTelemetryParam = null; + $this->_stationTelemetryEqns = null; + $this->_stationTelemetryBits = null; + $this->_stationTelemetryUnit = null; + } + + /** + * Get value parameter name + * + * @param int $valNumber + * @return string + */ + public function getValueParameterName($valNumber) + { + if ($this->_stationTelemetryParam === null && $this->stationTelemetryParamId !== null) { + $this->_stationTelemetryParam = StationTelemetryParamRepository::getInstance()->getObjectById($this->stationTelemetryParamId); + } + + if ($this->_stationTelemetryParam !== null + && $this->_stationTelemetryParam->isExistingObject() + && isset($this->_stationTelemetryParam->{'p'.$valNumber}) + && $this->_stationTelemetryParam->{'p'.$valNumber} != '' + ) { + + return $this->_stationTelemetryParam->{'p'.$valNumber}; + } else { + return "Value$valNumber"; + } + } + + /** + * Get bit parameter name + * + * @param int $valNumber + * @return string + */ + public function getBitParameterName($valNumber) + { + if ($this->_stationTelemetryParam === null && $this->stationTelemetryParamId !== null) { + $this->_stationTelemetryParam = StationTelemetryParamRepository::getInstance()->getObjectById($this->stationTelemetryParamId); + } + + if ($this->_stationTelemetryParam !== null && $this->_stationTelemetryParam->isExistingObject() && $this->_stationTelemetryParam->{'b'.$valNumber} != '') { + return $this->_stationTelemetryParam->{'b'.$valNumber}; + } else { + return "Bit$valNumber"; + } + } + + /** + * Get value eqns + * + * @param int $valNumber + * @return numeric + */ + public function getEqnsValue($valNumber) + { + if ($this->_stationTelemetryEqns === null && $this->stationTelemetryEqnsId !== null) { + $this->_stationTelemetryEqns = StationTelemetryEqnsRepository::getInstance()->getObjectById($this->stationTelemetryEqnsId); + } + + if ($this->_stationTelemetryEqns !== null && $this->_stationTelemetryEqns->isExistingObject()) { + $a = $this->_stationTelemetryEqns->{'a'.$valNumber}; + $b = $this->_stationTelemetryEqns->{'b'.$valNumber}; + $c = $this->_stationTelemetryEqns->{'c'.$valNumber}; + + if ($a === null && $b === null) { + // User has sent us a faulty eqns, just return raw value + return Array(0, 1, 0); + } else { + if ($a === null) { + $a = 0; + } + if ($b === null) { + $b = 0; + } + if ($c === null) { + $c = 0; + } + return Array($a, $b, $c); + } + + } else { + // We have no eqns, just return raw value + return Array(0, 1, 0); + } + } + + /** + * Check if value is set value + * + * @param int $valNumber + * @return bool + */ + public function isValueSet($valNumber) + { + $val = $this->{'val'.$valNumber}; + if ($val !== null) { + return true; + } + return false; + } + + /** + * Get value + * + * @param int $valNumber + * @return numeric + */ + public function getValue($valNumber) + { + $val = $this->{'val'.$valNumber}; + + $eqns = $this->getEqnsValue($valNumber); + $a = $eqns[0]; + $b = $eqns[1]; + $c = $eqns[2]; + + if ($a == null && $b == null) { + // User has sent us a faulty eqns, just return raw value + return $val; + + } else { + $result = 0; + + if ($a != null) { + $result += $a * $val * $val; + } + + if ($b != null) { + $result += $b * $val; + } + + if ($c != null) { + $result += $c; + } + + return $result; + } + } + + /** + * Get value unit + * + * @param int $valNumber + * @return string + */ + public function getValueUnit($valNumber) + { + $unit = ''; // default + if ($this->_stationTelemetryUnit === null && $this->stationTelemetryUnitId !== null) { + $this->_stationTelemetryUnit = StationTelemetryUnitRepository::getInstance()->getObjectById($this->stationTelemetryUnitId); + } + + if ($this->_stationTelemetryUnit !== null && $this->_stationTelemetryUnit->isExistingObject()) { + $unit = ' ' . $this->_stationTelemetryUnit->{'u'.$valNumber}; + } + + return $unit; + } + + /** + * Get bit sense + * + * @param int $valNumber + * @return int + */ + public function getBitSense($valNumber) + { + if ($this->_stationTelemetryBits === null && $this->stationTelemetryBitsId !== null) { + $this->_stationTelemetryBits = StationTelemetryBitsRepository::getInstance()->getObjectById($this->stationTelemetryBitsId); + } + + $sense = 1; // default to 1 + if ($this->_stationTelemetryBits !== null && $this->_stationTelemetryBits->isExistingObject()) { + $sense = substr($this->_stationTelemetryBits->bits, $valNumber-1, 1); + } + + return $sense; + } + + /** + * Get bit + * + * @param int $valNumber + * @return int + */ + public function getBit($valNumber) + { + if ($this->_stationTelemetryBits === null && $this->stationTelemetryBitsId !== null) { + $this->_stationTelemetryBits = StationTelemetryBitsRepository::getInstance()->getObjectById($this->stationTelemetryBitsId); + } + + $sense = $this->getBitSense($valNumber); + + $bit = substr($this->bits, $valNumber-1, 1); + if (($sense == 1 && $bit == 1) || ($sense == 0 && $bit == 0)) { + return 1; + } else { + return 0; + } + } + + /** + * Get bit label + * + * @param int $valNumber + * @return int + */ + public function getBitLabel($valNumber) + { + if ($this->_stationTelemetryUnit === null && $this->stationTelemetryUnitId !== null) { + $this->_stationTelemetryUnit = StationTelemetryUnitRepository::getInstance()->getObjectById($this->stationTelemetryUnitId); + } + + $label = 'On'; // default + if ($this->_stationTelemetryUnit !== null && $this->_stationTelemetryUnit->isExistingObject()) { + $label = $this->_stationTelemetryUnit->{'l'.$valNumber}; + } + + return $label; + } +} diff --git a/htdocs/includes/models/packetweather.class.php b/htdocs/includes/models/packetweather.class.php new file mode 100644 index 0000000..134b1be --- /dev/null +++ b/htdocs/includes/models/packetweather.class.php @@ -0,0 +1,72 @@ +getRainSummaryList($showRain1h, $showRain24h, $showRainSinceMidnight); + + if (empty($result)) { + if ($this->rain_1h === null && $this->rain_24h === null && $this->rain_since_midnight === null) { + return 'No rain measurements received'; + } else { + return 'No other rain measurements received'; + } + } else { + return implode(' ', $result); + } + } + + /** + * Returnes a rain summary array + * + * @param boolean $showRain1h + * @param boolean $showRain24h + * @param boolean $showRainSinceMidnight + * @return string + */ + public function getRainSummaryList($showRain1h = true, $showRain24h = true, $showRainSinceMidnight = true) + { + $result = []; + + if ($showRain1h && $this->rain_1h !== null) { + if (isImperialUnitUser()) { + $result[] = "Rain latest hour: " . round(convertMmToInch($this->rain_1h), 2) . " in"; + } else { + $result[] = "Rain latest hour: " . round($this->rain_1h, 2) . " mm"; + } + } + + if ($showRain24h && $this->rain_24h !== null) { + if (isImperialUnitUser()) { + $result[] = "Rain latest 24h hours: " . round(convertMmToInch($this->rain_24h), 2) . " in"; + } else { + $result[] = "Rain latest 24h hours: " . round($this->rain_24h, 2) . " mm"; + } + } + + if ($showRainSinceMidnight && $this->rain_since_midnight !== null) { + if (isImperialUnitUser()) { + $result[] = "Rain since midnight: " . round(convertMmToInch($this->rain_since_midnight), 2) . " in"; + } else { + $result[] = "Rain since midnight: " . round($this->rain_since_midnight, 2) . " mm"; + } + } + + return $result; + } +} diff --git a/htdocs/includes/models/sender.class.php b/htdocs/includes/models/sender.class.php new file mode 100644 index 0000000..4f61f6a --- /dev/null +++ b/htdocs/includes/models/sender.class.php @@ -0,0 +1,19 @@ +getObjectByNameAndSenderId($this->name, $this->id); + } +} diff --git a/htdocs/includes/models/station.class.php b/htdocs/includes/models/station.class.php new file mode 100644 index 0000000..b3a91cb --- /dev/null +++ b/htdocs/includes/models/station.class.php @@ -0,0 +1,322 @@ +sourceId == 1 && $this->stationTypeId == 1) { + $pos = strpos($this->name, '-'); + if ($pos !== false) { + $callsign = substr($this->name, 0, $pos); + } else { + $callsign = $this->name; + } + + if (strlen($callsign) >= 3 && preg_match('~[0-9]~', substr($callsign, 1, strlen($callsign)-1))) { + // At least 3 letters and a digit somewhere in the middle + return $callsign; + } + } + + return null; + } + + + /** + * Returns OGN sender address + * + * @return string + */ + public function getOgnSenderAddress() + { + if (isset($this->latestOgnSenderAddress) && $this->latestOgnSenderAddress != '') { + return $this->latestOgnSenderAddress; + } + return null; + } + + /** + * Returns OGN device + * + * @return Model + */ + public function getOgnDevice() + { + static $cache = array(); + $key = $this->id; + if (!isset($cache[$key])) { + if (isset($this->latestOgnSenderAddress) && $this->latestOgnSenderAddress != '') { + $cache[$key] = ModelRepository::getInstance()->getObjectFromSql('select * from ogn_device where device_id = ?', [$this->latestOgnSenderAddress]); + } else { + $cache[$key] = null; + } + } + return $cache[$key]; + } + + /** + * Returns OGN device DB aircraft type name + * + * @return string + */ + public function getOgnDdbAircraftTypeName() + { + $ognDevice = $this->getOgnDevice(); + if ($ognDevice) { + switch ($ognDevice->ddbAircraftType) { + case 1: + return 'Glider/Motoglider'; + case 2: + return 'Plane'; + case 3: + return 'Ultralight'; + case 4: + return 'Helicopter'; + case 5: + return 'Drone/UAV'; + case 6: + return 'Other'; + } + } + return null; + } + + /** + * Returns OGN aircraft type name + * + * @return string + */ + public function getOgnAircraftTypeName() + { + if (isset($this->latestOgnAircraftTypeId) && $this->latestOgnAircraftTypeId != '') { + switch ($this->latestOgnAircraftTypeId) { + case 1: + return 'Glider'; + case 2: + return 'Tow Plane'; + case 3: + return 'Helicopter'; + case 4: + return 'Parachute'; + case 5: + return 'Drop Plane'; + case 6: + return 'Hang Glider'; + case 7: + return 'Para Glider'; + case 8: + return 'Powered Aircraft'; + case 9: + return 'Jet Aircraft'; + case 10: + return 'UFO'; + case 11: + return 'Balloon'; + case 12: + return 'Airship'; + case 13: + return 'UAV'; + case 14: + return ''; + case 15: + return 'Static Object'; + } + } + return null; + } + + /** + * Returns source description + * + * @return string + */ + public function getSourceDescription() + { + if (isset($this->sourceId) && $this->sourceId != '') { + if ($this->sourceId == 1) { + return 'APRS-IS'; + } elseif ($this->sourceId == 2) { + return 'CWOP (Citizen Weather Observer Program)'; + } elseif ($this->sourceId == 5) { + return 'OGN (Open Glider Network)'; + } + } + return null; + } + + /** + * Get distance between specified lat/lng and the station latest position (confirmed position if exists) + * + * @param float $lat + * @param float $lng + * @return int; + */ + public function getDistance($lat, $lng) + { + static $cache = array(); + $key = $this->id . ':' . $lat . ':' . $lng; + if (!isset($cache[$key])) { + + $latestLatitude = null; + $latestLongitude = null; + if ($this->latestConfirmedLongitude !== null && $this->latestConfirmedLatitude !== null) { + $latestLatitude = $this->latestConfirmedLatitude; + $latestLongitude = $this->latestConfirmedLongitude; + } else if ($this->latestLongitude !== null && $this->latestLatitude !== null) { + $latestLatitude = $this->latestLatitude; + $latestLongitude = $this->latestLongitude; + } + + if ($lat !== null && $lng !== null && $latestLatitude !== null && $latestLongitude !== null) { + $theta = $lng - $latestLongitude; + $dist = sin(deg2rad($lat)) * sin(deg2rad($latestLatitude)) + cos(deg2rad($lat)) * cos(deg2rad($latestLatitude)) * cos(deg2rad($theta)); + $dist = acos($dist); + $dist = rad2deg($dist); + $miles = $dist * 60 * 1.1515; + $cache[$key] = round($miles * 1609.344, 0); + } else { + $cache[$key] = null; + } + } + return $cache[$key]; + } + + /** + * Returnes icon http path + * + * @param int $scaleWidth + * @param int $scaleHeight + * @return string + */ + public function getIconFilePath($scaleWidth = null, $scaleHeight = null) + { + if (strlen($this->latestConfirmedSymbol) >= 1 && strlen($this->latestConfirmedSymbolTable) >= 1) { + $symbolAsciiValue = ord(substr($this->latestConfirmedSymbol, 0, 1)); + $symbolTableAsciiValue = ord(substr($this->latestConfirmedSymbolTable, 0, 1)); + } else { + // Default values + $symbolAsciiValue = 125; + $symbolTableAsciiValue = 47; + } + + $scaleStrValue = ''; + if ($scaleWidth !== null && $scaleHeight !== null) { + $scaleStrValue = '-scale' . $scaleWidth . 'x' . $scaleHeight; + } + + return '/symbols/symbol-' . $symbolAsciiValue . '-' . $symbolTableAsciiValue . $scaleStrValue . '.png'; + } + + /** + * Get array of the latest used symbols for this station + * + * @param int $scaleWidth + * @param int $scaleHeight + * @return array + */ + public function getLatestIconFilePaths($scaleWidth = 24, $scaleHeight = 24) + { + $result = Array(); + if ($this->latestConfirmedPacketTimestamp > (time() - (60*60*24))) { + // Latest packet is not that old, go on + + $scaleStrValue = ''; + if ($scaleWidth !== null && $scaleHeight !== null) { + $scaleStrValue = '-scale' . $scaleWidth . 'x' . $scaleHeight; + } + + $sql = 'select symbol, symbol_table from packet where station_id = ? and timestamp > ? group by symbol, symbol_table'; + $stmt = PDOConnection::getInstance()->prepareAndExec($sql, [$this->id, $this->latestConfirmedPacketTimestamp - (60*60*24)]); + + $records = $stmt->fetchAll(PDO::FETCH_ASSOC); + foreach ($records as $record) { + + if (strlen($record['symbol']) >= 1 && strlen($record['symbol_table']) >= 1) { + $key = $record['symbol'] . ':' . $record['symbol_table']; + + $symbolAsciiValue = ord(substr($record['symbol'], 0, 1)); + $symbolTableAsciiValue = ord(substr($record['symbol_table'], 0, 1)); + $result[$key] = '/symbols/symbol-' . $symbolAsciiValue . '-' . $symbolTableAsciiValue . $scaleStrValue . '.png'; + } + } + } + + return array_values($result); + } + + /** + * Get packet frequency in number of seconds for the latest 10 packets + * + * @param string $date + * @param int &$numberOfPackets + * @return int + */ + public function getPacketFrequency($date = null, &$numberOfPackets) + { + $pdo = PDOConnection::getInstance(); + if ($this->latestPacketTimestamp !== null) { + $timestamp = $this->latestPacketTimestamp; + } else { + return null; + } + + // Find start timestamp + $sql = 'select timestamp ts from packet where station_id = ? and map_id in (1,2,5,7,9) and timestamp < ? order by timestamp desc limit 1'; + $stmt = $pdo->prepareAndExec($sql, [$this->id, $timestamp - 1]); + + $record = $stmt->fetch(PDO::FETCH_ASSOC); + if (!empty($record) && $record['ts'] != null && $record['ts'] < $timestamp) { + $startTimestamp = $timestamp - (($timestamp - $record['ts'])*10); + if ($timestamp - $startTimestamp < 600) { + $startTimestamp = $timestamp - 600; + } + } else { + if ($date === null) { + // Try to find frequency for the date before + $date = strftime('%Y-%m-%d', $timestamp - 86400); + return $this->getPacketFrequency($date, $numberOfPackets); + } else { + // Give up + return null; + } + } + + $sql = 'select (max(timestamp) - min(timestamp)) / count(*) freq, count(*) c from packet where station_id = ? and map_id in (1,2,5,7,9) and timestamp >= ?'; + $stmt = $pdo->prepareAndExec($sql, [$this->id, $startTimestamp]); + $record = $stmt->fetch(PDO::FETCH_ASSOC); + if (!empty($record) && $record['freq'] > 0) { + $numberOfPackets = $record['c']; + return $record['freq']; + } else { + return null; + } + } + + /* + * Returnes symbol description + * @param boolean $includeUndefinedOverlay + * @return string + */ + public function getLatestSymbolDescription($includeUndefinedOverlay = true) + { + $symbol = null; + $symbolTable = null; + + if (strlen($this->latestConfirmedSymbol) >= 1 && strlen($this->latestConfirmedSymbolTable) >= 1) { + $symbol = $this->latestConfirmedSymbol; + $symbolTable = $this->latestConfirmedSymbolTable; + } + + return getSymbolDescription($symbolTable, $symbol, $includeUndefinedOverlay); + } +} diff --git a/htdocs/includes/models/stationtelemetrybits.class.php b/htdocs/includes/models/stationtelemetrybits.class.php new file mode 100644 index 0000000..68078b7 --- /dev/null +++ b/htdocs/includes/models/stationtelemetrybits.class.php @@ -0,0 +1,9 @@ +