ESP-MQTT
This commit is contained in:
@@ -123,18 +123,6 @@ void NukiNetwork::setupDevice()
|
||||
|
||||
Log->print(F("Network device: "));
|
||||
Log->print(_device->deviceName());
|
||||
|
||||
|
||||
#ifndef NUKI_HUB_UPDATER
|
||||
_device->mqttOnConnect([&](bool sessionPresent)
|
||||
{
|
||||
onMqttConnect(sessionPresent);
|
||||
});
|
||||
_device->mqttOnDisconnect([&](espMqttClientTypes::DisconnectReason reason)
|
||||
{
|
||||
onMqttDisconnect(reason);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void NukiNetwork::reconfigureDevice()
|
||||
@@ -242,55 +230,128 @@ void NukiNetwork::initialize()
|
||||
}
|
||||
}
|
||||
|
||||
Log->print(F("MQTT Broker: "));
|
||||
Log->print(_mqttBrokerAddr);
|
||||
Log->print(F(":"));
|
||||
Log->println(_mqttPort);
|
||||
|
||||
_device->mqttSetClientId(_hostnameArr);
|
||||
_device->mqttSetCleanSession(MQTT_CLEAN_SESSIONS);
|
||||
_device->mqttSetKeepAlive(MQTT_KEEP_ALIVE);
|
||||
|
||||
char gpioPath[250];
|
||||
bool rebGpio = rebuildGpio();
|
||||
|
||||
if(rebGpio)
|
||||
if(strcmp(_mqttBrokerAddr, "") == 0)
|
||||
{
|
||||
Log->println(F("Rebuild MQTT GPIO structure"));
|
||||
Log->println(F("MQTT Broker not configured, aborting connection attempt."));
|
||||
}
|
||||
for (const auto &pinEntry: _gpio->pinConfiguration())
|
||||
else
|
||||
{
|
||||
switch (pinEntry.role)
|
||||
Log->print(F("MQTT Broker: "));
|
||||
Log->print(_mqttBrokerAddr);
|
||||
Log->print(F(":"));
|
||||
Log->println(_mqttPort);
|
||||
|
||||
esp_mqtt_client_config_t mqtt_cfg = { 0 };
|
||||
|
||||
mqtt_cfg.credentials.client_id = _hostnameArr;
|
||||
mqtt_cfg.session.disable_clean_session = !MQTT_CLEAN_SESSIONS;
|
||||
mqtt_cfg.session.keepalive = MQTT_KEEP_ALIVE;
|
||||
|
||||
size_t caLength = _preferences->getString(preference_mqtt_ca, _ca, TLS_CA_MAX_SIZE);
|
||||
size_t crtLength = _preferences->getString(preference_mqtt_crt, _cert, TLS_CERT_MAX_SIZE);
|
||||
size_t keyLength = _preferences->getString(preference_mqtt_key, _key, TLS_KEY_MAX_SIZE);
|
||||
|
||||
if(caLength > 1)
|
||||
{
|
||||
case PinRole::GeneralInputPullDown:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
if(rebGpio)
|
||||
{
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_role});
|
||||
publishString(_lockPath.c_str(), gpioPath, "input", false);
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_state});
|
||||
publishString(_lockPath.c_str(), gpioPath, std::to_string(digitalRead(pinEntry.pin)).c_str(), false);
|
||||
}
|
||||
break;
|
||||
case PinRole::GeneralOutput:
|
||||
if(rebGpio)
|
||||
{
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_role});
|
||||
publishString(_lockPath.c_str(), gpioPath, "output", false);
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_state});
|
||||
publishString(_lockPath.c_str(), gpioPath, "0", false);
|
||||
}
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_state});
|
||||
subscribe(_lockPath.c_str(), gpioPath);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
Log->println(F("MQTT over TLS."));
|
||||
|
||||
mqtt_cfg.broker.address.uri = ((String)"mqtts://" + _preferences->getString(preference_mqtt_broker, "") + ":" + _preferences->getString(preference_mqtt_broker_port, "8883")).c_str();
|
||||
mqtt_cfg.broker.verification.certificate = _ca;
|
||||
|
||||
if(crtLength > 1 && keyLength > 1) // length is 1 when empty
|
||||
{
|
||||
Log->println(F("MQTT with client certificate."));
|
||||
mqtt_cfg.credentials.authentication.certificate = _cert;
|
||||
mqtt_cfg.credentials.authentication.key = _key;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->println(F("MQTT without TLS."));
|
||||
mqtt_cfg.broker.address.uri = ((String)"mqtt://" + _preferences->getString(preference_mqtt_broker, "") + ":" + _preferences->getString(preference_mqtt_broker_port, "1883")).c_str();
|
||||
}
|
||||
|
||||
if(strlen(_mqttUser) == 0)
|
||||
{
|
||||
Log->println(F("MQTT: Connecting without credentials"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->print(F("MQTT: Connecting with user: ")); Log->println(_mqttUser);
|
||||
mqtt_cfg.credentials.username = _mqttUser;
|
||||
mqtt_cfg.credentials.authentication.password = _mqttPass;
|
||||
}
|
||||
|
||||
mqtt_cfg.session.last_will.topic = _mqttConnectionStateTopic;
|
||||
mqtt_cfg.session.last_will.msg = _lastWillPayload;
|
||||
mqtt_cfg.session.last_will.msg_len = sizeof(_lastWillPayload);
|
||||
mqtt_cfg.session.last_will.qos = 1;
|
||||
mqtt_cfg.session.last_will.retain = true;
|
||||
|
||||
esp_mqtt_client_handle_t _mqttClient = esp_mqtt_client_init(&mqtt_cfg);
|
||||
esp_mqtt_client_register_event(_mqttClient, (esp_mqtt_event_id_t)ESP_EVENT_ANY_ID, mqtt_event_handler_cb, NULL);
|
||||
|
||||
Log->println(F("Attempting MQTT connection"));
|
||||
esp_mqtt_client_start(_mqttClient);
|
||||
|
||||
if(_preferences->getBool(preference_mqtt_log_enabled, false) || _preferences->getBool(preference_webserial_enabled, false))
|
||||
{
|
||||
MqttLoggerMode mode;
|
||||
|
||||
if(_preferences->getBool(preference_mqtt_log_enabled, false) && _preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::MqttAndSerialAndWeb;
|
||||
else if (_preferences->getBool(preference_webserial_enabled, false)) mode = MqttLoggerMode::SerialAndWeb;
|
||||
else mode = MqttLoggerMode::MqttAndSerial;
|
||||
|
||||
char* _path = new char[200];
|
||||
memset(_path, 0, sizeof(_path));
|
||||
|
||||
String pathStr = _preferences->getString(preference_mqtt_lock_path);
|
||||
pathStr.concat(mqtt_topic_log);
|
||||
strcpy(_path, pathStr.c_str());
|
||||
Log = new MqttLogger(_mqttClient, _path, mode);
|
||||
}
|
||||
|
||||
char gpioPath[250];
|
||||
bool rebGpio = rebuildGpio();
|
||||
|
||||
if(rebGpio)
|
||||
{
|
||||
Log->println(F("Rebuild MQTT GPIO structure"));
|
||||
}
|
||||
for (const auto &pinEntry: _gpio->pinConfiguration())
|
||||
{
|
||||
switch (pinEntry.role)
|
||||
{
|
||||
case PinRole::GeneralInputPullDown:
|
||||
case PinRole::GeneralInputPullUp:
|
||||
if(rebGpio)
|
||||
{
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_role});
|
||||
publishString(_lockPath.c_str(), gpioPath, "input", false);
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_state});
|
||||
publishString(_lockPath.c_str(), gpioPath, std::to_string(digitalRead(pinEntry.pin)).c_str(), false);
|
||||
}
|
||||
break;
|
||||
case PinRole::GeneralOutput:
|
||||
if(rebGpio)
|
||||
{
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_role});
|
||||
publishString(_lockPath.c_str(), gpioPath, "output", false);
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_state});
|
||||
publishString(_lockPath.c_str(), gpioPath, "0", false);
|
||||
}
|
||||
buildMqttPath(gpioPath, {mqtt_topic_gpio_prefix, (mqtt_topic_gpio_pin + std::to_string(pinEntry.pin)).c_str(), mqtt_topic_gpio_state});
|
||||
subscribe(_lockPath.c_str(), gpioPath);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
_gpio->addCallback([this](const GpioAction& action, const int& pin)
|
||||
{
|
||||
gpioActionCallback(action, pin);
|
||||
});
|
||||
}
|
||||
_gpio->addCallback([this](const GpioAction& action, const int& pin)
|
||||
{
|
||||
gpioActionCallback(action, pin);
|
||||
});
|
||||
|
||||
_discoveryTopic = _preferences->getString(preference_mqtt_hass_discovery, "");
|
||||
_offEnabled = _preferences->getBool(preference_official_hybrid, false);
|
||||
@@ -334,11 +395,6 @@ bool NukiNetwork::update()
|
||||
{
|
||||
_mqttConnectCounter = 0;
|
||||
|
||||
if(_firstDisconnected) {
|
||||
_firstDisconnected = false;
|
||||
_device->mqttDisconnect(true);
|
||||
}
|
||||
|
||||
if(!_webEnabled) forceEnableWebServer = true;
|
||||
if(_restartOnDisconnect && (esp_timer_get_time() / 1000) > 60000) restartEsp(RestartReason::RestartOnDisconnectWatchdog);
|
||||
|
||||
@@ -369,18 +425,17 @@ bool NukiNetwork::update()
|
||||
_logIp = false;
|
||||
Log->print(F("IP: "));
|
||||
Log->println(_device->localIP());
|
||||
_firstDisconnected = true;
|
||||
}
|
||||
|
||||
if(!_device->mqttConnected() && _device->isConnected())
|
||||
while(!_mqttConnected && _device->isConnected())
|
||||
{
|
||||
delay(2000);
|
||||
_mqttConnectCounter++;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!_mqttConnected && _device->isConnected())
|
||||
{
|
||||
bool success = reconnect();
|
||||
if(!success)
|
||||
{
|
||||
delay(2000);
|
||||
_mqttConnectCounter++;
|
||||
return false;
|
||||
}
|
||||
_mqttConnectCounter = 0;
|
||||
if(forceEnableWebServer && !_webEnabled)
|
||||
{
|
||||
@@ -392,7 +447,7 @@ bool NukiNetwork::update()
|
||||
delay(2000);
|
||||
}
|
||||
|
||||
if(!_device->mqttConnected() || !_device->isConnected())
|
||||
if(!_mqttConnected || !_device->isConnected())
|
||||
{
|
||||
if(_networkTimeout > 0 && (ts - _lastConnectedTs > _networkTimeout * 1000) && ts > 60000)
|
||||
{
|
||||
@@ -508,131 +563,91 @@ bool NukiNetwork::update()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void NukiNetwork::onMqttConnect(const bool &sessionPresent)
|
||||
void NukiNetwork::mqtt_event_handler_cb(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
_connectReplyReceived = true;
|
||||
_inst->mqtt_event_handler(handler_args, base, event_id, event_data);
|
||||
}
|
||||
|
||||
void NukiNetwork::onMqttDisconnect(const espMqttClientTypes::DisconnectReason &reason)
|
||||
void NukiNetwork::mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
|
||||
{
|
||||
_connectReplyReceived = false;
|
||||
static const char *MQTT_TAG = "mqtt";
|
||||
|
||||
Log->print("MQTT disconnected. Reason: ");
|
||||
switch(reason)
|
||||
{
|
||||
case espMqttClientTypes::DisconnectReason::USER_OK:
|
||||
Log->println(F("USER_OK"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::MQTT_UNACCEPTABLE_PROTOCOL_VERSION:
|
||||
Log->println(F("MQTT_UNACCEPTABLE_PROTOCOL_VERSION"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::MQTT_IDENTIFIER_REJECTED:
|
||||
Log->println(F("MQTT_IDENTIFIER_REJECTED"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::MQTT_SERVER_UNAVAILABLE:
|
||||
Log->println(F("MQTT_SERVER_UNAVAILABLE"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::MQTT_MALFORMED_CREDENTIALS:
|
||||
Log->println(F("MQTT_MALFORMED_CREDENTIALS"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::MQTT_NOT_AUTHORIZED:
|
||||
Log->println(F("MQTT_NOT_AUTHORIZED"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::TLS_BAD_FINGERPRINT:
|
||||
Log->println(F("TLS_BAD_FINGERPRINT"));
|
||||
break;
|
||||
case espMqttClientTypes::DisconnectReason::TCP_DISCONNECTED:
|
||||
Log->println(F("TCP_DISCONNECTED"));
|
||||
break;
|
||||
default:
|
||||
Log->println(F("Unknown"));
|
||||
break;
|
||||
ESP_LOGD(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
|
||||
esp_mqtt_event_handle_t event = (esp_mqtt_event_t*)event_data;
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_CONNECTED");
|
||||
_mqttConnected = true;
|
||||
reconnect();
|
||||
break;
|
||||
case MQTT_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DISCONNECTED");
|
||||
_mqttConnected = false;
|
||||
break;
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_PUBLISHED:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DATA");
|
||||
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
|
||||
printf("DATA=%.*s\r\n", event->data_len, event->data);
|
||||
onMqttDataReceived((const char*)event->topic, (const uint8_t*)event->data, (size_t&)event->data_len);
|
||||
break;
|
||||
case MQTT_EVENT_ERROR:
|
||||
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_ERROR");
|
||||
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
|
||||
ESP_LOGI(MQTT_TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ESP_LOGI(MQTT_TAG, "Other event id:%d", event->event_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool NukiNetwork::reconnect()
|
||||
{
|
||||
_mqttConnectionState = 0;
|
||||
|
||||
while (!_device->mqttConnected() && (esp_timer_get_time() / 1000) > _nextReconnect)
|
||||
if (_mqttConnected)
|
||||
{
|
||||
if(strcmp(_mqttBrokerAddr, "") == 0)
|
||||
Log->println(F("MQTT connected"));
|
||||
_mqttConnectedTs = millis();
|
||||
_mqttConnectionState = 1;
|
||||
delay(100);
|
||||
for(const String& topic : _subscribedTopics)
|
||||
{
|
||||
Log->println(F("MQTT Broker not configured, aborting connection attempt."));
|
||||
_nextReconnect = (esp_timer_get_time() / 1000) + 5000;
|
||||
return false;
|
||||
esp_mqtt_client_subscribe(_mqttClient, topic.c_str(), MQTT_QOS_LEVEL);
|
||||
}
|
||||
|
||||
Log->println(F("Attempting MQTT connection"));
|
||||
|
||||
_connectReplyReceived = false;
|
||||
|
||||
if(strlen(_mqttUser) == 0)
|
||||
if(_firstConnect)
|
||||
{
|
||||
Log->println(F("MQTT: Connecting without credentials"));
|
||||
}
|
||||
else
|
||||
{
|
||||
Log->print(F("MQTT: Connecting with user: ")); Log->println(_mqttUser);
|
||||
_device->mqttSetCredentials(_mqttUser, _mqttPass);
|
||||
}
|
||||
|
||||
_device->setWill(_mqttConnectionStateTopic, 1, true, _lastWillPayload);
|
||||
_device->mqttSetServer(_mqttBrokerAddr, _mqttPort);
|
||||
_device->mqttConnect();
|
||||
|
||||
int64_t timeout = (esp_timer_get_time() / 1000) + 60000;
|
||||
|
||||
while(!_connectReplyReceived && (esp_timer_get_time() / 1000) < timeout)
|
||||
{
|
||||
delay(50);
|
||||
_device->update();
|
||||
if(_keepAliveCallback != nullptr)
|
||||
_firstConnect = false;
|
||||
publishString(_maintenancePathPrefix, mqtt_topic_network_device, _device->deviceName().c_str(), true);
|
||||
for(const auto& it : _initTopics)
|
||||
{
|
||||
_keepAliveCallback();
|
||||
esp_mqtt_client_publish(_mqttClient, it.first.c_str(), it.second.c_str(), 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (_device->mqttConnected())
|
||||
{
|
||||
Log->println(F("MQTT connected"));
|
||||
_mqttConnectedTs = millis();
|
||||
_mqttConnectionState = 1;
|
||||
delay(100);
|
||||
_device->mqttOnMessage(NukiNetwork::onMqttDataReceivedCallback);
|
||||
for(const String& topic : _subscribedTopics)
|
||||
{
|
||||
_device->mqttSubscribe(topic.c_str(), MQTT_QOS_LEVEL);
|
||||
}
|
||||
if(_firstConnect)
|
||||
{
|
||||
_firstConnect = false;
|
||||
publishString(_maintenancePathPrefix, mqtt_topic_network_device, _device->deviceName().c_str(), true);
|
||||
for(const auto& it : _initTopics)
|
||||
{
|
||||
_device->mqttPublish(it.first.c_str(), MQTT_QOS_LEVEL, true, it.second.c_str());
|
||||
}
|
||||
}
|
||||
publishString(_maintenancePathPrefix, mqtt_topic_mqtt_connection_state, "online", true);
|
||||
publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_ip, _device->localIP().c_str(), true);
|
||||
|
||||
publishString(_maintenancePathPrefix, mqtt_topic_mqtt_connection_state, "online", true);
|
||||
publishString(_maintenancePathPrefix, mqtt_topic_info_nuki_hub_ip, _device->localIP().c_str(), true);
|
||||
|
||||
_mqttConnectionState = 2;
|
||||
for(const auto& callback : _reconnectedCallbacks)
|
||||
{
|
||||
callback();
|
||||
}
|
||||
}
|
||||
else
|
||||
_mqttConnectionState = 2;
|
||||
for(const auto& callback : _reconnectedCallbacks)
|
||||
{
|
||||
Log->print(F("MQTT connect failed, rc="));
|
||||
_device->printError();
|
||||
_mqttConnectionState = 0;
|
||||
_nextReconnect = (esp_timer_get_time() / 1000) + 5000;
|
||||
//_device->mqttDisconnect(true);
|
||||
callback();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_mqttConnectionState = 0;
|
||||
}
|
||||
return _mqttConnectionState > 0;
|
||||
}
|
||||
|
||||
@@ -683,34 +698,20 @@ void NukiNetwork::registerMqttReceiver(MqttReceiver* receiver)
|
||||
_mqttReceivers.push_back(receiver);
|
||||
}
|
||||
|
||||
void NukiNetwork::onMqttDataReceivedCallback(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t len, size_t index, size_t total)
|
||||
void NukiNetwork::onMqttDataReceived(const char* topic, const uint8_t* payload, size_t& len)
|
||||
{
|
||||
uint8_t value[800] = {0};
|
||||
if((_mqttConnectedTs == -1 || (millis() - _mqttConnectedTs < 2000)) && topic) return;
|
||||
|
||||
size_t l = min(len, sizeof(value)-1);
|
||||
|
||||
for(int i=0; i<l; i++)
|
||||
{
|
||||
value[i] = payload[i];
|
||||
}
|
||||
|
||||
_inst->onMqttDataReceived(properties, topic, value, len, index, total);
|
||||
}
|
||||
|
||||
void NukiNetwork::onMqttDataReceived(const espMqttClientTypes::MessageProperties& properties, const char* topic, const uint8_t* payload, size_t& len, size_t& index, size_t& total)
|
||||
{
|
||||
if(_mqttConnectedTs == -1 || (millis() - _mqttConnectedTs < 2000)) return;
|
||||
|
||||
parseGpioTopics(properties, topic, payload, len, index, total);
|
||||
parseGpioTopics(topic, payload, len);
|
||||
|
||||
for(auto receiver : _mqttReceivers)
|
||||
{
|
||||
receiver->onMqttDataReceived(topic, (byte*)payload, index);
|
||||
receiver->onMqttDataReceived(topic, (byte*)payload, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NukiNetwork::parseGpioTopics(const espMqttClientTypes::MessageProperties &properties, const char *topic, const uint8_t *payload, size_t& len, size_t& index, size_t& total)
|
||||
void NukiNetwork::parseGpioTopics(const char *topic, const uint8_t *payload, size_t& len)
|
||||
{
|
||||
char gpioPath[250];
|
||||
buildMqttPath(gpioPath, {_lockPath.c_str(), mqtt_topic_gpio_prefix, mqtt_topic_gpio_pin});
|
||||
@@ -756,11 +757,6 @@ int NukiNetwork::mqttConnectionState()
|
||||
return _mqttConnectionState;
|
||||
}
|
||||
|
||||
bool NukiNetwork::encryptionSupported()
|
||||
{
|
||||
return _device->supportsEncryption();
|
||||
}
|
||||
|
||||
bool NukiNetwork::mqttRecentlyConnected()
|
||||
{
|
||||
return _mqttConnectedTs != -1 && (millis() - _mqttConnectedTs < 6000);
|
||||
@@ -779,7 +775,7 @@ void NukiNetwork::publishFloat(const char* prefix, const char* topic, const floa
|
||||
dtostrf(value, 0, precision, str);
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
_device->mqttPublish(path, MQTT_QOS_LEVEL, retain, str);
|
||||
esp_mqtt_client_publish(_mqttClient, path, str, 0, MQTT_QOS_LEVEL, retain);
|
||||
}
|
||||
|
||||
void NukiNetwork::publishInt(const char* prefix, const char *topic, const int value, bool retain)
|
||||
@@ -788,7 +784,7 @@ void NukiNetwork::publishInt(const char* prefix, const char *topic, const int va
|
||||
itoa(value, str, 10);
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
_device->mqttPublish(path, MQTT_QOS_LEVEL, retain, str);
|
||||
esp_mqtt_client_publish(_mqttClient, path, str, 0, MQTT_QOS_LEVEL, retain);
|
||||
}
|
||||
|
||||
void NukiNetwork::publishUInt(const char* prefix, const char *topic, const unsigned int value, bool retain)
|
||||
@@ -797,7 +793,7 @@ void NukiNetwork::publishUInt(const char* prefix, const char *topic, const unsig
|
||||
utoa(value, str, 10);
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
_device->mqttPublish(path, MQTT_QOS_LEVEL, retain, str);
|
||||
esp_mqtt_client_publish(_mqttClient, path, str, 0, MQTT_QOS_LEVEL, retain);
|
||||
}
|
||||
|
||||
void NukiNetwork::publishULong(const char* prefix, const char *topic, const unsigned long value, bool retain)
|
||||
@@ -806,7 +802,7 @@ void NukiNetwork::publishULong(const char* prefix, const char *topic, const unsi
|
||||
utoa(value, str, 10);
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
_device->mqttPublish(path, MQTT_QOS_LEVEL, retain, str);
|
||||
esp_mqtt_client_publish(_mqttClient, path, str, 0, MQTT_QOS_LEVEL, retain);
|
||||
}
|
||||
|
||||
void NukiNetwork::publishLongLong(const char* prefix, const char *topic, int64_t value, bool retain)
|
||||
@@ -827,7 +823,7 @@ void NukiNetwork::publishLongLong(const char* prefix, const char *topic, int64_t
|
||||
}
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
_device->mqttPublish(path, MQTT_QOS_LEVEL, retain, result);
|
||||
esp_mqtt_client_publish(_mqttClient, path, result, 0, MQTT_QOS_LEVEL, retain);
|
||||
}
|
||||
|
||||
void NukiNetwork::publishBool(const char* prefix, const char *topic, const bool value, bool retain)
|
||||
@@ -836,14 +832,14 @@ void NukiNetwork::publishBool(const char* prefix, const char *topic, const bool
|
||||
str[0] = value ? '1' : '0';
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
_device->mqttPublish(path, MQTT_QOS_LEVEL, retain, str);
|
||||
esp_mqtt_client_publish(_mqttClient, path, str, 0, MQTT_QOS_LEVEL, retain);
|
||||
}
|
||||
|
||||
bool NukiNetwork::publishString(const char* prefix, const char *topic, const char *value, bool retain)
|
||||
{
|
||||
char path[200] = {0};
|
||||
buildMqttPath(path, { prefix, topic });
|
||||
return _device->mqttPublish(path, MQTT_QOS_LEVEL, retain, value) > 0;
|
||||
return esp_mqtt_client_publish(_mqttClient, path, value, 0, MQTT_QOS_LEVEL, retain) > 0;
|
||||
}
|
||||
|
||||
void NukiNetwork::publishHASSConfig(char* deviceType, const char* baseTopic, char* name, char* uidString, const char *softwareVersion, const char *hardwareVersion, const char* availabilityTopic, const bool& hasKeypad, char* lockAction, char* unlockAction, char* openAction)
|
||||
@@ -899,7 +895,7 @@ void NukiNetwork::publishHASSConfig(char* deviceType, const char* baseTopic, cha
|
||||
path.concat(uidString);
|
||||
path.concat("/smartlock/config");
|
||||
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
|
||||
// Battery critical
|
||||
publishHassTopic("binary_sensor",
|
||||
@@ -1755,7 +1751,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][4] = "Intelligent";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "fob_action_1", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1773,7 +1769,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][4] = "Intelligent";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "fob_action_2", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1791,7 +1787,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][4] = "Intelligent";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "fob_action_3", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1808,7 +1804,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][3] = "Slowest";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "advertising_mode", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1869,7 +1865,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "timezone", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2019,7 +2015,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][6] = "Show Status";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "single_button_press_action", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2039,7 +2035,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][6] = "Show Status";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "double_button_press_action", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2083,7 +2079,7 @@ void NukiNetwork::publishHASSConfigAdditionalLockEntities(char *deviceType, cons
|
||||
json["options"][2] = "Lithium";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "battery_type", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2516,7 +2512,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["event_types"][1] = "ringlocked";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("event", "ring", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
|
||||
if((int)basicOpenerConfigAclPrefs[5] == 1)
|
||||
{
|
||||
@@ -2700,7 +2696,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][5] = "Ring";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "fob_action_1", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2719,7 +2715,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][5] = "Ring";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "fob_action_2", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2738,7 +2734,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][5] = "Ring";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "fob_action_3", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2755,7 +2751,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][3] = "Slowest";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "advertising_mode", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2816,7 +2812,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "timezone", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2845,7 +2841,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][15] = "Spare";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "operating_mode", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3055,7 +3051,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][7] = "CM & RTO & Ring";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "doorbell_suppression", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3099,7 +3095,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][3] = "Sound 3";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "sound_ring", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3116,7 +3112,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][3] = "Sound 3";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "sound_open", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3133,7 +3129,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][3] = "Sound 3";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "sound_rto", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3150,7 +3146,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][3] = "Sound 3";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "sound_cm", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3199,7 +3195,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][7] = "Open";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "single_button_press_action", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3220,7 +3216,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][7] = "Open";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "double_button_press_action", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3236,7 +3232,7 @@ void NukiNetwork::publishHASSConfigAdditionalOpenerEntities(char *deviceType, co
|
||||
json["options"][2] = "Lithium";
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath("select", "battery_type", uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3411,7 +3407,7 @@ void NukiNetwork::publishHassTopic(const String& mqttDeviceType,
|
||||
json = createHassJson(uidString, uidStringPostfix, displayName, name, baseTopic, stateTopic, deviceType, deviceClass, stateClass, entityCat, commandTopic, additionalEntries);
|
||||
serializeJson(json, _buffer, _bufferSize);
|
||||
String path = createHassTopicPath(mqttDeviceType, mqttDeviceName, uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, _buffer);
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), _buffer, 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3434,7 +3430,7 @@ void NukiNetwork::removeHassTopic(const String& mqttDeviceType, const String& mq
|
||||
if (_discoveryTopic != "")
|
||||
{
|
||||
String path = createHassTopicPath(mqttDeviceType, mqttDeviceName, uidString);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, "");
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), "", 0, MQTT_QOS_LEVEL, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3442,7 +3438,7 @@ void NukiNetwork::removeTopic(const String& mqttPath, const String& mqttTopic)
|
||||
{
|
||||
String path = mqttPath;
|
||||
path.concat(mqttTopic);
|
||||
_device->mqttPublish(path.c_str(), MQTT_QOS_LEVEL, true, "");
|
||||
esp_mqtt_client_publish(_mqttClient, path.c_str(), "", 0, MQTT_QOS_LEVEL, 1);
|
||||
|
||||
#ifdef DEBUG_NUKIHUB
|
||||
Log->print(F("Removing MQTT topic: "));
|
||||
@@ -3812,7 +3808,7 @@ void NukiNetwork::timeZoneIdToString(const Nuki::TimeZoneId timeZoneId, char* st
|
||||
|
||||
uint16_t NukiNetwork::subscribe(const char *topic, uint8_t qos)
|
||||
{
|
||||
return _device->mqttSubscribe(topic, qos);
|
||||
return esp_mqtt_client_subscribe(_mqttClient, topic, qos);
|
||||
}
|
||||
|
||||
void NukiNetwork::addReconnectedCallback(std::function<void()> reconnectedCallback)
|
||||
@@ -3822,7 +3818,7 @@ void NukiNetwork::addReconnectedCallback(std::function<void()> reconnectedCallba
|
||||
|
||||
void NukiNetwork::disableMqtt()
|
||||
{
|
||||
_device->disableMqtt();
|
||||
esp_mqtt_client_disconnect(_mqttClient);
|
||||
_mqttEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user