Simple Python script that reads Google Calendar and updates OH items with event information

Hello!

I’m not sure what are you trying to accomplish by adding parameters to the script. I’m not using, nor I’m parsing any parameters when the script is being called. Just make sure that you run it manually first time, so you can give a permission for accessing a calendar. And use

python CalSyncHAB.py

to run it, without any additional parameters.

Best regards,
Davor

I ran it without any paramters firstly, but the script told me:

Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly&redirect_uri=http%3A%2F%2Flocalhost%3A8090%2F&response_type=code&client_id=Xxxxxxxxxxxx-sse0n5dq6ti7nld5je9xxxxxxxxxxxx.apps.googleusercontent.com&access_type=offline

If your browser is on a different machine then exit and re-run this
application with the command-line parameter

  --noauth_local_webserver

That’s why I made the next attempts with --noauth_local_webserver, which is the only way to be prompted for credentials

There is no use of the parameter, because script doesn’t parse it. It would make sense if that was included in the script. Do you have any way on running it in a browser on the same machine OH is installed?

Best regards,
Davor

I guess no. It’s just a rasbian supposedly without any gui. But I can check that tomorrow.

Can I run the script on another machine and copy the output?

@davorf

Hi,

I think I’ve made a mistake somewhere as I’ve hit the following issue:

[14:20:23] openhabian@openHABianPi:/etc/openhab2/scripts/CalSyncHAB$ python CalSyncHAB.py
  File "CalSyncHAB.py", line 42
    RetrievedEvents = CalendarEvents.get('items', [])
    ^
IndentationError: unexpected indent 

Any suggestions?

Actually if I remember correctly I had to add this parameter to the script so that I could use the alternate oauth method on my headless Linux install that I can’t run a web browser on.

/usr/bin/python /etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py --noauth_local_webserver

The script passes it through as a Flag and it lets you oauth from another machine.

Hm, I’m on a headless linux machine as well.

What does the script expect when prompting

Enter verification code:

???
My google account name? My google password? Something else?

With that flag set, the message displayed above will have a slightly different URL that you run on another machine. That will give you a code to enter

Thanks @Mike_Bagdanoff this worked for me.
But here is the next problem. I get errors in openhab.log:

2017-04-26 07:45:00.865 [INFO ] [pse.smarthome.model.script.GoogleCal] - Traceback (most recent call last):
  File "/etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py", line 126, in <module>
    Main()
  File "/etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py", line 30, in Main
    Credentials = GetCredentials()
  File "/etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py", line 23, in GetCredentials
    AuthenticationFlow = client.flow_from_clientsecrets(S.CalendarClientSecretFile, S.CalendarScope)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/client.py", line 2125, in flow_from_clientsecrets
    cache=cache)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/clientsecrets.py", line 165, in loadfile
    return _loadfile(filename)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/clientsecrets.py", line 125, in _loadfile
    exc.strerror, exc.errno)
oauth2client.clientsecrets.InvalidClientSecretsError: ('Error opening file', u'OH2Auth.json', 'No such file or directory', 2)

This is my CalSyncHAB.ini:

[General]
ApplicationName: OpenHAB

[Calendar]
Scope: https://www.googleapis.com/auth/calendar.readonly
CalendarId: xxxxxxbv7t538hmdangsxxxxxx@group.calendar.google.com
MaxEvents: 5
TimeZone: +01:00
ClientSecretFile: OH2Auth.json

[OpenHAB]
HostName: 192.168.43.91
Port: 8080
ItemPrefix: GoogleCal_

my rule:

rule "GetCalEvents"
when
        Time cron "0 0/1 * ? * * *"
then
        var String results = executeCommandLine("python /etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py",1000)
        logInfo("GoogleCal", results)
end

And everything is placed here:

[07:47:51] openhabian@openhabianpi2:/etc/openhab2/scripts/CalSyncHAB$ ls -l
insgesamt 24
-rw-r--r-- 1 openhabian openhabian  299 Apr 26 07:26 CalSyncHAB.ini
-rwxr-xr-x 1 openhabian openhabian 5746 Mär  8 04:07 CalSyncHAB.py
-rw-r--r-- 1 openhabian openhabian  437 Apr 24 20:19 OH2Auth.json
-rwxr-xr-x 1 openhabian openhabian  970 Mär  8 04:07 Settings.py
-rw-r--r-- 1 openhabian openhabian 1172 Apr 24 20:28 Settings.pyc

Hello!

First of all, I would like to apologize if I made a confusion about parameter usage in the script. I’ve used parts of google Python examples to save some time, and, off the top of my head concluded that a script parameter is not being parsed.

Regarding the error message, check the CalSyncHAB folder permissions. If I recall correctly, script writes some temporary file to the folder, so, it should have write permission.

Best regards,
Davor

No problem, really :slight_smile:

I changed “ClientSecretFile” entry in the .ini file to the complete path. It’s now:

ClientSecretFile: /etc/openhab2/scripts/CalSyncHAB/OH2Auth.json

There are no more errors in openhab.log :slight_smile:
“result” only shows a dash.

But al my items are empty though I have entries in my calendar.

I also set write permission for my CalSynHAB folder, but without any effect.

My items are:

