Monday 26 March 2018

Making a simple Google Calendar events API with Google Apps Script

I was recently looking for a Rainmeter skin to display upcoming events from my Google Calendar on my Desktop. As GCal sadly no longer provides an XML feed for events these skins are few and far between. There is no client library provided by Google for what I needed as Rainmeter uses Lua as a scripting language.
I decided for simplicity's sake to minimise the work that needed to be done on the client as it is a lightweight desktop app and instead use Google Apps scripts to access the Calendar API to provide a simplified interface to it just providing the data that I need.

This is fairly straightforward and the documentation from Google is very helpful. There is a quickstart here to show you how to access events.

To publish the script as a web app, it must contain a doGet() or doPost() method.

My doGet() method when I has finished looked like this:
function doGet(e) {
    var events = listUpcomingEvents(e.parameter.calendarId);
    var jsonString = JSON.stringify(events);
    //Logger.log(jsonString);
    return ContentService.createTextOutput(jsonString).setMimeType(ContentService.MimeType.JSON);
}
The parameter calendarId can be set in the request which will choose which of my Google Calendars to access. My listUpcomingEvents method will list events from all calendars if the parameter is left null.

I convert the Javascript object returned by the method to a JSON string and output this as a response with a mime-type of JSON.

At note about colours:
When grabbing events using the API, colours are identified by an integer id based on the calendar colour scheme.
In order to actually get these (background) colours as hex values I used this:

function getColorById(id) {
     var colors = Calendar.Colors.get();
     var json = JSON.stringify(colors["event"]);
     var myObj = JSON.parse(json);
     return myObj[id].background;
}

That returns the Calendar event background colour for a particular id.





Notes on the Rainmeter scripts:
When I actually came to the Rainmeter end of the task I discovered that google apps scripts performs a redirect when executing and this isn't supported by the Rainmeter web parser. I solved this with the rather hacky approach of executing a libcurl command, writing the output to a file and then parsing the file.

Sunday 26 January 2014

Raspberry Pi and CEC

CEC (consumer electronics control) is a method for transmitting commands between devices through HDMI. It allows button presses from a remote control that are sent to a TV to be transmitted down the HDMI cable to the device powering the TV. This means that devices like set-top boxes can be controlled with a normal TV remote. Different television manufacturers have different names for CEC like Samsung Anynet+ and Sony BRAVIA Link.

CEC allows the user to run all sorts of commands:
  • One Touch Play allows devices to switch the TV to use it as the active source when playback starts
  • System Standby enables users to switch multiple devices to standby mode with the press of one button
  • Preset Transfer transfers the tuner channel setup to another TV set
  • One Touch Record allows users to record whatever is currently being shown on the HDTV screen on a selected recording device
  • Timer Programming allows users to use the electronic program guides (EPGs) that are built into many HDTVs and set-top-boxes to program the timer in recording devices like PVRs and DVRs
  • System Information checks all components for bus addresses and configuration
  • Deck Control allows a component to interrogate and control the operation (play, pause, rewind etc.), of a playback component (Blu-ray or HD DVD player or a Camcorder, etc.)
  • Tuner Control allows a component to control the tuner of another component
  • OSD Display uses the OSD of the TV set to display text
  • Device Menu Control allows a component to control the menu system of another component by passing through the user interface (UI) commands
  • Routing Control controls the switching of signal sources
  • Remote Control Pass Through allows remote control commands to be passed through to other devices within the system
  • Device OSD Name Transfer transfers the preferred device names to the TV set
  • System Audio Control allows the volume of an AV receiver, integrated amplifier or preamplifier to be controlled using any remote control from a suitably equipped device(s) in the system
Source: http://en.wikipedia.org/wiki/HDMI#CEC

The Raspberry Pi is one of few computing devices that has HDMI CEC support. In order to take advantage of this wonderful feature on the Raspberry Pi you can use the Raspbmc home media center. Raspbmc is XMBC (Xbox Media Center) for Raspberry Pi. You can also use OpenELEC which is another XMBC distro for the Pi.

