Building Management System

This BMS system will integrate automate multiple subsystems such as ambient temperature control, HVAC, fire detection, motion-activate security lighting. This is done using a Raspberry Pi.

Code (Python)



import RPi.GPIO as GPIO
import time
from datetime import datetime
import LCD1602 as lcd1602
import Freenove_DHT as DHT
import requests, json

# setup mode
GPIO.setmode(GPIO.BCM)


# init everything
def init_everything():
    global lcd
    global pir_sensor
    global lights_led, lights_on, last_time_triggered
    global security_button, security_enabled
    global url, response, x, humidity
    global hvac_off, heat, ac, dht_pin, dht, temp_list, weather_index
    global inc_temp, dec_temp, desired_temp
    global ac_led, heater_led
    global fire_alarm
    global logfile

    # lcd
    lcd = lcd1602.CharLCD1602()
    lcd.init_lcd()
    lcd.clear()

    # init pir sensor
    pir_sensor = 5  # pir sensor, random pin assignment
    GPIO.setup(pir_sensor, GPIO.IN)

    # init lights led
    lights_led = 16  # Lights LED, random pin assignment
    GPIO.setup(lights_led, GPIO.OUT)
    GPIO.output(lights_led, GPIO.LOW)
    lights_on = False
    last_time_triggered = time.time()

    # init security system
    security_button = 23  # door/window button , random pin
    GPIO.setup(security_button, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    security_enabled = True

    # init api system
    url = "http://api.openweathermap.org/data/2.5/weather?q=Irvine,US&appid=bf323aef8f185b426b5edec1cf1d211c"
    response = requests.get(url).json()
    x = response["main"]
    humidity = x["humidity"]

    # init hvac system
    hvac_off = True
    heat = False
    ac = False
    dht_pin = 17  # temp pin assignment
    GPIO.setup(dht_pin, GPIO.IN)
    dht = DHT.DHT(dht_pin)
    temp_list = []
    while len(temp_list) < 3:  # append three readings for first temperature
        for i in range(0, 15):
            chk = dht.readDHT11()
            if (chk == 0):
                break
            time.sleep(0.1)
        temp_now = dht.getTemperature()
        temp_list.append(temp_now)
        time.sleep(1)
    t = sum(temp_list) / 3
    t = int((t * 1.8) + 32)
    weather_index = round(t + 0.05 * humidity)  # init weather_index as 0
    desired_temp = weather_index  # init desired_temp as 69

    # init buttons for hvac
    inc_temp = 14  # temp pin assignment
    dec_temp = 18  # temp pin assignment
    GPIO.setup(inc_temp, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    GPIO.setup(dec_temp, GPIO.IN, pull_up_down=GPIO.PUD_UP)

    # init leds for hvac
    ac_led = 25  # temp pin assignment
    heater_led = 12  # temp pin assignment
    GPIO.setup(ac_led, GPIO.OUT)
    GPIO.output(ac_led, GPIO.LOW)
    GPIO.setup(heater_led, GPIO.OUT)
    GPIO.output(heater_led, GPIO.LOW)

    # init fire alarm system
    fire_alarm = False

    # open log file
    logfile = open('log.txt', 'w')


# ----------------------------------------------- helper functions ——------------------------------------------------#

# fire alarm flash
def flash_leds():
    GPIO.output(lights_led, GPIO.HIGH)
    GPIO.output(ac_led, GPIO.HIGH)
    GPIO.output(heater_led, GPIO.HIGH)
    time.sleep(0.5)
    GPIO.output(lights_led, GPIO.LOW)
    GPIO.output(ac_led, GPIO.LOW)
    GPIO.output(heater_led, GPIO.LOW)
    time.sleep(0.5)


# get ambient temperature
def get_temp():
    for i in range(0, 15):
        chk = dht.readDHT11()
        if (chk == 0):
            break
        time.sleep(0.1)
    temp_now = dht.getTemperature()
    temp_list.append(temp_now)
    if len(temp_list) > 3:
        temp_list.pop(0)
    temp = sum(temp_list) / 3
    return int((temp * 1.8) + 32)  # convert to fahrenheit


# change desired temperature
def change_desired_temp():
    global desired_temp
    if GPIO.input(inc_temp) == GPIO.LOW and desired_temp < 95:
        desired_temp += 1
        return
    if GPIO.input(dec_temp) == GPIO.LOW and desired_temp > 65:
        desired_temp -= 1
        return


# turn on heater
def turn_on_heater():
    global heat, ac, hvac_off
    heat = True
    log_event('HVAC HEAT')
    ac = False
    GPIO.output(ac_led, GPIO.LOW)  # turn off ac led if on
    hvac_off = False
    lcd.clear()
    lcd.write(5, 0, 'HEATER')  # display message
    lcd.write(7, 1, 'ON')
    GPIO.output(heater_led, GPIO.HIGH)  # turn on heater led
    time.sleep(3)
    lcd.clear()
    return

# turn on ac
def turn_on_ac():
    global heat, ac, hvac_off
    heat = False
    GPIO.output(heater_led, GPIO.LOW)  # turn off heater led if on
    ac = True
    log_event('HVAC AC')
    hvac_off = False
    lcd.clear()
    lcd.write(7, 0, 'AC')  # display message
    lcd.write(7, 1, 'ON')
    GPIO.output(ac_led, GPIO.HIGH)  # turn on ac led
    time.sleep(3)
    lcd.clear()
    return


# turn off hvac
def turn_off_hvac():
    global heat, ac, hvac_off
    heat = False
    ac = False
    hvac_off = True
    log_event('HVAC OFF')
    GPIO.output(heater_led, GPIO.LOW)  # turn off heater led
    GPIO.output(ac_led, GPIO.LOW)  # turn off ac led
    time.sleep(0.3)
    return

# turn on hvac
def turn_on_hvac():
    # turn on heat or ac
    if weather_index <= desired_temp - 3:
        turn_on_heater()
    else:
        if weather_index >= desired_temp + 3:
            turn_on_ac()


# save logs to file
def log_event(event):
    global logfile
    timestamp = datetime.now().strftime('%H:%M:%S')
    logfile.write(f"{timestamp} {event}\n")
    logfile.flush()


# -------------------------------------------------- run systems —--—------------------------------------------------#

# run PIR sensor + ambient light control system
def run_pir_sensor():
    global lights_on, last_time_triggered, pir_sensor, lights_led
    # motion detected
    if GPIO.input(pir_sensor):
        log_event('MOTION DETECTED')
        timestamp = datetime.now().strftime('%H:%M:%S')
        print("motion detected at: ", timestamp)
        # if lights not on, turn it on
        if not lights_on:
            GPIO.output(lights_led, GPIO.HIGH)  # turn on lights led
            lights_on = True
            log_event('LIGHTS ON')
        last_time_triggered = time.time()
    # no motion detected
    else:
        # if lights on, check if it has been > 10 secs
        if lights_on and (time.time() - last_time_triggered >= 10):
            GPIO.output(lights_led, GPIO.LOW)  # turn off lights led
            lights_on = False
            log_event('LIGHTS OFF')
        # if lights off or has not been > 10 secs, continue
    # time.sleep(0.3)


# run fire alarm system
def run_fire_alarm():
    global fire_alarm, security_enabled, weather_index
    fire_alarm = True
    log_event('FIRE ALARM ON')

    # open window/door
    lcd.clear()
    security_enabled = False
    log_event('DOOR OPEN')
    log_event('HVAC OFF')
    lcd.write(1, 0, 'Window/Door  O')
    lcd.write(2, 1, 'HVAC  HALTED')
    turn_off_hvac()
    time.sleep(3)  # display for 3 seconds

    # display emergency message
    lcd.clear()
    lcd.write(3, 0, 'FIRE! Dr: O')
    lcd.write(0, 1, 'Please evacuate!')

    # flashes leds
    while fire_alarm:
        flash_leds()
        ct = get_temp()
        weather_index = round(ct + 0.05 * humidity)
        if weather_index < 95:
            fire_alarm = False
            lcd.clear()
            lcd.write(0, 0, 'Resuming normal')
            lcd.write(1, 1, 'operations...')
            time.sleep(3)
    # resume normal operations
    log_event('FIRE ALARM OFF')
    lcd.clear()
    return


# run security system
def run_security():
    global security_enabled, security_button, lcd
    # button pressed
    if GPIO.input(security_button) == GPIO.LOW:
        # open/close door/window, turn on/off HVAC
        security_enabled = not security_enabled
        lcd.clear()

        # if door/window open, turn off HVAC
        if not security_enabled:
            log_event('DOOR OPEN')
            log_event('HVAC OFF')
            lcd.write(1, 0, 'Window/Door  O')
            lcd.write(2, 1, 'HVAC  HALTED')
            time.sleep(3)  # display for 3 seconds
            turn_off_hvac()
            lcd.clear()
            return
        else:
            log_event('DOOR CLOSED')
            lcd.write(1, 0, 'Window/Door  C')
            lcd.write(4, 1, 'HVAC  ON')
            time.sleep(3)  # display for 3 seconds
            turn_on_hvac()
            lcd.clear()
            return

    # time.sleep(0.2)


# run temperature control system
def run_hvac():
    global heat, ac, weather_index, desired_temp, security_enabled
    # listen for desired temp change and turn on/off hvac accordingly
    change_desired_temp()
    # time.sleep(0.5)
    if (weather_index <= desired_temp - 3) and not heat and security_enabled:
        turn_on_heater()
    else:
        if (weather_index >= desired_temp + 3) and not ac and security_enabled:
            turn_on_ac()



# display all statuses
def display_statuses():
    global weather_index, humidity, desired_temp
    # lights status
    if lights_on:
        lcd.write(12, 1, 'L:ON')
    else:
        lcd.write(11, 1, 'L:OFF')
    # window/door status
    if not security_enabled:
        lcd.write(12, 0, 'Dr:O')
    else:
        lcd.write(12, 0, 'Dr:C')

    # hvac status
    if hvac_off:
        lcd.write(0, 1, 'H:OFF')
    elif heat:
        lcd.write(0, 1, 'H:HEAT')
    elif ac:
        lcd.write(0, 1, 'H:AC')
    else:
        lcd.write(0, 1, 'H:ERR')  #fallback

    # update temps
    current_temp = get_temp()
    weather_index = round(current_temp + 0.05 * humidity)
    lcd.write(0, 0, str(desired_temp))
    lcd.write(2, 0, "/" + str(weather_index))

    #update time
    timestamp = datetime.now().strftime('%H:%M')
    lcd.write(7, 0, timestamp)


# main function (needs to run updated temp/listen for button presses/watch for fire, etc.)
def main():
    init_everything()
    global weather_index, humidity, desired_temp, temp_list
    while True:
        lcd.clear()
        if weather_index >= 95:
            run_fire_alarm()
        run_pir_sensor()
        run_security()
        run_hvac()
        display_statuses()
        time.sleep(0.5)

try:
    main()
finally:
    global logfile
    logfile.close()
    lcd.clear()
    GPIO.cleanup()

        

Demo / Screenshots