diff --git a/README.md b/README.md index 2123861..3323a4a 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![HACS Custom](https://img.shields.io/badge/HACS-Custom-blue.svg)](https://hacs.xyz/) [![Hassfest](https://github.com/WickedGhost/avinor_flight_data/actions/workflows/hassfest.yml/badge.svg)](https://github.com/WickedGhost/avinor_flight_data/actions/workflows/hassfest.yml) [![HACS Validation](https://github.com/WickedGhost/avinor_flight_data/actions/workflows/hacs.yml/badge.svg)](https://github.com/WickedGhost/avinor_flight_data/actions/workflows/hacs.yml) -[![Version 1.0.8](https://img.shields.io/badge/Version-1.0.8-orange.svg)](custom_components/avinor_flight_data/manifest.json) +[![Version 1.0.9](https://img.shields.io/badge/Version-1.0.9-orange.svg)](custom_components/avinor_flight_data/manifest.json) [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) Custom Home Assistant integration that keeps your dashboards up to date with arrivals and departures from the official Avinor data feed. @@ -16,6 +16,7 @@ Custom Home Assistant integration that keeps your dashboards up to date with arr - [Features](#features) - [Installation](#installation) - [Configuration](#configuration) +- [Known Limitations](#known-limitations) - [Flight Details (Airlabs)](#flight-details-airlabs) - [Companion Lovelace Card](#companion-lovelace-card) - [Example Dashboard Card](#example-dashboard-card) @@ -68,6 +69,12 @@ Custom Home Assistant integration that keeps your dashboards up to date with arr Each configured sensor reports the flight count as its state and exposes detailed flight data through the `flights` attribute. +## Known Limitations + +- This integration mirrors the public Avinor flight feed and does not supplement missing airport data from other sources. +- Avinor documents that the service does not include data from private airports such as Sandefjord Airport, Torp (TRF). +- Private airports may therefore show incomplete, delayed, or missing arrivals and departures even when the integration is working correctly. + ## Flight Details (Airlabs) This integration can optionally fetch details for a specific flight from the Airlabs Flight API: @@ -145,6 +152,8 @@ title: Ankomster OSL ## Release Notes +- **1.0.9** + - Documented the upstream Avinor limitation for private airports such as TRF/Torp. - **0.2.1** - Split the Lovelace card into its own repository. - Updated HACS/Hassfest workflows to meet current validation requirements. diff --git a/custom_components/avinor_flight_data/manifest.json b/custom_components/avinor_flight_data/manifest.json index 4b26769..ba10df5 100644 --- a/custom_components/avinor_flight_data/manifest.json +++ b/custom_components/avinor_flight_data/manifest.json @@ -8,5 +8,5 @@ "issue_tracker": "https://github.com/WickedGhost/avinor_flight_data/issues", "loggers": ["custom_components.avinor_flight_data"], "requirements": ["xmltodict==0.13.0"], - "version": "1.0.8" + "version": "1.0.9" } diff --git a/tests/test_api_parsing.py b/tests/test_api_parsing.py index 6ca14d2..6ed97fb 100644 --- a/tests/test_api_parsing.py +++ b/tests/test_api_parsing.py @@ -1,9 +1,14 @@ import asyncio +from types import SimpleNamespace import pytest from custom_components.avinor_flight_data.api import AvinorApiClient from custom_components.avinor_flight_data.api import AirlabsApiClient -from custom_components.avinor_flight_data.sensor import _apply_flight_type_filter, _compact_flight +from custom_components.avinor_flight_data.sensor import ( + AvinorFlightsSensor, + _apply_flight_type_filter, + _compact_flight, +) class StubClient(AvinorApiClient): @@ -108,6 +113,47 @@ def test_apply_flight_type_filter(): assert [f["flightId"] for f in _apply_flight_type_filter(flights, "s")] == ["SK3"] +def test_sensor_entity_applies_flight_type_per_entry(): + flights = [ + {"flightId": "SK1", "dom_int": "D"}, + {"flightId": "SK2", "dom_int": "I"}, + {"flightId": "SK3", "dom_int": "S"}, + ] + coordinator = SimpleNamespace(data={"lastUpdate": "2025-01-01T12:00:00Z", "flights": flights}) + + domestic_sensor = object.__new__(AvinorFlightsSensor) + domestic_sensor.coordinator = coordinator + domestic_sensor._entry = SimpleNamespace( + data={ + "airport": "OSL", + "direction": "A", + "flight_type": "D", + "time_from": 1, + "time_to": 7, + }, + options={}, + ) + + all_types_sensor = object.__new__(AvinorFlightsSensor) + all_types_sensor.coordinator = coordinator + all_types_sensor._entry = SimpleNamespace( + data={ + "airport": "TRF", + "direction": "A", + "flight_type": "", + "time_from": 1, + "time_to": 7, + }, + options={}, + ) + + assert domestic_sensor.native_value == 1 + assert [f["flightId"] for f in domestic_sensor.extra_state_attributes["flights"]] == ["SK1"] + + assert all_types_sensor.native_value == 3 + assert [f["flightId"] for f in all_types_sensor.extra_state_attributes["flights"]] == ["SK1", "SK2", "SK3"] + + def test_compact_flight_contains_expected_keys(): flight = { "flightId": "DY123",