chore: onewire
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user