mirror of
https://github.com/PiBrewing/craftbeerpi4.git
synced 2024-11-10 01:17:42 +01:00
Add Influxdb-cloud connection and log for actor, fermenter and kettles
This commit is contained in:
parent
1ecc8451e4
commit
f8024f3b49
8 changed files with 85 additions and 18 deletions
|
@ -240,6 +240,7 @@ class FermentationController:
|
||||||
if item:
|
if item:
|
||||||
item.target_temp = target_temp
|
item.target_temp = target_temp
|
||||||
self.save()
|
self.save()
|
||||||
|
self.cbpi.log.log_data(item.id, target_temp)
|
||||||
self.push_update()
|
self.push_update()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Failed to set Target Temp {} {}".format(id, e))
|
logging.error("Failed to set Target Temp {} {}".format(id, e))
|
||||||
|
|
|
@ -30,6 +30,7 @@ class KettleController(BasicController):
|
||||||
item = self.find_by_id(id)
|
item = self.find_by_id(id)
|
||||||
item.target_temp = target_temp
|
item.target_temp = target_temp
|
||||||
await self.save()
|
await self.save()
|
||||||
|
self.cbpi.log.log_data(item.id, target_temp)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("Failed to set Target Temp {} {}".format(id, e))
|
logging.error("Failed to set Target Temp {} {}".format(id, e))
|
||||||
|
|
||||||
|
|
|
@ -54,25 +54,66 @@ class LogController:
|
||||||
self.datalogger[name].info("%s,%s" % (formatted_time, value))
|
self.datalogger[name].info("%s,%s" % (formatted_time, value))
|
||||||
|
|
||||||
if self.influxdb == "Yes":
|
if self.influxdb == "Yes":
|
||||||
self.influxdb = self.cbpi.config.get("INFLUXDB", "No")
|
self.influxdbcloud = self.cbpi.config.get("INFLUXDBCLOUD", "No")
|
||||||
self.influxdbaddr = self.cbpi.config.get("INFLUXDBADDR", None)
|
self.influxdbaddr = self.cbpi.config.get("INFLUXDBADDR", None)
|
||||||
self.influxdbport = self.cbpi.config.get("INFLUXDBPORT", None)
|
self.influxdbport = self.cbpi.config.get("INFLUXDBPORT", None)
|
||||||
self.influxdbname = self.cbpi.config.get("INFLUXDBNAME", None)
|
self.influxdbname = self.cbpi.config.get("INFLUXDBNAME", None)
|
||||||
self.influxdbuser = self.cbpi.config.get("INFLUXDBUSER", None)
|
self.influxdbuser = self.cbpi.config.get("INFLUXDBUSER", None)
|
||||||
self.influxdbpwd = self.cbpi.config.get("INFLUXDBPWD", None)
|
self.influxdbpwd = self.cbpi.config.get("INFLUXDBPWD", None)
|
||||||
self.base64string = base64.b64encode(('%s:%s' % (self.influxdbuser,self.influxdbpwd)).encode())
|
|
||||||
self.influxdburl='http://' + self.influxdbaddr + ':' + str(self.influxdbport) + '/write?db=' + self.influxdbname
|
id = name
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
chars = {'ö':'oe','ä':'ae','ü':'ue','Ö':'Oe','Ä':'Ae','Ü':'Ue'}
|
||||||
sensor=self.cbpi.sensor.find_by_id(name)
|
sensor=self.cbpi.sensor.find_by_id(name)
|
||||||
sensorname=sensor.name.replace(" ", "_")
|
if sensor is not None:
|
||||||
out="measurement,source=" + sensorname + "___" + name + " value="+str(value)
|
itemname=sensor.name.replace(" ", "_")
|
||||||
header = {'User-Agent': name, 'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Basic %s' % self.base64string.decode('utf-8')}
|
for char in chars:
|
||||||
http = urllib3.PoolManager()
|
itemname = itemname.replace(char,chars[char])
|
||||||
req = http.request('POST',self.influxdburl, body=out, headers = header)
|
out="sensor,source=" + itemname + ",itemID=" + str(id) + " value="+str(value)
|
||||||
|
else:
|
||||||
|
actor=self.cbpi.actor.find_by_id(name)
|
||||||
|
if actor is not None:
|
||||||
|
itemname=actor.name.replace(" ", "_")
|
||||||
|
for char in chars:
|
||||||
|
itemname = itemname.replace(char,chars[char])
|
||||||
|
out="actor,source=" + itemname + ",itemID=" + str(id) + " value="+str(value)
|
||||||
|
else:
|
||||||
|
kettle=self.cbpi.kettle.find_by_id(name)
|
||||||
|
if kettle is not None:
|
||||||
|
itemname=kettle.name.replace(" ", "_")
|
||||||
|
for char in chars:
|
||||||
|
itemname = itemname.replace(char,chars[char])
|
||||||
|
out="kettle,source=" + itemname + ",itemID=" + str(id) + " value="+str(value)
|
||||||
|
else:
|
||||||
|
fermenter=self.cbpi.fermenter._find_by_id(name)
|
||||||
|
if fermenter is not None:
|
||||||
|
itemname=fermenter.name.replace(" ", "_")
|
||||||
|
for char in chars:
|
||||||
|
itemname = itemname.replace(char,chars[char])
|
||||||
|
out="fermenter,source=" + itemname + ",itemID=" + str(id) + " value="+str(value)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("InfluxDB write Error: {}".format(e))
|
logging.error("InfluxDB ID Error: {}".format(e))
|
||||||
|
|
||||||
|
if self.influxdbcloud == "Yes":
|
||||||
|
self.influxdburl="https://" + self.influxdbaddr + "/api/v2/write?org=" + self.influxdbuser + "&bucket=" + self.influxdbname + "&precision=s"
|
||||||
|
try:
|
||||||
|
header = {'User-Agent': name, 'Authorization': "Token {}".format(self.influxdbpwd)}
|
||||||
|
http = urllib3.PoolManager()
|
||||||
|
req = http.request('POST',self.influxdburl, body=out, headers = header)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error("InfluxDB write Error: {}".format(e))
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.influxdb = self.cbpi.config.get("INFLUXDB", "No")
|
||||||
|
self.base64string = base64.b64encode(('%s:%s' % (self.influxdbuser,self.influxdbpwd)).encode())
|
||||||
|
self.influxdburl='http://' + self.influxdbaddr + ':' + str(self.influxdbport) + '/write?db=' + self.influxdbname
|
||||||
|
|
||||||
|
try:
|
||||||
|
header = {'User-Agent': name, 'Content-Type': 'application/x-www-form-urlencoded','Authorization': 'Basic %s' % self.base64string.decode('utf-8')}
|
||||||
|
http = urllib3.PoolManager()
|
||||||
|
req = http.request('POST',self.influxdburl, body=out, headers = header)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error("InfluxDB write Error: {}".format(e))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@ class ConfigUpdate(CBPiExtension):
|
||||||
influxdbname = self.cbpi.config.get("INFLUXDBNAME", None)
|
influxdbname = self.cbpi.config.get("INFLUXDBNAME", None)
|
||||||
influxdbuser = self.cbpi.config.get("INFLUXDBUSER", None)
|
influxdbuser = self.cbpi.config.get("INFLUXDBUSER", None)
|
||||||
influxdbpwd = self.cbpi.config.get("INFLUXDBPWD", None)
|
influxdbpwd = self.cbpi.config.get("INFLUXDBPWD", None)
|
||||||
|
influxdbcloud = self.cbpi.config.get("INFLUXDBCLOUD", None)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,7 +195,7 @@ class ConfigUpdate(CBPiExtension):
|
||||||
except:
|
except:
|
||||||
logger.warning('Unable to update config')
|
logger.warning('Unable to update config')
|
||||||
|
|
||||||
## Check if CSV logfiles is on config
|
## Check if influxdb is on config
|
||||||
if influxdb is None:
|
if influxdb is None:
|
||||||
logger.info("INIT Influxdb")
|
logger.info("INIT Influxdb")
|
||||||
try:
|
try:
|
||||||
|
@ -208,7 +209,7 @@ class ConfigUpdate(CBPiExtension):
|
||||||
if influxdbaddr is None:
|
if influxdbaddr is None:
|
||||||
logger.info("INIT Influxdbaddr")
|
logger.info("INIT Influxdbaddr")
|
||||||
try:
|
try:
|
||||||
await self.cbpi.config.add("INFLUXDBADDR", "localhost", ConfigType.STRING, "IP Address of your influxdb server")
|
await self.cbpi.config.add("INFLUXDBADDR", "localhost", ConfigType.STRING, "IP Address of your influxdb server (If INFLUXDBCLOUD set to Yes use URL Address of your influxdb cloud server)")
|
||||||
except:
|
except:
|
||||||
logger.warning('Unable to update config')
|
logger.warning('Unable to update config')
|
||||||
|
|
||||||
|
@ -224,23 +225,33 @@ class ConfigUpdate(CBPiExtension):
|
||||||
if influxdbname is None:
|
if influxdbname is None:
|
||||||
logger.info("INIT Influxdbname")
|
logger.info("INIT Influxdbname")
|
||||||
try:
|
try:
|
||||||
await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", ConfigType.STRING, "Name of your influxdb database name")
|
await self.cbpi.config.add("INFLUXDBNAME", "cbpi4", ConfigType.STRING, "Name of your influxdb database name (If INFLUXDBCLOUD set to Yes use bucket of your influxdb cloud database)")
|
||||||
except:
|
except:
|
||||||
logger.warning('Unable to update config')
|
logger.warning('Unable to update config')
|
||||||
|
|
||||||
## Check if influxdber is in config
|
## Check if influxduser is in config
|
||||||
if influxdbuser is None:
|
if influxdbuser is None:
|
||||||
logger.info("INIT Influxdbuser")
|
logger.info("INIT Influxdbuser")
|
||||||
try:
|
try:
|
||||||
await self.cbpi.config.add("INFLUXDBUSER", " ", ConfigType.STRING, "User name for your influxdb database (only if required)")
|
await self.cbpi.config.add("INFLUXDBUSER", " ", ConfigType.STRING, "User name for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use organisation of your influxdb cloud database)")
|
||||||
except:
|
except:
|
||||||
logger.warning('Unable to update config')
|
logger.warning('Unable to update config')
|
||||||
|
|
||||||
## Check if influxdber is in config
|
## Check if influxdpwd is in config
|
||||||
if influxdbpwd is None:
|
if influxdbpwd is None:
|
||||||
logger.info("INIT Influxdbpwd")
|
logger.info("INIT Influxdbpwd")
|
||||||
try:
|
try:
|
||||||
await self.cbpi.config.add("INFLUXDBPWD", " ", ConfigType.STRING, "Password for your influxdb database (only if required)")
|
await self.cbpi.config.add("INFLUXDBPWD", " ", ConfigType.STRING, "Password for your influxdb database (only if required)(If INFLUXDBCLOUD set to Yes use token of your influxdb cloud database)")
|
||||||
|
except:
|
||||||
|
logger.warning('Unable to update config')
|
||||||
|
|
||||||
|
## Check if influxdb cloud is on config
|
||||||
|
if influxdbcloud is None:
|
||||||
|
logger.info("INIT influxdbcloud")
|
||||||
|
try:
|
||||||
|
await self.cbpi.config.add("INFLUXDBCLOUD", "No", ConfigType.SELECT, "Write sensor data to influxdb cloud (INFLUXDB must set to Yes)",
|
||||||
|
[{"label": "Yes", "value": "Yes"},
|
||||||
|
{"label": "No", "value": "No"}])
|
||||||
except:
|
except:
|
||||||
logger.warning('Unable to update config')
|
logger.warning('Unable to update config')
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,12 @@ class DummyActor(CBPiActor):
|
||||||
await super().start()
|
await super().start()
|
||||||
|
|
||||||
async def on(self, power=0):
|
async def on(self, power=0):
|
||||||
|
self.log_data(100)
|
||||||
logger.info("ACTOR %s ON " % self.id)
|
logger.info("ACTOR %s ON " % self.id)
|
||||||
self.state = True
|
self.state = True
|
||||||
|
|
||||||
async def off(self):
|
async def off(self):
|
||||||
|
self.log_data(0)
|
||||||
logger.info("ACTOR %s OFF " % self.id)
|
logger.info("ACTOR %s OFF " % self.id)
|
||||||
|
|
||||||
self.state = False
|
self.state = False
|
||||||
|
|
|
@ -63,11 +63,13 @@ class GPIOActor(CBPiActor):
|
||||||
self.power = 100
|
self.power = 100
|
||||||
await self.set_power(self.power)
|
await self.set_power(self.power)
|
||||||
|
|
||||||
|
self.log_data(self.power)
|
||||||
logger.info("ACTOR %s ON - GPIO %s " % (self.id, self.gpio))
|
logger.info("ACTOR %s ON - GPIO %s " % (self.id, self.gpio))
|
||||||
GPIO.output(self.gpio, self.get_GPIO_state(1))
|
GPIO.output(self.gpio, self.get_GPIO_state(1))
|
||||||
self.state = True
|
self.state = True
|
||||||
|
|
||||||
async def off(self):
|
async def off(self):
|
||||||
|
self.log_data(0)
|
||||||
logger.info("ACTOR %s OFF - GPIO %s " % (self.id, self.gpio))
|
logger.info("ACTOR %s OFF - GPIO %s " % (self.id, self.gpio))
|
||||||
GPIO.output(self.gpio, self.get_GPIO_state(0))
|
GPIO.output(self.gpio, self.get_GPIO_state(0))
|
||||||
self.state = False
|
self.state = False
|
||||||
|
@ -93,6 +95,8 @@ class GPIOActor(CBPiActor):
|
||||||
|
|
||||||
async def set_power(self, power):
|
async def set_power(self, power):
|
||||||
self.power = power
|
self.power = power
|
||||||
|
if self.state == True:
|
||||||
|
self.log_data(self.power)
|
||||||
await self.cbpi.actor.actor_update(self.id,power)
|
await self.cbpi.actor.actor_update(self.id,power)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -131,6 +135,7 @@ class GPIOPWMActor(CBPiActor):
|
||||||
|
|
||||||
logging.info("PWM Final Power: {}".format(self.power))
|
logging.info("PWM Final Power: {}".format(self.power))
|
||||||
|
|
||||||
|
self.log_data(self.power)
|
||||||
logger.info("PWM ACTOR %s ON - GPIO %s - Frequency %s - Power %s" % (self.id, self.gpio,self.frequency,self.power))
|
logger.info("PWM ACTOR %s ON - GPIO %s - Frequency %s - Power %s" % (self.id, self.gpio,self.frequency,self.power))
|
||||||
try:
|
try:
|
||||||
if self.p is None:
|
if self.p is None:
|
||||||
|
@ -142,12 +147,14 @@ class GPIOPWMActor(CBPiActor):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def off(self):
|
async def off(self):
|
||||||
|
self.log_data(0)
|
||||||
logger.info("PWM ACTOR %s OFF - GPIO %s " % (self.id, self.gpio))
|
logger.info("PWM ACTOR %s OFF - GPIO %s " % (self.id, self.gpio))
|
||||||
self.p.ChangeDutyCycle(0)
|
self.p.ChangeDutyCycle(0)
|
||||||
self.state = False
|
self.state = False
|
||||||
|
|
||||||
async def set_power(self, power):
|
async def set_power(self, power):
|
||||||
if self.p and self.state == True:
|
if self.p and self.state == True:
|
||||||
|
self.log_data(self.power)
|
||||||
self.p.ChangeDutyCycle(power)
|
self.p.ChangeDutyCycle(power)
|
||||||
await self.cbpi.actor.actor_update(self.id,power)
|
await self.cbpi.actor.actor_update(self.id,power)
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -27,11 +27,13 @@ class GenericMqttActor(MQTTActor):
|
||||||
|
|
||||||
async def on(self, power=None):
|
async def on(self, power=None):
|
||||||
self.normalize_power_value(power)
|
self.normalize_power_value(power)
|
||||||
|
self.log_data(self.power)
|
||||||
formatted_payload = self.payload.format(switch_onoff = "on", switch_10 = 1, power = self.power)
|
formatted_payload = self.payload.format(switch_onoff = "on", switch_10 = 1, power = self.power)
|
||||||
await self.publish_mqtt_message(self.topic, formatted_payload)
|
await self.publish_mqtt_message(self.topic, formatted_payload)
|
||||||
self.state = True
|
self.state = True
|
||||||
|
|
||||||
async def off(self):
|
async def off(self):
|
||||||
|
self.log_data(0)
|
||||||
formatted_payload = self.payload.format(switch_onoff = "off", switch_10 = 0, power = self.power)
|
formatted_payload = self.payload.format(switch_onoff = "off", switch_10 = 0, power = self.power)
|
||||||
await self.publish_mqtt_message(self.topic, formatted_payload)
|
await self.publish_mqtt_message(self.topic, formatted_payload)
|
||||||
self.state = False
|
self.state = False
|
|
@ -29,6 +29,7 @@ class MQTTActor(CBPiActor):
|
||||||
power = min(100, power)
|
power = min(100, power)
|
||||||
power = max(0, power)
|
power = max(0, power)
|
||||||
self.power = round(power)
|
self.power = round(power)
|
||||||
|
self.log_data(self.power)
|
||||||
await self.cbpi.satellite.publish(self.topic, json.dumps(
|
await self.cbpi.satellite.publish(self.topic, json.dumps(
|
||||||
{"state": "on", "power": self.power}), True)
|
{"state": "on", "power": self.power}), True)
|
||||||
self.state = True
|
self.state = True
|
||||||
|
@ -36,6 +37,7 @@ class MQTTActor(CBPiActor):
|
||||||
|
|
||||||
async def off(self):
|
async def off(self):
|
||||||
self.state = False
|
self.state = False
|
||||||
|
self.log_data(0)
|
||||||
await self.cbpi.satellite.publish(self.topic, json.dumps(
|
await self.cbpi.satellite.publish(self.topic, json.dumps(
|
||||||
{"state": "off", "power": self.power}), True)
|
{"state": "off", "power": self.power}), True)
|
||||||
pass
|
pass
|
||||||
|
|
Loading…
Reference in a new issue