From 1f8c3ae133fea3be572d041beaed9a03b2160eac Mon Sep 17 00:00:00 2001 From: makefu Date: Sun, 4 Feb 2018 19:48:18 +0100 Subject: make google-muell usable --- ampel/google_muell.py | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100755 ampel/google_muell.py (limited to 'ampel/google_muell.py') diff --git a/ampel/google_muell.py b/ampel/google_muell.py new file mode 100755 index 0000000..7cd6e52 --- /dev/null +++ b/ampel/google_muell.py @@ -0,0 +1,139 @@ +#! /usr/bin/env python +""" usage: google-muell [options] + + --esp=HOST esp8266 ip [Default: 192.168.1.23] + --client-secrets=FILE Path to client secrets file (from application) [Default: licht-kalender-secrets.json] + --credential-path=PATH Path to newly generated (or existing) credentials [Default: licht-creds.json] + --sleepval=SEC seconds to sleep [Default: 900] + --lol=LOL set log level [Default: debug] + +you can create the client-secrets by creating a new google application, create +oauth2 token and download it ( url here) + +""" + +from docopt import docopt +from ampel.fade import calc_chain +import time +from time import sleep +import json +import sys +from datetime import datetime, timedelta +import requests + +import httplib2 +from dateutil.parser import parse +from apiclient import discovery +from oauth2client import client +from oauth2client import tools +from oauth2client.file import Storage +import logging as log +SCOPES = 'https://www.googleapis.com/auth/calendar.readonly' +APPLICATION_NAME = 'licht-kalender-client' +calendarId = 'o56ig681gla2a5vupm4vgiv7tc@group.calendar.google.com' + +# Mapping colorId from calendar to RGB colors +colormap = { + "-1": [ 124, 179, 66 ], # default color (green) + "1": [ 121, 134, 203 ], # lavendel + "2": [ 51, 182, 121 ], # salbei + "3": [ 142, 36, 170 ], # grape + "4": [ 230, 124, 115], # light red + "5": [ 246, 191, 38], # banana + "6": [ 244, 81, 30 ], # mandarin + "7": [3, 155, 229], # pfau + "8": [ 128,128,128 ], # grey + "9": [ 63, 81, 181 ], # heidelbeere + "10": [0x0B,0x80,0x43 ], # basilicum + "11": [ 231,0,0 ], # true red + } + +def set_lol(lol): + numeric_level = getattr(log,lol.upper(),None) + if not isinstance(numeric_level,int): + raise AttributeError(f'No such log level {lol}') + log.basicConfig(level=numeric_level) + +def get_creds(secrets_file,credential_path): + ''' + provide a cred_dir where the credentials would be stored to + ''' + import argparse + flags = argparse.ArgumentParser(parents=[tools.argparser]).parse_args() + + store = Storage(credential_path) + credentials = store.get() + if not credentials or credentials.invalid: + flow = client.flow_from_clientsecrets(secrets_file, SCOPES) + flow.user_agent = APPLICATION_NAME + credentials = tools.run_flow(flow, store, flags) + log.info(f'Storing new credentials to {credential_path}') + else: + log.info(f'Using existing valid credentials {credential_path}') + + return credentials + +def next_date(credentials): + http = credentials.authorize(httplib2.Http()) + service = discovery.build('calendar', 'v3', http=http) + + now = datetime.utcnow().isoformat() + 'Z' # 'Z' indicates UTC time + log.debug('Getting the upcoming 10 events') + eventsResult = service.events().list( + calendarId=calendarId, timeMin=now, maxResults=10, singleEvents=True, + orderBy='startTime').execute() + events = eventsResult.get('items', []) + for event in events: + rem = event['reminders'] + # 'reminders': {'useDefault': False, 'overrides': [{'method': 'popup', 'minutes': 900}]} + start = parse(event['start'].get('dateTime', event['start'].get('date'))) + if rem.get('overrides',[]): + reminder = timedelta(minutes=rem['overrides'][0]['minutes']) + log.info(f"Got a reminder at {reminder}, subtracting time") + start = start - reminder + + if 'dateTime' in event['end']: + end = parse(event['end']['dateTime']) + else: + end = parse(event['end']['date']) - timedelta(seconds=1) # + timedelta(days=1) + + if start < datetime.now() < end: + log.info(f"event {event['summary']} is active now ({start} - {end})") + return event + else: + log.info(f"event between {start} and {end} is not active") + + + pass + + +def to_payload(arr): + return {"r":arr[0],"g":arr[1],"b":arr[2]} + +def main(): + args = docopt(__doc__) + set_lol(args['--lol']) + client_secrets = args['--client-secrets'] + sleepval = float(args["--sleepval"]) + esp = args["--esp"] + cred_path = args["--credential-path"] + creds = get_creds(client_secrets,cred_path) + while True: + try: + log.info("Fetching next Date") + t = next_date(creds) + if t: + color = colormap[str(t.get('colorId',-1))] + log.info(f"setting color to {color} according to colormap") + else: + color = colormap["-1"] + log.info(f"setting default color {color}") + requests.get(f"http://{esp}/color",params=to_payload(color)) + + except Exception as e: + log.error(f"Something went wrong while calculating the next date:{e}") + log.info(f"sleeping for {sleepval} seconds") + sleep(sleepval) + +if __name__ == "__main__": + main() -- cgit v1.2.3