114 lines
4 KiB
C
114 lines
4 KiB
C
/**
|
|
* MQTT Client to publish sensor data to homeassistant
|
|
* MQTT client doc: https://www.nongnu.org/lwip/2_1_x/group__mqtt.html#gafdfa0e65b217e92835d35858924565cf
|
|
* PICO W MQTT example: https://github.com/raspberrypi/pico-examples/blob/master/pico_w/wifi/mqtt/README
|
|
*/
|
|
|
|
#include "mqtt_client.h"
|
|
#include "pico/stdlib.h"
|
|
#include "pico/cyw43_arch.h"
|
|
#include "lwip/apps/mqtt.h"
|
|
// #include <cstdio>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
// keep alive in seconds
|
|
#define MQTT_KEEP_ALIVE_S 60
|
|
|
|
// qos passed to mqtt_subscribe
|
|
// At most once (QoS 0)
|
|
// At least once (QoS 1)
|
|
// Exactly once (QoS 2)
|
|
#define MQTT_PUBLISH_QOS 1
|
|
#define MQTT_PUBLISH_RETAIN 0
|
|
|
|
static void pub_request_cb(__unused void *arg, err_t err) {
|
|
if (err != 0) {
|
|
printf("pub_request_cb failed %d", err);
|
|
}
|
|
}
|
|
|
|
// static void publish_temperature(MQTT_CLIENT_DATA_T *state) {
|
|
// mqtt_publish(state->mqtt_client_inst, MQTT_TOPIC, temp_str, strlen(temp_str), MQTT_PUBLISH_QOS, MQTT_PUBLISH_RETAIN, pub_request_cb, state);
|
|
|
|
|
|
static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status) {
|
|
MQTT_CLIENT_DATA_T* state = (MQTT_CLIENT_DATA_T*)arg;
|
|
if (status == MQTT_CONNECT_ACCEPTED) {
|
|
state->connect_done = true;
|
|
printf("Connected to MQTT server\n");
|
|
} else if (status == MQTT_CONNECT_DISCONNECTED) {
|
|
if (!state->connect_done) {
|
|
panic("Failed to connect to mqtt server");
|
|
}
|
|
}
|
|
else {
|
|
panic("Unexpected status");
|
|
}
|
|
}
|
|
|
|
static void start_client(MQTT_CLIENT_DATA_T *state) {
|
|
const int port = MQTT_PORT;
|
|
state->mqtt_client_inst = mqtt_client_new();
|
|
if (!state->mqtt_client_inst) {
|
|
panic("MQTT client instance creation error");
|
|
}
|
|
printf("IP address of this device %s\n", ipaddr_ntoa(&(netif_list->ip_addr)));
|
|
printf("Connecting to mqtt server at %s\n", ipaddr_ntoa(&state->mqtt_server_address));
|
|
|
|
cyw43_arch_lwip_begin();
|
|
if (mqtt_client_connect(state->mqtt_client_inst, &state->mqtt_server_address, port, mqtt_connection_cb, state, &state->mqtt_client_info) != ERR_OK) {
|
|
panic("MQTT broker connection error");
|
|
}
|
|
cyw43_arch_lwip_end();
|
|
}
|
|
|
|
void mqtt_client_pub_message(mqtt_client_config *config, const char *message) {
|
|
if (mqtt_publish(config->state.mqtt_client_inst, config->topic, message, strlen(message), MQTT_PUBLISH_QOS, MQTT_PUBLISH_RETAIN, pub_request_cb, NULL) != ERR_OK) {
|
|
panic("MQTT publish error");
|
|
}
|
|
}
|
|
|
|
void mqtt_client_init(mqtt_client_config *config, const char *topic, const char *device_name) {
|
|
// Copy the topic string into the config struct, up to 200 characters
|
|
strncpy(config->topic, topic, 100);
|
|
// config->topic[100] = '\0'; // Ensure null-termination
|
|
strncpy(config->device_name, device_name, 50);
|
|
printf("mqtt client starting\n");
|
|
if (cyw43_arch_init()) {
|
|
panic("Failed to inizialize CYW43");
|
|
}
|
|
|
|
config->state.mqtt_client_info.client_id = config->device_name;
|
|
config->state.mqtt_client_info.keep_alive = MQTT_KEEP_ALIVE_S; // Keep alive in sec
|
|
config->state.mqtt_client_info.client_user = MQTT_USERNAME;
|
|
config->state.mqtt_client_info.client_pass = MQTT_PASSWORD;
|
|
ip_addr_t ip_addr;
|
|
// Initialize the IP address
|
|
if (ipaddr_aton(MQTT_SERVER, &ip_addr)) {
|
|
printf("IP address is valid and initialized.\n");
|
|
} else {
|
|
printf("Invalid IP address format.\n");
|
|
}
|
|
config->state.mqtt_server_address = ip_addr;
|
|
|
|
cyw43_arch_enable_sta_mode();
|
|
if (cyw43_arch_wifi_connect_timeout_ms(WIFI_SSID, WIFI_PASSWORD, CYW43_AUTH_WPA2_AES_PSK, 30000)) {
|
|
panic("Failed to connect");
|
|
}
|
|
printf("\nConnected to Wifi\n");
|
|
|
|
start_client(&config->state);
|
|
|
|
// while (!config->state.connect_done || mqtt_client_is_connected(config->state.mqtt_client_inst)) {
|
|
// cyw43_arch_poll();
|
|
// cyw43_arch_wait_for_work_until(make_timeout_time_ms(10000));
|
|
// }
|
|
// printf("mqtt client exiting\n");
|
|
// return 0;
|
|
}
|
|
|
|
void mqtt_client_do_network_stuff(mqtt_client_config *config) {
|
|
cyw43_arch_poll();
|
|
}
|