async def sense(on_sit_down, on_get_up): GPIO.setmode(GPIO.BCM) sitting_down = False while True: tick = 0 # Output low on the pin GPIO.setup(INPUT_PIN, GPIO.OUT) GPIO.output(INPUT_PIN, GPIO.LOW) await asyncio.sleep(0.1) # Change the pin back to input GPIO.setup(INPUT_PIN, GPIO.IN) # Count up until the pin goes high while (GPIO.input(INPUT_PIN) == GPIO.LOW): tick += 1 await asyncio.sleep(0.01) threshold = config.GET_UP_WAIT_TIME_SECONDS * 100 # If it's been long enough since the pin has gone high, we are not # sitting if tick >= threshold and sitting_down: logger.info( "Time since last pressure exceeded threshold, user is not sitting anymore") asyncio.create_task(on_get_up()) sitting_down = False # If it took short enough of a time for the pin to go high, we are applying enough pressure to count # as sitting if tick < SITTING_THRESHOLD and not sitting_down: logger.info("Enough pressure applied to sensor, user is sitting") asyncio.create_task(on_sit_down()) sitting_down = True
def main(): logger.info("Starting to sense the bench") try: asyncio.run(sense(start_session, end_session)) except KeyboardInterrupt: logger.info("Interrupted, exiting") finally: cleanup()
async def start_session(): logger.info("Writing session start event") timestamp = arrow.now(config.TIMEZONE).timestamp spreadsheet = await get_spreadsheet() event_row = await get_latest_event(spreadsheet) if len(event_row) > 1 and event_row[1] == "start": logger.warning( "Expected last event to be 'stop' but it was 'start'. Starting a new session." ) await insert_event(spreadsheet, timestamp, "start")
async def insert_session(spreadsheet, start_timestamp, end_timestamp): ws = await get_or_create_worksheet(spreadsheet, SESSION_TRACKING_WORKSHEET_NAME) start_date = arrow.get(start_timestamp).to(config.TIMEZONE) end_date = arrow.get(end_timestamp).to(config.TIMEZONE) duration_min = (end_date - start_date).seconds // 60 start_date_str = start_date.format('DD/MM/YYYY HH:mm:ss') end_date_str = end_date.format('DD/MM/YYYY HH:mm:ss') logger.info( f"Inserting session [{start_date_str}, {end_date_str}, {duration_min}]" ) await ws.insert_row([start_date_str, end_date_str, duration_min])
async def end_session(): logger.info("Writing session stop event") end_timestamp = arrow.now(config.TIMEZONE).timestamp spreadsheet = await get_spreadsheet() latest_event_row = await get_latest_event(spreadsheet) if len(latest_event_row) < 2: logger.warning("Tried to end a session when it was not running") return if len(latest_event_row) > 1 and latest_event_row[1] == "stop": logger.warning( "Expected last event to be 'start' but it was 'stop'. Not ending the session." ) return start_timestamp = int(latest_event_row[0]) await insert_event(spreadsheet, end_timestamp, "stop") await insert_session(spreadsheet, start_timestamp, end_timestamp)
def cleanup(): logger.info("Cleaning up GPIO") GPIO.cleanup()
async def insert_event(spreadsheet, timestamp, event): ws = await get_or_create_worksheet(spreadsheet, EVENT_TRACKING_WORKSHEET_NAME) logger.info(f"Inserting event [{timestamp}, {event}]") await ws.insert_row([timestamp, event])
async def get_spreadsheet(): logger.info(f"Opening spreadsheet {config.GOOGLE_SHEETS_URL}") agc = await make_client() sheet = await agc.open_by_url(config.GOOGLE_SHEETS_URL) return sheet