Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust temperature under usb power #142

Merged
merged 22 commits into from
Feb 12, 2023
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion enviro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def get_sensor_readings():
logging.info(f" - seconds since last reading: {seconds_since_last}")


readings = get_board().get_sensor_readings(seconds_since_last)
readings = get_board().get_sensor_readings(seconds_since_last, vbus_present)
# readings["voltage"] = 0.0 # battery_voltage #Temporarily removed until issue is fixed

# write out the last time log
Expand Down Expand Up @@ -473,6 +473,8 @@ def startup():
# get the reason we were woken up
reason = get_wake_reason()

add_missing_config_settings()

# give each board a chance to perform any startup it needs
# ===========================================================================
board = get_board()
Expand Down Expand Up @@ -510,6 +512,23 @@ def startup():
if reason == WAKE_REASON_RTC_ALARM:
sleep()

def add_missing_config_settings():
# check if ca file paramter is set, if not set it to not use SSL by setting to None
try:
config.mqtt_broker_ca_file
except AttributeError:
warn_missing_config_setting("mqtt_broker_ca_file")
config.mqtt_broker_ca_file = None

try:
config.usb_power_temperature_offset
except AttributeError:
warn_missing_config_setting("usb_power_temperature_offset")
config.usb_power_temperature_offset = DEFAULT_USB_POWER_TEMPERATURE_OFFSET

def warn_missing_config_setting(setting):
logging.warn(f" - config setting '{setting}' missing - please add it to config.py")

def sleep(time_override=None):
if time_override is not None:
logging.info(f"> going to sleep for {time_override} minute(s)")
Expand Down
2 changes: 1 addition & 1 deletion enviro/boards/grow.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def water(moisture_levels):
drip_noise()
time.sleep(0.5)

def get_sensor_readings(seconds_since_last):
def get_sensor_readings(seconds_since_last, is_usb_power):
# bme280 returns the register contents immediately and then starts a new reading
# we want the current reading so do a dummy read to discard register contents first
bme280.read()
Expand Down
17 changes: 14 additions & 3 deletions enviro/boards/indoor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import enviro.helpers as helpers
import math
from breakout_bme68x import BreakoutBME68X
from breakout_bh1745 import BreakoutBH1745

from enviro import config
from enviro import i2c

bme688 = BreakoutBME68X(i2c, address=0x77)
Expand Down Expand Up @@ -40,12 +42,21 @@ def colour_temperature_from_rgbc(r, g, b, c):
ct = 10000
return round(ct)

def get_sensor_readings(seconds_since_last):
def get_sensor_readings(seconds_since_last, is_usb_power):
data = bme688.read()

temperature = round(data[0], 2)
pressure = round(data[1] / 100.0, 2)
humidity = round(data[2], 2)

# Compensate for additional heating when on usb power - this also changes the
# relative humidity value.
if is_usb_power:
adjusted_temperature = temperature - config.usb_power_temperature_offset
macifell marked this conversation as resolved.
Show resolved Hide resolved
absolute_humidity = helpers.relative_to_absolute_humidity(humidity, temperature)
humidity = helpers.absolute_to_relative_humidity(absolute_humidity, adjusted_temperature)
temperature = adjusted_temperature

pressure = round(data[1] / 100.0, 2)
gas_resistance = round(data[3])
# an approximate air quality calculation that accounts for the effect of
# humidity on the gas sensor
Expand All @@ -64,4 +75,4 @@ def get_sensor_readings(seconds_since_last):
"aqi": aqi,
"luminance": lux_from_rgbc(r, g, b, c),
"color_temperature": colour_temperature_from_rgbc(r, g, b, c)
})
})
2 changes: 1 addition & 1 deletion enviro/boards/urban.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def particulates(particulate_data, measure):
multiplier = 10 if measure >= PM0_3_PER_LITRE else 1
return ((particulate_data[measure * 2] << 8) | particulate_data[measure * 2 + 1]) * multiplier

def get_sensor_readings(seconds_since_last):
def get_sensor_readings(seconds_since_last, is_usb_power):
# bme280 returns the register contents immediately and then starts a new reading
# we want the current reading so do a dummy read to discard register contents first
bme280.read()
Expand Down
2 changes: 1 addition & 1 deletion enviro/boards/weather.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def rainfall(seconds_since_last):

return amount, per_second

