Refactor LoRa protocol to batch+ack with ACK-based time bootstrap
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
bool compressBuffer(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_max, size_t &out_len);
|
||||
bool decompressBuffer(const uint8_t *in, size_t in_len, uint8_t *out, size_t out_max, size_t &out_len);
|
||||
@@ -7,21 +7,11 @@ enum class DeviceRole : uint8_t {
|
||||
Receiver = 1
|
||||
};
|
||||
|
||||
enum class PayloadType : uint8_t {
|
||||
MeterData = 0,
|
||||
TestCode = 1,
|
||||
TimeSync = 2,
|
||||
MeterBatch = 3,
|
||||
Ack = 4
|
||||
};
|
||||
|
||||
enum class BatchRetryPolicy : uint8_t {
|
||||
Keep = 0,
|
||||
Drop = 1
|
||||
};
|
||||
|
||||
constexpr uint8_t PROTOCOL_VERSION = 1;
|
||||
|
||||
// Pin definitions
|
||||
constexpr uint8_t PIN_LORA_SCK = 5;
|
||||
constexpr uint8_t PIN_LORA_MISO = 19;
|
||||
@@ -57,17 +47,7 @@ constexpr uint8_t LORA_PREAMBLE_LEN = 8;
|
||||
|
||||
// Timing
|
||||
constexpr uint32_t SENDER_WAKE_INTERVAL_SEC = 30;
|
||||
constexpr uint32_t TIME_SYNC_INTERVAL_SEC = 60;
|
||||
constexpr uint32_t TIME_SYNC_SLOW_INTERVAL_SEC = 3600;
|
||||
constexpr uint32_t TIME_SYNC_FAST_WINDOW_MS = 10UL * 60UL * 1000UL;
|
||||
constexpr uint32_t SENDER_TIMESYNC_WINDOW_MS = 300;
|
||||
constexpr uint32_t SENDER_TIMESYNC_CHECK_SEC_FAST = 60;
|
||||
constexpr uint32_t SENDER_TIMESYNC_CHECK_SEC_SLOW = 3600;
|
||||
constexpr uint32_t TIME_SYNC_DRIFT_THRESHOLD_SEC = 10;
|
||||
constexpr uint32_t TIME_SYNC_BURST_INTERVAL_MS = 10000;
|
||||
constexpr uint32_t TIME_SYNC_BURST_DURATION_MS = 10UL * 60UL * 1000UL;
|
||||
constexpr uint32_t TIME_SYNC_ERROR_TIMEOUT_MS = 2UL * 24UL * 60UL * 60UL * 1000UL;
|
||||
constexpr bool ENABLE_DS3231 = true;
|
||||
constexpr uint32_t SYNC_REQUEST_INTERVAL_MS = 15000;
|
||||
constexpr uint32_t OLED_PAGE_INTERVAL_MS = 4000;
|
||||
constexpr uint32_t OLED_AUTO_OFF_MS = 10UL * 60UL * 1000UL;
|
||||
constexpr uint32_t SENDER_OLED_READ_MS = 10000;
|
||||
@@ -107,6 +87,7 @@ constexpr const char *WEB_AUTH_DEFAULT_USER = "admin";
|
||||
constexpr const char *WEB_AUTH_DEFAULT_PASS = "admin";
|
||||
|
||||
constexpr uint8_t NUM_SENDERS = 1;
|
||||
constexpr uint32_t MIN_ACCEPTED_EPOCH_UTC = 1769904000UL; // 2026-02-01 00:00:00 UTC
|
||||
inline constexpr uint16_t EXPECTED_SENDER_IDS[NUM_SENDERS] = {
|
||||
0xF19C //433mhz sender
|
||||
//0x7EB4 //868mhz sender
|
||||
|
||||
@@ -6,19 +6,16 @@ enum class FaultType : uint8_t {
|
||||
None = 0,
|
||||
MeterRead = 1,
|
||||
Decode = 2,
|
||||
LoraTx = 3,
|
||||
TimeSync = 4
|
||||
LoraTx = 3
|
||||
};
|
||||
|
||||
enum class RxRejectReason : uint8_t {
|
||||
None = 0,
|
||||
CrcFail = 1,
|
||||
BadProtocol = 2,
|
||||
WrongRole = 3,
|
||||
WrongPayloadType = 4,
|
||||
LengthMismatch = 5,
|
||||
DeviceIdMismatch = 6,
|
||||
BatchIdMismatch = 7
|
||||
InvalidMsgKind = 2,
|
||||
LengthMismatch = 3,
|
||||
DeviceIdMismatch = 4,
|
||||
BatchIdMismatch = 5
|
||||
};
|
||||
|
||||
struct FaultCounters {
|
||||
|
||||
@@ -4,7 +4,3 @@
|
||||
#include "data_model.h"
|
||||
|
||||
bool meterDataToJson(const MeterData &data, String &out_json);
|
||||
bool jsonToMeterData(const String &json, MeterData &data);
|
||||
bool meterBatchToJson(const MeterData *samples, size_t count, uint16_t batch_id, String &out_json,
|
||||
const FaultCounters *faults = nullptr, FaultType last_error = FaultType::None);
|
||||
bool jsonToMeterBatch(const String &json, MeterData *out_samples, size_t max_count, size_t &out_count);
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
|
||||
constexpr size_t LORA_MAX_PAYLOAD = 230;
|
||||
|
||||
enum class LoraMsgKind : uint8_t {
|
||||
BatchUp = 0,
|
||||
AckDown = 1
|
||||
};
|
||||
|
||||
struct LoraPacket {
|
||||
uint8_t protocol_version;
|
||||
DeviceRole role;
|
||||
LoraMsgKind msg_kind;
|
||||
uint16_t device_id_short;
|
||||
PayloadType payload_type;
|
||||
uint8_t payload[LORA_MAX_PAYLOAD];
|
||||
size_t payload_len;
|
||||
int16_t rssi_dbm;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
bool rtc_ds3231_init();
|
||||
bool rtc_ds3231_is_present();
|
||||
bool rtc_ds3231_read_epoch(uint32_t &epoch_utc);
|
||||
bool rtc_ds3231_set_epoch(uint32_t epoch_utc);
|
||||
@@ -1,17 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "lora_transport.h"
|
||||
|
||||
void time_receiver_init(const char *ntp_server_1, const char *ntp_server_2);
|
||||
uint32_t time_get_utc();
|
||||
bool time_is_synced();
|
||||
void time_set_utc(uint32_t epoch);
|
||||
bool time_send_timesync(uint16_t device_id_short);
|
||||
bool time_handle_timesync_payload(const uint8_t *payload, size_t len);
|
||||
void time_get_local_hhmm(char *out, size_t out_len);
|
||||
void time_rtc_init();
|
||||
bool time_try_load_from_rtc();
|
||||
bool time_rtc_present();
|
||||
uint32_t time_get_last_sync_utc();
|
||||
uint32_t time_get_last_sync_age_sec();
|
||||
|
||||
Reference in New Issue
Block a user