Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Infineon Team
Published © MIT

Anything to Home Assistant - with PSOC™ & MicroPython

Bring any sensor into Home Assistant - easier than ever with MicroPython!

BeginnerProtip1 hour551
Anything to Home Assistant - with PSOC™ & MicroPython

Things used in this project

Hardware components

S2GO PRESSURE DPS368
Infineon S2GO PRESSURE DPS368
×1
Infineon PAS CO2 5V Miniboard
×1
Adafruit SHT30 Temperature & Humidity Sensor
×1
Sertronics Photo Resistor LM393 Breakout Board
×1
Infineon PSOC™ 6 Wi-Fi BT Prototyping Kit
×1
Breadboard (generic)
Breadboard (generic)
×1
Jumper wires (generic)
Jumper wires (generic)
×1

Software apps and online services

Home Assistant
Home Assistant
MQTT
MQTT
MicroPython
MicroPython

Story

Read more

Schematics

Schematics

Schematics for the sensors I am using.

Code

main.py

MicroPython
main.py script for running on MicroPython board.
import machine, network
import wifi_secrets, mqtt_secrets
import time

### CONNECT TO WIFI ###
sta = network.WLAN(network.STA_IF)
sta.connect(wifi_secrets.ssid, wifi_secrets.psk)

### DOWNLOAD DEPENDENCIES ###
import mip

try:
    import umqtt.simple
except:
    print("Exception: umqtt.simple not found. Trying to download...")
    mip.install('umqtt.simple')
    import umqtt.simple

try:
    import uhome
except:
    print("Exception: uhome not found. Trying to download...")
    mip.install('github:ederjc/uhome/uhome/uhome.py')
    import uhome

try:
    import sht30
except:
    print("Exception: sht30 not found. Trying to download...")
    mip.install('github:ederjc/micropython-sht30/sht30.py')
    import sht30

try:
    import pasco2
except:
    print("Exception: pasco2 not found. Trying to download...")
    mip.install("https://raw.githubusercontent.com/jaenrig-ifx/micropython-lib/mpy-lib/pasco2-sensor-module/micropython/drivers/sensor/pasco2/pasco2.py")
    import pasco2

try:
    import DPS
except:
    print("Exception: DPS not found. Trying to download...")
    mip.install("github:seanwagoner/MiPy/DPS.py")
    import DPS

### DEVICE SETUP ###
"""
This is an example of a simple device setup. It creates
a device which we can later use to assign entities to.
"""
device = uhome.Device('MicroPython Sensornode', mf='Infineon', mdl='PSOC 6')
mqttc = umqtt.simple.MQTTClient(device.id, mqtt_secrets.broker, user=mqtt_secrets.user, password=mqtt_secrets.password, keepalive=60)
device.connect(mqttc)

### DIAGNOSTIC ENTITIES ###
"""
These are some default entities that are useful for diagnostics.
"""
signal_strength = uhome.Sensor(device, 'Signal Strength', device_class="signal_strength", unit_of_measurement='dBm', entity_category="diagnostic")
wifi_ch = uhome.Sensor(device, 'WiFi Channel', device_class="enum", entity_category="diagnostic")
reset_cause = uhome.Sensor(device, 'Last Reset Cause', device_class="enum", entity_category="diagnostic")
ip_addr = uhome.Sensor(device, 'IP Address', device_class="enum", entity_category="diagnostic")

### SENSOR ENTITIES ###
"""
Entities for the connected sensors.
Look here for some docs:
- https://www.home-assistant.io/integrations/sensor.mqtt/
- https://www.home-assistant.io/integrations/sensor#device-class
"""
temperature = uhome.Sensor(device, 'Temperature', device_class="temperature", unit_of_measurement='C')
humidity = uhome.Sensor(device, 'Relative Humidity', device_class="humidity", unit_of_measurement='%')
co2 = uhome.Sensor(device, 'CO2', device_class="carbon_dioxide", unit_of_measurement='ppm')
atmospheric_pressure = uhome.Sensor(device, 'Atmospheric Pressure', device_class="pressure", unit_of_measurement='Pa')
brightness = uhome.Sensor(device, 'Brightness', device_class="illuminance", unit_of_measurement='lx')