def get_sensor_readings(seconds_since_last):
def get_sensor_readings(seconds_since_last, is_usb_power):
# bme280 returns the register contents immediately and then starts a new reading
# we want the current reading so do a dummy read to discard register contents first
bme280.read()
Expand Down
5 changes: 4 additions & 1 deletion enviro/config_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,7 @@
auto_water = False
moisture_target_a = 50
moisture_target_b = 50
moisture_target_c = 50
moisture_target_c = 50

# compensate for usb power
usb_power_temperature_offset = 4.5
8 changes: 8 additions & 0 deletions enviro/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,11 @@
UPLOAD_RATE_LIMITED = 2
UPLOAD_LOST_SYNC = 3
UPLOAD_SKIP_FILE = 4

# humidity
WATER_VAPOR_SPECIFIC_GAS_CONSTANT = 461.5
CRITICAL_WATER_TEMPERATURE = 647.096
CRITICAL_WATER_PRESSURE = 22064000

# default values
DEFAULT_USB_POWER_TEMPERATURE_OFFSET = 4.5
6 changes: 0 additions & 6 deletions enviro/destinations/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ def upload_reading(reading):
password = config.mqtt_broker_password
nickname = reading["nickname"]

# check if ca file paramter is set, if not set it to not use SSL by setting to None
try:
config.mqtt_broker_ca_file
except AttributeError:
config.mqtt_broker_ca_file = None

try:
if config.mqtt_broker_ca_file:
# Using SSL
Expand Down
43 changes: 42 additions & 1 deletion enviro/helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from enviro.constants import *
import machine, os, time
import machine, math, os, time

# miscellany
# ===========================================================================
Expand Down Expand Up @@ -57,3 +57,44 @@ def copy_file(source, target):
if not chunk:
break
outfile.write(chunk)

# temperature and humidity helpers
# ===========================================================================

# https://www.calctool.org/atmospheric-thermodynamics/absolute-humidity#what-is-and-how-to-calculate-absolute-humidity
def relative_to_absolute_humidity(relative_humidity, temperature_in_c):
temperature_in_k = celcius_to_kelvin(temperature_in_c)
actual_vapor_pressure = get_actual_vapor_pressure(relative_humidity, temperature_in_k)

return actual_vapor_pressure / (WATER_VAPOR_SPECIFIC_GAS_CONSTANT * temperature_in_k)

def absolute_to_relative_humidity(absolute_humidity, temperature_in_c):
temperature_in_k = celcius_to_kelvin(temperature_in_c)
saturation_vapor_pressure = get_saturation_vapor_pressure(temperature_in_k)

return (WATER_VAPOR_SPECIFIC_GAS_CONSTANT * temperature_in_k * absolute_humidity) / saturation_vapor_pressure * 100

def celcius_to_kelvin(temperature_in_c):
return temperature_in_c + 273.15

# https://www.calctool.org/atmospheric-thermodynamics/absolute-humidity#actual-vapor-pressure
# http://cires1.colorado.edu/~voemel/vp.html
def get_actual_vapor_pressure(relative_humidity, temperature_in_k):
return get_saturation_vapor_pressure(temperature_in_k) * (relative_humidity / 100)

def get_saturation_vapor_pressure(temperature_in_k):
v = 1 - (temperature_in_k / CRITICAL_WATER_TEMPERATURE)

# empirical constants
a1 = -7.85951783
a2 = 1.84408259
a3 = -11.7866497
a4 = 22.6807411
a5 = -15.9618719
a6 = 1.80122502

return CRITICAL_WATER_PRESSURE * math.exp(
CRITICAL_WATER_TEMPERATURE /
temperature_in_k *
(a1*v + a2*v**1.5 + a3*v**3 + a4*v**3.5 + a5*v**4 + a6*v**7.5)
)
2 changes: 1 addition & 1 deletion enviro/provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,4 +207,4 @@ def catchall(request):
logging.info(" - client connected!", ap.status("stations")[0])

logging.info("> running provisioning application...")
server.run(host="0.0.0.0", port=80)
server.run(host="0.0.0.0", port=80)
macifell marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@
# here you can customise the sensor readings by adding extra information
# or removing readings that you don't want, for example:
#
# del readings["temperature"] # remove the temperature reading
# del reading["temperature"] # remove the temperature reading
macifell marked this conversation as resolved.
Show resolved Hide resolved
#
# readings["custom"] = my_reading() # add my custom reading value
# reading["custom"] = my_reading() # add my custom reading value

# is an upload destination set?
if enviro.config.destination:
Expand Down