Hi all,
I modified the original workflow and code to make it work. I removed 1 minute timer and use only interrupt input to switch LED on from LED1 to LED4 one by one.
I think that the original code is toggling LED on/off every 1 minute regardless the timer. When the interrupt button event happens, it checks the timer 1 trigger (it is always false). The original code did not make sense. So, I decided to rewrite the python code to save the last time the interrupt happened.
When a new interrupt occurs, I check the time difference between the previous saved interrupt observed time and the current the interrupt observed time. If the time difference were less than 7sec, my code would ignore the current interrupt event. Otherwise, the code would save the current interrupt’s observed time and turn on the next LED light.
I look forward to read Dan’s detailed post regarding GPIO tutorial. See if I have missed something. I want to post my solution for feedback from any experienced developer. I welcome any comments.
Best,
Michael
'''
Last Updated: Dec 13, 2016
Author: Medium One
'''
import MQTT
import Store
import Analytics
import DateConversion
import datetime
import Filter
import json
# pinmap dictionary allows you to map the physical pin to the logical map address in read_pin/write_pin functions.
pinmap = {'1':0, '8':5, '9':6, '10':7}
waittime = 7
def read_pin(pin, tag):
send_mqtt_msg(u'0;4;{};{};'.format(pin, tag));
def write_pin(pin, val):
send_mqtt_msg(u'0;3;{};{};'.format(pin, val));
def send_mqtt_msg(msg):
mqtt_msg = msg
if not isinstance(msg, basestring):
mqtt_msg = ''.join(map(unichr, msg))
MQTT.publish_event_to_client('s3a7', mqtt_msg, 'latin1')
# debounce
log ("Detect an input trigger. It could be a timer or interrupt trigger.")
in1 = IONode.get_input('in1')
log ('The current interrupt (in1) : {0}'.format(in1))
log ('The current interrupt (in1) observed at {0}'.format(DateConversion.to_py_datetime(in1['observed_at'])))
# Testing purpose only
Store.delete('intrtime')
# get the previous interrupt time
log ('Retrive the previous interrupt date/time when LED toggles')
try:
prev_time = DateConversion.to_py_datetime(json.loads(Store.get('intrtime')))
except (ValueError, TypeError):
log ('No previous interrupt time. Assign utc_now datetime as the previous date and time.')
#prev_time = datetime.datetime.utcnow() - datetime.timedelta(seconds=3) # guarantee to toggle led
#prev_time = datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(seconds=3) # guarantee to toggle led
prev_time = DateConversion.to_py_datetime(in1['observed_at']) - datetime.timedelta(seconds=waittime+1)
log('From Store, in1 observed at {0}.'.format(prev_time))
timediff = DateConversion.to_py_datetime(in1['observed_at']) - prev_time
log ("Time Difference between in1(timer1) and last_2_interrupt_events[1] is {0} ".format(timediff))
if DateConversion.to_py_datetime(in1['observed_at']) - prev_time < datetime.timedelta(seconds=waittime):
log ('Difference in time between the timer trigger and the last interrupt trigger is less than 10 sec.')
log ('Escape to skip the rest of the code.')
escape()
else:
log ('Proceed to toggle the LED state.')
log ("Execute try")
log ("Store the current interrupt time.")
Store.set_data('intrtime',json.dumps(in1['observed_at'])) # store the time.
try:
prev_state = int(Store.get('prev_state'))
except (ValueError, TypeError):
log ("prev_state = None. Initialize prev_state to zero.")
prev_state = 0
log ("prev_state : {0}".format(prev_state))
# toggle LED state
next_state = 0
if prev_state == 3:
next_state = 0
else:
next_state = prev_state + 1
write_pin(pinmap['1'], 1 if next_state == 0 else 0 )
write_pin(pinmap['8'], 1 if next_state == 1 else 0 )
write_pin(pinmap['9'], 1 if next_state == 2 else 0 )
write_pin(pinmap['10'], 1 if next_state == 3 else 0 )
# Not working code.
#
#if next_state == 0:
# read_pin(pinmap['1'],'GPIO12')
#elif next_state == 1:
# read_pin(pinmap['8'],'GPIO13')
#elif next_state == 2:
# read_pin(pinmap['9'],'GPIO14')
#elif next_state == 3:
# read_pin(pinmap['10'],'GPIO15')
#else:
# log ("Something wrong.")
#Store.set_data('prev_state', str(next_state))