So since i was running into serval problems to get this working… and to help others to not get lost in this thread i will add all the steps needed here… most of them is copy&paste from this thread… Thanks to all who helped here
@davorf @FrankR @Mike_Bagdanoff @ei_Gelb_Geek @binderth
I also added some small adjustments and code lines for my Telegram Bot, which notifies our house group… so more than one human keep an eye on the trash cans ![]()



-
Make sure you have already python installed…
-
Upgrade pip:
sudo easy_install --upgrade pip
- after that is finished, run:
sudo python -m pip install --upgrade google-api-python-client
sudo python -m pip install configparser
sudo python -m pip install requests
- Create OAuth2 credentials
- go to https://console.developers.google.com/ and create a project named “OpenHAB” and create a new OAuth Client ID, Type: “others”
- download this OAuth 2.0-Client-ID as JSON (and save it for later)
- activate the Google Calandar API
- create a folder “CalSyncHAB” within /etc/openhab2/scripts
- create folder
sudo mkdir /etc/openhab2/scripts/CalSyncHAB
sudo git clone http://github.com/davorf/CalSyncHAB.git .
- rename your OAuth 2.0-Client-ID to “CalSyncHABSecret.json” and put it in under /etc/openhab2/scripts/CalSyncHAB
sudo chown openhab:openhabian /etc/openhab2/scripts/CalSyncHAB
- cd into CalSyncHAB folder and
sudo chown openhab:openhabian *
- open .ini file and for setting “ClientSecretFile” enter the complete path, e.g.
ClientSecretFile: /etc/openhab2/scripts/CalSyncHAB/CalSyncHABSecret.json
- create a script “/etc/openhab2/scripts/CalSyncHAB.sh” with: (in my case i need to remove the first line to get the .sh running)
#!/bin/sh
/usr/bin/python /etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py --noauth_local_webserver
sudo chown openhab:openhabian /etc/openhab2/scripts/CalSyncHAB.sh
- after that run the .sh copy the url shown by the script into your browser, click “Allow” and paste the given code back into the script prompt.
sudo -u openhab /etc/openhab2/scripts/CalSyncHAB.sh
- if this was successfull, we can delete that .sh file (we can use the .py file in our rules)
OpenHAB File Examples:
- /etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.ini
[General]
ApplicationName: OpenHAB
[Calendar]
Scope: https://www.googleapis.com/auth/calendar.readonly
CalendarId: <YOUR_CALENDAR_ID>@group.calendar.google.com
MaxEvents: 5
TimeZone: +02:00
ClientSecretFile: /etc/openhab2/scripts/CalSyncHAB/CalSyncHABSecret.json
[OpenHAB]
HostName: <IP_OF_YOUR_OH>
Port: 8080
ItemPrefix: gCal_Abfall_
- GoogleCal.items
//GoogleCalender
Group gCal_Abfall
Group gCal_Abfall_Event
Group:Switch:OR(ON, OFF) gCal_Abfall_Item "Müll-Abfuhr Termine morgen [(%d)]" <softener>
Group:Switch:OR(ON, OFF) gCal_Geburtstag_Item "Geburtstage morgen [(%d)]" <smiley>
String gCal_Abfall_Event1 (gCal_Abfall)
String gCal_Abfall_Event2 (gCal_Abfall)
String gCal_Abfall_Event3 (gCal_Abfall)
// your Google Cal Items need to match the item names!
Switch GelberSack "GelberSack" (gCal_Abfall_Item)
Switch Biotonne "Biotonne" (gCal_Abfall_Item)
Switch Restmuell "Restmuell" (gCal_Abfall_Item)
Switch Papiertonne "Papiertonne" (gCal_Abfall_Item)
String gCal_Abfall_Event1_Summary "Mülltonne: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event1_Location "Event1 Loc.: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event1_Description "Event1 Desc. [%s]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event1_StartTime "Abholung: [%1$td.%1$tm.%1$tY]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event1_EndTime "Event1 End [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <calendar> (gCal_Abfall_Event)
Switch gCal_Abfall_Event1_Approved "Mülltonne rausgestellt: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event2_Summary "Mülltonne: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event2_Location "Event2 Loc.: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event2_Description "Event2 Desc. [%s]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event2_StartTime "Abholung: [%1$td.%1$tm.%1$tY]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event2_EndTime "Event2 End [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <calendar> (gCal_Abfall_Event)
Switch gCal_Abfall_Event2_Approved "Mülltonne rausgestellt: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event3_Summary "Mülltonne: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event3_Location "Event3 Loc.: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event3_Description "Event3 Desc. [%s]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event3_StartTime "Abholung: [%1$td.%1$tm.%1$tY]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event3_EndTime "Event3 End [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <calendar> (gCal_Abfall_Event)
Switch gCal_Abfall_Event3_Approved "Mülltonne rausgestellt: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event4_Summary "Mülltonne: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event4_Location "Event4 Loc.: [%s]" <calendar> (gCal_Abfall_Event)
String gCal_Abfall_Event4_Description "Event4 Desc. [%s]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event4_StartTime "Abholung: [%1$td.%1$tm.%1$tY]" <calendar> (gCal_Abfall_Event)
DateTime gCal_Abfall_Event4_EndTime "Event4 End [%1$td.%1$tm.%1$tY %1$tH:%1$tM]" <calendar> (gCal_Abfall_Event)
Switch gCal_Abfall_Event4_Approved "Mülltonne rausgestellt: [%s]" <calendar> (gCal_Abfall_Event)
- GoogleCal.rules
// grab the calendar events from google via API
rule "GetCalEvents"
when
//at second :00 Every 30 Minutes, everyday from 5PM to 9PM
Time cron "0 0/30 17-21 ? * *"
then
var String results = executeCommandLine("python /etc/openhab2/scripts/CalSyncHAB/CalSyncHAB.py", 120*1000)
logInfo("GetCalEvents", results)
end
// Check garbage calendar events
rule "Check garbage calendar events"
when
// 30 seconds delay to get "GetCalEvents" rule time to parse Google Cal API
// at second :30 Every 30 Minutes, everyday from 5PM to 9PM
Time cron "30 0/30 17-21 ? * *"
then
logInfo("Garbage calendar", "Execution started")
gCal_Abfall.members.forEach[ gc |
val eventStart = gCal_Abfall_Event.members.filter[ act | act.name == gc.name+"_StartTime"].head
val eventDesc = gCal_Abfall_Event.members.filter[ act | act.name == gc.name+"_Description"].head
val eventSum = gCal_Abfall_Event.members.filter[ act | act.name == gc.name+"_Summary"].head
val eventApproved = gCal_Abfall_Event.members.filter[ act | act.name == gc.name+"_Approved"].head
// Execution every (Time cron) until EventStartTime or Tasks is approved by Item
if (eventApproved.state == OFF) {
// in this case i used 8 hours before EventStartTime (my events starting at 00:00, so I have enough time in the evening to get the trash cans out)
if (now.isAfter(new DateTime((eventStart.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).minusHours(8)) &&
now.isBefore(new DateTime((eventStart.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli))) {
val buffer = eventDesc.state.toString.split(";")
val calItem = gCal_Abfall_Item.members.filter[ ci | ci.name == eventSum.state.toString].head
if (calItem !== null) {
logInfo("Garbage calendar", gc.name + " starting now with '" + calItem.name + "' -> " + buffer.get(0))
// you need to have images with the event names in your openhab "html" folder, otherwise comment the line out
sendTelegramPhoto( "bot1", "http://openhabianpi:8080/static/" + calItem.name + ".png", "")
sendTelegram( "bot1", "🗑" + gc.name + " ausgelöst...\n\n" + calItem.name + " wird morgen früh abgeholt...\n -> " + buffer.get(0) + "\n\n(Wiedervorlage dieser Nachricht jede Stunde bis der Schalter auf erledigt gesetzt wurde.. ;-) )")
sendCommand(calItem, ON)
}
else {
logInfo("Garbage calendar", "WARNING: cannot find item named '" + eventSum.state + "'")
}
}
}
//Execution at EventStartTime if Task is not approved by Item
if (now.isAfter(new DateTime((eventStart.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli)) &&
//Change plusMinutes(60) to your Time Cron Interval
now.isBefore(new DateTime((eventStart.state as DateTimeType).zonedDateTime.toInstant.toEpochMilli).plusMinutes(60))) {
//Reset eventApproved status!
eventApproved.sendCommand(OFF)
//Reset calItem!
val buffer = eventDesc.state.toString.split(";")
val calItem = gCal_Abfall_Item.members.filter[ ci | ci.name == eventSum.state.toString].head
if (calItem !== OFF) {
sendCommand(calItem, OFF)
logInfo("Garbage calendar", gc.name + " ended now with'" + calItem.name + "' -> " + buffer.get(1))
}
else {
logInfo("Garbage calendar", "WARNING: cannot find item named '" + eventSum.state + "'")
}
}
]
logInfo("Garbage calendar", "Execution finished")
end
- YOURSITEMAP.sitemap
Frame label="Anstehende Termine für Morgen" {
Text item=gCal_Abfall_Item {
Frame label="Anstehende Müll-Abfuhr Termine" {
//Group item=gCal_Abfall_Item label="Anstehende Müll-Abfuhr Termine"
Text item=gCal_Abfall_Event1_Summary
//Text item=gCal_Abfall_Event1_Location
Text item=gCal_Abfall_Event1_Description
Text item=gCal_Abfall_Event1_StartTime
//Text item=gCal_Abfall_Event1_EndTime
Switch item=gCal_Abfall_Event1_Approved
Text item=gCal_Abfall_Event2_Summary
//Text item=gCal_Abfall_Event2_Location
Text item=gCal_Abfall_Event2_Description
Text item=gCal_Abfall_Event2_StartTime
//Text item=gCal_Abfall_Event2_EndTime
Switch item=gCal_Abfall_Event2_Approved
Text item=gCal_Abfall_Event3_Summary
//Text item=gCal_Abfall_Event3_Location
Text item=gCal_Abfall_Event3_Description
Text item=gCal_Abfall_Event3_StartTime
//Text item=gCal_Abfall_Event3_EndTime
Switch item=gCal_Abfall_Event3_Approved
Text item=gCal_Abfall_Event4_Summary
//Text item=gCal_Abfall_Event4_Location
Text item=gCal_Abfall_Event4_Description
Text item=gCal_Abfall_Event4_StartTime
//Text item=gCal_Abfall_Event4_EndTime
Switch item=gCal_Abfall_Event4_Approved
}
}
Text item=gCal_Geburtstag_Item
}
Hope this helps some newbies… Thank you and have fun ![]()
/Holger
.