[SOLVED] ESP8266 MQTT Gateway: Can't Subscribe from Domoticz with Mosquitto running on Pi 3
-
SOLUTION:
For anyone reading this topic, the solution is to use the MOSQUITTO (MQQT Broker) IP ADDRESS also for the MySensors Gateway.
I have read almost any post regarding this topic, but I'm afraid I wasn't able to find a solution.
I have an ESP8666 (NodeMCU) running MySensors MQTT Gateway with just one test sensor attached: everthig is working fine, I can monitor Sensor Data and MQTT messages in Serial Monitor.
Below the sketch I'm using:
#define MY_GATEWAY_MQTT_CLIENT #define MY_GATEWAY_ESP8266 // Set this node's subscribe and publish topic prefix #define MY_MQTT_PUBLISH_TOPIC_PREFIX "domoticz/in/mymqtt" #define MY_MQTT_SUBSCRIBE_TOPIC_PREFIX "domoticz/out/mymqtt" // Set MQTT client id #define MY_MQTT_CLIENT_ID "prova1" // Enable these if your MQTT broker requires username/password //#define MY_MQTT_USER "username" //#define MY_MQTT_PASSWORD "password" // Set WIFI SSID and password #define MY_WIFI_SSID "MYSSID" #define MY_WIFI_PASSWORD "MYPASS" // Set the hostname for the WiFi Client. This is the hostname // it will pass to the DHCP server if not static. #define MY_HOSTNAME "mqtt-sensor-gateway" // Enable MY_IP_ADDRESS here if you want a static ip address (no DHCP) //#define MY_IP_ADDRESS 192,168,1,46 // If using static ip you can define Gateway and Subnet address as well //#define MY_IP_GATEWAY_ADDRESS 192,168,178,1 //#define MY_IP_SUBNET_ADDRESS 255,255,255,0 // MQTT broker ip address. #define MY_CONTROLLER_IP_ADDRESS 192, 168, 1, 39 //MQTT broker if using URL instead of ip address. // #define MY_CONTROLLER_URL_ADDRESS "test.mosquitto.org" // The MQTT broker port to to open #define MY_PORT 1883 // Enable inclusion mode //#define MY_INCLUSION_MODE_FEATURE // Enable Inclusion mode button on gateway //#define MY_INCLUSION_BUTTON_FEATURE // Set inclusion mode duration (in seconds) //#define MY_INCLUSION_MODE_DURATION 60 // Digital pin used for inclusion mode button //#define MY_INCLUSION_MODE_BUTTON_PIN D1 // Set blinking period //#define MY_DEFAULT_LED_BLINK_PERIOD 300 // Flash leds on rx/tx/err //#define MY_DEFAULT_ERR_LED_PIN 16 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 16 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 16 // the PCB, on board LED #include <ESP8266WiFi.h> #include <MySensors.h> #include <SPI.h> #include <Wire.h> // BME280 libraries and variables // Bosch BME280 Embedded Adventures MOD-1022 weather multi-sensor Arduino code // Written originally by Embedded Adventures // https://github.com/embeddedadventures/BME280 #include <BME280_MOD-1022.h> #define BARO_CHILD 0 #define TEMP_CHILD 1 #define HUM_CHILD 2 const float ALTITUDE = 124; // <-- adapt this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value! // Sleep time between reads (in ms). Do not change this value as the forecast algorithm needs a sample every minute. const unsigned long SLEEP_TIME = 60000; const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" }; enum FORECAST { STABLE = 0, // "Stable Weather Pattern" SUNNY = 1, // "Slowly rising Good Weather", "Clear/Sunny " CLOUDY = 2, // "Slowly falling L-Pressure ", "Cloudy/Rain " UNSTABLE = 3, // "Quickly rising H-Press", "Not Stable" THUNDERSTORM = 4, // "Quickly falling L-Press", "Thunderstorm" UNKNOWN = 5 // "Unknown (More Time needed) }; float lastPressure = -1; float lastTemp = -1; float lastHum = -1; int lastForecast = -1; const int LAST_SAMPLES_COUNT = 5; float lastPressureSamples[LAST_SAMPLES_COUNT]; // this CONVERSION_FACTOR is used to convert from Pa to kPa in the forecast algorithm // get kPa/h by dividing hPa by 10 #define CONVERSION_FACTOR (1.0/10.0) int minuteCount = 0; bool firstRound = true; // average value is used in forecast algorithm. float pressureAvg; // average after 2 hours is used as reference value for the next iteration. float pressureAvg2; float dP_dt; boolean metric; MyMessage tempMsg(TEMP_CHILD, V_TEMP); MyMessage humMsg(HUM_CHILD, V_HUM); MyMessage pressureMsg(BARO_CHILD, V_PRESSURE); MyMessage forecastMsg(BARO_CHILD, V_FORECAST); float getLastPressureSamplesAverage() { float lastPressureSamplesAverage = 0; for (int i = 0; i < LAST_SAMPLES_COUNT; i++) { lastPressureSamplesAverage += lastPressureSamples[i]; } lastPressureSamplesAverage /= LAST_SAMPLES_COUNT; return lastPressureSamplesAverage; } // Algorithm found here // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf // Pressure in hPa --> forecast done by calculating kPa/h int sample(float pressure) { // Calculate the average of the last n minutes. int index = minuteCount % LAST_SAMPLES_COUNT; lastPressureSamples[index] = pressure; minuteCount++; if (minuteCount > 185) { minuteCount = 6; } if (minuteCount == 5) { pressureAvg = getLastPressureSamplesAverage(); } else if (minuteCount == 35) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change * 2; // note this is for t = 0.5hour } else { dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value. } } else if (minuteCount == 65) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) //first time initial 3 hour { dP_dt = change; //note this is for t = 1 hour } else { dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value } } else if (minuteCount == 95) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 1.5; // note this is for t = 1.5 hour } else { dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value } } else if (minuteCount == 125) { float lastPressureAvg = getLastPressureSamplesAverage(); pressureAvg2 = lastPressureAvg; // store for later use. float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 2; // note this is for t = 2 hour } else { dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value } } else if (minuteCount == 155) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 2.5; // note this is for t = 2.5 hour } else { dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value } } else if (minuteCount == 185) { float lastPressureAvg = getLastPressureSamplesAverage(); float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR; if (firstRound) // first time initial 3 hour { dP_dt = change / 3; // note this is for t = 3 hour } else { dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value } pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past. firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop. } int forecast = UNKNOWN; if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval. { forecast = UNKNOWN; } else if (dP_dt < (-0.25)) { forecast = THUNDERSTORM; } else if (dP_dt > 0.25) { forecast = UNSTABLE; } else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05))) { forecast = CLOUDY; } else if ((dP_dt > 0.05) && (dP_dt < 0.25)) { forecast = SUNNY; } else if ((dP_dt >(-0.05)) && (dP_dt < 0.05)) { forecast = STABLE; } else { forecast = UNKNOWN; } // uncomment when debugging //Serial.print(F("Forecast at minute ")); //Serial.print(minuteCount); //Serial.print(F(" dP/dt = ")); //Serial.print(dP_dt); //Serial.print(F("kPa/h --> ")); //Serial.println(weather[forecast]); return forecast; } void setup() { metric = getControllerConfig().isMetric; // was getConfig().isMetric; before MySensors v2.1.1 Wire.begin(0x76); // Wire.begin(sda, scl) } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("BME280 Sensor", "1.6"); // Register sensors to gw (they will be created as child devices) present(BARO_CHILD, S_BARO); present(TEMP_CHILD, S_TEMP); present(HUM_CHILD, S_HUM); } // Loop void loop() { // need to read the NVM compensation parameters BME280.readCompensationParams(); /* After taking the measurement the chip goes back to sleep, use when battery powered. // Oversampling settings (os1x, os2x, os4x, os8x or os16x). BME280.writeFilterCoefficient(fc_16); // IIR Filter coefficient, higher numbers avoid sudden changes to be accounted for (such as slamming a door) BME280.writeOversamplingPressure(os16x); // pressure x16 BME280.writeOversamplingTemperature(os8x); // temperature x8 BME280.writeOversamplingHumidity(os8x); // humidity x8 BME280.writeMode(smForced); // Forced sample. After taking the measurement the chip goes back to sleep */ // Normal mode for regular automatic samples BME280.writeStandbyTime(tsb_0p5ms); // tsb = 0.5ms BME280.writeFilterCoefficient(fc_16); // IIR Filter coefficient 16 BME280.writeOversamplingPressure(os16x); // pressure x16 BME280.writeOversamplingTemperature(os8x); // temperature x8 BME280.writeOversamplingHumidity(os8x); // humidity x8 BME280.writeMode(smNormal); while (1) { // Just to be sure, wait until sensor is done mesuring while (BME280.isMeasuring()) { } // Read out the data - must do this before calling the getxxxxx routines BME280.readMeasurements(); float temperature = BME280.getTemperatureMostAccurate(); // must get temp first float humidity = BME280.getHumidityMostAccurate(); float pressure_local = BME280.getPressureMostAccurate(); // Get pressure at current location float pressure = pressure_local/pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255); // Adjust to sea level pressure using user altitude int forecast = sample(pressure); if (!metric) { // Convert to fahrenheit temperature = temperature * 9.0 / 5.0 + 32.0; } Serial.println(); Serial.print("Temperature = "); Serial.print(temperature); Serial.println(metric ? " °C" : " °F"); Serial.print("Humidity = "); Serial.print(humidity); Serial.println(" %"); Serial.print("Pressure = "); Serial.print(pressure); Serial.println(" hPa"); Serial.print("Forecast = "); Serial.println(weather[forecast]); Serial.println(); if (temperature != lastTemp) { send(tempMsg.set(temperature, 1)); lastTemp = temperature; } if (humidity != lastHum) { send(humMsg.set(humidity, 1)); lastHum = humidity; } if (pressure != lastPressure) { send(pressureMsg.set(pressure, 2)); lastPressure = pressure; } if (forecast != lastForecast) { send(forecastMsg.set(weather[forecast])); lastForecast = forecast; } sleep(SLEEP_TIME); } }And my serial output is:
Temperature = 27.80 ⸮C Humidity = 57.31 % Pressure = 1014.62 hPa Forecast = stable 817497 GWT:TPS:TOPIC=domoticz/in/mymqtt/0/1/1/0/0,MSG SENT 817653 GWT:TPS:TOPIC=domoticz/in/mymqtt/0/2/1/0/1,MSG SENT 817715 GWT:TPS:TOPIC=domoticz/in/mymqtt/0/0/1/0/4,MSG SENT 817778 MCO:SLP:MS=60000,SMS=0,I1=255,M1=255,I2=255,M2=255 817838 MCO:SLP:WUP=-2But when I try to subscribe to MySensors MQTT Gateway from Domoticz, I can't obtain a connection: every time I get the error "Error: MQTT: Failed to start, return code: 14 (Check IP/Port)"
In Domoticz I've added a "MySensors Gateway with MQTT Interface" Hardware, with IP = IP of NodeMCU/MySensors and Port = 1883 (standard one).
I really hope someone can help me figure out this "noob error". Thank you very much in advance for your time.
-
I've just tried with a fresh install of domoticz: the MySensors MQTT Gateway is still unavailable.
2018-08-02 22:57:26.414 Error: MQTT: Failed to start, return code: 14 (Check IP/Port)EDIT:
Running an "empty" sketch for MQTT Gateway seems to be working correctly: I'm wondering if this is a problem related to Domoticz.
28193 GWT:TPC:IP=192.168.1.44 28225 GWT:RMQ:MQTT RECONNECT 28292 GWT:RMQ:MQTT CONNECTED 28323 GWT:TPS:TOPIC=domoticz/out/MyMQTT/0/255/0/0/17,MSG SENTEDIT 2:
I verified that MySensors MQTT is reporting correctly to Mosquitto Broker running on Pi 3. All values are reported correctly.
pi@raspberrypi:~ $ mosquitto_sub -h localhost -t "#" -v domoticz/in/MyMQTT/0/1/1/0/0 29.3 domoticz/in/MyMQTT/0/2/1/0/1 59.9 domoticz/in/MyMQTT/0/0/1/0/4 1014.09This is starting to feel more and more like a Domoticz "weird" problem.
-
I've just tried with a fresh install of domoticz: the MySensors MQTT Gateway is still unavailable.
2018-08-02 22:57:26.414 Error: MQTT: Failed to start, return code: 14 (Check IP/Port)EDIT:
Running an "empty" sketch for MQTT Gateway seems to be working correctly: I'm wondering if this is a problem related to Domoticz.
28193 GWT:TPC:IP=192.168.1.44 28225 GWT:RMQ:MQTT RECONNECT 28292 GWT:RMQ:MQTT CONNECTED 28323 GWT:TPS:TOPIC=domoticz/out/MyMQTT/0/255/0/0/17,MSG SENTEDIT 2:
I verified that MySensors MQTT is reporting correctly to Mosquitto Broker running on Pi 3. All values are reported correctly.
pi@raspberrypi:~ $ mosquitto_sub -h localhost -t "#" -v domoticz/in/MyMQTT/0/1/1/0/0 29.3 domoticz/in/MyMQTT/0/2/1/0/1 59.9 domoticz/in/MyMQTT/0/0/1/0/4 1014.09This is starting to feel more and more like a Domoticz "weird" problem.
@neo-mod a MQTT client (MY_GATEWAY_MQTT_CLIENT) connects to a mqtt broker. So your esp8266, which is configured as client, will connect to the mqtt broker at MY_CONTROLLER_IP_ADDRESS.
A client will not accept incoming connections. That's why Domoticz can't connect to the esp8266.
I've never used mqtt with MySensors so I don't know how to configure it with Domoticz infortunately, but maybe someone else can help.
-
Thank you so much! You just saved me (a certified n00b, I know xD) from countless hours of headache!
@mfalkvidd said in ESP8266 MQTT Gateway: Can't Subscribe from Domoticz with Mosquitto running on Pi 3:
Just a guess: maybe all you need is to use the rpi3 ip instead of the esp8266 ip?
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login