Skip to main content

Read Smartmeter P1 using Raspberry Pi and Node-RED

I’ve spend many hours to get my P1 smartmeter working with Node-RED on a Raspberry PI.
In my setup the P1 Smartmeter data is send over MQTT in a json payload and insert in a mongoDB, but feel free to use other outputs to send the payload.

In the tutorial below i asume you’re familiar with the P1 port, have connected to the the Pi and read data from it before.
So i only explain how to configure Node-RED to read the serial/tty port and extract the P1 data from the serialstream and send the output as payload with Node-RED.

Full Node-RED flow for reading P1 Smartmeter data
  1. Add the “Serial input” node to the flow and configure it as below where /dev/ttyUSB0 needs to correspondent to your tty port.

  2. Add a “Function” node and add the code below to the function node, outputs needs to be set to 1.
    var regExpDeliveredKWTariff1 = /^1-0:1\.8\.1\(0+(\d+\.\d+)\*kWh\)/m;
    var regExpDeliveredKWTariff2 = /^1-0:1\.8\.2\(0+(\d+\.\d+)\*kWh\)/m;
    var regExpGeneratedKWTariff1 = /^1-0:2\.8\.1\(0+(\d+\.\d+)\*kWh\)/m;
    var regExpGeneratedKWTariff2 = /^1-0:2\.8\.2\(0+(\d+\.\d+)\*kWh\)/m;
    var regExpCurrentKWTariff = /^0-0:96.14.0\(0+(.*?)\)/m;
    var regExpCurrentWattDelivered = /^1-0:1.7.0\((.*?)\*/m;
    var regExpCurrentWattGenerated = /^1-0:2.7.0\((.*?)\*/m;
    var regExpDeliveredGasM3 = /^0-1:24\.2\.1\(\d+[SW]\)\((\d+\.\d+)\*m3\)/m;
    
    var DeliveredKWTariff1 = regExpDeliveredKWTariff1.exec(msg.payload);
    var DeliveredKWTariff2 = regExpDeliveredKWTariff2.exec(msg.payload);
    var GeneratedKWTariff1 = regExpGeneratedKWTariff1.exec(msg.payload);
    var GeneratedKWTariff2 = regExpGeneratedKWTariff2.exec(msg.payload);
    var CurrentKWTariff = regExpCurrentKWTariff.exec(msg.payload);
    var CurrentWattDelivered = regExpCurrentWattDelivered.exec(msg.payload);
    var CurrentWattGenerated = regExpCurrentWattGenerated.exec(msg.payload);
    var DeliveredGasM3 = regExpDeliveredGasM3.exec(msg.payload);
    
    msg.payload = '{"smartmeter":' + '{"timestamp":' + Math.round(new Date().getTime()/1000.0) + ', ' + '"DeliveredKWTariff1":' + DeliveredKWTariff1[1] + ', ' + '"DeliveredKWTariff2":' + DeliveredKWTariff2[1] + ', ' + '"GeneratedKWTariff1":' + GeneratedKWTariff1[1] + ', ' + '"GeneratedKWTariff2":' + GeneratedKWTariff2[1] + ', ' + '"CurrentKWTariff":' + CurrentKWTariff[1] + ', ' + '"CurrentWattDelivered":' + CurrentWattDelivered[1]*1000 + ', ' + '"CurrentWattGenerated":' + CurrentWattGenerated[1]*1000 + ', ' + '"DeliveredGasM3":' + parseFloat(DeliveredGasM3[1],10) + '}'+ '}';
    
    return msg;
    Connect an desired "Output" node to the function node and you're ready to send the payload...

As told i’m sending the filtered P1 json payload to a MQTT server and to mongoDB. Below an example how it looks like:

 

Control Nest from linux shell (or other programs)

The steps below let’s you create a shell script to control the Nest Thermostat from the linux shell. Once created the shell script you can control your Nest Thermostat in other applications like PiMatic, Domoticz…

Step 1 – Create a Nest Developer account and product

Nest Developer Product ScreenYou need to create a Nest Developer account and product to get the API access you need to control your thermostat.
You must create a Nest Developer account here if you don’t have one – https://developer.nest.com/

Then create a Product.  Mine is called “Control Nest from shell”.  Make sure you grant read/write permissions for the Thermostat and Away.

Copy down the Product ID and Product Secret values.  You will need them later.  You will also need the Authorization URL in the next step so don’t close this window!

Step 2 – Get your PIN Code for your Nest Thermostat

Nest Thermostat Authorization ScreenCopy the Authorization URL shown on the right side of the Nest Developer Product Details page and paste it into a new browser window.  It should prompt you to allow your Product to connect to your personal Nest account.  Click on Continue.

It should then give you a PIN Code.  Copy this down carefully!!!

 

Step 3 – Get your Access Code

Now that you have a PIN Code, you need to generate an API Access Code using your PIN Code and the Product ID and Product Secret from your Nest Developer Product Details Page.

curl -X POST "https://api.home.nest.com/oauth2/access_token?client_id=%YOUR_PRODUCT_ID%&code=%YOUR_PIN_CODE%&client_secret=%YOUR_PRODUCT_SECRET%&grant_type=authorization_code"

Replace the %YOUR_*% values with the correct values for your application the Nest PIN. And replace & with &.  Then execute this in your command line.  You should get back a long access token that starts with a “c.”.  This long string is your Access Token and will be used for authorization for API calls.

Step 4 – Get Your Nest Thermostat and Structure IDs

Now that you have your Access Token you can retrieve the IDs for your Thermostat and Structure (Home) which you’ll need to setup the command line API aliases.

curl -L https://developer-api.nest.com/devices/thermostats\?auth\=%YOUR_ACCESS_TOKEN%

This command will return a big block of JSON data.  What you are looking for in there are two values: the device_id and the structure_id.  Copy those values, you will need them soon.

Step 5 – Create the shell script

Now you have your Access Token, Device ID and Structure ID it’s time to create the shell script to control your Nest Thermostat. Create a file with the data below, save it in /usr/bin and make it executable:

#!/bin/bash
DEVICEID=[YOUR DEVICE ID]
ACCESSTOKEN=[YOUR ACCESS TOKEN]
STRUCTUREID=[YOUR STRUCTURE ID]

case $1 in
"read.humidity")
curl -s -L https://developer-api.nest.com/devices/thermostats/${DEVICEID}/humidity\?auth\=${ACCESSTOKEN}
;;

"read.temp")
curl -s -L https://developer-api.nest.com/devices/thermostats/${DEVICEID}/ambient_temperature_c\?auth\=${ACCESSTOKEN}
;;

