[Solved] Show Google Calendar Events in HabPanel/Sitemap - CalDav Personal - Openhab 2.4

So I figured it out after a long time of twiddling around. I will post results for anyone who is interested in setting this up too.

  1. Install the Caldav Personal binding & the Caldav Command Binding in Paper UI (You Need Both)

  2. Navigate to the services folder in Openhab/conf/services

  3. There should be 3 Caldav Files there: caldavCommand.cfg, caldavPersonal.cfg and caldavio.cfg

  4. Get your google calendar ready to give caldav access.
    Because caldav needs to access the calendar as a “Less Secure App”, and 2 factor auth seems to make this who project a headache, I opted to create a new gmail account that has shared access to the calendar I want to use. I made a new gmail account, and shared the calendar with that gmail with the setting “See All Events And Details”. You can find this in the sharing setting of the calendar page.

  5. Enable “Less Secure Apps” by logging into your new google account and visiting this URL: https://myaccount.google.com/u/2/lesssecureapps

  6. Now caldav should be able to access the calendar to download the entries.

  7. Get the name of the calendar you want to use from google from the calendar settings page:

  8. Go back to Openhab File System and add the following to the bottom of the caldavio.cfg file:

    caldavio:<Calendar Name In Google>:url=https://www.google.com/calendar/dav/<your username>@gmail.com/events
    caldavio:<Calendar Name In Google>:username=<gmail username without @gmail.com>
    caldavio:<Calendar Name In Google>:password=<password for gmail account>
    caldavio:<Calendar Name In Google>:reloadInterval=2
    caldavio:<Calendar Name In Google>:preloadTime=200000
    caldavio:<Calendar Name In Google>:disableCertificateVerification=true
    
  9. Add the following to the bottom of the caldavPersonal.cfg file

    caldavPersonal:usedCalendars=<Calendar Name In Google>
    
  10. leave the caldavCommand.cfg as is

  11. Set up your Items File. Mine is pulling the next 5 events with Name, Start Time, End Time, and Location. Note where it says caldavPersonal=“calendar:Matt” replace Matt with the name of your calendar as above:

        String CalendarName1   "Up Next [%s]"                                                   <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:1 value:NAME" } 
        DateTime CalendarTimeStart1 "Starts [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"              <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:1 value:START" } 
        DateTime CalendarTimeEnd1 "Ends [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"                  <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:1 value:END" }
        String CalendarAt1 "At [%s]"                                                            <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:1 value:PLACE" } 
        String CalendarName2   "Coming up [%s]"                                                 <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:2 value:NAME" } 
        DateTime CalendarTimeStart2 "Starts [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"              <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:2 value:START" } 
        DateTime CalendarTimeEnd2 "Ends [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"                  <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:2 value:END" }
        String CalendarAt2 "At [%s]"                                                            <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:2 value:PLACE" } 
        String CalendarName3   "Later  [%s]"                                                    <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:3 value:NAME" } 
        DateTime CalendarTimeStart3 "Starts [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"              <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:3 value:START" } 
        DateTime CalendarTimeEnd3 "Ends [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"                  <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:3 value:END" }
        String CalendarAt3 "At [%s]"                                                            <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:3 value:PLACE" } 
        String CalendarName4   "Later [%s]"                                                     <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:4 value:NAME" } 
        DateTime CalendarTimeStart4 "Starts [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"              <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:4 value:START" } 
        DateTime CalendarTimeEnd4 "Ends [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"                  <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:4 value:END" }
        String CalendarAt4 "At [%s]"                                                            <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:4 value:PLACE" } 
        String CalendarName5   "Later [%s]"                                                     <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:5 value:NAME" } 
        DateTime CalendarTimeStart5 "Starts [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"              <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:5 value:START" } 
        DateTime CalendarTimeEnd5 "Ends [%1$ta, %1$te %1$tb %1$tl:%1$tM%1$tp]"                  <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:5 value:END" }
        String CalendarAt5 "At [%s]"                                                            <calendar>  { caldavPersonal="calendar:Matt type:EVENT eventNr:5 value:PLACE" } 
    
  12. Save all the changes to files and you should see the following message in the openhab.logs:
    CalDAV IO is properly configured.
    CalDav Loader has been started
    reload job scheduled for:

  13. Now caldav is successfully pulling your calendar entries.

  14. Depending on your application you can now implement into a sitemap or habpanel.
    For those who are interested this is the widget code I made to display mine as I didnt like the other widgets I found out there:

        <style>
    
        tbody.calbody {
            height: 101%;
            display: block;
            position: absolute;
            width: 100%;
        }
    
        table.caltable.ng-scope {
            width: 101%;
        }
    
        td.calcal {
            background-color: #a9a9a9;
            padding: 17px;
            vertical-align: middle;
            width: 32%;
            text-align: center;
            height: 100%;
        }
    
        td.calinfo {
            padding-top: 13px;
            width: 78%;
            vertical-align: top;
            padding-left: 16px;
        }
    
        .calday.ng-binding {
            padding-bottom: 0px !important;
            color: #4c4c4c;
        }
    
        .calmonth.ng-binding {
            padding-bottom: 0px;
            color: #212121;
        }
    
        .caldaynumber.ng-binding {
            font-size: 30px;
            line-height: 30px;
            color: #212121;
        }
    
        .calname.ng-binding {
            padding-bottom: 3px;
            font-size: 20px;
            font-weight: 400;
            line-height: 20px;
        }
    
        .calduration.ng-binding {
            padding-bottom: 0px;
    
        }
    
        .calloc.ng-binding {
            padding-bottom: 0px;
    
        }
    
        tr.calentry {
            border-bottom: 5px solid #333333;
            height: 33.333%;
            width: 100%;
            max-width: 100%;
            display: flex;
            position: relative;
        }
    
        </style>
    
    
    
        <table class="caltable">
            <tbody class="calbody">
                        <tr class="calentry">
                            <td class="calcal">
                                <div class="calday">{{itemValue('CalendarTimeStart1')| date:"EEE"}}</div>
                                <div class="calmonth">{{itemValue('CalendarTimeStart1')| date:"MMM"}}</div>
                                <div class="caldaynumber">{{itemValue('CalendarTimeStart1')| date:"dd"}}</div>
                            </td>
                            <td class="calinfo"><div class="calname">{{itemValue('CalendarName1')}}</div>
                                <div ng-if="((itemValue('CalendarTimeStart1') | date:'dd.MM.yyyy') < (itemValue('CalendarTimeEnd1') | date:'dd.MM.yyyy'))" class="calduration">All Day</div>
                                <div ng-if="((itemValue('CalendarTimeStart1') | date:'dd.MM.yyyy') == (itemValue('CalendarTimeEnd1') | date:'dd.MM.yyyy'))" class="calduration">{{itemValue('CalendarTimeStart1')| date:"shortTime"}} - {{itemValue('CalendarTimeEnd1')| date:"shortTime"}}</div>
                                <div class="calloc">{{itemValue('CalendarAt1')}}</div>
                            </td>
                        </tr>
                        <tr class="calentry">
                            <td class="calcal">
                                <div class="calday">{{itemValue('CalendarTimeStart2')| date:"EEE"}}</div>
                                <div class="calmonth">{{itemValue('CalendarTimeStart2')| date:"MMM"}}</div>
                                <div class="caldaynumber">{{itemValue('CalendarTimeStart2')| date:"dd"}}</div>
                            </td>
                            <td class="calinfo"><div class="calname">{{itemValue('CalendarName2')}}</div>
                                <div ng-if="((itemValue('CalendarTimeStart2') | date:'dd.MM.yyyy') < (itemValue('CalendarTimeEnd2') | date:'dd.MM.yyyy'))" class="calduration">All Day</div>
                                <div ng-if="((itemValue('CalendarTimeStart2') | date:'dd.MM.yyyy') == (itemValue('CalendarTimeEnd2') | date:'dd.MM.yyyy'))" class="calduration">{{itemValue('CalendarTimeStart2')| date:"shortTime"}} - {{itemValue('CalendarTimeEnd2')| date:"shortTime"}}</div>
                                <div class="calloc">{{itemValue('CalendarAt2')}}</div>
                            </td>
                        </tr>
                        <tr class="calentry">
                            <td class="calcal">
                                <div class="calday">{{itemValue('CalendarTimeStart3')| date:"EEE"}}</div>
                                <div class="calmonth">{{itemValue('CalendarTimeStart3')| date:"MMM"}}</div>
                                <div class="caldaynumber">{{itemValue('CalendarTimeStart3')| date:"dd"}}</div>
                            </td>
                            <td class="calinfo"><div class="calname">{{itemValue('CalendarName3')}}</div>
                                <div ng-if="((itemValue('CalendarTimeStart3') | date:'dd.MM.yyyy') < (itemValue('CalendarTimeEnd3') | date:'dd.MM.yyyy'))" class="calduration">All Day</div>
                                <div ng-if="((itemValue('CalendarTimeStart3') | date:'dd.MM.yyyy') == (itemValue('CalendarTimeEnd3') | date:'dd.MM.yyyy'))" class="calduration">{{itemValue('CalendarTimeStart3')| date:"shortTime"}} - {{itemValue('CalendarTimeEnd3')| date:"shortTime"}}</div>
                                <div class="calloc">{{itemValue('CalendarAt3')}}</div>
                            </td>
                        </tr>
            </tbody>
        </table>
    

Which renders out like this:

And that’s it.

It looks more complicated than it is, so I hope this guide helps anyone out there looking to do the same.

9 Likes