chch-power/chch-power.py

177 lines
6.1 KiB
Python
Raw Permalink Normal View History

2017-03-09 17:28:47 +01:00
#
2017-02-04 22:15:11 +01:00
import pifacedigitalio
import pifacecommon.mcp23s17
2017-02-04 22:15:11 +01:00
import time
2017-02-05 00:41:08 +01:00
from subprocess import call
2017-02-18 21:17:52 +01:00
import sys
2017-02-04 22:15:11 +01:00
button_count = 2
longpress_delay = 0.6 # minimum time in s for a long press
inter_press_max_delay = 0.8 # maximum time in s between two presses
button_debounce_wait = 0.08 # time in s befor signal stabilizes
2017-03-02 22:43:01 +01:00
pin = {
0: {
'shortpress': {
'count': 0,
'last_unpress': 0
},
'last_unpress': 0,
'last_press': 0,
'sched_time': 0
},
1: {
'shortpress': {
'count': 0,
'last_unpress': 0
},
'last_unpress': 0,
'last_press': 0,
'sched_time': 0
}
}
2017-02-18 21:17:52 +01:00
# dirty workaround to disable reset of output pins
def init_board_no_power_off(self):
ioconfig = (
pifacecommon.mcp23s17.BANK_OFF |
pifacecommon.mcp23s17.INT_MIRROR_OFF |
pifacecommon.mcp23s17.SEQOP_OFF |
pifacecommon.mcp23s17.DISSLW_OFF |
pifacecommon.mcp23s17.HAEN_ON |
pifacecommon.mcp23s17.ODR_OFF |
pifacecommon.mcp23s17.INTPOL_LOW
)
self.iocon.value = ioconfig
if self.iocon.value != ioconfig:
raise pifacedigitalio.NoPiFaceDigitalDetectedError(
"No PiFace Digital board detected (hardware_addr={h}, "
"bus={b}, chip_select={c}).".format(
h=self.hardware_addr, b=self.bus, c=self.chip_select))
else:
self.iodira.value = 0 # GPIOA as outputs
self.iodirb.value = 0xFF # GPIOB as inputs
self.gppub.value = 0xFF # input pullups on
self.enable_interrupts()
setattr(pifacedigitalio.PiFaceDigital, 'init_board', init_board_no_power_off)
2017-02-18 21:17:52 +01:00
def chch_status_output(pfd):
2019-09-02 21:50:17 +02:00
# update status file
2017-02-18 21:48:50 +01:00
f = open("/tmp/status", 'w')
2017-02-18 21:17:52 +01:00
status = "geschlossen"
for i in range(button_count):
if pfd.output_pins[i].value != 0:
2017-02-19 01:37:31 +01:00
status = "geöffnet"
2017-02-18 21:17:52 +01:00
break
try:
f.truncate(0)
f.write(status)
except OSError:
2017-03-02 22:43:01 +01:00
sys.stderr.write("Can not write to status file\n")
2019-09-02 21:50:17 +02:00
# start / stop lounge VM
if pfd.output_pins[0].value != 0:
try:
call(["/home/automation/proxmox-api-bash/vm_control.sh","chch","lounge","pve","310","start"])
except:
sys.stderr.write("Could not start lounge VM\n")
else:
try:
call(["/home/automation/proxmox-api-bash/vm_control.sh","chch","lounge","pve","310","shutdown"])
except:
sys.stderr.write("Could not start lounge VM\n")
2017-02-18 21:17:52 +01:00
2017-03-02 22:43:01 +01:00
def exec_chch_button_cmd(event):
c_pin = pin[event.pin_num]
print({'event':{'pin':event.pin_num,'at':c_pin['last_unpress'],'state':'executing'}})
count = c_pin['shortpress']['count']
# a longpress happend
if c_pin['last_unpress'] > c_pin['shortpress']['last_unpress']:
# '-' all off
if count == 0:
for i in range(button_count):
event.chip.output_pins[i].turn_off()
# '. -' all on
elif count == 1:
for i in range(button_count):
event.chip.output_pins[i].turn_on()
2017-02-04 22:15:11 +01:00
else:
2017-03-02 22:43:01 +01:00
sys.stderr.write("No mode with " + str(count) + " short press and a long press\n")
else:
2017-03-02 23:11:41 +01:00
# '.' room specific function
2017-03-02 23:16:57 +01:00
if count == 1:
2017-03-02 22:43:01 +01:00
if event.pin_num == 0:
2017-03-04 16:21:55 +01:00
call(["/home/automation/chch-power/light.sh","1"])
elif event.pin_num == 1:
call(["/home/automation/chch-power/light.sh","2"])
2017-03-02 22:43:01 +01:00
else:
sys.stderr.write("No room specific function for room " + str(event.pin_num) + "\n")
2017-03-02 23:11:41 +01:00
# '. .' toggle current room
2017-03-02 23:16:57 +01:00
elif count == 2:
2017-03-02 23:11:41 +01:00
event.chip.output_pins[event.pin_num].toggle()
2017-03-02 22:43:01 +01:00
else:
sys.stderr.write("No mode with " + str(count) + " short press at pin " + str(event.pin_num) + "\n")
2017-02-18 21:17:52 +01:00
chch_status_output(event.chip)
2017-03-02 22:43:01 +01:00
# cleanup
c_pin['last_unpress'] = 0
c_pin['last_press'] = 0
c_pin['shortpress']['count'] = 0
2017-02-04 22:15:11 +01:00
2017-03-02 22:43:01 +01:00
# count the number of short press
2017-02-04 22:15:11 +01:00
def switch_shortpressed(event):
2017-03-02 22:43:01 +01:00
c_pin = pin[event.pin_num]
if c_pin['shortpress']['count'] == 0:
c_pin['shortpress']['last_unpress'] = c_pin['last_unpress']
# determine delay between last rise of the switch and current rise
shortpress_delay = c_pin['last_unpress'] - c_pin['shortpress']['last_unpress']
if shortpress_delay > inter_press_max_delay:
2017-03-02 22:43:01 +01:00
c_pin['shortpress']['count'] = 1
2017-02-04 22:15:11 +01:00
else:
2017-03-02 22:43:01 +01:00
c_pin['shortpress']['count'] += 1
c_pin['shortpress']['last_unpress'] = c_pin['last_unpress']
print({'shortpress':{'delay':shortpress_delay,'count':c_pin['shortpress']['count']}})
def switch_pressed(event):
2019-07-06 23:18:54 +02:00
event_time = time.time()
2017-03-02 22:43:01 +01:00
c_pin = pin[event.pin_num]
# debouncing
c_pin['last_press'] = 0
time.sleep(button_debounce_wait)
2017-03-02 22:43:01 +01:00
if event.chip.input_pins[event.pin_num].value == 0:
return
# remove scheduled event
c_pin['sched_time'] = 0
2019-07-06 23:18:54 +02:00
c_pin['last_press'] = event_time
2017-03-02 22:43:01 +01:00
def switch_unpressed(event):
2019-07-06 23:18:54 +02:00
event_time = time.time()
2017-03-02 22:43:01 +01:00
c_pin = pin[event.pin_num]
if c_pin['last_press'] == 0:
return
2019-07-06 23:18:54 +02:00
c_pin['last_unpress'] = event_time
2017-03-02 22:43:01 +01:00
press_time = c_pin['last_unpress'] - c_pin['last_press']
if press_time < longpress_delay:
# parse data inter_press_max_delay seconds after no event
c_pin['sched_time'] = c_pin['last_unpress'] + inter_press_max_delay
print({'event':{'pin':event.pin_num,'at':c_pin['last_unpress'],'in':inter_press_max_delay,'state':'scheduled'}})
switch_shortpressed(event)
else:
c_pin['sched_time'] = 0
exec_chch_button_cmd(event)
2017-02-04 22:15:11 +01:00
if __name__ == "__main__":
2017-02-18 22:47:04 +01:00
listener = pifacedigitalio.InputEventListener()
2017-02-04 22:15:11 +01:00
for i in range(button_count):
listener.register(i, pifacedigitalio.IODIR_ON, switch_pressed)
listener.register(i, pifacedigitalio.IODIR_OFF, switch_unpressed)
listener.activate()
2017-02-18 22:44:26 +01:00
chch_status_output(listener.chip)
2017-03-02 22:43:01 +01:00
while True:
for i in range(button_count):
c_pin = pin[i]
if time.time() > c_pin['sched_time'] and c_pin['sched_time'] != 0:
c_pin['sched_time'] = 0
setattr(listener, 'pin_num', i)
exec_chch_button_cmd(listener)
2019-07-06 23:18:54 +02:00
time.sleep(0.01)