119 lines
4.3 KiB
Python
119 lines
4.3 KiB
Python
import pifacedigitalio
|
|
import pifacecommon.mcp23s17
|
|
import time
|
|
from subprocess import call
|
|
import sys
|
|
import os
|
|
|
|
button_count = 2
|
|
longpress_delay = 0.4
|
|
verylongpress_delay = 2
|
|
shortpress_count_max_delay = 0.5
|
|
inter_press_max_delay = 1.5
|
|
pin_last_rise_date = [0]*button_count
|
|
pin_last_shortpress = [0]*button_count
|
|
pin_shortpress_count = [0]*button_count
|
|
|
|
# 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)
|
|
|
|
def chch_status_output(pfd):
|
|
f = open("/tmp/status", 'w')
|
|
status = "geschlossen"
|
|
for i in range(button_count):
|
|
if pfd.output_pins[i].value != 0:
|
|
status = "geöffnet"
|
|
break
|
|
try:
|
|
f.truncate(0)
|
|
f.write(status)
|
|
except OSError:
|
|
sys.stderr("Can not write to status file\n")
|
|
|
|
def switch_pressed(event):
|
|
pin_last_rise_date[event.pin_num] = 0
|
|
time.sleep(0.02)
|
|
if event.chip.input_pins[event.pin_num].value != 0:
|
|
pin_last_rise_date[event.pin_num] = time.time()
|
|
|
|
def switch_unpressed(event):
|
|
if pin_last_rise_date[event.pin_num] != 0:
|
|
press_time = time.time() - pin_last_rise_date[event.pin_num]
|
|
if press_time < longpress_delay:
|
|
switch_shortpressed(event)
|
|
elif longpress_delay <= press_time and press_time < verylongpress_delay:
|
|
switch_longpressed(event)
|
|
else:
|
|
switch_verylongpressed(event)
|
|
pin_last_rise_date[event.pin_num] = 0
|
|
|
|
# toggle current room's power with a short and a long press
|
|
# call a script with two short and a long press
|
|
def switch_longpressed(event):
|
|
shortpress_delay = pin_last_rise_date[event.pin_num] - pin_last_shortpress[event.pin_num]
|
|
if shortpress_delay > inter_press_max_delay:
|
|
pin_shortpress_count[event.pin_num] = 0
|
|
elif pin_shortpress_count[event.pin_num] == 1:
|
|
event.chip.output_pins[event.pin_num].toggle()
|
|
elif pin_shortpress_count[event.pin_num] == 2:
|
|
if event.pin_num == 0:
|
|
call(["/home/automation/chch-power/light.sh"])
|
|
chch_status_output(event.chip)
|
|
|
|
# switch all power off with a very long press
|
|
# switch all power on with a short and a very long press
|
|
def switch_verylongpressed(event):
|
|
shortpress_delay = pin_last_rise_date[event.pin_num] - pin_last_shortpress[event.pin_num]
|
|
if shortpress_delay > inter_press_max_delay:
|
|
pin_shortpress_count[event.pin_num] = 0
|
|
for i in range(button_count):
|
|
event.chip.output_pins[i].turn_off()
|
|
elif pin_shortpress_count[event.pin_num] == 1:
|
|
for i in range(button_count):
|
|
event.chip.output_pins[i].turn_on()
|
|
chch_status_output(event.chip)
|
|
|
|
def switch_shortpressed(event):
|
|
now = time.time()
|
|
if pin_shortpress_count[event.pin_num] == 0:
|
|
pin_last_shortpress[event.pin_num] = now
|
|
shortpress_delay = now - pin_last_shortpress[event.pin_num]
|
|
print(shortpress_delay)
|
|
if shortpress_delay > shortpress_count_max_delay:
|
|
pin_shortpress_count[event.pin_num] = 1
|
|
else:
|
|
pin_shortpress_count[event.pin_num] += 1
|
|
pin_last_shortpress[event.pin_num] = now
|
|
chch_status_output(event.chip)
|
|
print(["count:", pin_shortpress_count[event.pin_num]])
|
|
|
|
if __name__ == "__main__":
|
|
listener = pifacedigitalio.InputEventListener()
|
|
for i in range(button_count):
|
|
listener.register(i, pifacedigitalio.IODIR_ON, switch_pressed)
|
|
listener.register(i, pifacedigitalio.IODIR_OFF, switch_unpressed)
|
|
listener.activate()
|
|
chch_status_output(listener.chip)
|