Integration with Google Analytics via Measurement Protocol

Hi all, brand new to SmartThings and loving the capabilities of Things. An open question for developers is;

I want to push the event tracking of my configured Things into Google Analytics using the Measurement Protocol, there is a very good guide by Blastam Analytics and a code snippet available, however I have no clue where I would add this code within the developer dashboard.

Code is here: http://www.blastam.com/blog/wp-content/uploads/SMARTTHINGS-APP.pdf
Guide is here: http://www.blastam.com/blog/index.php/2013/09/how-to-use-universal-analytics-measurement-protocol-to-integrate-smartthings

Everything is there apart from the step to add it into SmartThings, this would unlock so many possibilities for me if I could get this to work.

1 Like

You would add it under the SmartApps in IDE. You may have to customize it though because for one, only door sensors and motion are listed and 2 - the analytic link will most likely be different. But im not sure. I only used analytic for web traffic gauging.

***EDIT - you would only need to edit the UA-XXXXXXX number in the link i believe.

1 Like

Is there a version of that code that you can copy/paste?

Hi Ken yes, I had to pull it out of that PDF by screenshotting, using an OCR and then making it sure it was identical. here you go; I have replaced the UA ID for now but my local copy has it ready to go.

EDITED to remove email addys.

/**

  • Universal Tracking Code Modified from original code shared by Blastam.com
  • Original Author:xxx
  • Shamelessly Borrowed and Modified by: xxx
  • Date: 2015-09-30

** /

preferences {
section(“Which sensors do you want to track?”) {
input “contactl”, “capability.contactSensor”, title: “Select one”, multiple: true
}
section(“Google light…”) {
input “switchl”, “capability.switch”, required: false
}
section(“When there’s movement…”) {
input “motionl”, “capability.motionSensor”, title: “Where?”, multiple: false
}
}

def installed() {
subscribe(contactl, “contact”, contactHandler)
subscribe(motionl, “motion.active”, motionActiveHandler)
subscribe(motionl, “motion.inactive”, motionInactiveHandler)
initialize()
}

def updated() {
//log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}

def initialize() {
subscribe(contactl, “contact”, contactHandler)
subscribe(motionl, “motion.active”, motionActiveHandler)
subscribe(motionl, “motion.inactive”, motionInactiveHandler)
}

def contactHandler(evt) {
if (evt.value == “open”) {
httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxxxx&cid=l&t=event&ec=Door - " + evt.displaName + “&ea=Open”)
switchl.off()
} else if (evt.value == “closed”) {
httpPost("https://www.google-analytics.com/collect","v=l&tid=UA-xxxxxx&cid=l&t=event&ec.Door - " + evt.displayName + “&ea=Close”)
switchl.on()
}

def motionActiveHandler(evt) {
httpPost("https://www.google-analytics.com/collect","v=l&tid=UA-xxxxxx&cid=l&t=event&ec=Movement - " + evt.displayName + “&ea=Motion_Sensed”)
}

def motionInactiveHandler(evt) {
httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxxxx&cid=1&t=event&ec=Movement - " + evt.displayName + “&ea=Motion_Ceased”)
}

I get an error “startup failed: script14436384537541585553527.groovy: 58: expecting ‘*’, found ‘’ @ line 58, column 2. } ^ 1 error”

Im not a coder so im not sure what would need to be modified for this to work. Im sure someone will chime in here. Very interesting though.

By trial and error I found that code editor and got the same error too, so I was generally in the right place with the wrong code! I am going to double check every character in there as it is usually the silliest things.

If I can get this to work though it opens up the possibility of Open Data from all kinds of Offline tracking capabilities. Thanks for helping me get this far Ken, appreciate it.

No problem, sorry i couldnt be of more help in the coding area lol. Im learning slowly but surely.

Where is the measurements protocol in Analytics?

It isn’t, it’s a set of rules to collect data from a device or system: http://www.optimizesmart.com/understanding-universal-analytics-measurement-protocol/

This when configured will show up within the Behaviour > Events reporting within Google Analytics. Very similar to how autoevent tracking works within a site (hardcoded or using a Tag Management System).

There is a space between the * and the / on line 10 that shouldn’t be there. It should be **/.

Also, there is a missing } on line 52

Oh, and its missing the metadata section. Something like:

definition(
    name: "Ecobee (Connect)",
    namespace: "smartthings",
    author: "SmartThings",
    description: "Connect your Ecobee thermostat to SmartThings.",
    category: "SmartThings Labs",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Partner/ecobee@2x.png"
)
1 Like

I have no clue exactly where to put the missing closing bracket on line 52 but I am guessing the meta data goes after the credits. OK thankyou Brice I will give it a try again

Altogether, it should look like this (I have only verified the syntax, not actually what it is doing):smile:

/**
* Universal Tracking Code Modified from original code shared by Blastam.com
*
* Original Author:xxx
* Shamelessly Borrowed and Modified by: xxx
*
* Date: 2015-09-30
*
*
**/
definition(
    name: "Name here",
    namespace: "something",
    author: "someone",
    description: "Universal Tracking Code",
    category: "SmartThings Labs",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
)

preferences {
  section("Which sensors do you want to track?") {
    input "contactl", "capability.contactSensor", title: "Select one", multiple: true
  }
  section("Google light...") {
    input "switchl", "capability.switch", required: false
  }
  section("When there's movement...") {
    input "motionl", "capability.motionSensor", title: "Where?", multiple: false
  }
}

def installed() {
  initialize()
}

def updated() {
  //log.debug "Updated with settings: ${settings}"
  unsubscribe()
  initialize()
}

