chore: onewire

This commit is contained in:
2024-11-11 01:31:19 +06:00
parent 39f7755477
commit 8fe50deeed
16 changed files with 1180 additions and 66 deletions

View File

@@ -6,6 +6,7 @@
#include "debug.h"
#include "modbus_handler.h"
#include "onewire_temp.h"
#include "systick.h"
// MQTT
@@ -19,11 +20,12 @@
#define HOMIE_STATE_LOST "lost"
#define HOMIE_STATE_SLEEPING "sleeping"
#define HOMIE_STATE_DISCONNECTED "disconnected"
#define MAX_PAYLOAD_LENGTH 256
// nodes list buffer
char nodes_list[MAX_PAYLOAD_LENGTH];
// Parse Homie topic format: homie/node-id/device-name/property/[set|get]
// Returns: 1 if successful, 0 if invalid format or buffer overflow
static uint8_t parse_homie_topic(const char* topic, size_t topic_len,
static bool parse_homie_topic(const char* topic, size_t topic_len,
char* device_name, size_t name_max,
char* property, size_t prop_max,
uint8_t* is_set) {
@@ -34,11 +36,11 @@ static uint8_t parse_homie_topic(const char* topic, size_t topic_len,
// Skip first three segments (homie/node-id/device-name/)
while (segment < 3 && segment_start < topic_end) {
const char* slash = memchr(segment_start, '/', topic_end - segment_start);
if (!slash) return 0;
if (!slash) return false;
if (segment == 2) {
size_t len = slash - segment_start;
if (len >= name_max) return 0;
if (len >= name_max) return false;
memcpy(device_name, segment_start, len);
device_name[len] = '\0';
}
@@ -48,19 +50,19 @@ static uint8_t parse_homie_topic(const char* topic, size_t topic_len,
}
const char* slash = memchr(segment_start, '/', topic_end - segment_start);
if (!slash) return 0;
if (!slash) return false;
size_t len = slash - segment_start;
if (len >= prop_max) return 0;
if (len >= prop_max) return false;
memcpy(property, segment_start, len);
property[len] = '\0';
segment_start = slash + 1;
if (segment_start >= topic_end) return 0; // Missing set/get
if (segment_start >= topic_end) return false; // Missing set/get
*is_set = (*segment_start == 's');
return 1;
return true;
}
// MQTT client
@@ -138,14 +140,12 @@ void publish_message(MQTTClient* client, const char* payload,
if (MQTTPublish(client, topic, &message) != 0) {
DEBUG_PRINT("Publish failed\n");
} else {
DEBUG_PRINT("Message published successfully\n");
}
}
// publish retained messages
static void publish_retained(MQTTClient* client, const char* topic,
const char* payload) {
void publish_retained(MQTTClient* client, const char* topic,
const char* payload) {
MQTTMessage message = {.qos = QOS1,
.retained = 1,
.dup = 0,
@@ -157,7 +157,7 @@ static void publish_retained(MQTTClient* client, const char* topic,
}
}
// Send state update
// TODO: this is a modbus value only
void publish_value(MQTTClient* client, const char* device_name,
const char* property, uint16_t value) {
DEBUG_PRINT("publish_value(device_name=%s, property=%s, value=%u)\n",
@@ -192,7 +192,6 @@ void publish_value(MQTTClient* client, const char* device_name,
static void publish_device_attributes(MQTTClient* client) {
char topic[MAX_TOPIC_LENGTH];
static char nodes_list[MAX_PAYLOAD_LENGTH];
char* ptr = nodes_list;
size_t remaining = sizeof(nodes_list);
@@ -208,6 +207,7 @@ static void publish_device_attributes(MQTTClient* client) {
ptr = nodes_list;
*ptr = '\0';
// add rs485 devices
for (int i = 0; i < RS485_DEVICE_COUNT; i++) {
if (i > 0 && remaining > 1) {
*ptr++ = ',';
@@ -231,8 +231,8 @@ static void publish_device_attributes(MQTTClient* client) {
}
}
static void publish_node_attributes(MQTTClient* client,
const rs485_device_t* device) {
static void publish_rs485_node_attributes(MQTTClient* client,
const rs485_device_t* device) {
char topic[MAX_TOPIC_LENGTH];
// Node base attributes
@@ -304,7 +304,7 @@ void mqtt_init(mqtt_state_t* state) {
state->opts.qos = QOS1;
state->last_reconnect = 0;
state->last_yield = 0;
state->is_connected = 0;
state->is_connected = false;
}
// Find device by name and return its index
@@ -366,14 +366,19 @@ void mqtt_process(mqtt_state_t* state) {
rc = setup_mqtt_client(&state->network, &state->opts, &state->client);
if (rc == 0) {
state->is_connected = 1;
state->is_connected = true;
if (!discovery_published) {
publish_device_attributes(&state->client);
for (int i = 0; i < RS485_DEVICE_COUNT; i++) {
publish_node_attributes(&state->client, &RS485_DEVICES[i]);
publish_rs485_node_attributes(&state->client, &RS485_DEVICES[i]);
}
// with onewire we can discover new devices on the bus during runtime
// is it worth implementing?
onewire_temp_publish_discovery(&state->client, NODE_CONFIG.id);
discovery_published = 1;
}
@@ -384,7 +389,7 @@ void mqtt_process(mqtt_state_t* state) {
rc = subscribe_to_topic(&state->client, sub_topic, QOS1,
message_arrived);
if (rc != 0) {
state->is_connected = 0;
state->is_connected = false;
}
}
state->last_reconnect = now;
@@ -392,7 +397,7 @@ void mqtt_process(mqtt_state_t* state) {
} else if (now - state->last_yield >= MQTT_YIELD_INTERVAL) {
rc = MQTTYield(&state->client, MQTT_MAX_PACKET_WAIT);
if (rc != 0) {
state->is_connected = 0;
state->is_connected = false;
}
state->last_yield = now;
}