Update firmware build date format and enhance MQTT timestamp handling to always emit UTC with "+00:00" offset. Adjusted buffer sizes for timestamps in MQTTMessageBuilder and MQTTBridge to accommodate new format.
This commit is contained in:
1 parent
c29ede054b
commit
b45373a31f
4 files changed
+47
-26
No files matched your search
@@ -124,8 +124,8 @@ build_firmware() {
|
||||
# get git commit sha
|
||||
COMMIT_HASH=$(git rev-parse --short HEAD)
|
||||
|
||||
# set firmware build date
|
||||
FIRMWARE_BUILD_DATE=$(date '+%d-%b-%Y')
|
||||
# set firmware build date (e.g. "6 Jun 2026"; %-d drops the leading zero on GNU date / the Linux CI runner)
|
||||
FIRMWARE_BUILD_DATE=$(date '+%-d %b %Y')
|
||||
|
||||
# get FIRMWARE_VERSION, which should be provided by the environment
|
||||
if [ -z "$FIRMWARE_VERSION" ]; then
|
||||
@@ -133,7 +133,7 @@ build_firmware() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set firmware version string
|
||||
# set firmware version string (used for the output filename)
|
||||
# e.g: v1.0.0-abcdef
|
||||
FIRMWARE_VERSION_STRING="${FIRMWARE_VERSION}-${COMMIT_HASH}"
|
||||
|
||||
@@ -141,8 +141,18 @@ build_firmware() {
|
||||
# e.g: RAK_4631_Repeater-v1.0.0-SHA
|
||||
FIRMWARE_FILENAME="$1-${FIRMWARE_VERSION_STRING}"
|
||||
|
||||
# Tag the *embedded* version for observer builds, e.g. v1.0.0-observer-abcdef,
|
||||
# so `ver`, the MQTT firmware_version/client_version, and SNMP all identify the
|
||||
# fork. The filename above is intentionally left untagged: the env name already
|
||||
# contains "observer", and the web flasher keys off that existing pattern.
|
||||
VARIANT_TAG=""
|
||||
case "$1" in
|
||||
*observer*) VARIANT_TAG="-observer" ;;
|
||||
esac
|
||||
EMBEDDED_VERSION_STRING="${FIRMWARE_VERSION}${VARIANT_TAG}-${COMMIT_HASH}"
|
||||
|
||||
# add firmware version info to end of existing platformio build flags in environment vars
|
||||
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFIRMWARE_BUILD_DATE='\"${FIRMWARE_BUILD_DATE}\"' -DFIRMWARE_VERSION='\"${FIRMWARE_VERSION_STRING}\"'"
|
||||
export PLATFORMIO_BUILD_FLAGS="${PLATFORMIO_BUILD_FLAGS} -DFIRMWARE_BUILD_DATE='\"${FIRMWARE_BUILD_DATE}\"' -DFIRMWARE_VERSION='\"${EMBEDDED_VERSION_STRING}\"'"
|
||||
|
||||
# disable debug flags if requested
|
||||
disable_debug_flags
|
||||
|
||||
@@ -7,12 +7,15 @@
|
||||
|
||||
void MQTTMessageBuilder::formatIsoTimestampForMqtt(time_t now, Timezone* timezone, char* buffer, size_t buffer_size) {
|
||||
if (!buffer || buffer_size == 0) return;
|
||||
time_t local_wall = timezone ? timezone->toLocal(now) : now;
|
||||
struct tm* tm_info = localtime(&local_wall);
|
||||
if (tm_info && strftime(buffer, buffer_size, "%Y-%m-%dT%H:%M:%S.000000", tm_info) > 0) {
|
||||
// Always emit UTC with an explicit "+00:00" offset, matching Python's
|
||||
// datetime.now(timezone.utc).isoformat(). The system clock is UTC (SNTP offset 0),
|
||||
// so gmtime() is correct regardless of the prefs Timezone (now unused here).
|
||||
(void)timezone;
|
||||
struct tm* tm_info = gmtime(&now);
|
||||
if (tm_info && strftime(buffer, buffer_size, "%Y-%m-%dT%H:%M:%S.000000+00:00", tm_info) > 0) {
|
||||
return;
|
||||
}
|
||||
strncpy(buffer, "2024-01-01T12:00:00.000000", buffer_size - 1);
|
||||
strncpy(buffer, "2024-01-01T12:00:00.000000+00:00", buffer_size - 1);
|
||||
buffer[buffer_size - 1] = '\0';
|
||||
}
|
||||
|
||||
@@ -195,7 +198,7 @@ int MQTTMessageBuilder::buildPacketJSON(
|
||||
if (!packet) return 0;
|
||||
|
||||
time_t now = time(nullptr);
|
||||
char timestamp[32];
|
||||
char timestamp[40];
|
||||
formatIsoTimestampForMqtt(now, timezone, timestamp, sizeof(timestamp));
|
||||
|
||||
// Packet time/date: UTC (gmtime), same family as meshcoretomqtt serial fields
|
||||
@@ -268,7 +271,7 @@ int MQTTMessageBuilder::buildPacketJSONFromRaw(
|
||||
if (!packet || !raw_data || raw_len <= 0) return 0;
|
||||
|
||||
time_t now = time(nullptr);
|
||||
char timestamp[32];
|
||||
char timestamp[40];
|
||||
formatIsoTimestampForMqtt(now, timezone, timestamp, sizeof(timestamp));
|
||||
|
||||
struct tm* utc_timeinfo = gmtime(&now);
|
||||
@@ -334,7 +337,7 @@ int MQTTMessageBuilder::buildRawJSON(
|
||||
if (!packet) return 0;
|
||||
|
||||
time_t now = time(nullptr);
|
||||
char timestamp[32];
|
||||
char timestamp[40];
|
||||
formatIsoTimestampForMqtt(now, timezone, timestamp, sizeof(timestamp));
|
||||
|
||||
// Convert packet to hex
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
* into JSON messages for MQTT publishing according to the MeshCore
|
||||
* packet capture specification.
|
||||
*
|
||||
* Timestamps in JSON use the configured Timezone (prefs) for status, packet, and
|
||||
* raw topics. Packet payloads also include separate `time` and `date` strings in
|
||||
* UTC (gmtime) so they stay aligned with meshcoretomqtt serial regex fields.
|
||||
* Timestamps in the JSON `timestamp` field are emitted in UTC with an explicit
|
||||
* "+00:00" offset (equivalent to Python datetime.now(timezone.utc).isoformat()) for
|
||||
* status, packet, and raw topics. Packet payloads also include separate `time` and
|
||||
* `date` strings in UTC (gmtime) so they stay aligned with meshcoretomqtt serial
|
||||
* regex fields.
|
||||
*/
|
||||
class MQTTMessageBuilder {
|
||||
private:
|
||||
@@ -23,9 +25,10 @@ private:
|
||||
public:
|
||||
/**
|
||||
* Format the MQTT JSON `timestamp` field (same rule for status, packet, raw).
|
||||
* Applies Timezone prefs via `timezone->toLocal(now)`; if timezone is nullptr,
|
||||
* uses `now` unchanged. Output is naive local wall time, ISO-like
|
||||
* "%Y-%m-%dT%H:%M:%S.000000".
|
||||
* Always UTC with an explicit "+00:00" offset, ISO-8601
|
||||
* "%Y-%m-%dT%H:%M:%S.000000+00:00" (matches Python
|
||||
* datetime.now(timezone.utc).isoformat()). The `timezone` parameter is retained
|
||||
* for API compatibility but ignored — the system clock is UTC.
|
||||
*/
|
||||
static void formatIsoTimestampForMqtt(time_t now, Timezone* timezone, char* buffer, size_t buffer_size);
|
||||
|
||||
|
||||
@@ -1706,11 +1706,11 @@ void MQTTBridge::publishStatusToSlot(int index) {
|
||||
#endif
|
||||
|
||||
char origin_id[65];
|
||||
char timestamp[32];
|
||||
char timestamp[40];
|
||||
char radio_info[64];
|
||||
|
||||
// Status timestamp: same prefs-based wall clock as packet/raw JSON `timestamp`
|
||||
// (not libc getLocalTime — SNTP uses UTC offset 0; prefs Timezone is separate).
|
||||
// Status timestamp: UTC with explicit +00:00 offset, same as packet/raw JSON
|
||||
// `timestamp` (system clock is UTC — SNTP offset 0; prefs Timezone is separate).
|
||||
MQTTMessageBuilder::formatIsoTimestampForMqtt(time(nullptr), _timezone, timestamp, sizeof(timestamp));
|
||||
|
||||
snprintf(radio_info, sizeof(radio_info), "%.6f,%.1f,%d,%d",
|
||||
@@ -2412,11 +2412,11 @@ bool MQTTBridge::publishStatus() {
|
||||
char* json_buffer = _status_json_buffer;
|
||||
#endif
|
||||
char origin_id[65];
|
||||
char timestamp[32];
|
||||
char timestamp[40];
|
||||
char radio_info[64];
|
||||
|
||||
// Status timestamp: same prefs-based wall clock as packet/raw JSON `timestamp`
|
||||
// (not libc getLocalTime — SNTP uses UTC offset 0; prefs Timezone is separate).
|
||||
// Status timestamp: UTC with explicit +00:00 offset, same as packet/raw JSON
|
||||
// `timestamp` (system clock is UTC — SNTP offset 0; prefs Timezone is separate).
|
||||
MQTTMessageBuilder::formatIsoTimestampForMqtt(time(nullptr), _timezone, timestamp, sizeof(timestamp));
|
||||
|
||||
snprintf(radio_info, sizeof(radio_info), "%.6f,%.1f,%d,%d",
|
||||
@@ -3085,9 +3085,14 @@ void MQTTBridge::optimizeMqttClientConfig(PsychicMqttClient* client, bool needs_
|
||||
esp_mqtt_client_config_t* config = client->getMqttConfig();
|
||||
if (config) {
|
||||
#if defined(ESP_IDF_VERSION_MAJOR) && ESP_IDF_VERSION_MAJOR >= 5
|
||||
if (config->buffer.out_size == 0 || config->buffer.out_size > MQTT_CLIENT_BUFFER_SIZE) {
|
||||
config->buffer.out_size = MQTT_CLIENT_BUFFER_SIZE;
|
||||
}
|
||||
// Keep the output buffer (used to build the CONNECT/PUBLISH frames) in lockstep
|
||||
// with the input buffer. setBufferSize() above only sets buffer.size, so out_size
|
||||
// must be set here. The previous conditional only ever shrank out_size or set it
|
||||
// from 0 — when a slot was reconfigured from a small non-JWT buffer (512) up to
|
||||
// the JWT buffer (896), out_size stayed at 512 and the JWT CONNECT frame (username
|
||||
// + ~537-768B token) overflowed it, producing esp-mqtt "Connect message cannot be
|
||||
// created". Always matching MQTT_CLIENT_BUFFER_SIZE fixes the grow case.
|
||||
config->buffer.out_size = MQTT_CLIENT_BUFFER_SIZE;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user