Closed PhySix66 closed 2 months ago
Some additional info. I've done some testing to trace the source of the problem. With some Serial.print()-s I've come to the conclusion:
In HAMqtt.cpp
void HAMqtt::loop()
{
...
bool result = _mqtt->loop(); // error here -> PubSubClient::loop()
...
}
In PubSubClient.cpp
boolean PubSubClient::loop()
{
if (connected()) { // error here -> PubSubClient::connected()
...
}
}
boolean PubSubClient::connected()
{
...
else {
rc = (int)_client->connected(); // ERROR Here If ReConnecting ->(?) Client::connected()
// this is the code where it crashes
//Fix Test 1
// rc = (int)_client[0].connected(); // Tryed this as well, not good
//Fix Test 2 // Not good, fails
/*
if((int)_client->connected() > 0){
rc = true;
//Serial.println(F("_client[0].connected() == true"));
}else{
rc = false;
//Serial.println(F("_client[0].connected() == false"));
}*/
...
}
return rc;
}
In Client.h
class Client: public Stream {
public:
...
virtual uint8_t connected() = 0; // No idea where this points to
// this is the end for my rabithole
...
};
I only asume, that Client.h somehow points to WiFiClient.cpp
In WiFiClient.cpp
uint8_t WiFiClient::connected()
{
//Serial.print(F("WiFiClient::connected()"));
if (!_client || _client->state() == CLOSED)
{ //Serial.println(F(" == false"));
return 0;
}
return _client->state() == ESTABLISHED || available();
}
Problem Solved! Problem Source: USER (a.k.a ME)
I've made a bad, untested/unverified assumption based from the Arduinos Examples, namely: example/home-assistaint-integration/multi-switch
From this as the basis:
void setup() {
// you don't need to verify return status
Ethernet.begin(mac);
switch1.setName("Pretty label 1");
switch1.setIcon("mdi:lightbulb");
switch1.onCommand(onSwitchCommand);
switch2.setName("Pretty label 2");
switch2.setIcon("mdi:lightbulb");
switch2.onCommand(onSwitchCommand);
mqtt.begin(BROKER_ADDR);
}
I made these Foo()-s:
void InitMQTT_Device()
{
device.setUniqueId(esp_mac.b, sizeof(esp_mac));
Serial.print(F("MQTT UniqueID :")); Serial.println(device.getUniqueId());
// set device's details (optional)
//device.setName(ESP_HostName.c_str());
device.setName(ESP_HostName);
Serial.print(F("ESP_HostName :")); Serial.println(ESP_HostName);
device.setManufacturer("PhySix66");
device.setModel(esp_model_name);
device.setSoftwareVersion("0.0.1");
// This method enables availability for all device types registered on the device.
// For example, if you have 5 sensors on the same device, you can enable
// shared availability and change availability state of all sensors using
// single method call "device.setAvailability(false|true)"
//device.enableSharedAvailability();
// Optionally, you can enable MQTT LWT feature. If device will lose connection
// to the broker, all device types related to it will be marked as offline in
// the Home Assistant Panel.
//device.enableLastWill();
}
void InitMQTT_Switches()
{
// handle switch state (multi-switch) - OutPut via MCP23x17
switch0.setName("Switch0");
//switch0.setIcon("mdi:lightbulb");
switch0.setIcon("mdi:toggle-switch");
//switch0.setRetain(true); // Sets retain flag for the switch command. If set to true the command produced by Home Assistant will be retained.
switch0.onCommand(onSwitchCommand);
switch1.setName("Switch1");
switch1.setIcon("mdi:toggle-switch");
switch1.onCommand(onSwitchCommand);
//....
switch7.setName("Switch7");
switch7.setIcon("mdi:toggle-switch");
switch7.onCommand(onSwitchCommand);
}
void startMQTT()
{
if(mqtt_flags & MQTT_FLAG_EN)
{
if(!(AreBitSet(mqtt_flags, (MQTT_FLAG_SERVER_AV | MQTT_FLAG_INIT))))
{
Serial.println(F("mqtt.h: startMQTT() Not Inited()"));
IPAddress tempIP(0,0,0,0);
if(!WiFi.hostByName(BROKER_ADDR, tempIP, 800)) { // Get the IP address of the NTP server
Serial.print(F("MQTT Req DNS lookup failed for ")); Serial.println(BROKER_ADDR);
mqtt_flags &= ~MQTT_FLAG_SERVER_AV;
}
else
{
Serial.print(F("MQTT Req DNS lookup Success for ")); Serial.println(BROKER_ADDR);
Serial.print(F("IP Addr is ")); Serial.println(tempIP);
mqtt_flags |= MQTT_FLAG_SERVER_AV;
}
if(mqtt_flags & MQTT_FLAG_SERVER_AV)
{
InitMQTT_Device(); // <<- One of these caused the ERROR.
InitMQTT_Switches(); // <<- One of these caused the ERROR.
if(mqtt_flags & MQTT_FLAG_USE_CREDENTIALS)
{
// use this for mqtt-with-credentials
mqtt.begin(MQTT_ServerName, mqtt_port, mqtt_server_user_name, mqtt_server_password);
}
else
{
if(mqtt.begin(MQTT_ServerName) == true)
{
Serial.println(F("mqtt.begin == true"));
}
else
{
Serial.println(F("mqtt.begin == false"));
}
}
mqtt_flags |= MQTT_FLAG_INIT;
Serial.print(F("mqtt_flags: ")); Serial.println(mqtt_flags);
Serial.println(F("MQTT is Inited"));
}
}
}
else if(mqtt.isConnected())
{
mqtt_flags &= ~(MQTT_FLAG_SERVER_AV | MQTT_FLAG_INIT);
mqtt.disconnect();
Serial.println(F("MQTT DisConnected"));
}
}
And every time, when I reenabled the MQTT via startMQTT(), then I've also "reinitialized" it's device and switches... Or so I thought. Not sure about the details of what's happening, but I only assume, that during the second call of InitMQTT_Device() and InitMQTT_Switches() some memory allocation/curroption occurs, that messed up the _Client* client (var/pointer?) in the PubSubClient.cpp.
Note to noobs like me: To find the problem, I did a reinstall of the librarys where I poked arround (added some extra code): home-assistant-integration and the pubsubclient, and went back to square one. After the reflashing, with basicly the same code as in the exmaple, it still crashed. This got me thinking and lead me to the problem.
Win7x64 Arduino 1.8.19 HA-intergration 2.1.0 ESP8266-Olimex-Dev 2MB
I've made a WebInterface for the ESP8266, includeing the MQTT.
On startup everything is fine, but when I try to restart the Service the ESP8266 reboots. On the Web Page there is a Enable button which then is sent to the mqtt_flags register. If flag i set, then the mqtt startup initiates.
On the first start, it works. However when I change it fron Enabled to Disabled it seem to work. Even HAMqtt::isConnected() returns false.
After I've enabled #define ARDUINOHA_DEBUG in the ArduinoHADefines.h library I've got some clues via Serial Debug lines:
On the first run, from setting Disabled to Enabled I got his:
But when I set is from Enabled to Disabled I've never recive this line:
So it seem that it never truly disconnects or just some mqtt status flags never get set to the proper state.
I've even tried to add change bool HAMqtt::disconnect() like so:
With the resultin Serial:
But still, the same thing happens after ReEnabling the Service, the ESP8266 reboots.
PhySix66