Hello !Regarding websockets:Just found the howto I was talking about:it's in french (very convenient for me, sorrry guys ;-).But as a summary, it says the websocket function of mosquitto can be enabled just with a small config file.I will try this (quick & easy to test).Also, just to summarise my setup:I just received last week a brand new Orange Pi PC plus (kind of low cost raspberry which as a nice advantage imho: it has integrated emmc 8GB memory).It is setup with Armbiam Ubuntu Xenial (server), v5.25. (I am more familiar to ubuntu so it's easier for me too)I just setup mosquitto from depot ( apt-get install mosquitto ).I setup weewx using the quick start guide with depot ( http://www.weewx.com/docs/apt-get.htm )So it's all fresh install.I only modified mosquitto config to use "user/password" and play a bit with weewx and wxMesh as you know.finally, I have a general question regarding how the driver works:let me know if my understanding is correct or wrongthe "on_message" stuff is kind of asynchronousthen when a message is available on the broker, this function will be trigged and will load the message content in payload.
then the genLoopPackets is synchronous (I mean executed every n seconds, n=poll interval defined in weewx.conf)So every n seconds, it checks if payload as some content and if yes, it will process the data and deliver the "_packet" to next weewx process
If this is correct, does it mean that if several mqtt messages are delivered inside the n seconds interval, maybe only the last one will be processed ?
The background of the question is that I'm thinking if it may be possible to use a sub topic structure for mqttThe simplest idea I have in mind is to have: weather/<weewx_schemas_label>:weather/outTemp
weather/outHumidity
....
Then each of these topics may be sent at any time: Temp, humidity, barometer may be send only every few minutes. Wind may be sent every 1 or few seconds, rain may be send only when it's raining...weewx driver may subscribe to /weather/# to get them all and process whenever they arrive ?-Ok- I speak but don't have a clue on how to do that :-) not sure it is realistic.
The advantage could that it stick better to what I have seen from mqtt usage, then same published topics could be used by other subscribers (home-assistant, automatic watering for the garden or whatever)Best regards,
Le mardi 21 février 2017 00:05:11 UTC+1, mwall a écrit :i found it helpful to configure the broker so that it publishes using websockets. then you can use a web browser to see what is happening. this is especially useful when you're trying to decode someone else's topic hierarchy, or to figure out why your own topics are not showing up where you think they should be.
the hivemq folks wrote one of the first ones, which many people have now embedded:
http://www.hivemq.com/blog/full-featured-mqtt-client-browser
http://www.espert.io/mqtt/index.html
but many other browser-based clients are out there:
http://mitsuruog.github.io/what-mqtt/
https://www.cloudmqtt.com/docs-websocket.html
if you're using the mosquitto broker, you'll have to compile it with websocket compatibility. but once you do that, enabling websockets is just a matter of making the broker listen on the websocket port.
m
Not sure if it's a good or helpful example but wmr100 driver, as far as I understood, receive data asynchronously from the Wmr100 station (one packet for each sensor with different occurrence depending on the sensor)
Code is here
https://github.com/weewx/weewx/blob/master/bin/weewx/drivers/wmr100.py
Also weewx customizing Guide said some stations works this way (so called partial package):
LOOP packets are the raw data generated by the device driver. They get their name from the Davis Instruments documentation. For some devices they are generated at rigid intervals, such as every 2 seconds for the Davis Vantage series, for others, irregularly, every 20 or 30 seconds or so. LOOP packets may or may not contain all the data types. For example, a packet may contain only temperature data, another only barometric data, etc.. This kind of packet is called a partial record packet. For other types of hardware (notably the Vantage series), every LOOP packet contains every data type.
I understand your points about wind, Frederic. There's an interesting discussion underway in another thread in the user group: https://groups.google.com/d/msg/weewx-user/x2RYkjwyNjc/Ilcqr3-7BgAJ. "tempus" makes what I think is a good point: you may be able to sense wind direction, even if the wind speed is below the sensitivity of the wind speed sensor. So reporting wind direction and "None" for wind speed is a valid data scenario.
Feb 22 16:20:46 walrus weewx[29153]: wxMesh: Working on payload : TIME:0,INTE:22.60,INHU:32.59
Feb 22 16:20:46 walrus weewx[29153]: wxMesh: key: TIME value: 1487794846
Feb 22 16:20:46 walrus weewx[29153]: wxMesh: key: INTE value: 22.60
Feb 22 16:20:46 walrus weewx[29153]: wxMesh: key: INHU value: 32.59
Feb 22 16:20:46 walrus weewx[29153]: rtgd: queued loop packet: {'barometer': None, 'windchill': None, 'dewpoint': None, 'humidex': None, 'maxSolarRad': None, 'pressure': None, 'altimeter': None, 'usUnits': 17, 'appTemp': None, 'rainRate': 0.0, 'heatindex': None, 'dateTime': 1487794846.0, 'inHumidity': 32.59, 'inTemp': 22.600000000000005, 'cloudbase': None, 'inDewpoint': 41.58132605144329}
Feb 22 16:20:46 walrus weewx[29153]: rtgdthread: received packet: {'barometer': None, 'windchill': None, 'dewpoint': None, 'humidex': None, 'maxSolarRad': None, 'pressure': None, 'altimeter': None, 'usUnits': 17, 'appTemp': None, 'rainRate': 0.0, 'heatindex': None, 'dateTime': 1487794846.0, 'inHumidity': 32.59, 'inTemp': 22.600000000000005, 'cloudbase': None, 'inDewpoint': 41.58132605144329}
Feb 22 16:20:46 walrus weewx[29153]: rtgdthread: Unexpected exception of type <type 'exceptions.KeyError'>
Feb 22 16:20:46 walrus weewx[29153]: *** Traceback (most recent call last):
Feb 22 16:20:46 walrus weewx[29153]: *** File "/usr/share/weewx/user/rtgd.py", line 773, in run
Feb 22 16:20:46 walrus weewx[29153]: *** self.process_packet(_package['payload'])
Feb 22 16:20:46 walrus weewx[29153]: *** File "/usr/share/weewx/user/rtgd.py", line 790, in process_packet
Feb 22 16:20:46 walrus weewx[29153]: *** self.buffer.setLowsAndHighs(packet)
Feb 22 16:20:46 walrus weewx[29153]: *** File "/usr/share/weewx/user/rtgd.py", line 1614, in setLowsAndHighs
Feb 22 16:20:46 walrus weewx[29153]: *** outTemp = packet_d['outTemp']
Feb 22 16:20:46 walrus weewx[29153]: *** KeyError: 'outTemp'
Feb 22 16:20:46 walrus weewx[29153]: rtgdthread: Thread exiting. Reason: 'outTemp'
LOOP: 2017-02-22 12:33:40 CET (1487763220) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1487763220, dewpoint: None, heatindex: None, humidex: None, inDewpoint: 41.5373706516, inHumidity: 35.0, inTemp: 70.52, inTempBatteryStatus: 0, maxSolarRad: 559.235507813, pressure: None, rainRate: 0, usUnits: 1, windchill: NoneLOOP: 2017-02-22 12:33:46 CET (1487763226) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1487763226, dewpoint: None, heatindex: None, hourRain: 0.0, humidex: None, inDewpoint: None, maxSolarRad: 559.294551306, pressure: None, rain: None, rain24: 0.0, rainBatteryStatus: 0, rainRate: 0.0, totalRain: 94.72, usUnits: 1, windchill: NoneLOOP: 2017-02-22 12:33:48 CET (1487763228) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1487763228, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: 559.314190756, pressure: None, rainRate: 0, usUnits: 1, windBatteryStatus: 0, windchill: None, windDir: None, windGust: 0.0, windGustDir: None, windSpeed: 0.0LOOP: 2017-02-22 12:33:51 CET (1487763231) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1487763231, dewpoint: None, heatindex: None, humidex: None, inDewpoint: 41.5373706516, inHumidity: 35.0, inTemp: 70.52, inTempBatteryStatus: 0, maxSolarRad: 559.343713308, pressure: None, rainRate: 0, usUnits: 1, windchill: NoneLOOP: 2017-02-22 12:33:51 CET (1487763231) altimeter: None, appTemp: None, barometer: None, cloudbase: None, dateTime: 1487763231, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: 559.343713308, pressure: None, rainRate: 0, usUnits: 1, windBatteryStatus: 0, windchill: None, windDir: None, windGust: 0.0, windGustDir: None, windSpeed: 0.0LOOP: 2017-02-22 12:33:56 CET (1487763236) altimeter: None, appTemp: None, barometer: None, cloudbase: 9154.78830959,dateTime: 1487763236, dewpoint: 19.7668618938, heatindex: 58.46, humidex: 58.46, inDewpoint: None, maxSolarRad: 559.392682737, outHumidity: 22.0, outTemp: 58.46, outTempBatteryStatus: 1, pressure: None, rainRate: 0, usUnits: 1, windchill: None
I discovered a possible problem with this approach working well with other parts of weewx. Last night I was attempting to get the Realtime Gauge-Data (https://github.com/gjr80/weewx-realtime_gauge-data) extension going, and ran in to a problem because not each packet the my wxMesh driver subscribes to has the same data. Here, an indoor station packet arrives, is parsed and the temperature (INTE) and humidity (INHU) yielded to weewx, which causes rtgd to do some work. rtgdthread exits on a KeyError, because the packet does not contain outTemp.
The opposite can also happen, if an outdoor packet arrives, rtgdthread will exit because if cannot find the inTemp keyword.
...
Should the wxMesh driver set all possible data to None before parsing the incoming MQTT message? Or is this a problem for rtgdthread to deal with? Or StdWXCalculate in weewx?I'm asking not so much for these two specific modules, but as a general design guideline for my driver.
#!/bin/sh
while [ true ]
do
outTemp=$((20+ $(od -An -N1 -i /dev/random) % 5))
mosquitto_pub -t weewx/outTemp -m $outTemp -u <broker_username> -P <broker_password> -h <broker_ip>
barometer=$((1010+ $(od -An -N1 -i /dev/random) % 10))
mosquitto_pub -t weewx/barometer -m $barometer -u <broker_username> -P <broker_password> -h <broker_ip>
sleep 2
done
Hi Bill,I just wanted to share I received my ESP8266... 30min later it send some mqtt message every minute for outTemp & Humidity... Well it is still dummy values because the sensor is still on the way. But it's very simple to connect to WiFi then mosquitto.I think I will open a github.com page to share the code for sensor side.
/***************************************************
Adafruit MQTT Library ESP8266 Example
Must use ESP8266 Arduino from:
https://github.com/esp8266/Arduino
Works great with Adafruit's Huzzah ESP board & Feather
----> https://www.adafruit.com/product/2471
----> https://www.adafruit.com/products/2821
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Tony DiCola for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "Adafruit_HTU21DF.h"
const char* ssid = "XXX";
const char* password = "XXX";
const char* mqtt_server = "XXX";
/************************* MQTT Setup *********************************/
#define MQTT_USERNAME "YYY"
#define MQTT_PASSWD "YYY"
/************ Global State (you don't need to change this!) ******************/
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
void setup() {
Serial.begin(9600);
delay(10);
Serial.println(F("Adafruit MQTT publish of HTU21D"));
if (!htu.begin()) {
Serial.println("Couldn't find sensor!");
while (1);
}
setup_wifi();
mqttClient.setServer(mqtt_server, 1883);
mqttClient.setCallback(callback);
}
long lastMsg = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (unsigned int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
digitalWrite(BUILTIN_LED, LOW); // it is active low on the ESP-01)
} else {
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
}
}
void reconnect() {
// Loop until we're reconnected
while (!mqttClient.connected()) {
Serial.print("Attempting MQTT connection...");
// Attempt to connect
if (mqttClient.connect("ESP8266Client", "YYY", "YYY")) {
Serial.println("connected");
// Once connected, publish an announcement...
mqttClient.publish("outTopic", "hello world");
// ... and resubscribe
mqttClient.subscribe("weather");
} else {
Serial.print("failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void loop() {
char message[64];
char temperatureStr[6], humidityStr[6];
if (!mqttClient.connected()) {
reconnect();
}
mqttClient.loop();
long now = millis();
if (now - lastMsg > 10000) {
lastMsg = now;
dtostrf(htu.readTemperature(), 4, 2, temperatureStr);
dtostrf(htu.readHumidity(), 4, 2, humidityStr);
sprintf( message, "TIME:0,INTE:%s,INHU:%s", temperatureStr, humidityStr);
Serial.print("Publish message: ");
Serial.println(message);
mqttClient.publish("weather", message);
}
}
# The callback for when a PUBLISH message is received from the server. def on_message(self, client, userdata, msg): self.payload = str(msg.payload) self.topic = str(msg.topic) # Modification to record also the topic of the message . logdbg("Got message %s" % str(msg.payload))
def genLoopPackets(self): while True: self.client.loop() # read whatever values we can get from the MQTT broker logdbg("Working on payload : %s" % self.payload) if self.payload != "Empty" : data = {} ## start of modified part received_topic = self.topic key = mystring.split('/')[-1] # found on a forum, it is supposed to output last string after separator, ex: if topic is 'weewx/outHumidity', it shall return outHumidity value = self.payload data[key] = value
# end of modified part # map the data into a weewx loop packet _packet = {'usUnits': weewx.METRIC} for vname in data: _packet[self.label_map.get(vname, vname)] = _get_as_float(data, vname)
yield _packet self.payload = "Empty"
def on_message(self, client, userdata, msg): self.payload = str(msg.payload)
string_topic = str(msg.topic) key = string_topic.split('/')[-1] self.receive_buffer[key] = str(msg.payload)
def closePort(self): self.client.disconnect()
def genLoopPackets(self): self.client.loop_start() while True: time.sleep(self.poll_interval) data = self.receive_buffer _packet = {'dateTime': int(time.time() + 0.5),'usUnits': weewx.METRIC} logdbg("dateTime %s" % _packet["dateTime"])
for vname in data: _packet[self.label_map.get(vname, vname)] = _get_as_float(data, vname)
logdbg("buffer content for key: %s = %s" %(vname, data[vname])) yield _packet self.receive_buffer.clear() data.clear()
Mar 11 21:46:51 localhost weewx[11116]: engine: Starting up weewx version 3.6.2Mar 11 21:46:51 localhost weewx[11116]: engine: Station does not support reading the timeMar 11 21:46:51 localhost weewx[11116]: engine: Starting main packet loop.Mar 11 21:47:01 localhost weewx[11116]: wxMesh: dateTime 1489265221Mar 11 21:47:01 localhost weewx[11116]: wxMesh: buffer content for key: outHumidity = 73Mar 11 21:47:01 localhost weewx[11116]: wxMesh: buffer content for key: pressure = 1005.31Mar 11 21:47:01 localhost weewx[11116]: wxMesh: buffer content for key: barometer = 1018.59Mar 11 21:47:01 localhost weewx[11116]: wxMesh: buffer content for key: inTemp = 24.98Mar 11 21:47:01 localhost weewx[11116]: wxMesh: buffer content for key: outTemp = 22Mar 11 21:47:11 localhost weewx[11116]: wxMesh: dateTime 1489265232Mar 11 21:47:21 localhost weewx[11116]: wxMesh: dateTime 1489265242Mar 11 21:47:21 localhost weewx[11116]: wxMesh: buffer content for key: outHumidity = 70Mar 11 21:47:21 localhost weewx[11116]: wxMesh: buffer content for key: outTemp = 23Mar 11 21:47:31 localhost weewx[11116]: wxMesh: dateTime 1489265252Mar 11 21:47:41 localhost weewx[11116]: wxMesh: dateTime 1489265262
self.topic = ('weewx/#') self.receive_buffer = {}
Hello!
#!/usr/bin/python## weewx driver that reads data from MQTT subscription## This program is free software: you can redistribute it and/or modify it under# the terms of the GNU General Public License as published by the Free Software# Foundation, either version 3 of the License, or any later version.## This program is distributed in the hope that it will be useful, but WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS# FOR A PARTICULAR PURPOSE.#
## The units must be weewx.US: (this comment need to be updated)# degree_F, inHg, inch, inch_per_hour, mile_per_hour## To use this driver, put this file in the weewx user directory, then make# the following changes to weewx.conf:## [Station]# station_type = wxMesh# [wxMesh]# host = localhost # MQTT broker hostname# topic = weather # topic, mqtt topics should have format "topic/label_map", ex: weather/humi# driver = user.wxMesh## If the variables in the file have names different from those in weewx, then# create a mapping such as this:## [wxMesh]# ...# [[label_map]]# temp = outTemp# humi = outHumidity# in_temp = inTemp# in_humid = inHumidity
from __future__ import with_statementimport syslogimport timeimport paho.mqtt.client as mqttimport weewx.drivers
DRIVER_VERSION = "0.1"
def logmsg(dst, msg): syslog.syslog(dst, 'wxMesh: %s' % msg)
def logdbg(msg): logmsg(syslog.LOG_DEBUG, msg)
def loginf(msg): logmsg(syslog.LOG_INFO, msg)
def logerr(msg): logmsg(syslog.LOG_ERR, msg)
def _get_as_float(d, s): v = None if s in d: try: v = float(d[s]) except ValueError, e: logerr("cannot read value for '%s': %s" % (s, e)) return v
def loader(config_dict, engine): return wxMesh(**config_dict['wxMesh'])
class wxMesh(weewx.drivers.AbstractDevice): """weewx driver that reads data from a file"""
def __init__(self, **stn_dict): # where to find the data file self.host = stn_dict.get('host', 'localhost') # subscribe to all sub-topic of the topic define in weewx.conf self.topic = stn_dict.get('topic', 'weather') + "/#" self.username = stn_dict.get('username', 'XXX') self.password = stn_dict.get('password', 'password') # how often to poll the weather data file, seconds self.poll_interval = float(stn_dict.get('poll_interval', 5.0)) # mapping from variable names to weewx names self.label_map = stn_dict.get('label_map', {})
loginf("host is %s" % self.host) loginf("topic is %s" % self.topic) loginf("polling interval is %s" % self.poll_interval) loginf('label map is %s' % self.label_map) self.payload = "Empty" self.receive_buffer = {} #self.payloadList = [payload] self.client = mqtt.Client(client_id="XXX", protocol=mqtt.MQTTv31)
#self.client.on_connect = self.on_connect self.client.on_message = self.on_message
self.client.username_pw_set(self.username, self.password) self.client.connect(self.host, 1883, 60) self.client.subscribe(self.topic, qos=0)
# The callback for when a PUBLISH message is received from the server.
def on_message(self, client, userdata, msg): self.payload = str(msg.payload) string_topic = str(msg.topic) key = string_topic.split('/')[-1] self.receive_buffer[key] = str(msg.payload)
def closePort(self): self.client.disconnect()
def genLoopPackets(self):
self.client.loop_start() # enable to receive ('on_message') in background while True: time.sleep(self.poll_interval) # wait for some MQTT data to be published data = self.receive_buffer if data: # if data is not empty then prepare loop packet
_packet = {'dateTime': int(time.time() + 0.5),'usUnits': weewx.METRIC} logdbg("dateTime %s" % _packet["dateTime"]) for vname in data: _packet[self.label_map.get(vname, vname)] = _get_as_float(data, vname) logdbg("buffer content for key: %s = %s" %(vname, data[vname])) yield _packet self.receive_buffer.clear() data.clear()
@property def hardware_name(self): return "wxMesh"
LOOP: 2017-03-12 11:41:15 CET (1489315275) altimeter: None, appTemp: None, baro: 1015.0, barometer: None, cloudbase: None, dateTime: 1489315275, dewpoint: None, heatindex: None, humidex: None, inDewpoint: None, maxSolarRad: None, pressure: None, rainRate: 0, usUnits: 1, windchill: None
if 'key1' in dict.keys():
This has no meaning and I guess it would be better to filter.also it may happens that some mqtt topics may be not for weewx but for other personnal use.I would like to check if a key is existing in weewx schema before put it in the packet, but no clue how to do that.
Matthew, I have a big question for better understanding of how weewx deals with drivers !There is an infinite loop in the driver (while true:).So my understanding is that weewx launch the driver as a kind of background thread that output packet with that yield command ?So it's just never go out of the while true loop as long as weewx run.Then in case of weewx stop, weewx will force exit this infinite loop and launch the "close_port()" procedure ?
by the way, if my understanding is correct, does it mean I shall check regularly if mqtt connexion is still valid and reconnect if needed ?The connexion is in the __init__ then, if disconnected for any reason, we cannot recover, am I right ?
also during the weekend I noticed that at reboot, as weewx start before my ethernet connexion is fully setup, it seems I get a crash (the driver is not able to connect).Is it possible to use this weewx.WeeWxIOError during the __init__ of the driver ?
Mar 23 10:02:46 localhost weewx[786]: import of driver failed: [Errno 101] Le réseau n'est pas accessible (<class 'socket.error'>)Mar 23 10:02:46 localhost weewx[786]: engine: Unable to load driver: [Errno 101] Le réseau n'est pas accessibleMar 23 10:02:46 localhost weewx[786]: **** Waiting 60 seconds then retrying...Mar 23 10:04:04 localhost weewx[786]: engine: retrying...Mar 23 10:04:04 localhost weewx[786]: engine: Using configuration file /etc/weewx/weewx.conf
[[label_map]] barometer = barometer pressure = pressure altimeter = altimeter inTemp = inTemp outTemp = outTemp inHumidity = inHumidity ....
[[label_map]] OT = outTemp
Bill, I have a question about the format of the MQTT message. I have my raspberry pi running weewx, I also have that unit using mathew's mqtt publisher to push data to my mosquitto server. I set up another virtual machine running weewx with your driver, but for the life of me cannot get your driver to pick up the info from it. It keeps saying the payload is empty, but I have mqtt dashboard running on my android phone that I tested with and get updates just fine. My goal is to actually migrate from my fileparse setup on my PI to an mqtt based server on the freenas box. Presumably Mathiew's mqtt implimentation will use the standard weewx labels so I would assume I wouldn't even need a label map for the wxMesh driver. Unless I'm way off on that.
Only issue I had was the paho-mqtt needed to be installed with pip. Thanks for all this.
Andy
if then_record is None:
return None
else:
if obs_type not in then_record or then_record[obs_type] is None:
return None
else:
then_vt = weewx.units.as_value_tuple(then_record, obs_type)
now = convert(now_vt, group).value
then = convert(then_vt, group).value
return now - then
This conversation has been copied over from the weewx-user group (https://groups.google.com/d/msg/weewx-user/zhl4I7oRtt8/5pwhOAioBgAJ). I believe it is more appropriate to continue here.
[Databases]
# This section binds to the actual database to be used
[[archive_sqlite1]]
database_type = SQLite
database_name = ws2080.sdb
[[archive_sqlite2]]
database_type = SQLite
database_name = mqttmesh.sdb
[[label_map]]
SEN1 = Sensor1Meter
SEN2 = Sensor2Meter
SEN3 = Sensor3Meter
SEN4 = Sensor4Meter
Correct.... The standard OWFS running as a driver for my main inputs and my modified version of yours that now runs as a service to obtain additional data from some other sensors
def __init__(self, **stn_dict):
# where to find the data file
self.host = stn_dict.get('host', 'localhost')
# subscribe to all sub-topic of the topic define in weewx.conf
self.topic = stn_dict.get('topic', 'weather') + "/#"
self.username = stn_dict.get('username', 'XXX') <---- Is this line not indented in your wxMesh.py file?
self.password = stn_dict.get('password', 'password')
# how often to poll the weather data file, seconds
self.poll_interval = float(stn_dict.get('poll_interval', 5.0))
# mapping from variable names to weewx names
self.label_map = stn_dict.get('label_map', {})
loginf("host is %s" % self.host)
loginf("topic is %s" % self.topic)
loginf("polling interval is %s" % self.poll_interval)
loginf('label map is %s' % self.label_map)
self.payload = "Empty"
self.receive_buffer = {} <---- This line should be indented
#self.payloadList = [payload]
self.client = mqtt.Client(client_id="XXX", protocol=mqtt.MQTTv31)
#self.client.on_connect = self.on_connect
self.client.on_message = self.
on_message
self.client.username_pw_set(self.username, self.password) <---- Too much indent, probably harmless
self.client.connect(self.host, 1883, 60)
self.client.subscribe(self.topic, qos=0)
# The callback for when a PUBLISH message is received from the server.
def on_message(self, client, userdata, msg):
self.payload = str(msg.payload)
string_topic = str(msg.topic)
key = string_topic.split('/')[-1]
self.receive_buffer[key] = str(msg.payload)<----Too much indent, probably harmless
_packet = {'dateTime': int(time.time() + 0.5),'usUnits': weewx.METRIC}
I'm not very good at python (I was barely able to modify Bill driver for my need ;-)), but don't hesitate to ask again in case I'm not clear.
One last thing: I move (very very slowly) my github from https://github.com/bonjour81/ESP8266-MQTT-WEEWX to https://github.com/bonjour81/station_meteo
I try (very very slowly) to learn how to use git a little more like it should be
Also, if you like, I would be very happy to discuss about your project ! (separately from this discussion). it looks like we have a more or less similar project (ESP8266 + mqtt + weewx).
Best regards,
wget https://raw.githubusercontent.com/bonjour81/ESP8266-MQTT-WEEWX/master/weewx/wxMQTT.py
mv wxMQTT.py wxMesh.py
Try going in to your bin/user/ directory and run these commands at your shell prompt
wget https://raw.githubusercontent.com/bonjour81/ESP8266-MQTT-WEEWX/master/weewx/wxMQTT.py
mv wxMQTT.py wxMesh.py
pi@pi3:/tmp $ sha1sum wxMQTT.py826d007e040b540cb5c6092842667c9966852db9 wxMQTT.py
pi@pi3:/tmp $ sha256sum wxMQTT.pye99e86a15f3315eb1dd0db38f4ce759c4af2cb4965f71e031000a380c087d32b wxMQTT.py
Hello Vince,
with wget https: // ... copied the file wxMQTT.py. Checksum is ok.
Are the wxMesh.py and wxMQTT.py files the same?
station_type = wxMesh
...
[wxMesh]
driver = user.wxMesh
The error messages have changed (see log file). I suspect it's because of the MQTT data. MQTT sends float values with me. I have to change the Arduino program. Many thanks for the help. I'm probably a little further.
# Set to 1 for extra debug info, otherwise comment it out or set to zero.
debug = 0
# Set to 1 for extra debug info, otherwise comment it out or set to zero.
debug =1
tail -f /var/log/syslog
It seems there is some margin to improve robustness of the driver ;).
# This section is for information about the station.
[Station]
station_type = wxMesh
#Description of the station location
location = Wetter Rheinbach Voreifel
#
#Latitude and longitude in decimal degrees
latitude = 50.3552
longitude = 6.5346
# Altitude of the station, with unit it is in. This is downloaded from
# from the station if the hardware supports it.
altitude = 270, meter # Choose 'foot' or 'meter' for unit
# Set to type of station hardware. There must be a corresponding stanza
# in this file with a 'driver' parameter indicating the driver to be used.
# station_type = Simulator
# If you have a website, you may specify an URL
#station_url = http://www.example.com
# The start of the rain year (1=January; 10=October, etc.). This is
# downloaded from the station if the hardware supports it.
# rain_year_start = 1
... additional configuration of {Station]
# new section for configuring wxMesh driver
[wxMesh]
host = 192.168.1.30
username = AX700
password = 84N7601
topic = weewx/
driver = user.wxMesh
poll_interval = 3
loop_on_init = true
[[label_map]]
HUMT = outTemp
RHUM = outHumidity
et cetera
Hello,
Ask a question about wxMesh / MQTT / Rain Sensor.
My home rain sensor sends one pulse per spoon (3.4 ml) of rain over MQTT to weewx.
-
The ESP8266 ... sends ...
Adafruit_MQTT_Publish rain_pub = Adafruit_MQTT_Publish (& mqtt, "weewx / rain", 1);
...
rain_pub.publish (dregm); // value as char "0.034"
About 3 spoons correspond to 1 mm of rain per m2. My hardware does not provide hourly or daily rainfall. The skin (blue leather sofa) displays the following values for rain on an impulse:
current weather
Rain - rate 0.9 mm / h - wrong
Highs and lows of the day
Today's rainfall: 0.3 mm - correct!
Max.Rain rate: 1.4 mm / h 18:17:57 - wrong
One day later, in the "Rain (total hour)", 35 mm of rain is shown.
Question: How can I positively influence the automatic summation of rainfall?
Where can I change the internal formula for summing the Rain Rate, Max. Rain Rate?
or what value do I have to send per impulse?
Hi Cyril,Which driver gives those logs ?
Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: outTemp = 11.05Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: Vbat = 3.52Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: outHumidity = 91.60Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: Isolar = 0.008Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: UV = 0.44Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: rain = 0.00Dec 13 10:41:11 meteo weewx[1013]: wxMesh: packet content: Vsolar = 4.64Dec 13 10:41:11 meteo weewx[1013]: manager: Added record 2019-12-13 10:40:00CET (1576230000) to database 'weewx.sdb'Dec 13 10:41:11 meteo weewx[1013]: manager: Added record 2019-12-13 10:40:00CET (1576230000) to daily summary in 'weewx.sdb'Dec 13 10:41:11 meteo weewx[1013]: reportengine: Running reports for latest time in the database.Dec 13 10:41:11 meteo weewx[1013]: reportengine
# This section configures the mqtt driver
[wxMesh]driver = user.wxMesh
# MQTT specificshost = 192.168.1.181 #localhostclient = weewx_mqttusername = replace_with_your_broker_userpassword = replace_with_your_broker_passwordtopic = weewxpoll_interval = 2
[[label_map]]barometer = barometerpressure = pressurealtimeter = altimeterinTemp = inTempoutTemp = outTempinHumidity = inHumidityoutHumidity = outHumiditywindSpeed = windSpeedwindDir = windDirwindGust = windGustwindGustDir = windGustDirrainRate = rainRaterain = raindewpoint = dewpointwindchill = windchillheatindex = heatindexET = ETradiation = radiationUV = UVextraTemp1 = extraTemp1extraTemp2 = extraTemp2extraTemp3 = extraTemp3soilTemp1 = soilTemp1soilTemp2 = soilTemp2soilTemp3 = soilTemp3soilTemp4 = soilTemp4leafTemp1 = leafTemp1leafTemp2 = leafTemp2extraHumid1 = extraHumid1extraHumid2 = extraHumid2soilMoist1 = soilMoist1soilMoist2 = soilMoist2soilMoist3 = soilMoist3soilMoist4 = soilMoist4leafWet1 = leafWet1leafWet2 = leafWet2rxCheckPercent = rxCheckPercenttxBatteryStatus = txBatteryStatusconsBatteryVoltage = consBatteryVoltagehail = hailhailRate = hailRateheatingTemp = heatingTempheatingVoltage = heatingVoltagesupplyVoltage = supplyVoltagereferenceVoltage = referenceVoltagewindBatteryStatus = windBatteryStatusrainBatteryStatus = rainBatteryStatusoutTempBatteryStatus = outTempBatteryStatusinTempBatteryStatus = inTempBatteryStatus