"read.targettemp")
curl -s -L https://developer-api.nest.com/devices/thermostats/${DEVICEID}/target_temperature_c\?auth\=${ACCESSTOKEN}
;;

"set.targettemp")
curl -s -L -X PUT "https://developer-api.nest.com/devices/thermostats/${DEVICEID}/target_temperature_c?auth=${ACCESSTOKEN}" -H "Content-Type: application/json" -d "$2"
;;

"set.presence")
if [ "$2" == "away" ];
then
curl -s -L -X PUT "https://developer-api.nest.com/structures/${STRUCTUREID}/away?auth=${ACCESSTOKEN}" -H "Content-Type: application/json" -d '"away"'
fi

if [ "$2" == "home" ];
then
curl -s -L -X PUT "https://developer-api.nest.com/structures/${STRUCTUREID}/away?auth=${ACCESSTOKEN}" -H "Content-Type: application/json" -d '"home"'
fi

if [ -z $2 ];
then
echo "Presence not set! Must be set to home or away."
fi
;;

*)
echo "Parameters missing, usage:"
echo "nest read.temp Reads actual temperature from Nest"
echo "nest read.humidity Reads humidity from Nest"
echo "nest read.targettemp Reads target temperature from Nest"
echo "nest set.targettemp 20 Sets target temperature on Nest to 20"
echo "nest set.presence away Sets presence on Nest to away"
echo "nest set.presence home Sets presence on Nest to home"
;;
esac

