summaryrefslogtreecommitdiffstats
path: root/ampel/google_muell.py
blob: e7ff84304d5a3b6318c83921116af61327e70e48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#! /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": [ 54, 234, 255 ],     # 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": [ 255, 183, 0 ],   # banana, gelber sack
        "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 = tools.argparser.parse_args(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()