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

Home Assistant (HASS) Discovery via MQTT #156

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
14 changes: 14 additions & 0 deletions enviro/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,20 @@ def upload_readings():

return True

# HASS Discovery
def hass_discovery():
destination = config.destination
try:
exec(f"import enviro.destinations.{destination}")
destination_module = sys.modules[f"enviro.destinations.{destination}"]
destination_module.hass_discovery(model)
config.hass_discovery_triggered = True
except ImportError:
logging.error(f"! cannot find destination {destination}")
return False
except:
logging.error(f"Unknown error in setting HASS Discovery")

def startup():
import sys

Expand Down
2 changes: 2 additions & 0 deletions enviro/config_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
mqtt_broker_password = None
# mqtt broker if using local SSL
mqtt_broker_ca_file = None
# Home Assistant Discovery setting
hass_discovery = False # This could arguably be set to a text field for better customisability

# adafruit ui settings
adafruit_io_username = None
Expand Down
61 changes: 61 additions & 0 deletions enviro/destinations/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,64 @@ def upload_reading(reading):
logging.debug(f" - an exception occurred when uploading.", buf.getvalue())

return UPLOAD_FAILED

def hass_discovery(board_type):
mqtt_discovery("Enviro Temperature", "temperature", "°C", "temperature", board_type) # Temperature
mqtt_discovery("Enviro Pressure", "pressure", "hPa", "pressure", board_type) # Pressure
mqtt_discovery("Enviro Humidity", "humidity", "%", "humidity", board_type) # Humidity
mqtt_discovery("Enviro Voltage", "voltage", "V", "voltage", board_type) # Voltage
if (board_type == "weather"):
mqtt_discovery("Enviro Luminance", "illuminance", "lx", "luminance", board_type) # Luminance
mqtt_discovery("Enviro Wind Speed", "wind_speed", "m/s", "wind_speed", board_type) # Wind Speed
mqtt_discovery("Enviro Rain", "precipitation", "mm", "rain", board_type) # Rain
mqtt_discovery("Enviro Rain Per Second", "precipitation", "mm/s", "rain_per_second", board_type) # Rain Per Second
#mqtt_discovery("Enviro Wind Direction", "", "°", "wind_direction", board_type) # Wind Direction //HASS doesn't have a device class for direction//
elif (board_type == "grow"):
mqtt_discovery("Enviro Luminance", "illuminance", "lx", "luminance", board_type) # Luminance
mqtt_discovery("Enviro Moisture A", "humidity", "%", "moisture_a", board_type) # Moisture A
mqtt_discovery("Enviro Moisture B", "humidity", "%", "moisture_b", board_type) # Moisture B
mqtt_discovery("Enviro Moisture C", "humidity", "%", "moisture_c", board_type) # Moisture C
elif (board_type == "indoor"):
mqtt_discovery("Enviro Luminance", "illuminance", "lx", "luminance", board_type) # Luminance
#mqtt_discovery("Enviro Gas Resistance", "", "Ω", "gas_resistance", board_type) # Gas Resistance //HASS doesn't support resistance as a device class//
mqtt_discovery("Enviro AQI", "aqi", "&", "aqi", board_type) # AQI
mqtt_discovery("Enviro Colour Temperature", "temperature", "K", "color_temperature", board_type) # Colo(u)r Temperature
elif (board_type == "urban"):
mqtt_discovery("Enviro Noise", "voltage", "V", "noise", board_type) # Noise
mqtt_discovery("Enviro PM1", "pm1", "µg/m³", "pm1", board_type) # PM1
mqtt_discovery("Enviro PM2.5", "pm25", "µg/m³", "pm2_5", board_type) # PM2_5
mqtt_discovery("Enviro PM10", "pm10", "µg/m³", "pm10", board_type) # PM10


def mqtt_discovery(name, device_class, unit, value_name, model ):
server = config.mqtt_broker_address
username = config.mqtt_broker_username
password = config.mqtt_broker_password
nickname = config.nickname
from ucollections import OrderedDict
obj = OrderedDict({
"dev":
{
"ids":[nickname],
"name":nickname,
"mdl":"Enviro " + model,
"mf":"Pimoroni"
},
"unit_of_meas":unit,
"dev_cla":device_class,
"val_tpl":"{{ value_json.readings." + value_name +" }}",
"state_cla": "measurement",
"stat_t":"enviro/" + nickname,
"name":name,
"uniq_id":"sensor." + nickname + "." + value_name,
})
try:
# attempt to publish reading
mqtt_client = MQTTClient(nickname, server, user=username, password=password, keepalive=60)
mqtt_client.connect()
mqtt_client.publish(f"homeassistant/sensor/{nickname}/{value_name}/config", ujson.dumps(obj), retain=True)
mqtt_client.disconnect()
return UPLOAD_SUCCESS
except:
logging.debug(f" - an exception occurred when uploading")

1 change: 1 addition & 0 deletions enviro/html/provision-step-4-destination.html
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ <h2>Enter your username and password.</h2>
<fieldset>
<input type="text" name="mqtt_broker_username" value="{{config.mqtt_broker_username}}" placeholder="Username (e.g. data_junkie)" autocapitalize="none" autocorrect="off" autocomplete="off" spellcheck="false" />
<input type="text" name="mqtt_broker_password" value="{{config.mqtt_broker_password}}" placeholder="Password (e.g. ih3artd4ta)" autocapitalize="none" autocorrect="off" autocomplete="off" spellcheck="false" />
<input type="checkbox" name="hass_discovery" value="{{config.hass_discovery}}" />
</fieldset>
</div>

Expand Down
1 change: 1 addition & 0 deletions enviro/provisioning.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ def provision_step_4_destination(request):
config.mqtt_broker_address = request.form["mqtt_broker_address"]
config.mqtt_broker_username = request.form["mqtt_broker_username"]
config.mqtt_broker_password = request.form["mqtt_broker_password"]
config.hass_discovery = request.form["hass_discovery"]

# adafruit io
config.adafruit_io_username = request.form["adafruit_io_username"]
Expand Down
5 changes: 5 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@
filesystem_stats = os.statvfs(".")
enviro.logging.debug(f"> {filesystem_stats[3]} blocks free out of {filesystem_stats[2]}")

# Add HASS Discovery command before taking new readings
if enviro.config.destination == "mqtt":
if enviro.config.hass_discovery:
enviro.hass_discovery()

# TODO should the board auto take a reading when the timer has been set, or wait for the time?
# take a reading from the onboard sensors
enviro.logging.debug(f"> taking new reading")
Expand Down