Shellscript: Sunset or Sunrise times

I was looking for a script which shows the sunrise or sunset times for my location. I want to use these times to turn on or off the lights in my house. I couldn’t find a script that satisfy my needs so i need to make it by my self, i’m not a professional coder by the script below satisfy my needs…

#!/bin/bash
#
# This scripts downloads today's sunrise or sunset times from weather.yahoo.com
# You'll need to obtain a location ID from weather.yahoo.com for your location
# Go to http://weather.yahoo.com and enter your city or zip code a new URL opens
# EXAMPLE: http://weather.yahoo.com/nederland/noord-brabant/tilburg-733881/ 
# In the example 733881 is the location ID for my location...

# Example parameters:
# thisscript.sh sunset # shows today's sunset
# thisscript.sh sunrise # shows today's sunrise
# thisscript.sh sunset \"30 minutes\" # shows today's sunset +30 minutes
# thisscript.sh sunset \"2 hours\" # shows today's sunset +2 hours
# thisscript.sh sunset \"30 minutes ago\" # shows today's sunset -30 minutes
# thisscript.sh sunset \"2 hours ago\" # shows today's sunset -2 hours
# thisscript.sh sunrise \"30 minutes\" # shows today's sunrise +30 minutes
# thisscript.sh sunrise \"2 hours\" # shows today's sunrise +2 hours
# thisscript.sh sunrise \"30 minutes ago\" # shows today's sunrise -30 minutes
# thisscript.sh sunrise \"2 hours ago\" # shows today's sunrise -2 hours

# Enter your location ID obtained from weather.yahoo.com URL 
LOCATION=733881

if [ ! $1 ]; then
echo "Parameter(s) missing!!!"
echo ""
echo "Example parameters:"
echo "thisscript.sh sunset # shows today's sunset"
echo "thisscript.sh sunrise # shows today's sunrise"
echo "thisscript.sh sunset \"30 minutes\" # shows today's sunset +30 minutes"
echo "thisscript.sh sunset \"2 hours\" # shows today's sunset +2 hours"
echo "thisscript.sh sunset \"30 minutes ago\" # shows today's sunset -30 minutes"
echo "thisscript.sh sunset \"2 hours ago\" # shows today's sunset -2 hours"
echo "thisscript.sh sunrise \"30 minutes\" # shows today's sunrise +30 minutes"
echo "thisscript.sh sunrise \"2 hours\" # shows today's sunrise +2 hours"
echo "thisscript.sh sunrise \"30 minutes ago\" # shows today's sunrise -30 minutes"
echo "thisscript.sh sunrise \"2 hours ago\" # shows today's sunrise -2 hours"
fi

case $1 in

sunset) 
SUNSET12H=`curl -s http://weather.yahooapis.com/forecastrss?w=${LOCATION}|grep astronomy|awk -F\" '{print $4}'`
SUNSET24H=`date --date="${SUNSET12H}" +%T`
date --date "${SUNSET24H} $2" +%R 
;;

sunrise)
SUNRISE12H=`curl -s http://weather.yahooapis.com/forecastrss?w=${LOCATION}|grep astronomy|awk -F\" '{print $2}'`
SUNRISE24H=`date --date="${SUNRISE12H}" +%T`
date --date "${SUNRISE24H} $2" +%R 
;;
esac

Project – HomeAutomation

A long time ago… I started a project to automate my home.
One of the first things i’ve automated are the lights in my home using a raspberry pi and an 433mhz transmitter. Using a website i now can turn on or off the lights i also can see which lights are powered on. I’m using it for i while i’m pretty happy with it, even my wifi is using it 😉

At the moment i’ve started a new project of which i’m reporting very soon. I’ll give you a little hint of what i’m working on… I’m automating the main entrance of my house…