def initialize() {
  subscribe(contactl, "contact", contactHandler)
  subscribe(motionl, "motion.active", motionActiveHandler)
  subscribe(motionl, "motion.inactive", motionInactiveHandler)
}

def contactHandler(evt) {
  if (evt.value == "open") {
    httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxxxx&cid=l&t=event&ec=Door - " + evt.displaName + "&ea=Open")
    switchl.off()
  }
  else if (evt.value == "closed") {
    httpPost("https://www.google-analytics.com/collect","v=l&tid=UA-xxxxxx&cid=l&t=event&ec.Door - " + evt.displayName + "&ea=Close")
    switchl.on()
  }
}

def motionActiveHandler(evt) {
  httpPost("https://www.google-analytics.com/collect","v=l&tid=UA-xxxxxx&cid=l&t=event&ec=Movement - " + evt.displayName + "&ea=Motion_Sensed")
}

def motionInactiveHandler(evt) {
  httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxxxx&cid=1&t=event&ec=Movement - " + evt.displayName + "&ea=Motion_Ceased")
}
1 Like

Perfect thank you Brice!

Its function is to push events into Google Analytics so I can measure performance of Things over time. Once I get it to fully work (beyond this huge syntax help thank you!) I will create a full post & how to on my site with full credits and the reasoning behind its function. All part of the whole movement towards the #IoT & Open Data

I just made one edit to the code. I noticed that on install, the subscribe commands were both in installed() and in initialize(), which is also called from installed(). Now the subscribes have been removed from installed().

1 Like

OK got as far as this but now virtual device does not send a hit, neither does installing it :frowning:

UA tracking ID masked as well as other identifiables.

definition(
name: “Universal Analytics integration via Measurement Protocol”,
namespace: “smartthings”,
author: “SmartThings”,
description: “Push SmartThings device event data into Google Analytics.”,
category: “SmartThings Labs”,
iconUrl: “xxxx”,
iconX2Url: “xxxx”
)

preferences {
section(“When there’s movement…”) {
input “Motion”, “capability.motionSensor”, title: “Where?”, multiple: false, required: true
}
}

def installed() {
initialize()
}

def updated() {
//log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}

def initialize() {
subscribe(motion, “motion.active”, motionActiveHandler)
subscribe(motion, “motion.inactive”, motionInactiveHandler)
}

def motionDetectedHandler(evt) {
log.debug “motionDetectedHandler called: $evt”
}

def motionActiveHandler(evt) {
httpPost(“https://www.google-analytics.com/collect?v=1&tid=UA-xxxx-1&cid=1&t=event&ec=Movement&ea=Motion_Sensed”)
}

def motionInactiveHandler(evt) {
httpPost(“https://www.google-analytics.com/collect?v=1&tid=UA-xxxx-1&cid=1&t=event&ec=Movement&ea=Motion_Ceased”)
}

1 Like

I’m interested in logging all my ST activity, especially the temperature, it seems like the development of this has halted or at least in this forum, are there any news?

EDIT: I modified the code a bit trying to get my temperature sensors into the whole logging, this is the code I ended up with, any tips or pointers? My Tracking ID has the following format: UA-XXXXXXXX-X should I enter it as is?

/**

  • Universal Tracking Code Modified from original code shared by Blastam.com
  • Original Author:xxx
  • Shamelessly Borrowed and Modified by: xxx
  • Date: 2015-09-30

**/
definition(
name: “Logging”,
namespace: “xxx”,
author: “xxx”,
description: “Universal Tracking Code”,
category: “SmartThings Labs”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”,
iconX3Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”
)

preferences {
section(“Which sensors do you want to track?”) {
input “contactl”, “capability.contactSensor”, title: “Select one”, multiple: true
}
section(“Google light…”) {
input “switchl”, “capability.switch”, required: false, multiple: true
}
section(“When there’s movement…”) {
input “motionl”, “capability.motionSensor”, title: “Where?”, multiple: true
}
section(“Which thermostats do you want to track?”) {
input “temperaturel”, “capability.temperatureMeasurement”, title: “Select one”, multiple: true
}
}

def installed() {
initialize()
}

def updated() {
//log.debug “Updated with settings: ${settings}”
unsubscribe()
initialize()
}

def initialize() {
subscribe(contactl, “contact”, contactHandler)
subscribe(motionl, “motion.active”, motionActiveHandler)
subscribe(motionl, “motion.inactive”, motionInactiveHandler)
subscribe(temperaturel, “temperature”, myHandler)
}

def contactHandler(evt) {
if (evt.value == “open”) {
httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxx&cid=l&t=event&ec=Door - " + evt.displaName + “&ea=Open”)
switchl.off()
}
else if (evt.value == “closed”) {
httpPost("https://www.google-analytics.com/collect","v=l&tid=UA-xxxx&cid=l&t=event&ec.Door - " + evt.displayName + “&ea=Close”)
switchl.on()
}
}

def motionActiveHandler(evt) {
httpPost("https://www.google-analytics.com/collect","v=l&tid=UA-xxxx&cid=l&t=event&ec=Movement - " + evt.displayName + “&ea=Motion_Sensed”)
}

def motionInactiveHandler(evt) {
httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxx&cid=1&t=event&ec=Movement - " + evt.displayName + “&ea=Motion_Ceased”)
}

def myHandler(evt) {
httpPost("https://www.google-analytics.com/collect","v=1&tid=UA-xxxx&cid=1&t=event&ec=Temperature - " + evt.displayName + “&ea=Temperature”)
}

So so sorry, I have been really busy. I did however get around to blogging about setting it up (eventually!). I have linked to my code snippet as well: https://searchnewscentral.com/blog/2018/02/28/tracking-offline-events-using-google-analytics-the-measurement-protocol/