String     GoogleCal_Event1_Summary "Event1 Sum.: [%s]" <calendar>
String     GoogleCal_Event1_Location "Event1 Loc.: [%s]" <calendar>
String     GoogleCal_Event1_Description "Event1 Desc. [%s]" <calendar>
DateTime   GoogleCal_Event1_StartTime  "Event1 Start [%1$tH:%1$tM]" <calendar>
DateTime   GoogleCal_Event1_EndTime "Event1 End [%1$tH:%1$tM]" <calendar>

and I have of course 5 of these.

EDIT: is it possible to have more than one calendar or to change the calendar by just editing .ini file?

Hello!

Could you try using “primary” as CalendarId (without quotes, of course) and adding some events to your primary calendar?
Regarding your second question, it’s not possible to have more than one calendar (at least, not with a single script - maybe it would work if you would use multiple scripts in multiple locations - but you would need to have multiple sets of OH items too), but you can change CalendarId in .ini file and make the script synchronize any calendar you have available in your Google account.

Best regards,
Davor

Hello Davor!
First of all thank you for your help and patience!

I changed CalendarID to:

CalendarId: primary

and added some serial events to my primary calendar,

but my items are still empty.

Then I changed CalendarId to my google mail (with @gmail.com), but this also did not help.


PS: Meanwhile I managed to write some lines into a file and found out that within GetCredentials() the script crashes in

Credentials = tools.run_flow(AuthenticationFlow, CredentialStore, Flags)

and never returns to Main().

OMG, Everything is working fine now! :slight_smile:

I repeated the inital call to the script from outside OH2. CalSyncHAB.py told me that I had to start it with --noauth_local_webserver which means that there must have went something wrong when I entered the verification code some days ago. So, I called the script with the parameter, copied the shown url to my windows machine, retrieved the verification code from google site and pasted it into the script prompt. A few seconds later all my items were filled with my calendar events.

Thanks again for all your help!!!

Hello!

Glad you made it work. I wish I could provide more support, but I had a really busy week at work.

Best regards,
Davor

Hello davorf,

as I said: no problem! :slight_smile:

But I’m afraid I have to come up with the next problem. My items have been updated, but only because I started the script from outside openhab. I just saw, that my rule

var String results = executeCommandLine("python /etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py",10000)

is called, but it does not update my items. The script is still stuck within

Credentials = tools.run_flow(AuthenticationFlow, CredentialStore, Flags)

when being called by the rule.

Hello!

Since you’re using the same script from OH, it should work. Maybe it’s the way you’re calling it from the rule. This is the line from my rule:

executeCommandLine("C:\\Python27\\python.exe@@C:\\OpenHAB\\external\\CalSyncHAB\\CalSyncHAB.py", 120*1000)

but I’m using it on Windows. Also, do you have Python 3.x installed, besides Python 2.x? Maybe it’s trying to run the script using Python 3.x.

Best regards,
Davor

Hi davorf,

what I did:

  • I changed my rule to:
var String results = executeCommandLine("/usr/bin/python /home/openhabian/CalSyncHAB/CalSyncHAB.py",120*1000)
logInfo("GoogleCalCron", results)
  • I made sure that /usr/bin/python --version shows “Python 2.7.9”
  • I set every single folder and every single file within “/usr/bin/python /home/openhabian/CalSyncHAB” to read, write, exec rights for every user
    -> Still the same behavior

Then I deleted all files and also the credentials in google and started from the scratch. The only thing that changed is that now in openhab.log i get:

Failed to start a local webserver listening on either port 8080
or port 8090. Please check your firewall settings and locally
running programs that may be blocking or using those ports.

Falling back to --noauth_local_webserver and continuing with
authorization.


Go to the following link in your browser:


    https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcalendar.readonly&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&response_type=code&client_id=165856906695-igqva571onj2k0egmmsl5dnj3ato8ks9.apps.googleusercontent.com&access_type=offline

Enter verification code: Traceback (most recent call last):
  File "/home/openhabian/CalSyncHAB/CalSyncHAB.py", line 126, in <module>
    Main()
  File "/home/openhabian/CalSyncHAB/CalSyncHAB.py", line 30, in Main
    Credentials = GetCredentials()
  File "/home/openhabian/CalSyncHAB/CalSyncHAB.py", line 25, in GetCredentials
    Credentials = tools.run_flow(AuthenticationFlow, CredentialStore, Flags)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/_helpers.py", line 133, in positional_wrapper
    return wrapped(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/oauth2client/tools.py", line 239, in run_flow
    code = input('Enter verification code: ').strip()
EOFError: EOF when reading a line

This looks like the script can’t send the credentials to google. Why else would it ask “Enter verification code:”? That seems to me is the reason why the scripts never returns to Main() from GetCredentials(). It is waiting for input.

When calling the exact same script from the command line ("/usr/bin/python /home/openhabian/CalSyncHAB/CalSyncHAB.py") there is no prompting for the verification code, everything is alright and my items get updated within seconds.

It looks like the problem is caused by “executeCommandLine”, but I can’t find out why.

Re set up the credentials auth manually, then put the@@ between /usr/bin/Python and the rest:

executeCommandLine("/usr/bin/python@@/home/openhabian/CalSyncHAB/CalSyncHAB.py",120*1000)

That tells executeCommandLine that the other part is the args.

Hi Mike,
how do I re setup the credentials manually?

I already tried the version with @@, but without any success. Without @@ the script is started but stuck within GetCredentials()