Merge pull request #441 from d-buchmann/master
Resolve merge conflicts for adding BME680
This commit was merged in pull request #441.
This commit is contained in:
86
octoprint_enclosure/BME680.py
Normal file
86
octoprint_enclosure/BME680.py
Normal file
@@ -0,0 +1,86 @@
|
||||
import bme680
|
||||
import time
|
||||
|
||||
|
||||
try:
|
||||
sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY)
|
||||
except IOError:
|
||||
sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY)
|
||||
|
||||
hum_weighting = float(0.25) # so hum effect is 25% of the total air quality score
|
||||
gas_weighting = float(0.75) # so gas effect is 75% of the total air quality score
|
||||
|
||||
sensor.set_humidity_oversample(bme680.OS_2X)
|
||||
sensor.set_pressure_oversample(bme680.OS_2X)
|
||||
sensor.set_temperature_oversample(bme680.OS_2X)
|
||||
sensor.set_filter(bme680.FILTER_SIZE_3)
|
||||
|
||||
sensor.set_gas_heater_temperature(320)
|
||||
sensor.set_gas_heater_duration(150)
|
||||
sensor.select_gas_heater_profile(0)
|
||||
sensor.set_gas_status(bme680.ENABLE_GAS_MEAS)
|
||||
|
||||
gas_reference = float(250000)
|
||||
hum_reference = float(40)
|
||||
getgasreference_count = int(0)
|
||||
|
||||
|
||||
def GetGasReference(gas_reference):
|
||||
# Now run the sensor for a burn-in period, then use combination of relative humidity and gas resistance to estimate indoor air quality as a percentage.
|
||||
# print("Getting a new gas reference value")
|
||||
readings = int(10)
|
||||
while True:
|
||||
sensor.get_sensor_data()
|
||||
if sensor.data.heat_stable:
|
||||
for i in range(1, readings): # // read gas for 10 x 0.150mS = 1.5secs
|
||||
sensor.get_sensor_data()
|
||||
gas_reference = gas_reference + sensor.data.gas_resistance
|
||||
gas_reference = gas_reference / readings
|
||||
return
|
||||
|
||||
def CalculateIAQ(score):
|
||||
IAQ_text = "Air quality is "
|
||||
score = float((100 - score) * 5)
|
||||
if score >= 301:
|
||||
IAQ_text = IAQ_text + "Hazardous"
|
||||
elif score >= 201 and score <= 300:
|
||||
IAQ_text = IAQ_text + "Very Unhealthy"
|
||||
elif score >= 176 and score <= 200:
|
||||
IAQ_text = IAQ_text + "Unhealthy"
|
||||
elif score >= 151 and score <= 175:
|
||||
IAQ_text = IAQ_text + "Unhealthy for Sensitive Groups"
|
||||
elif score >= 51 and score <= 150:
|
||||
IAQ_text = IAQ_text + "Moderate"
|
||||
elif score >= 00 and score <= 50:
|
||||
IAQ_text = IAQ_text + "Good"
|
||||
return IAQ_text
|
||||
|
||||
#Calculate humidity contribution to IAQ index
|
||||
current_humidity = float(sensor.data.humidity)
|
||||
if (current_humidity >= 38 and current_humidity <= 42):
|
||||
hum_score = float(0.25*100) # Humidity +/-5% around optimum
|
||||
else:
|
||||
#sub-optimal
|
||||
if (current_humidity < 38):
|
||||
hum_score = float(0.25/hum_reference*current_humidity*100)
|
||||
else:
|
||||
hum_score = ((-0.25/(100-hum_reference)*current_humidity)+0.416666)*100
|
||||
|
||||
#Calculate gas contribution to IAQ index
|
||||
gas_lower_limit = float(5000) # Bad air quality limit
|
||||
gas_upper_limit = float(50000) # Good air quality limit
|
||||
|
||||
if gas_reference > gas_upper_limit:
|
||||
gas_reference = gas_upper_limit
|
||||
if gas_reference < gas_lower_limit:
|
||||
gas_reference = gas_lower_limit
|
||||
|
||||
gas_score = float((0.75/(gas_upper_limit-gas_lower_limit)*gas_reference -(gas_lower_limit*(0.75/(gas_upper_limit-gas_lower_limit))))*100)
|
||||
|
||||
#Combine results for the final IAQ index value (0-100% where 100% is good quality air)
|
||||
air_quality_score = float(hum_score + gas_score)
|
||||
|
||||
GetGasReference(gas_reference)
|
||||
|
||||
print('{0:0.1f}'.format(air_quality_score))
|
||||
|
||||
@@ -808,13 +808,13 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP
|
||||
try:
|
||||
sensor_data = []
|
||||
for sensor in list(filter(lambda item: item['input_type'] == 'temperature_sensor', self.rpi_inputs)):
|
||||
temp, hum = self.get_sensor_data(sensor)
|
||||
temp, hum, airquality = self.get_sensor_data(sensor)
|
||||
if self._settings.get(["debug_temperature_log"]) is True:
|
||||
self._logger.debug("Sensor %s Temperature: %s humidity %s", sensor['label'], temp, hum)
|
||||
if temp is not None and hum is not None:
|
||||
self._logger.debug("Sensor %s Temperature: %s humidity %s Airquality %s", sensor['label'], temp, hum, airquality)
|
||||
if temp is not None and hum is not None and airquality is not None:
|
||||
sensor["temp_sensor_temp"] = temp
|
||||
sensor["temp_sensor_humidity"] = hum
|
||||
sensor_data.append(dict(index_id=sensor['index_id'], temperature=temp, humidity=hum))
|
||||
sensor_data.append(dict(index_id=sensor['index_id'], temperature=temp, humidity=hum, airquality=airquality))
|
||||
self.temperature_sensor_data = sensor_data
|
||||
self.handle_temp_hum_control()
|
||||
self.handle_temperature_events()
|
||||
@@ -978,45 +978,58 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP
|
||||
def get_sensor_data(self, sensor):
|
||||
try:
|
||||
if self.development_mode:
|
||||
temp, hum = self.read_dummy_temp()
|
||||
temp, hum, airquality = self.read_dummy_temp()
|
||||
else:
|
||||
if sensor['temp_sensor_type'] in ["11", "22", "2302"]:
|
||||
temp, hum = self.read_dht_temp(sensor['temp_sensor_type'], sensor['gpio_pin'])
|
||||
elif sensor['temp_sensor_type'] == "18b20":
|
||||
temp = self.read_18b20_temp(sensor['ds18b20_serial'])
|
||||
hum = 0
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "bme280":
|
||||
temp, hum = self.read_bme280_temp(sensor['temp_sensor_address'])
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "bme680":
|
||||
temp, hum, airquality = self.read_bme680_temp(sensor['temp_sensor_address'])
|
||||
elif sensor['temp_sensor_type'] == "am2320":
|
||||
temp, hum = self.read_am2320_temp() # sensor has fixed address
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "rpi":
|
||||
temp = self.read_rpi_temp() # rpi CPU Temp
|
||||
hum = 0
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "si7021":
|
||||
temp, hum = self.read_si7021_temp(sensor['temp_sensor_address'], sensor['temp_sensor_i2cbus'])
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "tmp102":
|
||||
temp = self.read_tmp102_temp(sensor['temp_sensor_address'])
|
||||
hum = 0
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "max31855":
|
||||
temp = self.read_max31855_temp(sensor['temp_sensor_address'])
|
||||
hum = 0
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "mcp9808":
|
||||
temp = self.read_mcp_temp(sensor['temp_sensor_address'])
|
||||
hum = 0
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "temp_raw_i2c":
|
||||
temp, hum = self.read_raw_i2c_temp(sensor)
|
||||
airquality = 0
|
||||
elif sensor['temp_sensor_type'] == "hum_raw_i2c":
|
||||
hum, temp = self.read_raw_i2c_temp(sensor)
|
||||
airquality = 0
|
||||
else:
|
||||
self._logger.info("temp_sensor_type no match")
|
||||
temp = None
|
||||
hum = None
|
||||
if temp != -1 and hum != -1:
|
||||
if temp != -1 and hum != -1 and airquality != -1:
|
||||
temp = round(self.to_float(temp), 1) if not sensor['use_fahrenheit'] else round(
|
||||
self.to_float(temp) * 1.8 + 32, 1)
|
||||
hum = round(self.to_float(hum), 1)
|
||||
return temp, hum
|
||||
return None, None
|
||||
airquality = round(self.to_float(airquality), 1)
|
||||
return temp, hum, airquality
|
||||
return None, None, None
|
||||
except Exception as ex:
|
||||
self.log_error(ex)
|
||||
|
||||
@@ -1053,7 +1066,7 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP
|
||||
|
||||
self.dummy_value = return_value
|
||||
|
||||
return return_value, return_value
|
||||
return return_value, return_value, return_value
|
||||
|
||||
def read_raw_i2c_temp(self, sensor):
|
||||
try:
|
||||
@@ -1143,6 +1156,31 @@ class EnclosurePlugin(octoprint.plugin.StartupPlugin, octoprint.plugin.TemplateP
|
||||
"Failed to execute python scripts, try disabling use SUDO on advanced section of the plugin.")
|
||||
self.log_error(ex)
|
||||
return (0, 0)
|
||||
|
||||
def read_bme680_temp(self, address):
|
||||
try:
|
||||
script = os.path.dirname(os.path.realpath(__file__)) + "/BME680.py "
|
||||
cmd = [sys.executable, script, str(address)]
|
||||
if self._settings.get(["use_sudo"]):
|
||||
cmd.insert(0, "sudo")
|
||||
if self._settings.get(["debug_temperature_log"]) is True:
|
||||
self._logger.debug("Temperature BME680 cmd: %s", cmd)
|
||||
|
||||
stdout = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)
|
||||
output, errors = stdout.communicate()
|
||||
|
||||
if self._settings.get(["debug_temperature_log"]) is True:
|
||||
if len(errors) > 0:
|
||||
self._logger.error("BME680 error: %s", errors)
|
||||
else:
|
||||
self._logger.debug("BME680 result: %s", output)
|
||||
temp, hum, airq = output.split("|")
|
||||
return (self.to_float(temp.strip()), self.to_float(hum.strip()), self.to_float(airq.strip()))
|
||||
except Exception as ex:
|
||||
self._logger.info(
|
||||
"Failed to execute python scripts, try disabling use SUDO on advanced section of the plugin.")
|
||||
self.log_error(ex)
|
||||
return (0, 0)
|
||||
|
||||
def read_am2320_temp(self):
|
||||
try:
|
||||
|
||||
@@ -609,6 +609,7 @@
|
||||
<option value="18b20">DS18B20</option>
|
||||
<option value="si7021">SI7021</option>
|
||||
<option value="bme280">BME280</option>
|
||||
<option value="bme680">BME680</option>
|
||||
<option value="am2320">AM2320</option>
|
||||
<option value="tmp102">TMP102</option>
|
||||
<option value="max31855">MAX31855</option>
|
||||
|
||||
2
setup.py
2
setup.py
@@ -33,7 +33,7 @@ plugin_url = "https://github.com/vitormhenrique/OctoPrint-Enclosure"
|
||||
plugin_license = "AGPLv3"
|
||||
|
||||
# Any additional requirements besides OctoPrint should be listed here
|
||||
plugin_requires = ["RPi.GPIO>=0.6.5", "requests>=2.7", "smbus2>=0.3.0", "gpiozero==1.6.2", "RPi.bme280"]
|
||||
plugin_requires = ["RPi.GPIO>=0.6.5", "requests>=2.7", "smbus2>=0.3.0", "gpiozero==1.6.2", "RPi.bme280", "bme680"]
|
||||
|
||||
additional_setup_parameters = {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user