diff --git a/components/airgradient-local-server/internal/config_json.cpp b/components/airgradient-local-server/internal/config_json.cpp index dbca3c49..88895015 100644 --- a/components/airgradient-local-server/internal/config_json.cpp +++ b/components/airgradient-local-server/internal/config_json.cpp @@ -246,10 +246,6 @@ ParseStatus apply_item(const cJSON *item, LocalServerConfig &out, ConfigFieldId return take_enum(item, GPS_MODE_VALUES, out.gps_mode) ? ParseStatus::Ok : ParseStatus::InvalidValue; } - if (std::strcmp(key, fields::GPS_INTERVAL) == 0) { - field = ConfigFieldId::GpsInterval; - return take_int(item, out.gps_interval_seconds) ? ParseStatus::Ok : ParseStatus::InvalidValue; - } if (std::strcmp(key, fields::FRONT_LED_BRIGHTNESS) == 0) { field = ConfigFieldId::FrontLedBrightness; return take_int(item, out.front_led_brightness) ? ParseStatus::Ok : ParseStatus::InvalidValue; @@ -446,10 +442,6 @@ size_t serialize(const LocalServerConfig &cfg, char *buf, size_t buf_len) { if (cfg.gps_mode.has_value()) { cJSON_AddStringToObject(root, fields::GPS_MODE, cfg.gps_mode->c_str()); } - if (cfg.gps_interval_seconds.has_value()) { - cJSON_AddNumberToObject(root, fields::GPS_INTERVAL, - static_cast(*cfg.gps_interval_seconds)); - } if (cfg.front_led_brightness.has_value()) { cJSON_AddNumberToObject(root, fields::FRONT_LED_BRIGHTNESS, static_cast(*cfg.front_led_brightness)); @@ -532,8 +524,6 @@ const char *config_field_wire_key(ConfigFieldId id) { return fields::MEASUREMENT_INTERVAL; case ConfigFieldId::GpsMode: return fields::GPS_MODE; - case ConfigFieldId::GpsInterval: - return fields::GPS_INTERVAL; case ConfigFieldId::FrontLedBrightness: return fields::FRONT_LED_BRIGHTNESS; case ConfigFieldId::BackLedBrightness: diff --git a/components/airgradient-local-server/internal/field_names.h b/components/airgradient-local-server/internal/field_names.h index 9f31e901..e18a98a1 100644 --- a/components/airgradient-local-server/internal/field_names.h +++ b/components/airgradient-local-server/internal/field_names.h @@ -53,7 +53,6 @@ inline constexpr const char *CLOUD_CONNECTION = "cloudConnection"; inline constexpr const char *CONFIGURATION_CONTROL = "configurationControl"; inline constexpr const char *MEASUREMENT_INTERVAL = "measurementInterval"; inline constexpr const char *GPS_MODE = "gpsMode"; -inline constexpr const char *GPS_INTERVAL = "gpsInterval"; inline constexpr const char *FRONT_LED_BRIGHTNESS = "frontLedBrightness"; inline constexpr const char *BACK_LED_BRIGHTNESS = "backLedBrightness"; inline constexpr const char *TOUCH_LED_INTENSITY = "touchLedIntensity"; diff --git a/components/airgradient-local-server/tests/config_json.tests.cpp b/components/airgradient-local-server/tests/config_json.tests.cpp index 310571f9..997109f7 100644 --- a/components/airgradient-local-server/tests/config_json.tests.cpp +++ b/components/airgradient-local-server/tests/config_json.tests.cpp @@ -53,13 +53,12 @@ TEST_CASE("config parse: all enum fields accept catalog values", "[config][parse TEST_CASE("config parse: Go product fields parse with exact types", "[config][parse]") { LocalServerConfig cfg; const auto res = parse( - R"({"measurementInterval":30,"gpsMode":"always","gpsInterval":15,"frontLedBrightness":1,"backLedBrightness":2,"touchLedIntensity":2,"buzzerEnabled":true})", + R"({"measurementInterval":30,"gpsMode":"always","frontLedBrightness":1,"backLedBrightness":2,"touchLedIntensity":2,"buzzerEnabled":true})", cfg); REQUIRE(res.status == config_json::ParseStatus::Ok); REQUIRE(cfg.measurement_interval_seconds == 30); REQUIRE(cfg.gps_mode == "always"); - REQUIRE(cfg.gps_interval_seconds == 15); REQUIRE(cfg.front_led_brightness == 1); REQUIRE(cfg.back_led_brightness == 2); REQUIRE(cfg.touch_led_intensity == 2); @@ -273,7 +272,6 @@ TEST_CASE("config serialize: emits only present fields", "[config][serialize]") cfg.post_data_to_cloud = false; cfg.measurement_interval_seconds = 30; cfg.gps_mode = "always"; - cfg.gps_interval_seconds = 15; cfg.front_led_brightness = 1; cfg.back_led_brightness = 2; cfg.touch_led_intensity = 2; @@ -291,7 +289,6 @@ TEST_CASE("config serialize: emits only present fields", "[config][serialize]") REQUIRE(cJSON_IsFalse(cJSON_GetObjectItem(root, "postDataToCloud"))); REQUIRE(cJSON_GetObjectItem(root, "measurementInterval")->valueint == 30); REQUIRE(std::strcmp(cJSON_GetObjectItem(root, "gpsMode")->valuestring, "always") == 0); - REQUIRE(cJSON_GetObjectItem(root, "gpsInterval")->valueint == 15); REQUIRE(cJSON_GetObjectItem(root, "frontLedBrightness")->valueint == 1); REQUIRE(cJSON_GetObjectItem(root, "backLedBrightness")->valueint == 2); REQUIRE(cJSON_GetObjectItem(root, "touchLedIntensity")->valueint == 2); @@ -369,8 +366,6 @@ TEST_CASE("config field wire keys map correctly", "[config][parse]") { REQUIRE(std::strcmp(config_json::config_field_wire_key(ConfigFieldId::MeasurementInterval), "measurementInterval") == 0); REQUIRE(std::strcmp(config_json::config_field_wire_key(ConfigFieldId::GpsMode), "gpsMode") == 0); - REQUIRE(std::strcmp(config_json::config_field_wire_key(ConfigFieldId::GpsInterval), - "gpsInterval") == 0); REQUIRE(std::strcmp(config_json::config_field_wire_key(ConfigFieldId::FrontLedBrightness), "frontLedBrightness") == 0); REQUIRE(std::strcmp(config_json::config_field_wire_key(ConfigFieldId::BackLedBrightness), diff --git a/components/airgradient-local-server/types/local_config.h b/components/airgradient-local-server/types/local_config.h index 4c04d7ce..3220318f 100644 --- a/components/airgradient-local-server/types/local_config.h +++ b/components/airgradient-local-server/types/local_config.h @@ -53,7 +53,6 @@ struct LocalServerConfig { std::optional configuration_control; // "configurationControl" std::optional measurement_interval_seconds; // "measurementInterval" std::optional gps_mode; // "gpsMode" - std::optional gps_interval_seconds; // "gpsInterval" std::optional front_led_brightness; // "frontLedBrightness" std::optional back_led_brightness; // "backLedBrightness" std::optional touch_led_intensity; // "touchLedIntensity" diff --git a/components/airgradient-local-server/types/local_server_result.h b/components/airgradient-local-server/types/local_server_result.h index f01fa4db..3fcde556 100644 --- a/components/airgradient-local-server/types/local_server_result.h +++ b/components/airgradient-local-server/types/local_server_result.h @@ -46,7 +46,6 @@ enum class ConfigFieldId : uint8_t { CorrectionsHumidity, // "corrections.humidity" MeasurementInterval, // "measurementInterval" GpsMode, // "gpsMode" - GpsInterval, // "gpsInterval" FrontLedBrightness, // "frontLedBrightness" BackLedBrightness, // "backLedBrightness" TouchLedIntensity, // "touchLedIntensity" diff --git a/products/go/docs/ble_service.md b/products/go/docs/ble_service.md index 2dfba6b1..01953545 100644 --- a/products/go/docs/ble_service.md +++ b/products/go/docs/ble_service.md @@ -168,7 +168,7 @@ All characteristic payloads use CBOR (RFC 8949) encoded with TinyCBOR's |---|---|---|---| | Measures | ~120B | ~135B | Yes | | Status | ~95B | ~115B | Yes | -| Config (read, 19 keys) | — | <512B | Yes (Read-Long) | +| Config (read, 18 keys) | — | <512B | Yes (Read-Long) | | Config (notify, one field + type) | — | <180B | Yes | | History control (CBOR) | ~40B | ~180B | Yes | | History data (binary, 4 pts) | 223B | 223B | Yes | @@ -376,17 +376,16 @@ config**, **set config values**, and **execute commands**. ### Read (phone reads characteristic) -Returns the full device configuration as a 19-key CBOR map. The BLE service +Returns the full device configuration as an 18-key CBOR map. The BLE service keeps this value updated whenever the orchestrator calls `update_config()`. -#### CBOR Payload (Map) — 19 Keys +#### CBOR Payload (Map) — 18 Keys | Key | CBOR Type | `GoSettings` field | Encoded with | |---|---|---|---| | `"meas_int"` | uint | `measure_interval_seconds` | `cbor_encode_uint` (1–3600 seconds) | | `"temp_f"` | bool | `use_fahrenheit` | `cbor_encode_boolean` | | `"pm_aqi"` | bool | `pm_use_usaqi` | `cbor_encode_boolean` | -| `"gps_int"` | uint | `gps_interval_seconds` | `cbor_encode_uint` (1–60 seconds) | | `"gps_mode"` | text | `gps_mode` | See mapping below | | `"inact_to"` | uint | `inactivity_timeout_seconds` | `cbor_encode_uint` | | `"auto_lock"` | uint | `auto_lock_seconds` | `cbor_encode_uint` | @@ -897,7 +896,7 @@ failed `setup_ble()` is non-fatal (advertise without OTA). See | `notify_tracking_status(power, gps, tracking, session_id)` | Refreshes the full 9-key snapshot via `update_status()` (Read stays full), then pushes a `{tracking, session}` transition delta via `notify(data, len)`. Used for urgent tracking transitions (start success, start failure, manual stop). Best-effort delivery — Read remains authoritative. | | `notify_charging_status(power, gps, tracking, session_id)` | Refreshes the full 9-key snapshot via `update_status()` (Read stays full), then pushes a `{charging, bat_pct, bat_v}` power delta via `notify(data, len)`. Used for charging transitions (plug in, unplug, charge complete). Disjoint keys from the tracking delta, no `"type"` discriminator — client merges by key. | | `notify_disconnect(reason)` | Pushes a NOTIFY-only `{disc}` delta via `notify(data, len)` (snapshot untouched) announcing an imminent link drop and why (`overheat`/`low_batt`/`user`/`op_stationary`/`op_offline`). Called from `change_mode()` (leaving Portable) and `shutdown()`; gated on `is_connected()`; the caller settles before teardown so it can drain. | -| `update_config(settings)` | Encode the full snapshot via `encode_config()` (19 keys, no `"type"`), `set_value()` only. Sole writer of the Config snapshot; buffer sized to the 512-byte ATT ceiling. | +| `update_config(settings)` | Encode the full snapshot via `encode_config()` (18 keys, no `"type"`), `set_value()` only. Sole writer of the Config snapshot; buffer sized to the 512-byte ATT ceiling. | | `notify_config(prev, cur)` | Refreshes the snapshot via `update_config(cur)`, then sends the changed-fields delta (`encode_config_delta()`: `"type":"config"` + changed keys) via `notify(data, len)`. | | `notify_command_progress(cmd)` | Inline CBOR encoding (2 keys: type + cmd), `notify(data, len)` (stored value untouched). Sent before long-running commands. | | `notify_command_result(cmd, success, error)` | Inline CBOR encoding (3-4 keys), `notify(data, len)` (stored value untouched). | @@ -1243,7 +1242,7 @@ cover: - **CBOR encoding**: `encode_measures()` (field omission, GPS inclusion), `encode_status()` (all 9 keys, battery clamping) and `encode_status_transition()` - (2-key delta), `encode_config()` (full 19-key snapshot, no `"type"`) and + (2-key delta), `encode_config()` (full 18-key snapshot, no `"type"`) and `encode_config_delta()` (`"type":"config"` + changed keys only), `notify_config(prev, cur)` (delta via `notify(data, len)`, Read stays full, snapshot refreshed first), `notify_command_result()` / diff --git a/products/go/docs/cloud_service.md b/products/go/docs/cloud_service.md index 86d9f628..357944a3 100644 --- a/products/go/docs/cloud_service.md +++ b/products/go/docs/cloud_service.md @@ -164,7 +164,6 @@ and queues a value-only `FetchConfigEventPayload`. Supported fields map into | `temperatureUnit` | `"c"`, `"f"` | `use_fahrenheit` | | `measurementInterval` | Integer 1 .. 3600 | `measure_interval_seconds` | | `gpsMode` | `"off"`, `"tracking"`, `"always"` | `gps_mode` | -| `gpsInterval` | Integer 1 .. 60 | `gps_interval_seconds` | | `frontLedBrightness` | Integer 0 .. 3 | `front_led_brightness` | | `backLedBrightness` | Integer 0 .. 3 | `back_led_brightness` | | `touchLedIntensity` | Integer 0 .. 2 | `touch_led_intensity` | diff --git a/products/go/docs/gps_service.md b/products/go/docs/gps_service.md index 2372a2a0..4cab277e 100644 --- a/products/go/docs/gps_service.md +++ b/products/go/docs/gps_service.md @@ -31,13 +31,12 @@ queue at the configured interval. ## Configuration -`GpsService::Config` fields — hardware-specific values come from `board_config.h`; -interval is derived from `GoSettings::gps_interval_seconds * 1000`. +`GpsService::Config` fields — hardware-specific values come from `board_config.h`. | Field | Default | Notes | |---|---|---| | `baud_rate` | `115200` | GPS module baud rate; hardware-specific, not a user setting. `GpsDriver::begin()` handles the TAU1113 baud-rate negotiation (starts at 9600, sends binary switch command, re-opens at 115200). | -| `posting_interval_ms` | `5000` | How often to post `GpsFixUpdate` to the event queue; set from `GoSettings::gps_interval_seconds` | +| `posting_interval_ms` | `5000` | How often to post `GpsFixUpdate` to the event queue | | `task_stack_size` | `4096` | RTOS task stack in bytes; tune at integration time | | `task_priority` | `3` | Below display worker (4); above idle | @@ -52,9 +51,8 @@ interval is derived from `GoSettings::gps_interval_seconds * 1000`. UartSerial gps_uart(BOARD_GPS_UART_PORT, BOARD_GPS_TX_PIN, BOARD_GPS_RX_PIN); GpsDriver gps_driver(gps_uart); -// Build config from settings. +// Build the GPS service configuration. GpsService::Config cfg{}; -cfg.posting_interval_ms = settings.gps_interval_seconds * 1000; GpsService gps_svc(gps_driver, event_queue, cfg); @@ -82,7 +80,7 @@ if (is_fix_valid(fix.fix)) { // use fix.position, fix.altitude_m, fix.fix, fix.timestamp } -// Update interval when settings change. +// Update the service-local posting interval when required. gps_svc.set_posting_interval_ms(new_interval_ms); // Clean shutdown before deep sleep. diff --git a/products/go/docs/local_server.md b/products/go/docs/local_server.md index b5e7940c..95c4a469 100644 --- a/products/go/docs/local_server.md +++ b/products/go/docs/local_server.md @@ -146,7 +146,6 @@ objects from the same subset. Device behavior fields are: | `temperatureUnit` | `c`, `f` | Select product display temperature unit | | `measurementInterval` | Integer 1 .. 3600 | Set the measurement interval in seconds | | `gpsMode` | `off`, `tracking`, `always` | Disable GPS, run it only while tracking, or keep it active | -| `gpsInterval` | Integer 1 .. 60 | Set the GPS posting interval in seconds | | `frontLedBrightness` | Integer 0 .. 3 | Set front LED brightness: off, dim, mid, or bright | | `backLedBrightness` | Integer 0 .. 3 | Set AQI LED brightness: off, dim, mid, or bright | | `touchLedIntensity` | Integer 0 .. 2 | Set touch LED intensity: off, dim, or bright | @@ -158,7 +157,7 @@ Connectivity, sensor, and correction fields are: |---|---|---| | `cloudConnection` | Boolean | Inverse of the product `disable_cloud` setting | | `configurationControl` | `cloud`, `local`, `both` | Arbitrate Local Server PUT and Cloud Fetch sources | -| `co2AbcDays` | Integer `-1` or 1 .. 200 | Set the automatic background calibration period for the supported CO2 sensor. `-1` disables it; positive values are converted to hours. | +| `co2AbcDays` | Integer `0` or 1 .. 200 | Set the automatic background calibration period for the supported CO2 sensor. `0` disables it; positive values are converted to hours. | | `tvocLearningOffset` | Integer 1 .. 1000 | Set the SGP41 VOC gas-index learning-time offset in whole hours. | | `noxLearningOffset` | Integer 1 .. 1000 | Set the SGP41 NOx gas-index learning-time offset in whole hours. | | `corrections` | Object | Configure `pm25`, `temperature`, and `humidity` correction entries | diff --git a/products/go/docs/settings.md b/products/go/docs/settings.md index fb69b5d6..73999608 100644 --- a/products/go/docs/settings.md +++ b/products/go/docs/settings.md @@ -38,7 +38,6 @@ See [`go_settings.h`](../main/go_settings.h) for full signatures. | `measure_interval_seconds` | `"mi"` | `int` | `10` | 1 .. 3600 | All sensors measured together at this cadence; no per-group on/off | | `use_fahrenheit` | `"uf"` | `bool` | `false` | — | Temperature display unit (false=C, true=F) | | `pm_use_usaqi` | `"pmu"` | `bool` | `false` | — | PM display format (false=µg/m³, true=USAQI) | -| `gps_interval_seconds` | `"gis"` | `int` | `5` | 1 .. 60 | How often the GPS task posts fixes to the event queue | | `gps_mode` | `"gpm"` | `int` (stored) / `GpsMode` (in struct) | `OnWhenTracking` (1) | 0 .. 2 | GPS operating mode: AlwaysOff / OnWhenTracking / AlwaysOn | | `operating_mode` | `"opm"` | `int` (stored) / `OperatingMode` (in struct) | `Portable` (0) | 0 .. 2 | Serialized as int; cast to `OperatingMode` on load | | `inactivity_timeout_seconds` | `"ito"` | `int` | `5` | 5 .. 600 | Persisted and exposed over BLE; not currently used by the runtime auto-lock path | @@ -128,7 +127,6 @@ All validation is implemented in an anonymous namespace in `go_settings.cpp` | `inactivity_timeout_seconds` | `>= 5 && <= 600` | | `use_fahrenheit` | No range check (bool) | | `pm_use_usaqi` | No range check (bool) | -| `gps_interval_seconds` | `>= 1 && <= 60` | | `gps_mode` | Underlying int in `0 .. 2` (matches `GpsMode` enum values) | | `operating_mode` | Underlying int in `0 .. 2` (matches `OperatingMode` enum values) | | `auto_lock_seconds` | `0`, `10`, `30`, or `60` | diff --git a/products/go/go_ble_client.md b/products/go/go_ble_client.md index f5c9272c..860a471a 100644 --- a/products/go/go_ble_client.md +++ b/products/go/go_ble_client.md @@ -510,14 +510,13 @@ This characteristic supports three operations: Read the characteristic to receive the full device configuration. -#### Payload (19-key CBOR map) +#### Payload (18-key CBOR map) | Key | Type | Description | |---|---|---| | `"meas_int"` | uint | Measurement interval in seconds (1–3600). All sensors measured together at this cadence. | | `"temp_f"` | bool | `true` = Fahrenheit, `false` = Celsius | | `"pm_aqi"` | bool | `true` = US AQI for PM, `false` = raw ug/m3 | -| `"gps_int"` | uint | GPS update interval in seconds (1–60) | | `"gps_mode"` | text | GPS mode (see table below) | | `"inact_to"` | uint | Inactivity timeout (seconds) | | `"auto_lock"` | uint | Auto-lock timeout (seconds) | @@ -568,7 +567,6 @@ them and persisted loading canonicalizes them. "meas_int": 10, "temp_f": false, "pm_aqi": false, - "gps_int": 5, "gps_mode": "tracking", "inact_to": 300, "auto_lock": 60, @@ -617,7 +615,6 @@ silently ignored for backward compatibility. They do not modify any setting. | `"meas_int"` | uint | 1–3600 seconds | | `"temp_f"` | bool | | | `"pm_aqi"` | bool | | -| `"gps_int"` | uint | 1–60 seconds | | `"gps_mode"` | text | `"off"`, `"tracking"`, or `"always"` | | `"inact_to"` | uint | | | `"auto_lock"` | uint | | @@ -1614,7 +1611,7 @@ negotiated interval; only its speed is affected. ### Required MTUs by operation -- **Config Read**: the full 19-key snapshot is typically about 239 bytes and is +- **Config Read**: the full 18-key snapshot is typically about 239 bytes and is bounded by a 512-byte characteristic buffer. Use Read-Long / Read Blob and collect all fragments. Config Read does not require MTU 512, but it does require a client API that supports long reads. diff --git a/products/go/main/go_app.cpp b/products/go/main/go_app.cpp index 7fb8a299..3ad229bf 100644 --- a/products/go/main/go_app.cpp +++ b/products/go/main/go_app.cpp @@ -491,14 +491,12 @@ void GoApp::run_button_wake_path(const RtcAppState &state) { .nox_learning_offset = settings.nox_learning_offset, }); - auto *gps_service = - new GpsService(*gps_driver, event_queue, - { - .baud_rate = GPS_BAUD, - .posting_interval_ms = settings.gps_interval_seconds * 1000, - .task_stack_size = 4096, - .task_priority = 3, - }); + auto *gps_service = new GpsService(*gps_driver, event_queue, + { + .baud_rate = GPS_BAUD, + .task_stack_size = 4096, + .task_priority = 3, + }); // InputService: suppress the first ButtonPower event (the wake press) auto *input_service = new InputService(*touch, _board.gpio_hal(), event_queue, @@ -709,11 +707,9 @@ void GoApp::run_interactive(WakeCause cause, BootHandoff handoff) { .tvoc_learning_offset = settings.tvoc_learning_offset, .nox_learning_offset = settings.nox_learning_offset}); - auto *gps_service = new GpsService(*gps_driver, event_queue, - {.baud_rate = GPS_BAUD, - .posting_interval_ms = settings.gps_interval_seconds * 1000, - .task_stack_size = 4096, - .task_priority = 3}); + auto *gps_service = + new GpsService(*gps_driver, event_queue, + {.baud_rate = GPS_BAUD, .task_stack_size = 4096, .task_priority = 3}); auto *input_service = new InputService(*touch, _board.gpio_hal(), event_queue, {.pin_cap_int = PIN_CAP_INT, diff --git a/products/go/main/go_ble.cpp b/products/go/main/go_ble.cpp index 4bc3ada0..86a7e024 100644 --- a/products/go/main/go_ble.cpp +++ b/products/go/main/go_ble.cpp @@ -1816,9 +1816,6 @@ static void enc_temp_f(CborEncoder &m, const GoSettings &s) { static void enc_pm_aqi(CborEncoder &m, const GoSettings &s) { cbor_encode_boolean(&m, s.pm_use_usaqi); } -static void enc_gps_int(CborEncoder &m, const GoSettings &s) { - cbor_encode_uint(&m, static_cast(s.gps_interval_seconds)); -} static void enc_gps_mode(CborEncoder &m, const GoSettings &s) { cbor_encode_text_stringz(&m, gps_mode_to_wire(s.gps_mode)); } @@ -1875,9 +1872,6 @@ static bool dif_temp_f(const GoSettings &a, const GoSettings &b) { static bool dif_pm_aqi(const GoSettings &a, const GoSettings &b) { return a.pm_use_usaqi != b.pm_use_usaqi; } -static bool dif_gps_int(const GoSettings &a, const GoSettings &b) { - return a.gps_interval_seconds != b.gps_interval_seconds; -} static bool dif_gps_mode(const GoSettings &a, const GoSettings &b) { return a.gps_mode != b.gps_mode; } @@ -1935,7 +1929,6 @@ static const ConfigField CONFIG_FIELDS[] = { {BLE_KEY_MEAS_INT, enc_meas_int, dif_meas_int}, {BLE_KEY_TEMP_F, enc_temp_f, dif_temp_f}, {BLE_KEY_PM_AQI, enc_pm_aqi, dif_pm_aqi}, - {BLE_KEY_GPS_INT, enc_gps_int, dif_gps_int}, {BLE_KEY_GPS_MODE, enc_gps_mode, dif_gps_mode}, {BLE_KEY_INACT_TO, enc_inact_to, dif_inact_to}, {BLE_KEY_AUTO_LOCK, enc_auto_lock, dif_auto_lock}, @@ -2223,17 +2216,6 @@ BleConfigDecodeResult BleService::decode_config_write(const uint8_t *buf, size_t else if (key_is(BLE_KEY_PM_INT) || key_is(BLE_KEY_OTHER_INT) || key_is(BLE_KEY_DISP_INT)) { cbor_value_advance(&it); handled = true; - } else if (key_is(BLE_KEY_GPS_INT)) { - cbor_value_advance(&it); - result.recognized_config_key_count++; - uint64_t v = 0; - if (cbor_value_is_unsigned_integer(&it) && cbor_value_get_uint64(&it, &v) == CborNoError && - v >= GPS_INTERVAL_SECONDS_MIN && v <= GPS_INTERVAL_SECONDS_MAX) { - settings.gps_interval_seconds = static_cast(v); - } else { - result.has_invalid_config_values = true; - } - handled = true; } else if (key_is(BLE_KEY_INACT_TO)) { cbor_value_advance(&it); result.recognized_config_key_count++; diff --git a/products/go/main/go_ble_protocol.h b/products/go/main/go_ble_protocol.h index fcb2fdd8..614321b7 100644 --- a/products/go/main/go_ble_protocol.h +++ b/products/go/main/go_ble_protocol.h @@ -72,7 +72,6 @@ inline constexpr const char *BLE_KEY_OTHER_INT = "other_int"; inline constexpr const char *BLE_KEY_DISP_INT = "disp_int"; inline constexpr const char *BLE_KEY_TEMP_F = "temp_f"; inline constexpr const char *BLE_KEY_PM_AQI = "pm_aqi"; -inline constexpr const char *BLE_KEY_GPS_INT = "gps_int"; inline constexpr const char *BLE_KEY_GPS_MODE = "gps_mode"; inline constexpr const char *BLE_KEY_INACT_TO = "inact_to"; inline constexpr const char *BLE_KEY_AUTO_LOCK = "auto_lock"; diff --git a/products/go/main/go_cloud.cpp b/products/go/main/go_cloud.cpp index a896d7b1..75f1ac19 100644 --- a/products/go/main/go_cloud.cpp +++ b/products/go/main/go_cloud.cpp @@ -52,7 +52,6 @@ constexpr const char *JSON_PM_STANDARD = "pmStandard"; constexpr const char *JSON_TEMPERATURE_UNIT = "temperatureUnit"; constexpr const char *JSON_MEASUREMENT_INTERVAL = "measurementInterval"; constexpr const char *JSON_GPS_MODE = "gpsMode"; -constexpr const char *JSON_GPS_INTERVAL = "gpsInterval"; constexpr const char *JSON_FRONT_LED_BRIGHTNESS = "frontLedBrightness"; constexpr const char *JSON_BACK_LED_BRIGHTNESS = "backLedBrightness"; constexpr const char *JSON_TOUCH_LED_INTENSITY = "touchLedIntensity"; @@ -329,13 +328,6 @@ FetchConfigEventPayload parse_cloud_config(const char *buffer, size_t bytes) { update.update_mask |= static_cast(GoConfigField::GpsMode); } - const cJSON *gps_interval = cJSON_GetObjectItemCaseSensitive(root, JSON_GPS_INTERVAL); - if (gps_interval != nullptr && - parse_int_range(gps_interval, JSON_GPS_INTERVAL, GPS_INTERVAL_SECONDS_MIN, - GPS_INTERVAL_SECONDS_MAX, update.gps_interval_seconds)) { - update.update_mask |= static_cast(GoConfigField::GpsInterval); - } - int led_value = 0; const cJSON *front_led_brightness = cJSON_GetObjectItemCaseSensitive(root, JSON_FRONT_LED_BRIGHTNESS); diff --git a/products/go/main/go_config_types.h b/products/go/main/go_config_types.h index 5f17fbb8..dc86d9a2 100644 --- a/products/go/main/go_config_types.h +++ b/products/go/main/go_config_types.h @@ -35,7 +35,6 @@ enum class GoConfigField : uint32_t { TvocLearningOffset = 1U << 8, NoxLearningOffset = 1U << 9, MeasurementInterval = 1U << 10, - GpsInterval = 1U << 11, GpsMode = 1U << 12, FrontLedBrightness = 1U << 13, BackLedBrightness = 1U << 14, @@ -47,10 +46,6 @@ constexpr int MEASURE_INTERVAL_SECONDS_MIN = 1; constexpr int MEASURE_INTERVAL_SECONDS_MAX = 3600; constexpr int MEASURE_INTERVAL_SECONDS_DEFAULT = 10; -constexpr int GPS_INTERVAL_SECONDS_MIN = 1; -constexpr int GPS_INTERVAL_SECONDS_MAX = 60; -constexpr int GPS_INTERVAL_SECONDS_DEFAULT = 5; - constexpr int CO2_ABC_DAYS_DISABLED = -1; constexpr int CO2_ABC_DAYS_MIN = 1; constexpr int CO2_ABC_DAYS_MAX = 200; @@ -64,10 +59,6 @@ inline bool is_measure_interval_seconds_valid(int value) { return value >= MEASURE_INTERVAL_SECONDS_MIN && value <= MEASURE_INTERVAL_SECONDS_MAX; } -inline bool is_gps_interval_seconds_valid(int value) { - return value >= GPS_INTERVAL_SECONDS_MIN && value <= GPS_INTERVAL_SECONDS_MAX; -} - inline bool is_gps_mode_valid(int value) { return value >= static_cast(GpsMode::AlwaysOff) && value <= static_cast(GpsMode::AlwaysOn); @@ -102,7 +93,6 @@ struct GoConfigUpdate { bool disable_cloud = false; ConfigurationControl configuration_control = ConfigurationControl::Both; int measure_interval_seconds = MEASURE_INTERVAL_SECONDS_DEFAULT; - int gps_interval_seconds = GPS_INTERVAL_SECONDS_DEFAULT; GpsMode gps_mode = GpsMode::OnWhenTracking; LedBrightness front_led_brightness = LedBrightness::Off; LedBrightness back_led_brightness = LedBrightness::Off; diff --git a/products/go/main/go_local_api.cpp b/products/go/main/go_local_api.cpp index 22652597..04ca4d66 100644 --- a/products/go/main/go_local_api.cpp +++ b/products/go/main/go_local_api.cpp @@ -29,6 +29,7 @@ constexpr const char *CONFIG_CONTROL_BOTH = "both"; constexpr const char *GPS_MODE_OFF = "off"; constexpr const char *GPS_MODE_TRACKING = "tracking"; constexpr const char *GPS_MODE_ALWAYS = "always"; +constexpr int LOCAL_SERVER_CO2_ABC_DAYS_DISABLED = 0; constexpr const char *CORRECTION_NONE = "none"; constexpr const char *CORRECTION_EPA_2021 = "epa_2021"; @@ -387,7 +388,6 @@ GoLocalApiService::make_active_config(const GoSettings &settings) { active.disable_cloud = settings.disable_cloud; active.configuration_control = settings.configuration_control; active.measure_interval_seconds = settings.measure_interval_seconds; - active.gps_interval_seconds = settings.gps_interval_seconds; active.gps_mode = settings.gps_mode; active.front_led_brightness = settings.front_led_brightness; active.back_led_brightness = settings.back_led_brightness; @@ -407,12 +407,13 @@ LocalServerConfig GoLocalApiService::map_config(const ActiveConfigSnapshot &acti active.use_fahrenheit ? TEMPERATURE_UNIT_FAHRENHEIT : TEMPERATURE_UNIT_CELSIUS; config.cloud_connection = !active.disable_cloud; config.measurement_interval_seconds = active.measure_interval_seconds; - config.gps_interval_seconds = active.gps_interval_seconds; config.front_led_brightness = static_cast(active.front_led_brightness); config.back_led_brightness = static_cast(active.back_led_brightness); config.touch_led_intensity = static_cast(active.touch_led_intensity); config.buzzer_enabled = active.buzzer_enabled; - config.co2_abc_days = active.co2_abc_days; + config.co2_abc_days = active.co2_abc_days == CO2_ABC_DAYS_DISABLED + ? LOCAL_SERVER_CO2_ABC_DAYS_DISABLED + : active.co2_abc_days; config.tvoc_learning_offset = active.tvoc_learning_offset; config.nox_learning_offset = active.nox_learning_offset; @@ -484,13 +485,13 @@ bool GoLocalApiService::is_exact_control_recovery(const LocalServerConfig &parti !partial.temperature_unit.has_value() && !partial.post_data_to_cloud.has_value() && !partial.cloud_connection.has_value() && !partial.measurement_interval_seconds.has_value() && !partial.gps_mode.has_value() && - !partial.gps_interval_seconds.has_value() && !partial.front_led_brightness.has_value() && - !partial.back_led_brightness.has_value() && !partial.touch_led_intensity.has_value() && - !partial.buzzer_enabled.has_value() && !partial.co2_abc_days.has_value() && - !partial.tvoc_learning_offset.has_value() && !partial.nox_learning_offset.has_value() && - !partial.led_mode.has_value() && !partial.led_bar_brightness.has_value() && - !partial.display_brightness.has_value() && !partial.mqtt_broker_url.has_value() && - !partial.http_domain.has_value() && !partial.corrections.has_value(); + !partial.front_led_brightness.has_value() && !partial.back_led_brightness.has_value() && + !partial.touch_led_intensity.has_value() && !partial.buzzer_enabled.has_value() && + !partial.co2_abc_days.has_value() && !partial.tvoc_learning_offset.has_value() && + !partial.nox_learning_offset.has_value() && !partial.led_mode.has_value() && + !partial.led_bar_brightness.has_value() && !partial.display_brightness.has_value() && + !partial.mqtt_broker_url.has_value() && !partial.http_domain.has_value() && + !partial.corrections.has_value(); } ConfigSubmitResult GoLocalApiService::translate_config(const LocalServerConfig &partial, @@ -541,14 +542,6 @@ ConfigSubmitResult GoLocalApiService::translate_config(const LocalServerConfig & update.update_mask |= static_cast(GoConfigField::GpsMode); } - if (partial.gps_interval_seconds.has_value()) { - if (!is_gps_interval_seconds_valid(*partial.gps_interval_seconds)) { - return {ConfigSubmitStatus::InvalidValue, ConfigFieldId::GpsInterval}; - } - update.gps_interval_seconds = *partial.gps_interval_seconds; - update.update_mask |= static_cast(GoConfigField::GpsInterval); - } - if (partial.front_led_brightness.has_value()) { if (!is_led_brightness_valid(*partial.front_led_brightness)) { return {ConfigSubmitStatus::InvalidValue, ConfigFieldId::FrontLedBrightness}; @@ -597,10 +590,14 @@ ConfigSubmitResult GoLocalApiService::translate_config(const LocalServerConfig & } if (partial.co2_abc_days.has_value()) { - if (!is_co2_abc_days_valid(*partial.co2_abc_days)) { + if (*partial.co2_abc_days == LOCAL_SERVER_CO2_ABC_DAYS_DISABLED) { + update.co2_abc_days = CO2_ABC_DAYS_DISABLED; + } else if (*partial.co2_abc_days < CO2_ABC_DAYS_MIN || + *partial.co2_abc_days > CO2_ABC_DAYS_MAX) { return {ConfigSubmitStatus::InvalidValue, ConfigFieldId::Co2AbcDays}; + } else { + update.co2_abc_days = *partial.co2_abc_days; } - update.co2_abc_days = *partial.co2_abc_days; update.update_mask |= static_cast(GoConfigField::Co2AbcDays); } diff --git a/products/go/main/go_local_api.h b/products/go/main/go_local_api.h index 77299219..40e7adc4 100644 --- a/products/go/main/go_local_api.h +++ b/products/go/main/go_local_api.h @@ -84,7 +84,6 @@ class GoLocalApiService final : public MeasuresProvider, bool disable_cloud = false; ConfigurationControl configuration_control = ConfigurationControl::Both; int measure_interval_seconds = MEASURE_INTERVAL_SECONDS_DEFAULT; - int gps_interval_seconds = GPS_INTERVAL_SECONDS_DEFAULT; GpsMode gps_mode = GpsMode::OnWhenTracking; LedBrightness front_led_brightness = LedBrightness::Off; LedBrightness back_led_brightness = LedBrightness::Off; diff --git a/products/go/main/go_orchestrator.cpp b/products/go/main/go_orchestrator.cpp index 52170cf1..a78ba5c7 100644 --- a/products/go/main/go_orchestrator.cpp +++ b/products/go/main/go_orchestrator.cpp @@ -112,10 +112,6 @@ static bool merge_config_update(const GoConfigUpdate &update, GoConfigSource sou candidate.measure_interval_seconds = update.measure_interval_seconds; has_update = true; } - if (has_go_config_field(update.update_mask, GoConfigField::GpsInterval)) { - candidate.gps_interval_seconds = update.gps_interval_seconds; - has_update = true; - } if (has_go_config_field(update.update_mask, GoConfigField::GpsMode)) { candidate.gps_mode = update.gps_mode; has_update = true; @@ -1569,8 +1565,7 @@ void Orchestrator::start_gps_test() { void Orchestrator::finish_gps_test() { AG_LOGI(TAG, "gps test: finish"); - // Restore the settings posting cadence. - _svc.gps_service.set_posting_interval_ms(_settings.gps_interval_seconds * 1000); + _svc.gps_service.set_posting_interval_ms(GPS_POSTING_INTERVAL_MS_DEFAULT); // Reconcile the receiver against settings: stop it if the test ungated it; // leave it running when settings keep GPS active. if (!is_gps_active()) { @@ -1785,9 +1780,6 @@ void Orchestrator::apply_settings_runtime_delta(const GoSettings &previous_setti (previous_settings.gps_mode == GpsMode::OnWhenTracking && _tracking_active); reschedule_sensor_timer(previous_settings); - if (previous_settings.gps_interval_seconds != _settings.gps_interval_seconds) { - _svc.gps_service.set_posting_interval_ms(_settings.gps_interval_seconds * 1000); - } const bool is_gps_active_now = is_gps_active(); if (!was_gps_active && is_gps_active_now) { diff --git a/products/go/main/go_settings.cpp b/products/go/main/go_settings.cpp index 757457a2..c6dbdbf4 100644 --- a/products/go/main/go_settings.cpp +++ b/products/go/main/go_settings.cpp @@ -10,7 +10,6 @@ namespace { constexpr const char *KEY_MEASURE_INTERVAL_SECONDS = "mi"; constexpr const char *KEY_INACTIVITY_TIMEOUT_SECONDS = "ito"; -constexpr const char *KEY_GPS_INTERVAL_SECONDS = "gis"; constexpr const char *KEY_GPS_MODE = "gpm"; constexpr const char *KEY_OPERATING_MODE = "opm"; constexpr const char *KEY_DEVICE_NAME = "dn"; @@ -204,12 +203,6 @@ GoSettings load_go_settings(ConfigStore &store) { settings.inactivity_timeout_seconds = inactivity_timeout_seconds; } - int gps_interval_seconds = 0; - if (store.get_int(KEY_GPS_INTERVAL_SECONDS, gps_interval_seconds) == ConfigStoreResult::OK && - is_gps_interval_seconds_valid(gps_interval_seconds)) { - settings.gps_interval_seconds = gps_interval_seconds; - } - int gps_mode = 0; if (store.get_int(KEY_GPS_MODE, gps_mode) == ConfigStoreResult::OK && is_gps_mode_valid(gps_mode)) { @@ -322,8 +315,7 @@ GoSettings load_go_settings(ConfigStore &store) { bool GoSettings::equals(const GoSettings &other) const { return measure_interval_seconds == other.measure_interval_seconds && use_fahrenheit == other.use_fahrenheit && pm_use_usaqi == other.pm_use_usaqi && - gps_interval_seconds == other.gps_interval_seconds && gps_mode == other.gps_mode && - operating_mode == other.operating_mode && + gps_mode == other.gps_mode && operating_mode == other.operating_mode && inactivity_timeout_seconds == other.inactivity_timeout_seconds && auto_lock_seconds == other.auto_lock_seconds && device_name == other.device_name && front_led_brightness == other.front_led_brightness && @@ -351,10 +343,6 @@ bool is_go_settings_valid(const GoSettings &settings) { return false; } - if (!is_gps_interval_seconds_valid(settings.gps_interval_seconds)) { - return false; - } - if (!is_gps_mode_valid(static_cast(settings.gps_mode))) { return false; } @@ -416,11 +404,6 @@ bool save_go_settings(ConfigStore &store, const GoSettings &settings) { return false; } - if (store.set_int(KEY_GPS_INTERVAL_SECONDS, settings.gps_interval_seconds) != - ConfigStoreResult::OK) { - return false; - } - if (store.set_int(KEY_GPS_MODE, static_cast(settings.gps_mode)) != ConfigStoreResult::OK) { return false; } @@ -595,14 +578,14 @@ bool clear_factory_settings(ConfigStore &store) { void print_settings(const GoSettings &settings) { AG_LOGI(TAG, - "** settings | meas_int=%d | gps_int=%d gps_mode=%d " + "** settings | meas_int=%d | gps_mode=%d " "op_mode=%d | inactivity_to=%d auto_lock=%d | fahrenheit=%s usaqi=%s | " "led: front=%d back=%d touch=%d | buzzer=%s | " "device_name=%s | disable_cloud=%s config_control=%d co2_abc_days=%d " "tvoc_learning_offset=%d nox_learning_offset=%d static_ip=%s " "onboarding_done=%s **", - settings.measure_interval_seconds, settings.gps_interval_seconds, settings.gps_mode, - settings.operating_mode, settings.inactivity_timeout_seconds, settings.auto_lock_seconds, + settings.measure_interval_seconds, settings.gps_mode, settings.operating_mode, + settings.inactivity_timeout_seconds, settings.auto_lock_seconds, settings.use_fahrenheit ? "true" : "false", settings.pm_use_usaqi ? "true" : "false", static_cast(settings.front_led_brightness), static_cast(settings.back_led_brightness), diff --git a/products/go/main/go_settings.h b/products/go/main/go_settings.h index ea9d5fc8..26d9fe7c 100644 --- a/products/go/main/go_settings.h +++ b/products/go/main/go_settings.h @@ -19,7 +19,6 @@ struct GoSettings { bool pm_use_usaqi = false; // --- GPS --- - int gps_interval_seconds = GPS_INTERVAL_SECONDS_DEFAULT; GpsMode gps_mode = GpsMode::OnWhenTracking; // --- Device behavior --- diff --git a/products/go/main/gps/gps_service.h b/products/go/main/gps/gps_service.h index 18fb9d69..be16c7b6 100644 --- a/products/go/main/gps/gps_service.h +++ b/products/go/main/gps/gps_service.h @@ -23,11 +23,13 @@ #include +inline constexpr int GPS_POSTING_INTERVAL_MS_DEFAULT = 5000; + class GpsService { public: struct Config { int baud_rate = 115200; - int posting_interval_ms = 5000; // from GoSettings::gps_interval_seconds + int posting_interval_ms = GPS_POSTING_INTERVAL_MS_DEFAULT; uint16_t task_stack_size = 4096; uint8_t task_priority = 3; // must be below display worker (4) }; diff --git a/products/go/tests/ble-integration/ago_protocol.py b/products/go/tests/ble-integration/ago_protocol.py index 85261261..e0b1dee4 100644 --- a/products/go/tests/ble-integration/ago_protocol.py +++ b/products/go/tests/ble-integration/ago_protocol.py @@ -118,7 +118,7 @@ CONFIG_READ_KEYS = { "meas_int", "temp_f", "pm_aqi", - "gps_int", "gps_mode", + "gps_mode", "inact_to", "auto_lock", "dev_name", "op_mode", "fled", "bled", "tled", @@ -142,7 +142,6 @@ "meas_int": (int,), "temp_f": (bool,), "pm_aqi": (bool,), - "gps_int": (int,), "gps_mode": (str,), "inact_to": (int,), "auto_lock": (int,), diff --git a/products/go/tests/ble-integration/test_config.py b/products/go/tests/ble-integration/test_config.py index 2bf6990b..dbba45ce 100644 --- a/products/go/tests/ble-integration/test_config.py +++ b/products/go/tests/ble-integration/test_config.py @@ -36,7 +36,7 @@ async def config_payload(ago_client: BleakClient) -> dict: # --------------------------------------------------------------------------- class TestConfigRead: - """Verify reading the Config characteristic returns a valid 19-key map.""" + """Verify reading the Config characteristic returns a valid 18-key map.""" def test_read_config(self, config_payload: dict): """Reading Config must return valid CBOR map.""" @@ -45,7 +45,7 @@ def test_read_config(self, config_payload: dict): ) def test_all_keys_present(self, config_payload: dict): - """Config read must contain exactly the 19 expected keys.""" + """Config read must contain exactly the 18 expected keys.""" missing = proto.CONFIG_READ_KEYS - set(config_payload.keys()) extra = set(config_payload.keys()) - proto.CONFIG_READ_KEYS assert not missing, f"Missing Config keys: {missing}" diff --git a/products/go/tests/go_ble.tests.cpp b/products/go/tests/go_ble.tests.cpp index f062446c..0c3a5550 100644 --- a/products/go/tests/go_ble.tests.cpp +++ b/products/go/tests/go_ble.tests.cpp @@ -793,7 +793,7 @@ TEST_CASE("BLE: encode_status clamps negative battery values to 0") { // CBOR encoding: Config // --------------------------------------------------------------------------- -TEST_CASE("BLE: encode_config produces 19 keys with compact device config") { +TEST_CASE("BLE: encode_config produces 18 keys with compact device config") { StorageService storage(*null_cache_ptr, *null_nand_ptr); BleService svc(nullptr, storage, default_ble_server); auto settings = make_default_settings(); @@ -803,7 +803,7 @@ TEST_CASE("BLE: encode_config produces 19 keys with compact device config") { REQUIRE(len > 0); auto entries = decode_cbor_map(buf, len); - CHECK(entries.size() == 19); + CHECK(entries.size() == 18); CHECK(find_entry(entries, "meas_int") != nullptr); CHECK(find_entry(entries, "pm_int") == nullptr); @@ -811,7 +811,6 @@ TEST_CASE("BLE: encode_config produces 19 keys with compact device config") { CHECK(find_entry(entries, "disp_int") == nullptr); CHECK(find_entry(entries, "temp_f") != nullptr); CHECK(find_entry(entries, "pm_aqi") != nullptr); - CHECK(find_entry(entries, "gps_int") != nullptr); CHECK(find_entry(entries, "gps_mode") != nullptr); CHECK(find_entry(entries, "inact_to") != nullptr); CHECK(find_entry(entries, "auto_lock") != nullptr); @@ -971,7 +970,7 @@ TEST_CASE("BLE: notify_config sends delta and keeps READ as full snapshot") { REQUIRE(config_char.notify_count == 1); auto read_entries = decode_cbor_map(config_char.last_value.data(), config_char.last_value.size()); - CHECK(read_entries.size() == 19); // full snapshot, no "type" + CHECK(read_entries.size() == 18); // full snapshot, no "type" CHECK(find_entry(read_entries, "type") == nullptr); auto notify_entries = decode_cbor_map(config_char.last_notified_value.data(), @@ -1012,7 +1011,6 @@ TEST_CASE("BLE: max-size config snapshot encodes within the 512-byte ceiling") { GoSettings s = make_default_settings(); s.measure_interval_seconds = 3600; - s.gps_interval_seconds = GPS_INTERVAL_SECONDS_MAX; s.inactivity_timeout_seconds = TEST_MAX_INACTIVITY_TIMEOUT_SECONDS; s.auto_lock_seconds = TEST_MAX_AUTO_LOCK_SECONDS; s.device_name = std::string(64, 'x'); @@ -1486,9 +1484,6 @@ TEST_CASE("BLE: decode_config_write rejects invalid requested config values") { SECTION("measurement interval") { len = encode_set_uint(buf, sizeof(buf), "meas_int", MEASURE_INTERVAL_SECONDS_MIN - 1); } - SECTION("GPS interval") { - len = encode_set_uint(buf, sizeof(buf), "gps_int", GPS_INTERVAL_SECONDS_MAX + 1); - } SECTION("GPS mode") { len = encode_set_text(buf, sizeof(buf), "gps_mode", "sometimes"); } SECTION("front LED") { len = @@ -1517,7 +1512,6 @@ TEST_CASE("BLE: decode_config_write rejects invalid requested config values") { CHECK_FALSE(result.has_unknown_keys); CHECK(result.has_invalid_config_values); CHECK(settings.measure_interval_seconds == original.measure_interval_seconds); - CHECK(settings.gps_interval_seconds == original.gps_interval_seconds); CHECK(settings.gps_mode == original.gps_mode); CHECK(settings.front_led_brightness == original.front_led_brightness); CHECK(settings.back_led_brightness == original.back_led_brightness); @@ -1638,18 +1632,6 @@ TEST_CASE("BLE: decode_config_write counts a single recognized config key") { CHECK_FALSE(result.has_unknown_keys); } -TEST_CASE("BLE: decode_config_write counts two recognized config keys") { - uint8_t buf[128]; - size_t len = encode_set_two_uints(buf, sizeof(buf), "meas_int", 30, "gps_int", 5); - - GoSettings settings; - auto result = BleService::decode_config_write(buf, len, settings); - - CHECK(result.op == BleConfigOp::Set); - CHECK(result.recognized_config_key_count == 2); - CHECK_FALSE(result.has_unknown_keys); -} - TEST_CASE("BLE: decode_config_write counts duplicate config-key occurrences") { uint8_t buf[128]; size_t len = encode_set_two_uints(buf, sizeof(buf), "meas_int", 30, "meas_int", 40); diff --git a/products/go/tests/go_cloud.tests.cpp b/products/go/tests/go_cloud.tests.cpp index 2bc12e67..cfd76ab4 100644 --- a/products/go/tests/go_cloud.tests.cpp +++ b/products/go/tests/go_cloud.tests.cpp @@ -456,7 +456,7 @@ TEST_CASE("FETCH parses supported root scalars and ignores cloud policy fields", "[CloudService][fetch][config]") { CloudFixture f; const char body[] = - R"({"pmStandard":"us-aqi","temperatureUnit":"f","measurementInterval":3600,"gpsMode":"always","gpsInterval":60,"frontLedBrightness":0,"backLedBrightness":3,"touchLedIntensity":2,"buzzerEnabled":true,"co2CalibrationRequested":true,"ledTestRequested":true,"disableCloudConnection":true,"configurationControl":"local","corrections":[]})"; + R"({"pmStandard":"us-aqi","temperatureUnit":"f","measurementInterval":3600,"gpsMode":"always","frontLedBrightness":0,"backLedBrightness":3,"touchLedIntensity":2,"buzzerEnabled":true,"co2CalibrationRequested":true,"ledTestRequested":true,"disableCloudConnection":true,"configurationControl":"local","corrections":[]})"; cloud_spy::fetch_body_to_write = body; cloud_spy::fetch_bytes_to_write = std::strlen(body); @@ -471,7 +471,6 @@ TEST_CASE("FETCH parses supported root scalars and ignores cloud policy fields", REQUIRE(has_go_config_field(update.update_mask, GoConfigField::TemperatureUnit)); REQUIRE(has_go_config_field(update.update_mask, GoConfigField::MeasurementInterval)); REQUIRE(has_go_config_field(update.update_mask, GoConfigField::GpsMode)); - REQUIRE(has_go_config_field(update.update_mask, GoConfigField::GpsInterval)); REQUIRE(has_go_config_field(update.update_mask, GoConfigField::FrontLedBrightness)); REQUIRE(has_go_config_field(update.update_mask, GoConfigField::BackLedBrightness)); REQUIRE(has_go_config_field(update.update_mask, GoConfigField::TouchLedIntensity)); @@ -482,7 +481,6 @@ TEST_CASE("FETCH parses supported root scalars and ignores cloud policy fields", REQUIRE(update.use_fahrenheit); REQUIRE(update.measure_interval_seconds == MEASURE_INTERVAL_SECONDS_MAX); REQUIRE(update.gps_mode == GpsMode::AlwaysOn); - REQUIRE(update.gps_interval_seconds == GPS_INTERVAL_SECONDS_MAX); REQUIRE(update.front_led_brightness == LedBrightness::Off); REQUIRE(update.back_led_brightness == LedBrightness::Bright); REQUIRE(update.touch_led_intensity == TouchLedIntensity::Bright); @@ -506,7 +504,7 @@ TEST_CASE("FETCH rejects malformed device settings independently", "[CloudService][fetch][config]") { CloudFixture f; const char body[] = - R"({"temperatureUnit":"c","measurementInterval":0,"gpsMode":"ALWAYS","gpsInterval":1.5,"frontLedBrightness":4,"backLedBrightness":-1,"touchLedIntensity":3,"buzzerEnabled":"true","co2CalibrationRequested":"true","ledTestRequested":1})"; + R"({"temperatureUnit":"c","measurementInterval":0,"gpsMode":"ALWAYS","frontLedBrightness":4,"backLedBrightness":-1,"touchLedIntensity":3,"buzzerEnabled":"true","co2CalibrationRequested":"true","ledTestRequested":1})"; cloud_spy::fetch_body_to_write = body; cloud_spy::fetch_bytes_to_write = std::strlen(body); @@ -520,7 +518,6 @@ TEST_CASE("FETCH rejects malformed device settings independently", REQUIRE(has_go_config_field(update.update_mask, GoConfigField::TemperatureUnit)); REQUIRE_FALSE(has_go_config_field(update.update_mask, GoConfigField::MeasurementInterval)); REQUIRE_FALSE(has_go_config_field(update.update_mask, GoConfigField::GpsMode)); - REQUIRE_FALSE(has_go_config_field(update.update_mask, GoConfigField::GpsInterval)); REQUIRE_FALSE(has_go_config_field(update.update_mask, GoConfigField::FrontLedBrightness)); REQUIRE_FALSE(has_go_config_field(update.update_mask, GoConfigField::BackLedBrightness)); REQUIRE_FALSE(has_go_config_field(update.update_mask, GoConfigField::TouchLedIntensity)); diff --git a/products/go/tests/go_local_api.tests.cpp b/products/go/tests/go_local_api.tests.cpp index 8cc02c39..90afdaa9 100644 --- a/products/go/tests/go_local_api.tests.cpp +++ b/products/go/tests/go_local_api.tests.cpp @@ -171,7 +171,6 @@ TEST_CASE("Go local API initializes safe snapshots") { REQUIRE(config.configuration_control.has_value()); REQUIRE(config.measurement_interval_seconds.has_value()); REQUIRE(config.gps_mode.has_value()); - REQUIRE(config.gps_interval_seconds.has_value()); REQUIRE(config.front_led_brightness.has_value()); REQUIRE(config.back_led_brightness.has_value()); REQUIRE(config.touch_led_intensity.has_value()); @@ -185,7 +184,6 @@ TEST_CASE("Go local API initializes safe snapshots") { CHECK(*config.configuration_control == "both"); CHECK(*config.measurement_interval_seconds == MEASURE_INTERVAL_SECONDS_DEFAULT); CHECK(*config.gps_mode == "tracking"); - CHECK(*config.gps_interval_seconds == GPS_INTERVAL_SECONDS_DEFAULT); CHECK(*config.front_led_brightness == static_cast(LedBrightness::Off)); CHECK(*config.back_led_brightness == static_cast(LedBrightness::Off)); CHECK(*config.touch_led_intensity == static_cast(TouchLedIntensity::Off)); @@ -351,7 +349,6 @@ TEST_CASE("Go local API maps the supported active config subset") { settings.configuration_control = ConfigurationControl::Local; settings.measure_interval_seconds = 30; settings.gps_mode = GpsMode::AlwaysOn; - settings.gps_interval_seconds = 15; settings.front_led_brightness = LedBrightness::Dim; settings.back_led_brightness = LedBrightness::Mid; settings.touch_led_intensity = TouchLedIntensity::Bright; @@ -371,7 +368,6 @@ TEST_CASE("Go local API maps the supported active config subset") { CHECK(*config.configuration_control == "local"); CHECK(config.measurement_interval_seconds == 30); CHECK(config.gps_mode == "always"); - CHECK(config.gps_interval_seconds == 15); CHECK(config.front_led_brightness == static_cast(LedBrightness::Dim)); CHECK(config.back_led_brightness == static_cast(LedBrightness::Mid)); CHECK(config.touch_led_intensity == static_cast(TouchLedIntensity::Bright)); @@ -434,7 +430,6 @@ TEST_CASE("Go local API translates one atomic supported update") { partial.configuration_control = "local"; partial.measurement_interval_seconds = 30; partial.gps_mode = "off"; - partial.gps_interval_seconds = 15; partial.front_led_brightness = 1; partial.back_led_brightness = 2; partial.touch_led_intensity = 2; @@ -455,9 +450,8 @@ TEST_CASE("Go local API translates one atomic supported update") { field_mask(GoConfigField::Pm25Correction) | field_mask(GoConfigField::TemperatureCorrection) | field_mask(GoConfigField::HumidityCorrection) | field_mask(GoConfigField::MeasurementInterval) | field_mask(GoConfigField::GpsMode) | - field_mask(GoConfigField::GpsInterval) | field_mask(GoConfigField::FrontLedBrightness) | - field_mask(GoConfigField::BackLedBrightness) | field_mask(GoConfigField::TouchLedIntensity) | - field_mask(GoConfigField::BuzzerEnabled); + field_mask(GoConfigField::FrontLedBrightness) | field_mask(GoConfigField::BackLedBrightness) | + field_mask(GoConfigField::TouchLedIntensity) | field_mask(GoConfigField::BuzzerEnabled); CHECK(request.config.update_mask == expected_mask); CHECK(request.config.pm_use_usaqi); CHECK(request.config.use_fahrenheit); @@ -465,7 +459,6 @@ TEST_CASE("Go local API translates one atomic supported update") { CHECK(request.config.configuration_control == ConfigurationControl::Local); CHECK(request.config.measure_interval_seconds == 30); CHECK(request.config.gps_mode == GpsMode::AlwaysOff); - CHECK(request.config.gps_interval_seconds == 15); CHECK(request.config.front_led_brightness == LedBrightness::Dim); CHECK(request.config.back_led_brightness == LedBrightness::Mid); CHECK(request.config.touch_led_intensity == TouchLedIntensity::Bright); @@ -641,10 +634,10 @@ TEST_CASE("Go local API rejects invalid scalar values and cross-field candidates ConfigFieldId::ConfigurationControl); partial = LocalServerConfig{}; - partial.co2_abc_days = CO2_ABC_DAYS_DISABLED - 1; + partial.co2_abc_days = CO2_ABC_DAYS_DISABLED; require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::InvalidValue, ConfigFieldId::Co2AbcDays); - partial.co2_abc_days = 0; + partial.co2_abc_days = CO2_ABC_DAYS_DISABLED - 1; require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::InvalidValue, ConfigFieldId::Co2AbcDays); partial.co2_abc_days = CO2_ABC_DAYS_MAX + 1; @@ -683,7 +676,7 @@ TEST_CASE("Go local API rejects invalid scalar values and cross-field candidates ConfigFieldId::ConfigurationControl); } -TEST_CASE("Go local API rejects invalid interval GPS and output settings") { +TEST_CASE("Go local API rejects invalid interval, GPS mode, and output settings") { Fixture fixture; fixture.service->set_access(ConfigAccess::ReadWrite); @@ -700,14 +693,6 @@ TEST_CASE("Go local API rejects invalid interval GPS and output settings") { require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::InvalidValue, ConfigFieldId::GpsMode); - partial = LocalServerConfig{}; - partial.gps_interval_seconds = GPS_INTERVAL_SECONDS_MIN - 1; - require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::InvalidValue, - ConfigFieldId::GpsInterval); - partial.gps_interval_seconds = GPS_INTERVAL_SECONDS_MAX + 1; - require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::InvalidValue, - ConfigFieldId::GpsInterval); - partial = LocalServerConfig{}; partial.front_led_brightness = -1; require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::InvalidValue, @@ -729,7 +714,7 @@ TEST_CASE("Go local API maps CO2 ABC days into config updates") { fixture.service->set_access(ConfigAccess::ReadWrite); LocalServerConfig partial{}; - partial.co2_abc_days = CO2_ABC_DAYS_DISABLED; + partial.co2_abc_days = 0; require_status(fixture.service->submit_config(partial), ConfigSubmitStatus::Accepted); LocalApiRequest request = fixture.receive_request(); REQUIRE(has_go_config_field(request.config.update_mask, GoConfigField::Co2AbcDays)); @@ -747,10 +732,10 @@ TEST_CASE("Go local API maps CO2 ABC days into config updates") { REQUIRE(request.config.co2_abc_days == CO2_ABC_DAYS_MAX); GoSettings settings{}; - settings.co2_abc_days = CO2_ABC_DAYS_MAX; + settings.co2_abc_days = CO2_ABC_DAYS_DISABLED; fixture.service->publish_config_snapshot(settings); const LocalServerConfig active = fixture.service->get_config(); - REQUIRE(active.co2_abc_days == CO2_ABC_DAYS_MAX); + REQUIRE(active.co2_abc_days == 0); } TEST_CASE("Go local API maps TVOC and NOx learning offsets into config updates") { diff --git a/products/go/tests/go_orchestrator.tests.cpp b/products/go/tests/go_orchestrator.tests.cpp index 11aa75ca..4e9332b7 100644 --- a/products/go/tests/go_orchestrator.tests.cpp +++ b/products/go/tests/go_orchestrator.tests.cpp @@ -2362,10 +2362,8 @@ TEST_CASE("button wake: pre-armed snackbar clears in single timer fire", // 12. Settings // ============================================================================ -TEST_CASE("apply_settings_change: leaves an unchanged GPS interval alone", - "[Orchestrator][settings]") { +TEST_CASE("apply_settings_change: leaves GPS service cadence alone", "[Orchestrator][settings]") { TestFixture f; - f.settings.gps_interval_seconds = 5; auto orch = f.make_orchestrator(); // apply_to_settings is real (UIManager). Mock NVS calls for save_go_settings. @@ -2886,7 +2884,6 @@ TEST_CASE("dispatch: cloud applies shared config fields and ignores policy field static_cast(GoConfigField::TemperatureCorrection) | static_cast(GoConfigField::HumidityCorrection) | static_cast(GoConfigField::MeasurementInterval) | - static_cast(GoConfigField::GpsInterval) | static_cast(GoConfigField::GpsMode) | static_cast(GoConfigField::FrontLedBrightness) | static_cast(GoConfigField::BackLedBrightness) | @@ -2897,7 +2894,6 @@ TEST_CASE("dispatch: cloud applies shared config fields and ignores policy field evt.fetch_config.update.disable_cloud = true; evt.fetch_config.update.configuration_control = ConfigurationControl::Local; evt.fetch_config.update.measure_interval_seconds = 30; - evt.fetch_config.update.gps_interval_seconds = 15; evt.fetch_config.update.gps_mode = GpsMode::AlwaysOn; evt.fetch_config.update.front_led_brightness = LedBrightness::Dim; evt.fetch_config.update.back_led_brightness = LedBrightness::Mid; @@ -2922,13 +2918,12 @@ TEST_CASE("dispatch: cloud applies shared config fields and ignores policy field CHECK_FALSE(A::settings(orch).disable_cloud); CHECK(A::settings(orch).configuration_control == ConfigurationControl::Both); CHECK(A::settings(orch).measure_interval_seconds == 30); - CHECK(A::settings(orch).gps_interval_seconds == 15); CHECK(A::settings(orch).gps_mode == GpsMode::AlwaysOn); CHECK(A::settings(orch).front_led_brightness == LedBrightness::Dim); CHECK(A::settings(orch).back_led_brightness == LedBrightness::Mid); CHECK(A::settings(orch).touch_led_intensity == TouchLedIntensity::Bright); CHECK(A::settings(orch).buzzer_enabled); - CHECK(test_spy::gps_posting_interval_ms == 15000); + CHECK(test_spy::gps_posting_interval_ms == 0); CHECK(test_spy::gps_started); REQUIRE(A::corrected_measures(orch).pm_a.pm_25 == 21.0f); REQUIRE(A::corrected_measures(orch).temp_hum_a.temperature == 29.0f); @@ -3846,13 +3841,13 @@ TEST_CASE("GPS Test: entry starts receiver + fast posting, first fix freezes TTF A::dispatch(orch, fix); CHECK(A::gps_ttff_ms(orch) == latched); - // Exit (any tap) restores the settings posting cadence and stops the + // Exit (any tap) restores the default posting cadence and stops the // receiver the test ungated (GPS still inactive per settings). test_spy::gps_stop_and_idle_called = false; InputEventData touch_enter{InputSource::TouchEnter, InputType::ShortPress}; A::on_input(orch, touch_enter); CHECK(f.ui_manager.current_screen() == Screen::HardwareTest); - CHECK(test_spy::gps_posting_interval_ms == f.settings.gps_interval_seconds * 1000); + CHECK(test_spy::gps_posting_interval_ms == GPS_POSTING_INTERVAL_MS_DEFAULT); CHECK(test_spy::gps_stop_and_idle_called); } diff --git a/products/go/tests/go_settings.tests.cpp b/products/go/tests/go_settings.tests.cpp index 71cde8f0..477a9e37 100644 --- a/products/go/tests/go_settings.tests.cpp +++ b/products/go/tests/go_settings.tests.cpp @@ -128,7 +128,7 @@ class FakeConfigStore : public ConfigStore { std::size_t _write_attempt_count = 0; }; -static constexpr std::size_t GO_SETTINGS_WRITE_COUNT = 34; +static constexpr std::size_t GO_SETTINGS_WRITE_COUNT = 33; // ============================================================================ // Defaults — load from empty store returns struct defaults @@ -140,7 +140,6 @@ TEST_CASE("load from empty store returns struct defaults", "[settings]") { REQUIRE(s.measure_interval_seconds == 10); REQUIRE(s.inactivity_timeout_seconds == 5); - REQUIRE(s.gps_interval_seconds == 5); REQUIRE(s.gps_mode == GpsMode::OnWhenTracking); REQUIRE(s.operating_mode == OperatingMode::Portable); REQUIRE(s.device_name == "airgradient-go"); @@ -207,7 +206,6 @@ TEST_CASE("save then load round-trips all fields", "[settings]") { GoSettings original; original.measure_interval_seconds = 60; original.inactivity_timeout_seconds = 30; - original.gps_interval_seconds = 10; original.gps_mode = GpsMode::AlwaysOn; original.operating_mode = OperatingMode::Offline; original.device_name = "my-device"; @@ -226,7 +224,6 @@ TEST_CASE("save then load round-trips all fields", "[settings]") { REQUIRE(loaded.measure_interval_seconds == original.measure_interval_seconds); REQUIRE(loaded.inactivity_timeout_seconds == original.inactivity_timeout_seconds); - REQUIRE(loaded.gps_interval_seconds == original.gps_interval_seconds); REQUIRE(loaded.gps_mode == original.gps_mode); REQUIRE(loaded.operating_mode == original.operating_mode); REQUIRE(loaded.device_name == original.device_name); @@ -252,7 +249,6 @@ TEST_CASE("shared Go config fields and update model", "[settings][config]") { REQUIRE(static_cast(GoConfigField::TvocLearningOffset) == (1U << 8)); REQUIRE(static_cast(GoConfigField::NoxLearningOffset) == (1U << 9)); REQUIRE(static_cast(GoConfigField::MeasurementInterval) == (1U << 10)); - REQUIRE(static_cast(GoConfigField::GpsInterval) == (1U << 11)); REQUIRE(static_cast(GoConfigField::GpsMode) == (1U << 12)); REQUIRE(static_cast(GoConfigField::FrontLedBrightness) == (1U << 13)); REQUIRE(static_cast(GoConfigField::BackLedBrightness) == (1U << 14)); @@ -272,11 +268,6 @@ TEST_CASE("shared Go config validation covers interface-managed fields", "[setti REQUIRE_FALSE(is_measure_interval_seconds_valid(MEASURE_INTERVAL_SECONDS_MIN - 1)); REQUIRE_FALSE(is_measure_interval_seconds_valid(MEASURE_INTERVAL_SECONDS_MAX + 1)); - REQUIRE(is_gps_interval_seconds_valid(GPS_INTERVAL_SECONDS_MIN)); - REQUIRE(is_gps_interval_seconds_valid(GPS_INTERVAL_SECONDS_MAX)); - REQUIRE_FALSE(is_gps_interval_seconds_valid(GPS_INTERVAL_SECONDS_MIN - 1)); - REQUIRE_FALSE(is_gps_interval_seconds_valid(GPS_INTERVAL_SECONDS_MAX + 1)); - REQUIRE(is_gps_mode_valid(static_cast(GpsMode::AlwaysOff))); REQUIRE(is_gps_mode_valid(static_cast(GpsMode::OnWhenTracking))); REQUIRE(is_gps_mode_valid(static_cast(GpsMode::AlwaysOn))); @@ -602,17 +593,6 @@ TEST_CASE("save rejects invalid inactivity_timeout_seconds", "[settings][validat REQUIRE_FALSE(save_go_settings(store, s)); } -TEST_CASE("save rejects invalid gps_interval_seconds", "[settings][validation]") { - FakeConfigStore store; - GoSettings s; - - s.gps_interval_seconds = 0; - REQUIRE_FALSE(save_go_settings(store, s)); - - s.gps_interval_seconds = 61; - REQUIRE_FALSE(save_go_settings(store, s)); -} - TEST_CASE("save rejects invalid gps_mode", "[settings][validation]") { FakeConfigStore store; GoSettings s; @@ -693,7 +673,6 @@ TEST_CASE("load ignores invalid stored values", "[settings][validation]") { // Overwrite specific keys with invalid values store.set_int("mi", 0); // below range - store.set_int("gis", 999); // above range store.set_int("gpm", 99); // invalid enum store.set_int("opm", -1); // invalid enum store.set_int("als", 42); // not in allowed set @@ -704,7 +683,6 @@ TEST_CASE("load ignores invalid stored values", "[settings][validation]") { // All should fall back to defaults REQUIRE(loaded.measure_interval_seconds == 10); - REQUIRE(loaded.gps_interval_seconds == 5); REQUIRE(loaded.gps_mode == GpsMode::OnWhenTracking); REQUIRE(loaded.operating_mode == OperatingMode::Portable); REQUIRE(loaded.auto_lock_seconds == 10); diff --git a/products/go/tests/local-server-integration/ago_local_api.py b/products/go/tests/local-server-integration/ago_local_api.py index 1620b73d..37c2b799 100644 --- a/products/go/tests/local-server-integration/ago_local_api.py +++ b/products/go/tests/local-server-integration/ago_local_api.py @@ -50,7 +50,6 @@ "configurationControl", "measurementInterval", "gpsMode", - "gpsInterval", "frontLedBrightness", "backLedBrightness", "touchLedIntensity", @@ -66,12 +65,11 @@ "temperatureUnit": ("c", "f"), "measurementInterval": (1, 2), "gpsMode": ("off", "tracking"), - "gpsInterval": (1, 2), "frontLedBrightness": (0, 1), "backLedBrightness": (0, 1), "touchLedIntensity": (0, 1), "buzzerEnabled": (False, True), - "co2AbcDays": (-1, 1), + "co2AbcDays": (0, 1), "tvocLearningOffset": (1, 2), "noxLearningOffset": (1, 2), } @@ -232,13 +230,12 @@ def validate_config(payload: dict[str, Any]) -> None: assert payload["configurationControl"] in {"cloud", "local", "both"} _assert_integer(payload["measurementInterval"], 1, 3600) assert payload["gpsMode"] in {"off", "tracking", "always"} - _assert_integer(payload["gpsInterval"], 1, 60) _assert_integer(payload["frontLedBrightness"], 0, 3) _assert_integer(payload["backLedBrightness"], 0, 3) _assert_integer(payload["touchLedIntensity"], 0, 2) assert isinstance(payload["buzzerEnabled"], bool) - _assert_integer(payload["co2AbcDays"], -1, 200) - assert payload["co2AbcDays"] == -1 or payload["co2AbcDays"] >= 1 + _assert_integer(payload["co2AbcDays"], 0, 200) + assert payload["co2AbcDays"] == 0 or payload["co2AbcDays"] >= 1 _assert_integer(payload["tvocLearningOffset"], 1, 1000) _assert_integer(payload["noxLearningOffset"], 1, 1000) diff --git a/products/go/tests/local-server-integration/test_errors.py b/products/go/tests/local-server-integration/test_errors.py index cd366771..7e3f2a4e 100644 --- a/products/go/tests/local-server-integration/test_errors.py +++ b/products/go/tests/local-server-integration/test_errors.py @@ -45,12 +45,11 @@ def test_invalid_enum(ago_http_client: httpx.Client) -> None: pytest.param(("measurementInterval", 0), id="measurementInterval-range"), pytest.param(("measurementInterval", 1.5), id="measurementInterval-type"), pytest.param(("gpsMode", "sometimes"), id="gpsMode"), - pytest.param(("gpsInterval", 0), id="gpsInterval"), pytest.param(("frontLedBrightness", 4), id="frontLedBrightness"), pytest.param(("backLedBrightness", 4), id="backLedBrightness"), pytest.param(("touchLedIntensity", 3), id="touchLedIntensity"), pytest.param(("buzzerEnabled", 1), id="buzzerEnabled-type"), - pytest.param(("co2AbcDays", 0), id="co2AbcDays"), + pytest.param(("co2AbcDays", -1), id="co2AbcDays"), pytest.param(("tvocLearningOffset", 0), id="tvocLearningOffset"), pytest.param(("noxLearningOffset", 0), id="noxLearningOffset"), ], diff --git a/products/reference/main/test_local_server.cpp b/products/reference/main/test_local_server.cpp index b209d794..e7f90a07 100644 --- a/products/reference/main/test_local_server.cpp +++ b/products/reference/main/test_local_server.cpp @@ -227,9 +227,6 @@ class DemoConfigProvider : public ConfigProvider { if (p.gps_mode.has_value()) { return {ConfigSubmitStatus::NotSupported, ConfigFieldId::GpsMode}; } - if (p.gps_interval_seconds.has_value()) { - return {ConfigSubmitStatus::NotSupported, ConfigFieldId::GpsInterval}; - } if (p.front_led_brightness.has_value()) { return {ConfigSubmitStatus::NotSupported, ConfigFieldId::FrontLedBrightness}; }