Since I couldn’t make CalDAV Personal binding to work with Google Calendar, and, according to this post, there is a problem with CalDAV Personal binding in OH2, I’ve made a simple Python script that authenticates via OAuth2, and uses Google Calendar API to populate OH items with an event information.
First, you need to create OAuth2 credentials (https://console.developers.google.com), download credentials in JSON format and place it in CalSyncHAB folder (cloned or downloaded from a github). After installing Python (both 2.x and 3.x will work), you need to install following packages:
Application name - name of the application that will ask for an authentication
Scope - should not be changed
CalendarId - ID of the calendar you want to retrieve information from (if you have only one calendar, “primary” keyword will suffice, if not, you have to use Calendar ID shown in the settings of that calendar)
MaxEvents - maximal number of events retrieved (starting from current date and time)
TimeZone - in format ±HH:mm
ClientSecretFile - name of the OAuth2 credentials file in JSON format
HostName - IP address or host name of the OH server
Port - Port of the OH server (usually 8080)
SSLConnection - Should be left as False (not used at the moment)
Username - not used at the moment
Password - not used at the moment
ItemPrefix - prefix of the calendar items in OpenHAB - for example, if you use ItemPrefix Calendar_Google_Primary_ you should create following items:
If you’ve set MaxEvents to 5, you should have 5 sets of those items - for example Calendar_Google_Primary_Event1_Summary to Calendar_Google_Primary_Event5_Summary
After executing script for the first time (first time it should be done manually, not via OpenHAB), it will open Web Browser and ask you for a permission to access your calendar. You need to sign in to your Google account (if you aren’t signed in already) and press Allow button.
Then you can use rules to trigger this Python script via executeCommandLine on some specific time (cron expression) or via switch in UI. Finally, the script can be found here:
If this explanation sounds confusing, feel free to post your questions here, or open an issue on the github repository.
I’m using Project Rotini as primary UI on my wall tablet, and it has calendar widget that uses standard OH items (description, location, start time and end time namely). I’ve also made standard OH sitemap frame, with all those items for the next 5 days, to use it in HABDroid and Basic UI. And I’m using executeCommandLine every hour to update those items.
2017-02-25 13:48:15.180 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_Summary' for the unknown item 'Calendar_Google_Home_Event1_Summary'.
2017-02-25 13:48:15.203 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_Summary' for the unknown item 'Calendar_Google_Home_Event1_Summary'.
2017-02-25 13:48:15.222 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_Location' for the unknown item 'Calendar_Google_Home_Event1_Location'.
2017-02-25 13:48:15.242 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_Location' for the unknown item 'Calendar_Google_Home_Event1_Location'.
2017-02-25 13:48:15.262 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_Description' for the unknown item 'Calendar_Google_Home_Event1_Description'.
2017-02-25 13:48:15.281 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_Description' for the unknown item 'Calendar_Google_Home_Event1_Description'.
2017-02-25 13:48:15.302 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_StartTime' for the unknown item 'Calendar_Google_Home_Event1_StartTime'.
2017-02-25 13:48:15.322 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_StartTime' for the unknown item 'Calendar_Google_Home_Event1_StartTime'.
2017-02-25 13:48:15.341 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_EndTime' for the unknown item 'Calendar_Google_Home_Event1_EndTime'.
2017-02-25 13:48:15.361 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event1_EndTime' for the unknown item 'Calendar_Google_Home_Event1_EndTime'.
2017-02-25 13:48:15.383 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_Summary' for the unknown item 'Calendar_Google_Home_Event2_Summary'.
2017-02-25 13:48:15.412 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_Summary' for the unknown item 'Calendar_Google_Home_Event2_Summary'.
2017-02-25 13:48:15.432 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_Location' for the unknown item 'Calendar_Google_Home_Event2_Location'.
2017-02-25 13:48:15.452 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_Location' for the unknown item 'Calendar_Google_Home_Event2_Location'.
2017-02-25 13:48:15.471 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_Description' for the unknown item 'Calendar_Google_Home_Event2_Description'.
2017-02-25 13:48:15.491 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_Description' for the unknown item 'Calendar_Google_Home_Event2_Description'.
2017-02-25 13:48:15.511 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_StartTime' for the unknown item 'Calendar_Google_Home_Event2_StartTime'.
2017-02-25 13:48:15.532 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_StartTime' for the unknown item 'Calendar_Google_Home_Event2_StartTime'.
2017-02-25 13:48:15.553 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_EndTime' for the unknown item 'Calendar_Google_Home_Event2_EndTime'.
2017-02-25 13:48:15.573 [INFO ] [thome.io.rest.core.item.ItemResource] - Received HTTP POST request at 'items/Calendar_Google_Home_Event2_EndTime' for the unknown item 'Calendar_Google_Home_Event2_EndTime'.
This looks like a problem with OH rather than the problem with Python/Script. Script does trigger HTTP POST, but OpenHAB shows an error. Check OH calendar item names and item prefix in CalSyncHAB.ini.
Since it looks like the OH error, you can check openhab.log and events.log. It seems to me that it happens after Python script execution. Could you post part of your .items file that is used for the calendar, and CalSyncHAB.ini (without sensitive information, of course). Have you changed settings on Google Calendar (allowing of less secure applications, calendar name)?
I’ve updated CalSyncHAB script, and I would suggest anyone using it to get the newest version. There was a bug that would, occasionally, show some events as blank. This would happen in case of slow OH server response. POST request for removal of an old value would be sent to the OH server REST API first. After that, POST request with a new value would follow. In case that first POST request gets delay, update with a new value would happen first, and after that, delayed removal would occur. This is solved in the new version by separating removal of old values from update of a new ones and 2 seconds delay between those two.
What do I need to do within google console? Do I need to create a new project? If so, what kind of?
There was an “API Project api-project-xxxxxxxxxxxx” already and I created “Browser key 1” and Browser key 2" for this one, but now I am completely stuck. Thanks in advance.
leads to: “/usr/bin/python: cannot import name IncompleteRead; ‘pip’ is a package and cannot be directly executed”
same result with sudo
My python version is 2.7.9
EDIT: I found: sudo pip install --upgrade google-api-python-client
but this leads to:
Traceback (most recent call last):
File "/usr/bin/pip", line 9, in <module>
load_entry_point('pip==1.5.6', 'console_scripts', 'pip')()
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 356, in load_entry_point
return get_distribution(dist).load_entry_point(group, name)
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2476, in load_entry_point
return ep.load()
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2190, in load
['__name__'])
File "/usr/lib/python2.7/dist-packages/pip/__init__.py", line 74, in <module>
from pip.vcs import git, mercurial, subversion, bazaar # noqa
File "/usr/lib/python2.7/dist-packages/pip/vcs/mercurial.py", line 9, in <module>
from pip.download import path_to_url
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 25, in <module>
from requests.compat import IncompleteRead
ImportError: cannot import name IncompleteRead
Firstly, go to https://console.developers.google.com/apis, and then choose Credentials on the menu (located on the left side of the screen). After that, press the blue button “Create credentials” located below the page title, and choose “OAuth client ID”. Select “Other” as application type, fill in “Name” field, and press “Create” button. It will show your “Client ID” and “Client secret” in a pop-up window. After closing this pop-up, you can download JSON credentials file by pressing Download JSON button located on the right side (it looks like download button on dropbox, google drive, etc).
Regarding your second post, I really can’t help you. I’m using Python on a Windows machine, and I don’t have access to any Linux at the moment.
Now I am facing the next problem. While not having a webserver running on my rpi I executed
python CalSyncHAB.py --noauth_local_webserver
and entered my google account password when I was asked "Enter verification code:"
But all the time I only receive: “Authentication has failed: invalid_grant” though there was no typo in my password.
After the third attempt everything seems to be locked as I received: “Authentication has failed: invalid_grantCode was already redeemed.”