feat: added PicoW_Sensor code template

Credits to @ext-erich.styger that provided the template
This commit is contained in:
SylvanArnold
2025-04-22 11:30:45 +02:00
committed by Sylvan Arnold
parent b2e9eab44e
commit 6cd510e749
985 changed files with 606823 additions and 0 deletions

View File

@@ -0,0 +1,627 @@
/*
* Copyright (c) 2023, Erich Styger
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Useful read: https://github.com/particle-iot/lwip/blob/master/doc/mqtt_client.txt
*/
#include "platform.h"
#if PL_CONFIG_USE_MQTT_CLIENT
#include "pico/cyw43_arch.h"
#include "lwip/apps/mqtt.h"
#include "lwip/dns.h"
#include "mqtt_client.h"
#include "dns_resolver.h"
#include "McuLog.h"
#include "McuUtility.h"
#include "McuRTOS.h"
#if PL_CONFIG_USE_MINI
#include "minIni/McuMinINI.h"
#include "MinIniKeys.h"
#endif
#if MQTT_CLIENT_IS_EV_CHARGER
#include "Modbus/McuHeidelberg.h"
#endif
#if LWIP_TCP
#define MQTT_EXTRA_LOGS (0) /* set to 1 to produce extra log output */
#if MQTT_CLIENT_IS_EV_CHARGER
/* HomeAssistant Tesla Powerwall topics */
#define TOPIC_NAME_SOLAR_POWER "homeassistant/sensor/powerwall_solar_now/state"
#define TOPIC_NAME_SITE_POWER "homeassistant/sensor/powerwall_load_now/state"
#define TOPIC_NAME_GRID_POWER "homeassistant/sensor/powerwall_site_now/state"
#define TOPIC_NAME_BATTERY_POWER "homeassistant/sensor/powerwall_battery_now/state"
#define TOPIC_NAME_BATTERY_PERCENTAGE "homeassistant/sensor/powerwall_charge/state"
#define TOPIC_NAME_CHARGER_CHARGING_POWER "home/charger/power"
#elif MQTT_CLIENT_IS_SENSOR
#define TOPIC_NAME_SENSOR_TEMPERATURE "home/roof/temperature"
#define TOPIC_NAME_SENSOR_HUMIDITY "home/roof/humidity"
#endif
typedef enum topic_ID_e {
Topic_ID_None,
#if MQTT_CLIENT_IS_EV_CHARGER
Topic_ID_Solar_Power, /* power from PV panels */
Topic_ID_Site_Power, /* power to the house/site */
Topic_ID_Grid_Power, /* power from/to grid */
Topic_ID_Battery_Power, /* power from/to battery */
Topic_ID_Battery_Percentage,/* battery level percentage */
Topic_ID_Charging_Power, /* actual charging power */
#elif MQTT_CLIENT_IS_SENSOR
Topic_ID_Sensor_Temperature,
Topic_ID_Sensor_Humidity,
#endif
} topic_ID_e;
/* default entries for the MQTT broker connection */
#define MQTT_DEFAULT_BROKER "homeassistant"
#define MQTT_DEFAULT_CLIENT "client"
#define MQTT_DEFAULT_USER "user"
#define MQTT_DEFAULT_PASS "password"
#define MQTT_DEFAULT_PUBLISH true
typedef struct mqtt_t {
mqtt_client_t *mqtt_client; /* lwIP MQTT client handle */
DnsResolver_info_t addr; /* broker lwip address, resolved by DNS if hostname is used */
unsigned char broker[32]; /* broker IP or hostname string. For hostname, DNS will be used */
unsigned char client_id[32]; /* client ID used for connection: each client should have a unique ID */
unsigned char client_user[32]; /* client user name used for connection */
unsigned char client_pass[96]; /* client user password */
topic_ID_e in_pub_ID; /* incoming published ID, set in the incoming_publish_cb and used in the incoming_data_cb */
/* configuration settings */
bool doLogging; /* if it shall write log messages */
bool doPublishing; /* if it publish messages */
} mqtt_t;
static mqtt_t mqtt; /* information used for MQTT connection */
static const struct mqtt_connect_client_info_t mqtt_client_info = {
mqtt.client_id, /* client ID */
mqtt.client_user, /* client user name */
mqtt.client_pass, /* client password */
100, /* keep alive timeout in seconds */
NULL, /* will_topic */
NULL, /* will_msg */
0, /* will_qos */
0 /* will_retain */
#if LWIP_ALTCP && LWIP_ALTCP_TLS
, NULL
#endif
};
static void mqtt_publish_request_cb(void *arg, err_t err) {
#if 0 && MQTT_EXTRA_LOGS
const struct mqtt_connect_client_info_t *client_info = (const struct mqtt_connect_client_info_t*)arg;
McuLog_trace("MQTT client \"%s\" publish request cb: err %d", client_info->client_id, (int)err);
#endif
}
#if MQTT_CLIENT_IS_SENSOR
int MqttClient_Publish_SensorValues(float temperature, float humidity) {
err_t res;
uint8_t buf[64];
const uint8_t qos = 0; /* quos: 0: fire&forget, 1: at least once */
const uint8_t retain = 0;
if (!MqttClient_GetDoPublish()) {
return ERR_DISABLED;
}
if (mqtt.mqtt_client!=NULL) { /* connected? */
if (mqtt.doLogging) {
McuLog_trace("publish t:%f h:%f", temperature, humidity);
}
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"{\"temperature\": ");
McuUtility_strcatNumFloat(buf, sizeof(buf), temperature, 2);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)", \"unit\": \"°C\"}");
res = mqtt_publish(mqtt.mqtt_client, TOPIC_NAME_SENSOR_TEMPERATURE, buf, strlen(buf), qos, retain, mqtt_publish_request_cb, NULL);
if (res!=ERR_OK) {
McuLog_error("Failed temperature mqtt_publish: %d", res);
(void)MqttClient_Disconnect(); /* try disconnect and connect again */
(void)MqttClient_Connect();
return res;
}
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"{\"humidity\": ");
McuUtility_strcatNumFloat(buf, sizeof(buf), humidity, 2);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)", \"unit\": \"%\"}");
res = mqtt_publish(mqtt.mqtt_client, TOPIC_NAME_SENSOR_HUMIDITY, buf, strlen(buf), qos, retain, mqtt_publish_request_cb, NULL);
if (res!=ERR_OK) {
McuLog_error("Failed humidity mqtt_publish: %d", res);
(void)MqttClient_Disconnect(); /* try disconnect and connect again */
(void)MqttClient_Connect();
return res;
}
return ERR_OK;
} else {
return ERR_FAILED;
}
}
#endif
#if MQTT_CLIENT_IS_EV_CHARGER
int MqttClient_Publish_ChargingPower(uint32_t powerW) {
err_t res;
uint8_t buf[64];
const uint8_t qos = 0; /* quos: 0: fire&forget, 1: at least once */
const uint8_t retain = 0;
if (!MqttClient_GetDoPublish()) {
return ERR_DISABLED;
}
if (mqtt.mqtt_client!=NULL) { /* connected? */
if (mqtt.doLogging) {
McuLog_trace("publish P: %d W", powerW);
}
McuUtility_strcpy(buf, sizeof(buf), (unsigned char*)"{\"chargeP\": ");
McuUtility_strcatNum32u(buf, sizeof(buf), powerW);
McuUtility_strcat(buf, sizeof(buf), (unsigned char*)", \"unit\": \"W\"}");
res = mqtt_publish(mqtt.mqtt_client, TOPIC_NAME_CHARGER_CHARGING_POWER, buf, strlen(buf), qos, retain, mqtt_publish_request_cb, NULL);
if (res!=ERR_OK) {
McuLog_error("Failed charging power mqtt_publish: %d", res);
(void)MqttClient_Disconnect(); /* try disconnect and connect again */
(void)MqttClient_Connect();
return res;
}
return ERR_OK;
} else {
return ERR_FAILED;
}
}
#endif
bool MqttClient_GetDoPublish(void) {
return mqtt.doPublishing && mqtt.mqtt_client!=NULL;
}
void MqttClient_SetDoPublish(bool publish) {
#if PL_CONFIG_USE_MINI
McuMinINI_ini_putl(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_PUBLISH, publish, NVMC_MININI_FILE_NAME);
#endif
mqtt.doPublishing = publish;
}
int MqttClient_Publish(const unsigned char *topic, const unsigned char *value) {
err_t res;
uint8_t buf[64];
const uint8_t qos = 0; /* quos: 0: fire&forget, 1: at least once */
const uint8_t retain = 0;
if (!MqttClient_GetDoPublish()) {
return ERR_DISABLED;
}
if (mqtt.mqtt_client!=NULL) { /* connected? */
if (mqtt.doLogging) {
McuLog_trace("publish topic: \"%s\" value: \"%s\"", topic, value);
}
res = mqtt_publish(mqtt.mqtt_client, topic, value, strlen(value), qos, retain, mqtt_publish_request_cb, NULL);
if (res!=ERR_OK) {
McuLog_error("Failed mqtt_publish: %d", res);
(void)MqttClient_Disconnect(); /* try disconnect and connect again */
(void)MqttClient_Connect();
return res;
}
return ERR_OK;
} else {
return ERR_FAILED;
}
}
static void GetDataString(unsigned char *buf, size_t bufSize, const u8_t *data, u16_t len) {
buf[0] = '\0';
for(int i=0; i<len; i++){
McuUtility_chcat(buf, bufSize, data[i]);
}
}
#if MQTT_CLIENT_IS_EV_CHARGER
static int32_t scanWattValue(const unsigned char *str) {
/* string in in kW and it returns the number in Watt, so for example:
* "1" => 1000, * "1.2" => 1200, "3.025" = 3025, "-1.002" = -1002
*/
int32_t watt;
float f;
if (sscanf(str, "%f", &f)!=1) { /* check number of conversions, shall be 1 */
McuLog_error("failed conversion of %s", str);
return 0; /* conversion failed, return 0 */
}
watt = (int)(f*1000.0f);
return watt;
}
#endif
static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags) {
const struct mqtt_connect_client_info_t *client_info = (const struct mqtt_connect_client_info_t*)arg;
LWIP_UNUSED_ARG(data);
unsigned char buf[32];
int32_t watt;
#if MQTT_EXTRA_LOGS
McuLog_trace("MQTT client \"%s\" data cb: len %d, flags %d", client_info->client_id, (int)len, (int)flags);
#endif
if(flags & MQTT_DATA_FLAG_LAST) {
/* Last fragment of payload received (or whole part if payload fits receive buffer. See MQTT_VAR_HEADER_BUFFER_LEN) */
#if MQTT_CLIENT_IS_EV_CHARGER
if (mqtt.in_pub_ID == Topic_ID_Solar_Power) {
GetDataString(buf, sizeof(buf), data, len);
if (mqtt.doLogging) {
McuLog_trace("solarP: %s kW", buf);
}
watt = scanWattValue(buf);
if (watt>=0) { /* can only be positive */
McuHeidelberg_SetSolarPowerWatt(watt);
}
} else if(mqtt.in_pub_ID == Topic_ID_Site_Power) {
GetDataString(buf, sizeof(buf), data, len);
if (mqtt.doLogging) {
McuLog_trace("siteP: %s kW", buf);
}
watt = scanWattValue(buf);
if (watt>=0) { /* can only be positive */
McuHeidelberg_SetSitePowerWatt(watt);
}
} else if(mqtt.in_pub_ID == Topic_ID_Grid_Power) {
GetDataString(buf, sizeof(buf), data, len);
if (mqtt.doLogging) {
McuLog_trace("gridP: %s kW", buf);
}
watt = scanWattValue(buf);
McuHeidelberg_SetGridPowerWatt(watt);
} else if(mqtt.in_pub_ID == Topic_ID_Battery_Power) {
GetDataString(buf, sizeof(buf), data, len);
if (mqtt.doLogging) {
McuLog_trace("battP: %s, kW", buf);
}
} else if(mqtt.in_pub_ID == Topic_ID_Battery_Percentage) {
GetDataString(buf, sizeof(buf), data, len);
if (mqtt.doLogging) {
McuLog_trace("bat%%: %s%%", buf);
}
#elif MQTT_CLIENT_IS_SENSOR
if (mqtt.in_pub_ID == Topic_ID_Sensor_Temperature) {
McuLog_trace("Temperature");
} else if (mqtt.in_pub_ID == Topic_ID_Sensor_Humidity) {
McuLog_trace("Humidity");
#endif
} else {
McuLog_trace("mqtt_incoming_data_cb: Ignoring payload...");
}
} else {
McuLog_trace("mqtt_incoming_data_cb: fragmented payload ...");
/* Handle fragmented payload, store in buffer, write to file or whatever */
}
}
static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len) {
const struct mqtt_connect_client_info_t *client_info = (const struct mqtt_connect_client_info_t*)arg;
#if MQTT_CLIENT_IS_EV_CHARGER
if (McuUtility_strcmp(topic, TOPIC_NAME_SOLAR_POWER)==0) {
mqtt.in_pub_ID = Topic_ID_Solar_Power;
} else if (McuUtility_strcmp(topic, TOPIC_NAME_SITE_POWER)==0) {
mqtt.in_pub_ID = Topic_ID_Site_Power;
} else if (McuUtility_strcmp(topic, TOPIC_NAME_GRID_POWER)==0) {
mqtt.in_pub_ID = Topic_ID_Grid_Power;
} else if (McuUtility_strcmp(topic, TOPIC_NAME_BATTERY_POWER)==0) {
mqtt.in_pub_ID = Topic_ID_Battery_Power;
} else if (McuUtility_strcmp(topic, TOPIC_NAME_BATTERY_PERCENTAGE)==0) {
mqtt.in_pub_ID = Topic_ID_Battery_Percentage;
} else if (McuUtility_strcmp(topic, TOPIC_NAME_CHARGER_CHARGING_POWER)==0) {
mqtt.in_pub_ID = Topic_ID_Charging_Power;
#elif MQTT_CLIENT_IS_SENSOR
if (McuUtility_strcmp(topic, TOPIC_NAME_SENSOR_TEMPERATURE)==0) {
mqtt.in_pub_ID = Topic_ID_Sensor_Temperature;
} else if (McuUtility_strcmp(topic, TOPIC_NAME_SENSOR_HUMIDITY)==0) {
mqtt.in_pub_ID = Topic_ID_Sensor_Humidity;
#endif
} else { /* unknown */
McuLog_trace("MQTT client \"%s\" publish cb: topic %s, len %d", client_info->client_id, topic, (int)tot_len);
mqtt.in_pub_ID = Topic_ID_None;
}
}
static void mqtt_request_cb(void *arg, err_t err) {
#if MQTT_EXTRA_LOGS
const struct mqtt_connect_client_info_t *client_info = (const struct mqtt_connect_client_info_t*)arg;
McuLog_trace("MQTT client \"%s\" request cb: err %d", client_info->client_id, (int)err);
#endif
}
static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status) {
const struct mqtt_connect_client_info_t *client_info = (const struct mqtt_connect_client_info_t*)arg;
LWIP_UNUSED_ARG(client);
err_t err;
#if MQTT_EXTRA_LOGS
McuLog_trace("MQTT client \"%s\" connection cb: status %d", client_info->client_id, (int)status);
#endif
if (status!=MQTT_CONNECT_ACCEPTED) {
McuLog_error("MQTT client \"%s\" connection cb: FAILED status %d", client_info->client_id, (int)status);
}
/* subscribe to topics */
if (status == MQTT_CONNECT_ACCEPTED) {
McuLog_trace("MQTT connect accepted");
#if MQTT_CLIENT_IS_EV_CHARGER
err = mqtt_sub_unsub(client,
TOPIC_NAME_SOLAR_POWER, /* solar P in kW */
1, /* quos: 0: fire&forget, 1: at least once */
mqtt_request_cb, /* callback */
LWIP_CONST_CAST(void*, client_info),
1 /* subscribe */
);
if (err!=ERR_OK) {
McuLog_error("failed subscribing, err %d", err);
}
err = mqtt_sub_unsub(client,
TOPIC_NAME_SITE_POWER, /* site/house P in kW */
1, /* quos */
mqtt_request_cb,
LWIP_CONST_CAST(void*, client_info),
1);
if (err!=ERR_OK) {
McuLog_error("failed subscribing, err %d", err);
}
err = mqtt_sub_unsub(client,
TOPIC_NAME_GRID_POWER, /* grid P in kW */
1, /* quos */
mqtt_request_cb,
LWIP_CONST_CAST(void*, client_info),
1);
if (err!=ERR_OK) {
McuLog_error("failed subscribing, err %d", err);
}
err = mqtt_sub_unsub(client,
TOPIC_NAME_BATTERY_POWER, /* battery P in kW */
1, /* quos */
mqtt_request_cb,
LWIP_CONST_CAST(void*, client_info),
1);
if (err!=ERR_OK) {
McuLog_error("failed subscribing, err %d", err);
}
err = mqtt_sub_unsub(client,
TOPIC_NAME_BATTERY_PERCENTAGE, /* topic: percentage of battery charge */
1, /* quos */
mqtt_request_cb, LWIP_CONST_CAST(void*, client_info),
1);
if (err!=ERR_OK) {
McuLog_error("failed subscribing, err %d", err);
}
#elif MQTT_CLIENT_IS_SENSOR
/* no subscriptions */
#endif
} else if (status==MQTT_CONNECT_DISCONNECTED) {
McuLog_trace("MQTT connect disconnect");
}
}
#endif /* LWIP_TCP */
uint8_t MqttClient_Connect(void) {
#if LWIP_TCP
int nofRetry;
mqtt.mqtt_client = mqtt_client_new(); /* create client handle */
err_t err;
if (mqtt.mqtt_client==NULL) {
McuLog_fatal("new mqtt client is NULL");
}
/* setup connection information */
#if PL_CONFIG_USE_MINI
McuMinINI_ini_gets(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_BROKER, MQTT_DEFAULT_BROKER, mqtt.broker, sizeof(mqtt.broker), NVMC_MININI_FILE_NAME);
McuMinINI_ini_gets(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_CLIENT, MQTT_DEFAULT_CLIENT, mqtt.client_id, sizeof(mqtt.client_id), NVMC_MININI_FILE_NAME);
McuMinINI_ini_gets(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_USER, MQTT_DEFAULT_USER, mqtt.client_user, sizeof(mqtt.client_user), NVMC_MININI_FILE_NAME);
McuMinINI_ini_gets(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_PASS, MQTT_DEFAULT_PASS, mqtt.client_pass, sizeof(mqtt.client_pass), NVMC_MININI_FILE_NAME);
mqtt.doPublishing = McuMinINI_ini_getbool(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_PASS, MQTT_DEFAULT_PUBLISH, NVMC_MININI_FILE_NAME);
#else
McuUtility_strcpy(mqtt.broker, sizeof(mqtt.broker), MQTT_DEFAULT_BROKER);
McuUtility_strcpy(mqtt.client_id, sizeof(mqtt.client_id), MQTT_DEFAULT_CLIENT);
McuUtility_strcpy(mqtt.client_user, sizeof(mqtt.client_user), MQTT_DEFAULT_USER);
McuUtility_strcpy(mqtt.client_pass, sizeof(mqtt.client_pass), MQTT_DEFAULT_PASS);
mqtt.doPublishing = MQTT_DEFAULT_PUBLISH;
#endif
/* resolve host name to IP address: */
for (nofRetry=60; nofRetry>=0; nofRetry--) {
if (DnsResolver_ResolveName(mqtt.broker, &mqtt.addr, 5*1000)!=0) { /* use DNS to resolve name to IP address */
McuLog_error("failed to resolve broker name %s, retry ...", mqtt.broker);
vTaskDelay(pdMS_TO_TICKS(5000));
} else {
break; /* success! leaving loop */
}
}
if (nofRetry<0) {
McuLog_fatal("failed to resolve broker name %s, giving up", mqtt.broker);
return ERR_FAILED;
}
/* setup callbacks for incoming data: */
mqtt_set_inpub_callback(
mqtt.mqtt_client, /* client handle */
mqtt_incoming_publish_cb, /* callback for incoming publish messages */
mqtt_incoming_data_cb, /* callback for incoming data */
LWIP_CONST_CAST(void*, &mqtt_client_info) /* argument for callbacks */
);
/* connect to broker */
cyw43_arch_lwip_begin(); /* start section for to lwIP access */
err = mqtt_client_connect(
mqtt.mqtt_client, /* client handle */
&mqtt.addr.resolved_addr, /* broker IP address */
MQTT_PORT, /* port to be used */
mqtt_connection_cb, LWIP_CONST_CAST(void*, &mqtt_client_info), /* connection callback with argument */
&mqtt_client_info /* client information */
);
cyw43_arch_lwip_end(); /* end section accessing lwIP */
if (err!=ERR_OK) {
McuLog_error("failed connecting client to server");
} else {
McuLog_trace("client connecting");
}
return err;
#else
return ERR_FAILED;
#endif /* LWIP_TCP */
}
uint8_t MqttClient_Disconnect(void) {
if (mqtt.mqtt_client!=NULL) {
McuLog_trace("disconnecting client");
cyw43_arch_lwip_begin(); /* start section for to lwIP access */
mqtt_disconnect(mqtt.mqtt_client);
mqtt_client_free(mqtt.mqtt_client);
cyw43_arch_lwip_end(); /* end section accessing lwIP */
mqtt.mqtt_client = NULL;
}
return ERR_OK;
}
static uint8_t SetBroker(const unsigned char *broker) {
unsigned char buf[64];
McuUtility_ScanDoubleQuotedString(&broker, buf, sizeof(buf));
McuUtility_strcpy(mqtt.broker, sizeof(mqtt.broker), buf);
#if PL_CONFIG_USE_MINI
McuMinINI_ini_puts(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_BROKER, mqtt.broker, NVMC_MININI_FILE_NAME);
#endif
return ERR_OK;
}
static uint8_t SetID(const unsigned char *id) {
unsigned char buf[64];
McuUtility_ScanDoubleQuotedString(&id, buf, sizeof(buf));
McuUtility_strcpy(mqtt.client_id, sizeof(mqtt.client_id), buf);
#if PL_CONFIG_USE_MINI
McuMinINI_ini_puts(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_CLIENT, mqtt.client_id, NVMC_MININI_FILE_NAME);
#endif
return ERR_OK;
}
static uint8_t SetUser(const unsigned char *user) {
unsigned char buf[64];
McuUtility_ScanDoubleQuotedString(&user, buf, sizeof(buf));
McuUtility_strcpy(mqtt.client_user, sizeof(mqtt.client_user), buf);
#if PL_CONFIG_USE_MINI
McuMinINI_ini_puts(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_USER, mqtt.client_user, NVMC_MININI_FILE_NAME);
#endif
return ERR_OK;
}
static uint8_t SetPassword(const unsigned char *pass) {
unsigned char buf[96];
McuUtility_ScanDoubleQuotedString(&pass, buf, sizeof(buf));
McuUtility_strcpy(mqtt.client_pass, sizeof(mqtt.client_pass), buf);
#if PL_CONFIG_USE_MINI
McuMinINI_ini_puts(NVMC_MININI_SECTION_MQTT, NVMC_MININI_KEY_MQTT_PASS, mqtt.client_pass, NVMC_MININI_FILE_NAME);
#endif
return ERR_OK;
}
static uint8_t PrintStatus(const McuShell_StdIOType *io) {
McuShell_SendStatusStr((unsigned char*)"mqttclient", (unsigned char*)"mqttclient status\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" log", mqtt.doLogging?(unsigned char*)"on\r\n":(unsigned char*)"off\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" publish", MqttClient_GetDoPublish()?(unsigned char*)"on\r\n":(unsigned char*)"off\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" client", mqtt.mqtt_client==NULL?(unsigned char*)"diconnected\r\n":(unsigned char*)"connected\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" broker", mqtt.broker, io->stdOut);
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" client ID", mqtt.client_id, io->stdOut);
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" client user", mqtt.client_user, io->stdOut);
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
McuShell_SendStatusStr((unsigned char*)" client password", mqtt.client_pass, io->stdOut);
McuShell_SendStr((unsigned char*)"\r\n", io->stdOut);
return ERR_OK;
}
static uint8_t PrintHelp(const McuShell_StdIOType *io) {
McuShell_SendHelpStr((unsigned char*)"mqttclient", (unsigned char*)"Group of mqttclient commands\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" help|status", (unsigned char*)"Print help or status information\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" log on|off", (unsigned char*)"Turn logging on or off\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" publish on|off", (unsigned char*)"Publishing on or off\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" connect|disconnect", (unsigned char*)"Connect or disconnect from server\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" set broker \"<broker>\"", (unsigned char*)"Set broker name\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" set id \"<id>\"", (unsigned char*)"Set client ID\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" set user \"<user>\"", (unsigned char*)"Set client user name\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" set pass \"<password>\"", (unsigned char*)"Set client password\r\n", io->stdOut);
McuShell_SendHelpStr((unsigned char*)" pub \"<topic>\" \"<txt>\"", (unsigned char*)"Publish text to a topic\r\n", io->stdOut);
return ERR_OK;
}
uint8_t MqttClient_ParseCommand(const unsigned char *cmd, bool *handled, const McuShell_StdIOType *io) {
const unsigned char *p;
uint16_t val16u;
if (McuUtility_strcmp((char*)cmd, McuShell_CMD_HELP)==0 || McuUtility_strcmp((char*)cmd, "mqttclient help")==0) {
*handled = true;
return PrintHelp(io);
} else if ((McuUtility_strcmp((char*)cmd, McuShell_CMD_STATUS)==0) || (McuUtility_strcmp((char*)cmd, "mqttclient status")==0)) {
*handled = true;
return PrintStatus(io);
} else if (McuUtility_strcmp((char*)cmd, "mqttclient log on")==0) {
*handled = true;
mqtt.doLogging = true;
} else if (McuUtility_strcmp((char*)cmd, "mqttclient log off")==0) {
*handled = true;
mqtt.doLogging = false;
} else if (McuUtility_strcmp((char*)cmd, "mqttclient publish on")==0) {
*handled = true;
MqttClient_SetDoPublish(true);
} else if (McuUtility_strcmp((char*)cmd, "mqttclient publish off")==0) {
*handled = true;
MqttClient_SetDoPublish(false);
} else if (McuUtility_strcmp((char*)cmd, "mqttclient connect")==0) {
*handled = true;
MqttClient_Connect();
} else if (McuUtility_strcmp((char*)cmd, "mqttclient disconnect")==0) {
*handled = true;
MqttClient_Disconnect();
} else if (McuUtility_strncmp((char*)cmd, "mqttclient set broker ", sizeof("mqttclient set broker ")-1)==0) {
*handled = TRUE;
p = cmd + sizeof("mqttclient set broker ")-1;
return SetBroker(p);
} else if (McuUtility_strncmp((char*)cmd, "mqttclient set id ", sizeof("mqttclient set id ")-1)==0) {
*handled = TRUE;
p = cmd + sizeof("mqttclient set id ")-1;
return SetID(p);
} else if (McuUtility_strncmp((char*)cmd, "mqttclient set user ", sizeof("mqttclient set user ")-1)==0) {
*handled = TRUE;
p = cmd + sizeof("mqttclient set user ")-1;
return SetUser(p);
} else if (McuUtility_strncmp((char*)cmd, "mqttclient set pass ", sizeof("mqttclient set pass ")-1)==0) {
*handled = TRUE;
p = cmd + sizeof("mqttclient set pass ")-1;
return SetPassword(p);
} else if (McuUtility_strncmp((char*)cmd, "mqttclient pub ", sizeof("mqttclient pub ")-1)==0) {
unsigned char topic[128], text[128];
*handled = TRUE;
p = cmd + sizeof("mqttclient pub ")-1;
if (McuUtility_ScanDoubleQuotedString(&p, topic, sizeof(topic))!=ERR_OK) {
return ERR_FAILED;
}
McuUtility_SkipSpaces(&p);
if (McuUtility_ScanDoubleQuotedString(&p, text, sizeof(text))!=ERR_OK) {
return ERR_FAILED;
}
return MqttClient_Publish(topic, text);
}
return ERR_OK;
}
void MqttClient_Deinit(void) {
MqttClient_Disconnect();
}
void MqttClient_Init(void) {
mqtt.doLogging = true;
mqtt.doPublishing = MQTT_DEFAULT_PUBLISH;
}
#endif /* PL_CONFIG_USE_MQTT_CLIENT */