"""
The uhome module keeps track of all entities.
With this method we can send the discovery
message for all entities to Home Assistant:
"""
device.discover_all()

### PUBLISH ENTITY VALUES ###
"""
Here we publish the values of the diagnostic entities.
Some of these values are published only once, while others
should be published regularly to keep Home Assistant up to date.
"""
def publishDiagnostics(tmr=None):
    """
    Helper function to publish variable diagnostic values.
    """
    signal_strength.publish(f'{sta.status('rssi'):.0f}')
    wifi_ch.publish(f'{sta.config('channel')}')
    reset_cause.publish(f'{machine.reset_cause()}')
    ip_addr.publish(f'{sta.ifconfig()[0]}')

diagnostics_tmr = machine.Timer(0, mode=machine.Timer.PERIODIC, period=30000, callback=publishDiagnostics)

def publishSHT(tmr=None):
    '''
    Callback function for retrieving
    brightness value from ADC and publishing
    to Home Assistant.
    '''
    temp, hum = sht.measure()
    print(f'SHT30:\tTemperature:\t{temp} C')
    print(f'SHT30:\tHumidity:\t{hum} %RH')
    temperature.publish(f'{temp:.1f}')
    humidity.publish(f'{hum:.0f}')

def publishCO2(tmr=None):
    '''
    Callback function for retrieving
    CO2 measurement and publishing to Home Assistant.
    '''
    for i in range(10):
        co2ppm = pasco2.get_co2_value()
        if co2ppm != -1:
            co2.publish(f'{co2ppm:.0f}')
            print(f'PASCO2:\tCO2 value:\t{co2ppm} ppm')
            break
        time.sleep(1)
    
def publishDPS(tmr=None):
    '''
    Callback function for retrieving
    pressure measurement and publishing
    to Home Assistant.
    '''
    p = dps.measurePressureOnce()
    atmospheric_pressure.publish(f'{p:.2f}')
    print(f'DPS368:\tPressure:\t{p} Pa')

def publishLight(tmr=None):
    '''
    Callback function for retrieving
    brightness value from ADC and publishing
    to Home Assistant.
    This value is not actually in lux but the raw
    value from ADC.
    '''
    light_value = 32767 - light_adc.read_u16() # Value is inverted, hence max(16 bit) - value.
    print(f'Light:\tAnalog raw:\t{light_value}')
    brightness.publish(f'{light_value}')

### SENSOR SETUP ###
i2c = machine.I2C(scl='P6_0', sda='P6_1', freq=400000)

sht = sht30.SHT30(i2c, i2c_address=sht30.ALTERNATE_I2C_ADDRESS)
sht_tmr = machine.Timer(1, mode=machine.Timer.PERIODIC, period=32000, callback=publishSHT)

dps = DPS.DPS(i2c)
dps_tmr = machine.Timer(2, mode=machine.Timer.PERIODIC, period=3000, callback=publishDPS)

pasco2 = pasco2.PASCO2(i2c, measInterval=60)
pasco2.initialize()
co2_tmr = machine.Timer(3, mode=machine.Timer.PERIODIC, period=60000, callback=publishCO2)

light_adc = machine.ADC('P10_3')
light_tmr = machine.Timer(4, mode=machine.Timer.PERIODIC, period=19000, callback=publishLight)

while True:
    if not sta.isconnected(): sta = sta.connect(wifi_secrets.ssid, wifi_secrets.psk) # Reconnect to WiFi if connection is lost.
    device.loop() # Handle all device specific tasks (mandatory).

mqtt_secrets

MicroPython
This file should contain IP address, username and password of your MQTT broker.
broker = ''
user = ''
password = ''

wifi_secrets

MicroPython
This file should contain your Wi-Fi SSID (network name) and Pre-Shared-Key (password).
ssid = ''
psk = ''

uhome

MicroPython module for Home Assistant integration.

Infineon PASCO2 sensor driver

Infineon PASCO2 sensor driver module for MicroPython.

Infineon DPS sensor driver

Infineon DPS sensor driver MicroPython module.

Adafruit SHT30 sensor driver

Adafruit SHT30 sensor driver for MicroPython.

Credits

Infineon Team
96 projects • 147 followers
Contact
Thanks to bwduncan, rsc1975, and seanwagoner.

Comments

Please log in or sign up to comment.