Office Overview
Custom built Raspberry Pi model B used as a room controller and extension of my home assistant installation. Monitoring and controlling devices in the Office utilizing the Room Assistant software.
This device is located in the equipment rack mounted to my office desk. Providing motion sensing and temp readings, not very complex at this point.
Down the road this will interface with LED lighting and any other physical devices that can be automated.
Office Info and Use
The main functions are occupancy and temp sensing. The occupancy sensor is tied to LIFX lights on my desk and a lamp in the room through a home assistant automation to trigger the lights on motion detection.
Hardware
Raspberry pi model 1b is the brain here, providing MQTT communication to the controller and reading sensor inputs via GPIO pins.
- Motion Sensor (PIR)
- Temp Sensor (DS18B20)
- Input Switches (Not Connected)
- Relay Control (Not Connected)
Network and Power
This lives directly next to network equipment and power on my desk, simple installation.
Controls
Future control of a relay to be added with an LED light strip for accent lighting to the desk.
Temp Sensor
Using a DHT11 sensor and a script to report the temp every min (cron job through room-assistant script.
I’m using the old depreciated Adafruit_Python_DHT library due to issues with the new circuit python version and already having this working.
Room-Assistant config excerpt:
shell:
sensors:
# DS18B20 Shelll Sensor
- name: Office Temperature
command: 'python3.7 /home/pi/room-assistant/script/temperature_sensor_code.py'
cron: '* * * * *'
icon: mdi:temperature-fahrenheit
unitOfMeasurement: '°F'
deviceClass: temperature
Mounting
The Raspberry Pi came with a robust aluminum case, which I have modified to mount to a 2 RU blank rack panel, screwed into the 2 post 19” rack rails living on my desk. Simple, industrial and functional.
Software
Everything is controlled and mapped to the home assistant dashboard over MQTT via the room-assistant system.
Room Assistant Config
This config file is the meat and potatoes of the program. Find it in /home/$USER/room-assistant/config/local.yml
on the Raspberry Pi.
# ########################
# Raspi Config
# Office controller - Office Desk
# hass-raspi2
# 10.10.10.71
# ########################
# ############
# GPIO Pin-Out
# ############
#
# Inputs:
# Pin: 04 Use: ds18b20 temp sensor using the shell functions below
# Pin: 24 Use: Office Light Switch (NC)
# Pin: 25 Use: Office Motion Sensor
# Pin: 35 Use: CPU voltage
#
# Outputs:
# Pin: 17 Use: Office LED (NC) Relay
# #######################
# Global Config settings
# #######################
global:
instanceName: office
integrations:
- homeAssistant
- gpio
- shell
# #######################
# Cluster settings
# #######################
# Config options for clustering multiple Room-Assistant
# Give leader more weight
cluster:
weight: 2
networkInterface: eth0
port: 6425
timeout: 60
peerAddresses:
# raspi1 patio
- 10.10.10.70:6425
# raspi2 office
# - 10.10.10.71:6425 <-- this cpu
# raspi3 sprinkler
- 10.10.10.72:6425
#raspi4 kitchen
- 192.168.1.75:6425
#raspi5 crawlspace
- 10.0.0.74:6425
# raspi6 garage
- 10.10.10.73:6425
# #######################
# home assistant settings
# #######################
homeAssistant:
# mqttUrl: mqtt://10.10.10.5:1883
mqttUrl: mqtt://10.10.10.21:1883
mqttOptions:
username: homeassistant
password: {LONG_RANDOM_STRING}
# #######################
# GPIO settings
# #######################
gpio:
binarySensors:
# PIR motion sensor
- name: Office Motion Sensor
pin: 25
deviceClass: motion
# General Input Switch
- name: Office Switch
pin: 24
# #######################
# Switches settings
# #######################
switches:
# Output GPIO intended for a relay to switch an LED strip
- name: Office LED
pin: 17
# #######################
# Shell settings
# #######################
shell:
sensors:
# DS18B20 Shelll Sensor
- name: Office Temperature
command: 'python3.7 /home/pi/room-assistant/script/temperature_sensor_code.py'
cron: '* * * * *'
icon: mdi:temperature-fahrenheit
unitOfMeasurement: '°F'
deviceClass: temperature
- name: Office CPU Temp
command: '/home/pi/room-assistant/script/cpuTemp.sh'
cron: '*/2 * * * *'
unitOfMeasurement: F
deviceClass: temperature
# Script to check voltage and return boolean if no errors seen.
# See the script for more
- name: Office CPU Voltage
command: '/home/pi/room-assistant/script/cpuVolt.sh'
cron: '1 */1 * * *'
deviceClass: power
# Report CPU uptime in sec
- name: Office CPU Up Time
command: '/home/pi/room-assistant/script/cpuUp.sh'
cron: '* * * * *'
unitOfMeasurement: 's'
# Free memory `free -h` results
- name: Office CPU Free Memory
command: '/home/pi/room-assistant/script/freeMem.sh'
cron: '*/10 * * * *'
unitOfMeasurement: 'MB'
# - name: Office Wifi Strength
# command: 'iwconfig wlan0 | grep -i quality'
# regex: 'Signal level=(-?[0-9]+) dBm'
# cron: '*/30 * * * *'
# icon: mdi:wifi
# unitOfMeasurement: dBm
# deviceClass: signal_strength
# - name: Office CPU Free Storage
# command: '/home/pi/room-assistant/script/cpuStorage.sh'
# cron: '1 * */1 * *'
# unitOfMeasurement: 'GB'
# deviceClass: timestamp
# #######################
# Entity settings
# #######################
entities:
behaviors:
office_motion_sensor:
debounce:
wait: 0.75
maxWait: 2
Scripts
Some additional helper scripts were also developed to return info on the device for integrations and status’s over in home assistant.
Add these to room assistant using the shell.sensors
function like this:
shell:
sensors:
# DHT11 Sensor reporting the temp °F result
- name: Garage Temperature
command: 'python3.7 /home/pi/room-assistant/script/myDHT.py'
regex: '(-?[0-9.]+)F'
cron: '*/2 * * * *'
icon: mdi:temperature-fahrenheit
unitOfMeasurement: '°F'
deviceClass: temperature
cpuUp.sh
return the uptime in seconds formatted as int
#!/bin/bash
echo `cat /proc/uptime |awk '{print $1}' |cut -d '.' -f1`
cpuTemp.sh
return the CPU reported temp
#!/bin/bash
cpuTemp=`vcgencmd measure_temp |cut -d "=" -f2 |cut -d "'" -f1 | awk '{print ($1 *9/5) + 32}'`
echo $cpuTemp
freeMem.sh
returns the remaining RAM on the pi
#!/bin/bash
memfree=`cat /proc/meminfo | grep MemFree | awk '{print $2}'`;
memtotal=`cat /proc/meminfo | grep MemTotal | awk '{print $2}'`;
awk '/MemFree/{free=$2} /MemTotal/{total=$2} END{print (free*100)/total}' /proc/meminfo
#echo $(($memfree * 100 / $memtotal))
myDHT.py
adapted DHT11 temp sensor reading temp and humid
import Adafruit_DHT
import time
DHT_SENSOR = Adafruit_DHT.DHT11
DHT_PIN = 27
while True:
humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)
if humidity is not None and temperature is not None:
temperature_f = temperature * (9 / 5) + 32
print("Temp={0:0.1f}F Humidity={1:0.1f}%".format(temperature_f, humidity))
exit()
else:
time.sleep(.05);
temperature_sensor_code.py
read DS18B20 sensor, report value in F
# Temp DS180b20 reading into F result on raspi
#
# https://pimylifeup.com/raspberry-pi-temperature-sensor/
# Modified from
# - git clone https://github.com/pimylifeup/temperature_sensor.git
import os
import glob
import time
os.system('modprobe w1-gpio')
os.system('modprobe w1-therm')
base_dir = '/sys/bus/w1/devices/'
device_folder = glob.glob(base_dir + '28*')[0]
device_file = device_folder + '/w1_slave'
def read_temp_raw():
lines = []
i = 0
# try to read the file 20 times, return the result
while not lines and (i < 19):
try:
f = open(device_file, 'r')
lines = f.readlines()
i += 1
except NameError:
time.sleep(1)
else:
if not lines:
f.close()
else:
f.close()
return lines
def read_temp():
lines = read_temp_raw()
if lines[0].strip()[-3:] != 'YES':
lines = read_temp_raw()
equals_pos = lines[1].find('t=')
if equals_pos != -1:
temp_string = lines[1][equals_pos+2:]
temp_c = float(temp_string) / 1000.0
temp_f = temp_c * 9.0 / 5.0 + 32.0
return temp_f
# print to reduced decimal place
print('{0:06.3f}'.format(read_temp()))
cpuVolt.sh
return boolean if no issues with voltage (power supply failure)
#!/bin/bash
THROTTLED=`/opt/vc/bin/vcgencmd get_throttled |cut -d "=" -f2`
RESULTS=0
if [[ "$THROTTLED" != *"0x0"* ]];then
RESULTS=1
fi
echo $RESULTS