forked from Chaospott/Heizberry
parent
8a23323ac0
commit
a374a7c106
6 changed files with 311 additions and 2 deletions
@ -1,2 +1,14 @@ |
||||
# Heizberry |
||||
Service to control the Equiva thermostats in the foobar. |
||||
# Heizberry Pi |
||||
Service to control the Equiva thermostats in the foobar. Can be installed on Raspberry Pi. Requires Bluetooth 4.0/LE module. |
||||
|
||||
## Installation |
||||
1. Install Raspberry Pi with Raspian. |
||||
2. Find MAC-addresses of thermostats |
||||
- sudo addgroup pi bluetooth |
||||
- run bluetoothctl |
||||
2. Connect bluetooth USB dongle. |
||||
Controller will be found. |
||||
3. Type command scan on |
||||
Bluetooth devices are searched. |
||||
[NEW] Device 00:1A:22:0D:BE:EE CC-RT-BLE |
||||
|
||||
|
@ -0,0 +1,169 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
import argparse |
||||
import re |
||||
import serial |
||||
import time |
||||
import signal |
||||
import logging |
||||
import sys |
||||
import schedule |
||||
import paho.mqtt.client as mqtt |
||||
from beamer import acer as beamercodes |
||||
code = beamercodes.clubbeamer() |
||||
|
||||
def on_connect(client, userdata, flags, rc): |
||||
global beamer_state |
||||
global input_source |
||||
|
||||
log.debug("Connected with result code " + str(rc)) |
||||
|
||||
beamer_state = readBeamerState() |
||||
client.publish("foobar/oben/cantina/beamer/status", beamer_state, qos=1, retain=True) |
||||
|
||||
input_source = readInputSource() |
||||
client.publish("foobar/oben/cantina/beamer/source", input_source, qos=1, retain=True) |
||||
|
||||
client.subscribe("foobar/oben/cantina/beamer/action") |
||||
|
||||
|
||||
def on_publish(client, userdata, mid): |
||||
log.debug("mid: "+str(mid)) |
||||
|
||||
|
||||
def on_message(client, userdata, message): |
||||
msg = message.payload.decode("utf-8") |
||||
log.debug('received message: {}'.format(msg)) |
||||
if (msg == "on"): |
||||
ser.write(code.set['on']) |
||||
|
||||
if (msg == "off"): |
||||
ser.write(code.set['off']) |
||||
|
||||
if (msg == "vga"): |
||||
ser.write(code.set['vga']) |
||||
|
||||
if (msg == "hdmi1"): |
||||
ser.write(code.set['hdmi1'][0]) |
||||
time.sleep(1) |
||||
ser.write(code.set['hdmi1'][1]) |
||||
|
||||
if (msg == "hdmi2"): |
||||
ser.write(code.set['hdmi2'][0]) |
||||
time.sleep(0.5) |
||||
ser.write(code.set['hdmi2'][1]) |
||||
time.sleep(0.5) |
||||
ser.write(code.set['hdmi2'][2]) |
||||
|
||||
|
||||
def readBeamerState(): |
||||
ser.write(b"* 0 Lamp ?\r") |
||||
read_val = ser.read(size=64) |
||||
if(re.match(b'.*Lamp.1.*', read_val)): |
||||
status = "on" |
||||
else: |
||||
status = "off" |
||||
return status |
||||
|
||||
|
||||
def beamerStatusChanged(): |
||||
global beamer_state |
||||
if (beamer_state != readBeamerState()): |
||||
log.debug('Beamer state has changed') |
||||
beamer_state = readBeamerState() |
||||
return True |
||||
else: |
||||
return False |
||||
|
||||
|
||||
def readInputSource(): |
||||
ser.write(b"* 0 Src ?\r") |
||||
read_val = ser.read(size=64) |
||||
if(re.match(b'.*Src.0.*', read_val)): |
||||
return "no_input" |
||||
elif (re.match(b'.*Src.1.*', read_val)): |
||||
return "vga" |
||||
elif (re.match(b'.*Src.8.*', read_val)): |
||||
return "hdmi" |
||||
elif (readBeamerState()): |
||||
return "off" |
||||
|
||||
def inputSourceChanged(): |
||||
global input_source |
||||
if (input_source != readInputSource()): |
||||
log.debug('Input source has changed to {}'.format(readInputSource() )) |
||||
input_source = readInputSource() |
||||
return True |
||||
else: |
||||
return False |
||||
|
||||
def terminate(signum, frame): |
||||
log.warn('SIGTERM received. Shutting down!') |
||||
log.info('Closing serial connection') |
||||
ser.close() |
||||
log.info('stopping mqtt client') |
||||
client.loop_stop() |
||||
log.info('disconnecting mqtt client') |
||||
client.disconnect() |
||||
log.info('beamerctl stopped all functions; exit') |
||||
sys.exit(0) |
||||
|
||||
|
||||
def getArgs(): |
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument("-v", "--verbose", action="store_true", |
||||
help="increase output verbosity") |
||||
return parser.parse_args() |
||||
|
||||
def periodicUpdate(): |
||||
log.debug('run scheduled statusupdates') |
||||
client.publish("foobar/oben/cantina/beamer/status", readBeamerState(), qos=1, retain=True) |
||||
client.publish("foobar/oben/cantina/beamer/source", readInputSource(), qos=1, retain=True) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
beamer_state = False |
||||
input_source = False |
||||
|
||||
signal.signal(signal.SIGINT, terminate) |
||||
args = getArgs() |
||||
logging.basicConfig( |
||||
level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s') |
||||
log = logging.getLogger('beamerctl') |
||||
if args.verbose: |
||||
log.setLevel(logging.DEBUG) |
||||
log.info('Loglevel set to DEBUG') |
||||
else: |
||||
log.setLevel(logging.WARN) |
||||
|
||||
serialport = '/dev/ttyUSB0' |
||||
|
||||
try: |
||||
ser = serial.Serial(port=serialport, baudrate=9600, timeout=1) |
||||
except serial.serialutil.SerialException as e: |
||||
log.critical(e) |
||||
sys.exit(1) |
||||
|
||||
client = mqtt.Client() |
||||
client.on_connect = on_connect |
||||
client.on_message = on_message |
||||
client.connect("10.42.0.244", 1883, 60) |
||||
|
||||
client.loop_start() |
||||
|
||||
log.debug('schedule periodic statusupdates') |
||||
schedule.every(1).minutes.do(periodicUpdate) |
||||
|
||||
time.sleep(5) |
||||
|
||||
while True: |
||||
schedule.run_pending() |
||||
|
||||
if (inputSourceChanged()): |
||||
client.publish("foobar/oben/cantina/beamer/source", |
||||
input_source, qos=1, retain=True) |
||||
|
||||
if (beamerStatusChanged()): |
||||
client.publish("foobar/oben/cantina/beamer/status", |
||||
beamer_state, qos=1, retain=True) |
||||
time.sleep(1) |
@ -0,0 +1,13 @@ |
||||
[Unit] |
||||
Description=heizberry |
||||
After=network-online.target |
||||
|
||||
[Service] |
||||
Type=Simple |
||||
ExecStart=/srv/herizberry/heizberry.py |
||||
|
||||
Restart=always |
||||
RestartSec=3 |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,99 @@ |
||||
#!/usr/bin/env python3 |
||||
|
||||
import argparse |
||||
import re |
||||
import time |
||||
import signal |
||||
import logging |
||||
import sys |
||||
import schedule |
||||
import paho.mqtt.client as mqtt |
||||
from eq3bt import Thermostat |
||||
|
||||
thermostatBallpit = Thermostat('00:1A:22:0D:BE:EE') |
||||
|
||||
global temperature_off = 12 |
||||
global temperature_on = 19 |
||||
|
||||
|
||||
def on_connect(client, userdata, flags, rc): |
||||
log.debug("Connected with result code " + str(rc)) |
||||
|
||||
sendReadings() |
||||
|
||||
|
||||
def on_publish(client, userdata, mid): |
||||
log.debug("mid: "+str(mid)) |
||||
|
||||
|
||||
def on_message(client, userdata, message): |
||||
msg = message.payload.decode("utf-8") |
||||
log.debug('received message: %s from %s', format(msg), format(message.topic)) |
||||
|
||||
if (message.topic == "foobar/oben/baellebad/heizung/action") |
||||
if (msg == "on"): |
||||
thermostatBallpit.target_temperature=temperature_on |
||||
else |
||||
if (msg == "on"): |
||||
thermostatBallpit.target_temperature=temperature_on |
||||
else |
||||
thermostatBallpit.target_temperature=msg |
||||
|
||||
|
||||
|
||||
def sendReadings(): |
||||
log.debug('read target temperature from thermostats') |
||||
|
||||
# Bällebad |
||||
# Update readings |
||||
thermostatBallpit.update() |
||||
|
||||
# Send target temperatures |
||||
temp=thermostatBallpit.target_temperature |
||||
if(temp == temperature_on) |
||||
temp = temp + " on" |
||||
|
||||
if(temp == temperature_off) |
||||
temp = temp + " off" |
||||
|
||||
client.publish("foobar/oben/baellebad/status", temp, qos=1, retain=True) |
||||
|
||||
|
||||
def terminate(signum, frame): |
||||
log.warn('SIGTERM received. Shutting down!') |
||||
log.info('stopping mqtt client') |
||||
client.loop_stop() |
||||
log.info('disconnecting mqtt client') |
||||
client.disconnect() |
||||
log.info('heizberry stopped all functions; exit') |
||||
sys.exit(0) |
||||
|
||||
|
||||
def getArgs(): |
||||
parser = argparse.ArgumentParser() |
||||
parser.add_argument("-v", "--verbose", action="store_true", |
||||
help="increase output verbosity") |
||||
return parser.parse_args() |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
signal.signal(signal.SIGINT, terminate) |
||||
args = getArgs() |
||||
logging.basicConfig( |
||||
level=logging.DEBUG, format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s') |
||||
log = logging.getLogger('heizberry') |
||||
if args.verbose: |
||||
log.setLevel(logging.DEBUG) |
||||
log.info('Loglevel set to DEBUG') |
||||
else: |
||||
log.setLevel(logging.WARN) |
||||
|
||||
client = mqtt.Client("Heizberry_oben") |
||||
client.on_connect = on_connect |
||||
client.on_message = on_message |
||||
client.connect("10.42.0.244", 1883, 60) |
||||
|
||||
client.loop_start() |
||||
|
||||
log.debug('schedule periodic readings') |
||||
schedule.every(1).minutes.do(sendReadings) |
@ -0,0 +1,13 @@ |
||||
[Unit] |
||||
Description=heizberry |
||||
After=network-online.target |
||||
|
||||
[Service] |
||||
Type=Simple |
||||
ExecStart=/srv/herizberry/heizberry.py |
||||
|
||||
Restart=always |
||||
RestartSec=3 |
||||
|
||||
[Install] |
||||
WantedBy=multi-user.target |
@ -0,0 +1,3 @@ |
||||
paho_mqtt==1.3.0 |
||||
schedule==0.4.3 |
||||
python-eq3bt==0.1.10 |
Loading…
Reference in new issue