XBMC has CEC support which works fantastically for your home media center if the Pi is plugged into your TV. This allows you to control XBMC with commands like Play/Pause etc directly from your normal TV remote.

In order to configure your XBMC to allow CEC go to:
System > Settings > System > Input Devices > Peripherals > CEC adapter
and turn it on.

XBMC should then detect the television device and connect to it. On some televisions you may have to enable CEC in the settings or manually connect to XBMC.

You can find out more information, and whether your TV supports CEC, here:
http://wiki.xbmc.org/index.php?title=CEC


Or if you are interested in setting up CEC without using XBMC on Raspbian Wheezy, read on.

The CEC on XBMC relies on libCEC which is a library for CEC produced by Pulse Eight. It is pretty much the only CEC library out there. You can see it on Git Hub at https://github.com/Pulse-Eight/libcec

It supports many platforms including the Raspberry Pi.

Here are some instruction on installing it:

First of all install the necessary dependencies and packages
sudo apt-get install git-core autoconf automake libtool liblockdev1-dev

Change directory into the src directory
cd /usr/local/src

Clone the Github repository
sudo git clone https://github.com/Pulse-Eight/libcec.git

Change directory into the the newly created libcec directory
cd libcec


To compile, execute the following:

sudo ./bootstrap

sudo ./configure --with-rpi-include-path=/opt/vc/include --with-rpi-lib-path=/opt/vc/lib --enable-rpi

sudo make

sudo make install

You then need to link the libraries with the following commands:

sudo ln -s /usr/local/lib/libcec.so /usr/lib/

sudo ln -s /usr/local/lib/libcec.so.2 /usr/lib/

If all went according to plan then libCEC should now be installed. If it didn't then it might be because you are out of space on you SD card partition. If you are then try expanding the root partition of your SD card through the raspi-config interface and try again.

To test that the library is working enter cec-client -l into the command line and you should get something like this:

Found devices: 1
device:           1
com port:     RPI
vendor id:        2708
product id:       1001
firmware version: 1
type:         Raspberry Pi


This means that it has found the CEC ability on the Pi.

You can now test out the CEC (assuming you have it connected to a TV) and find out the television details:

echo "scan" | cec-client -d 1 -s "standby 0" RPI

This should print out lots of details.

Some useful commands are:


Get current power mode: echo "pow 0000" | cec-client -d 1 -s "standby 0" RPI


Tell the TV to enter standby mode: echo "standby 0000" | cec-client -d 1 -s "standby 0" RPI


Turn on the TV: echo "on 0000" | cec-client -d 1 -s "standby 0" RPI


Tell the TV to use the Raspberry Pi as active source: echo "as" | cec-client -d 1 -s "standby 0" RPI


In order to listen for TV remote button presses you can use the cec-client -l

This should then print out the button every time it is pressed.


I hope this was helpful.

Setting up an Apache web server on a Raspberry Pi

This guide will show you how to set up an Apache web server on Raspberry Pi by installing a LAMP (Linux, Apache, MySQL, PHP) stack. This is with the Raspbian Wheezy Debian Distribution. Make sure that you have resized the root partition of the SD card before doing this as it takes up a lot of space. You can resize the root partition from the raspi-config interface.

First we need to make sure that the package lists are up to date by running:

sudo apt-get update

After that's all done enter this:


sudo apt-get install apache2 php5 php5-mysql mysql-server

This will install the Apache web server as well as PHP and MySQL. It will take quite a long time to install so be patient.

About halfway through you will be prompted by MySQL to enter a password (make sure it's secure).

When it has all finished installing, you can test whether the web server is up and running by entering the IP address of your pi into a web browser on a computer on the same network. If you do not know the IP address you can enter the command ifconfig on the Pi and look for the IP address. 

The webpage should look like this:


It works!

This is the default web page for this server.

The web server software is running but no content has been added, yet.


If you get this page then you have successfully installed Apache web server on your Raspberry Pi.

The files in the web server are stored in /var/www/


If it didn't work try going over the steps above again and make sure that you 
have enough space on your SD card and you have expanded the root partition 
of the SD card.