iCal (Google Calendar) as trigger (i.e. school days, holidays)


(Roger V) #1

Any coders up for building an iCal reader in Smart Apps?
I’ll buy beer :slight_smile:

Goal: Get the kid up on school days with a chain of z-wave events i.e. lights coming on, turn on the TV (I guess via an IR blaster), but ideally recognize holidays.

If not, I’ll settle for days of the week… still, would be great, useful for meetings, etc. wherein someone could revise the wake-up routine via google calendar.

Roger in LA


(Zach Naimon) #2
def weekdays = ["Mon","Tue","Wed","Thu","Fri"].contains(new Date().format("EEE"))
if(weekdays){
   doStuff()
}

Else, for a google calendar API, probably something like

httpPostJson(uri: "http://path.to/googleCalendar/api", body: [day]) {responce ->
		log.debug responce.data
                def resp = responce.data
		}

and try to process the json that comes back.


(Solardave1) #3

I just taser them.


(Zach Naimon) #4

Yeah? I have a smartTaser

if(wakeUpTime()){
  taser.aim(childPresenceTag)
  taster.fire()
}

(Roger V) #5

Awesome, thanks guys. I can probably figure this out (total n00b), though I think it might be a good IFTTT smart-app for the lazy and/or coding impaired.

My mom would resort to rolling frozen marbles into the bed when I was about age 10 if I didn’t get up :slight_smile:

RogerV in LA


(Chrisb) #6

Frozen Marbles… I’ll have to remember that!!


(Dan Lieberman) #7

@rogerv – The issue with the Google API is that you need to get an authorization key using OAuth before you can talk to the service. You can do this by hand today, and enter your authorization key into your SmartApp, but authorization keys don’t last forever and need to be regularly refreshed.

We’re working on adding OAuth2 support to the platform, and while the Google API isn’t the specific use-case that we’re developing for, it should work for the Google API without too much trouble.

@wackware has been playing around with this idea for a while as well, but was held up with the authorization issue. Once the support is in, I expect that folks like him will start playing around with it.

Also, IFTTT support will be coming to the platform very soon. The integration work has been done, we’re just finalizing the last bits with them to get the channel launched on their side.

-d


(Tyler Weaver) #8

I wrote a iCal parser for a project I’m doing to integrate my lock with my AirBnB calendar. Below is the code, feel free to modify it for your own uses.

String readLine(ByteArrayInputStream is) {
  int size = is.available();
  if (size <= 0) {
    return null;
  }

  String ret = "";
  byte data = 0;
  char ch;

  while (true) {
    data = is.read();
    if (data == -1) {
      // we are done here
      break;
    }

    ch = (char)(data&0xff);
    if (ch == '\n') {
      break;
    }

    ret += ch;

    if (ret.endsWith("\\n")) {
      ret = ret.replaceAll(/\\n/,"");
      break;
    }
  }

  return ret;
}

def parseICal(ByteArrayInputStream is) {
  def iCalEvents = []
  def iCalEvent = null
  def sincePhone = 100

  while (true) {
    def line = readLine(is)

    if (line == null) {
      break;
    }

    if (line == "BEGIN:VEVENT") {
      iCalEvent = [record:'']
    } else if (line == "END:VEVENT") {
      iCalEvents.push(iCalEvent)
      iCalEvent = null
    } else if (iCalEvent != null) {
      // parse line
      def compoundKey = null
      def subKey = null
      def key = null
      def value = null

      sincePhone++;

      if ( line ==~ /^[A-Z]+[;:].*/ ) {
        // grab everything before the :
        key = line.replaceAll(/:.*/, '')
        // grab everything before the ;
        compoundKey = key.replaceAll(/;.*/, '')
        // grab everything after the ${key}:
        value = line.replaceFirst(key + ':', '').trim()
        // grab everything before the ; in the key
        if (compoundKey != key) {
          // we found a compound date key
          subKey = key.replaceFirst(compoundKey + ';', '').trim()
        }

        if (key == 'DESCRIPTION') {
          // we found the start of the description
          key = value.replaceAll(/:.*/, '')
          value = value.replaceFirst(key + ':', '').trim()
        }

        if (key == 'UID') { iCalEvent.put('uid',value) }
        else if (key == 'CREATED') { iCalEvent.put('created', value) }
        else if (key == 'RRULE') { iCalEvent.put('rRule', value) }
        else if (key == 'RDATE') { iCalEvent.put('rDate', value) }
        else if (key == 'DTSTAMP') { iCalEvent.put('dtStamp', parseDate(value)) }
        else if (key == 'CHECKIN') { iCalEvent.put('checkin', value) }
        else if (key == 'CHECKOUT') { iCalEvent.put('checkout', value) }
        else if (key == 'NIGHTS') { iCalEvent.put('nights', value) }
        else if (key == 'EMAIL') { iCalEvent.put('email', value) }
        else if (key == 'SUMMARY') { iCalEvent.put('summary', value) }
        else if (key == 'LOCATION') { iCalEvent.put('location', value) }
        else if (key == 'PHONE') { sincePhone = 0; }
        else if (compoundKey == 'DTSTART') {
          iCalEvent.put('dtStartString', value)
          iCalEvent.put('dtStart', parseDate(value))
          iCalEvent.put('dtStartTz', subKey)
        } else if (compoundKey == 'DTEND') {
          iCalEvent.put('dtEndString', value)
          iCalEvent.put('dtEnd', parseDate(value)) 
          iCalEvent.put('dtEndTz', subKey)
        }
      }

      if (sincePhone == 1) {
        // phone number
        iCalEvent.put('phone', line)
      }

      if (line) {
        iCalEvent['record'] = iCalEvent['record'] + line + '\n'
      }
    }
  }
  

  return iCalEvents
}

Date parseDate(String value) {
  if ( value ==~ /[0-9]*T[0-9]*Z/ ) {
    Date.parse("yyyyMMdd'T'HHmmss'Z'", value)
  } else if ( value ==~ /[0-9]*T[0-9]*/ ) {
    Date.parse("yyyyMMdd'T'HHmmss", value)
  } else if ( value ==~ /[0-9]*/ ) {
    Date.parse("yyyyMMdd", value)
  } else {
    println "WARNING: unknown date format: ${value}"
    null
  }
}