예제 #1
0
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
예제 #2
0
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()
예제 #3
0
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")
예제 #4
0
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])
예제 #5
0
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)
예제 #6
0
def cleanup():
    logger.info("Cleaning up GPIO")
    GPIO.cleanup()
예제 #7
0
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])
예제 #8
0
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