Compare commits

...

6 Commits

Author SHA1 Message Date
Sebastian Lohff 25b13553c7 co2: round to first decimal place 2021-01-11 01:47:54 +01:00
Sebastian Lohff 3a086962c0 WIP: MQTT combined mode 2021-01-10 23:32:09 +01:00
Sebastian Lohff 34f35cf13a Discard first DS18B12 measurement on ESP
Looks a bit like it's in fahrenheit, but it is definitely messing up my
graphs!
2021-01-10 03:22:37 +01:00
Sebastian Lohff 36e033e0f7 Don't shadow python builtins 2021-01-10 03:17:10 +01:00
Sebastian Lohff 53821074d6 Rename mqtt_topic to default topic 2021-01-10 03:16:51 +01:00
Sebastian Lohff 59f32940f7 Add debug flag 2021-01-10 03:13:50 +01:00
6 changed files with 59 additions and 13 deletions

View File

@ -15,13 +15,20 @@ def main():
if sys.implementation.name != 'micropython': if sys.implementation.name != 'micropython':
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument("-c", "--config", default="/etc/mqtt-sensord.conf") parser.add_argument("-c", "--config", default="/etc/mqtt-sensord.conf")
parser.add_argument("-d", "--debug", action="store_true", default=False)
args = parser.parse_args() args = parser.parse_args()
config_path = args.config config_path = args.config
debug = args.debug
else: else:
# most probably on micropython # most probably on micropython
config_path = "mqtt-sensord.conf" config_path = "mqtt-sensord.conf"
debug = False
config = sensorlib.load_config(config_path) config = sensorlib.load_config(config_path)
debug = debug or config.get('debug')
config['debug'] = debug
esp_reset_time = config['host'].get('esp-reset-time')
sensorlib.Sensor.configure(config['host']['name'], sys.platform) sensorlib.Sensor.configure(config['host']['name'], sys.platform)
mcfg = config['mqtt'] mcfg = config['mqtt']
@ -30,9 +37,10 @@ def main():
else: else:
client_id = None client_id = None
mqtt_mode = config['mqtt'].get('mode', 'split')
mqtt = MQTTClient(mcfg['host'], mcfg['user'], mcfg['password'], client_id) mqtt = MQTTClient(mcfg['host'], mcfg['user'], mcfg['password'], client_id)
mqtt_topic = mcfg['sensor_topic'] default_mqtt_topic = mcfg.get('sensor_topic')
print("Connected to", mqtt.host, "with topic", mqtt_topic) print("Connected to", mqtt.host, "with default topic", default_mqtt_topic)
mqtt.set_callback(sensorlib.Sensor.run_mqtt_callback) mqtt.set_callback(sensorlib.Sensor.run_mqtt_callback)
sensors = [] sensors = []
@ -48,17 +56,35 @@ def main():
print("Subscribe to", topic) print("Subscribe to", topic)
mqtt.subscribe(topic) mqtt.subscribe(topic)
last_measurement = time.time() last_measurement = start_time = time.time()
while True: while True:
# handle regular sensor data # handle regular sensor data
if debug:
print("Getting values from sensors...") print("Getting values from sensors...")
if mqtt_mode == 'split':
for sensor in sensors: for sensor in sensors:
if sensor.HAS_SENSOR_DATA: if sensor.HAS_SENSOR_DATA:
data = sensor.gen_datapoint() data = sensor.gen_datapoint()
print(mqtt_topic, data) if debug:
mqtt.send_data(mqtt_topic, data) print(default_mqtt_topic, data)
mqtt.send_data(default_mqtt_topic, data)
if not mqtt.is_async(): if not mqtt.is_async():
mqtt.process_mqtt() mqtt.process_mqtt()
elif mqtt_mode == 'combined':
data = {
'hostname': config['host']['name'],
'platform': sys.platform,
}
for sensor in sensors:
if sensor.HAS_SENSOR_DATA:
data[sensor.id] = sensor.get_data()
if debug:
print(default_mqtt_topic, data)
mqtt.send_data(default_mqtt_topic, data)
if not mqtt.is_async():
mqtt.process_mqtt()
else:
raise RuntimeError("Unknown mqtt mode {}".format(mqtt_mode))
if mqtt.is_async(): if mqtt.is_async():
time.sleep(max(0.0, time.time() + config['host']['interval'] - last_measurement)) time.sleep(max(0.0, time.time() + config['host']['interval'] - last_measurement))
@ -68,6 +94,11 @@ def main():
time.sleep(0.1) time.sleep(0.1)
last_measurement = time.time() last_measurement = time.time()
if sys.implementation.name == 'micropython' and esp_reset_time and \
last_measurement - start_time > esp_reset_time:
import machine
machine.reset()
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -15,3 +15,6 @@ class MQTTClientBase:
def is_async(self): def is_async(self):
return False return False
def process_mqtt(self):
pass

View File

@ -9,8 +9,13 @@ class MQTTClient(MQTTClientBase):
def _connect(self): def _connect(self):
self._mqtt = mqtt.Client(self.client_id) self._mqtt = mqtt.Client(self.client_id)
self._mqtt.username_pw_set(self.user, self.password) self._mqtt.username_pw_set(self.user, self.password)
self._mqtt.on_connect = self.on_connect
self._mqtt.connect(self.host) self._mqtt.connect(self.host)
def on_connect(self, *args, **kwargs):
#print("Connected! client={} userdata={} msg={}".format(client, userdata, msg))
print("Connected!", *args, **kwargs)
def send_data(self, topic, data): def send_data(self, topic, data):
self._mqtt.publish(topic, json.dumps(data)) self._mqtt.publish(topic, json.dumps(data))

View File

@ -41,7 +41,7 @@ class Sensor(object):
def get_data(self): def get_data(self):
raise NotImplementedError("You missed a spot!") raise NotImplementedError("You missed a spot!")
def gen_datapoint(self): def gen_datapoint(self, legacy=True):
return { return {
'type': 'measurement', 'type': 'measurement',
'tags': { 'tags': {

View File

@ -18,11 +18,18 @@ class DS18B20(Sensor):
self.o = onewire.OneWire(machine.Pin(self.pin)) self.o = onewire.OneWire(machine.Pin(self.pin))
self.ds = ds18x20.DS18X20(self.o) self.ds = ds18x20.DS18X20(self.o)
self.sID = self.ds.scan()[0] self.sID = self.ds.scan()[0]
self._first_measurement = True
def get_data(self): def get_data(self):
self.ds.convert_temp() self.ds.convert_temp()
time.sleep(0.1) time.sleep(0.1)
return {"temp": self.ds.read_temp(self.sID)} val = self.ds.read_temp(self.sID)
if self._first_measurement:
if val > 70.0:
val = None
else:
self._first_measurement = False
return {"temp": val}
@sensor @sensor

View File

@ -134,12 +134,12 @@ class CO2Meter(Sensor):
def get_temp(self): def get_temp(self):
if 0x42 in self.values: if 0x42 in self.values:
return self.values[0x42] / 16.0 - 273.15 return round(self.values[0x42] / 16.0 - 273.15, 1)
return None return None
def get_humidity(self): def get_humidity(self):
if 0x44 in self.values: if 0x44 in self.values:
return self.values[0x44] / 100.0 return round(self.values[0x44] / 100.0, 1)
return None return None
def get_data(self): def get_data(self):