Weather station with ePaper display (Dashboard) for Jeedom on Raspberry Pi (via the JSON RPC API)

Last week, we were able to test the 2.7-inch ePaper (eInk) screen from Chinese manufacturer Waveshare. We did not go very far in the presentation. I needed some time to learn how to master the Python Imaging Library (or fork Pillow). I propose in this new tutorial to go much further. We will build a weather station connected to a Jeedom home automation server. Jeedom’s weather plugin (free) makes it easy to retrieve 5-day forecasts from the openweathermap.org website. Of course, this is just a pretext. The idea is to show the different mechanisms to set up to query the Jeedom server, retrieve the data from a device and how to generate the ePaper display.

Note. You can test and debug your code on any Windows PC or Linux, Mac or Raspberry Pi without having an eInk screen. It will be enough to save the image generated by the Python Imaging library.

Equipment used for the weather station ePaper

For this project, I used the following material. The screen measures 2.7 inches diagonally with a resolution of 264 x 176 pixels. It is big enough to display the weather forecast in detail. It has 4 buttons on the side that we will use to navigate between the screens. They could also be used to trigger a home automation scenario or to display other states.

You can also choose another screen in the Waveshare range

Screen

Colrs

Grey level

Resolution (pixels)

Screen size (mm)

Total size (mm)

Refresh time (s)

Interface

Compatible with HAT(1)

1.54 inch

black, white

2

200×200

27.60 × 27.60

48.0 × 33.0

2

SPI

x

1.54 inch (B)

red, black, white

2

200×200

27.60 × 27.60

48.0 × 33.0

8

SPI

x

2.13 inch

black, white

2

250×122

48.55 × 23.71

65.0 × 30.2

2

SPI

2.13 inch (B)

red, black, white

2

212×104

48.55 × 23.71

65.0 × 30.2

15

SPI

2.7 inch

black, white

2

264×176

57.29 × 38.19

85.0 × 56.0

6

SPI

2.7 inch (B)

red, black, white

2

264×176

57.29 × 38.19

85.0 × 56.0

15

SPI

2.9 inch

black, white

2

296×128

66.89 × 29.05

89.5 × 38.0

2

SPI

x

2.9 inch (B)

red, black, white

2

296×128

66.89 × 29.05

89.5 × 38.0

15

SPI

x

4.2 inch

black, white

2

400×300

84.80 × 63.60

103.0 × 78.5

4

SPI

x

4.2 inch (B)

red, black, white

2

400×300

84.80 × 63.60

103.0 × 78.5

15

SPI

x

4.3 inch

black, white

4

800×600

88.00 × 66.00

118.0 × 75.0

1.5

UART

x

7.5 inch

black, white

2

640×384

163.20×97.92

170.2×111.2

6

SPI

7.5 inch (B)

red, black, white

2

640×384

163.20×97.92

170.2×111.2

31

SPI

(1) Connector compatible with Raspberry Pi 2B / 3B / Zero / Zero W. Other displays must be connected using Jumpers.

Python libraries to install
If you’re new to Waveshare ePaper screens, I suggest you read the previous article about how to use them with one or two simple examples.

The epd driver (for EPaper Display I imagine) only “displays” an image. So we will have to generate it in Python beforehand. The Python Imaging library (Pil) or its fork Pillow seems the most powerful in the field. Attention Pil and Pillow can not cohabit on the same machine.

To install Pil you can use the pip command. You may need to precede the pip command with a sudo.

pip install python-pil request

On macOS, the easiest way is to use brew

brew install pil request

The Python Pil / Pillow library quickly

The Pil or Pillow library allows you to manipulate images (convert, resize, orient …), add geometric shapes (line, ellipse, polygon, arc of circle …) or text on an existing image. Here we will create a mask with the dimension of the 2.7 ” ePaper screen.

mask = Image.new('1', (EPD_HEIGHT,EPD_WIDTH), 255)

As we saw in the previous article, the image produced is vertical. If you want a horizontal display, the trick is to create an image in the horizontal and vertical dimensions are reversed and then turn it 90 ° before displaying it on the ePaper screen. Create a new script named demopill.py and paste the following code

#Import libraries
from PIL import Image
from PIL import ImageDraw

#Image Size
EPD_WIDTH       = 176
EPD_HEIGHT      = 264
# Create a white mask 
mask = Image.new('1', (EPD_HEIGHT,EPD_WIDTH), 255)   
#Create a Draw object than allows to add elements (line, text, circle...) 
draw = ImageDraw.Draw(mask)
#Some Text
draw.text((EPD_HEIGHT/4,EPD_WIDTH/2), 'Demo Python PILL', fill = 0)
#Horizontal line
draw.line((0,EPD_WIDTH/2 + 12, EPD_HEIGHT, EPD_WIDTH/2 + 12), fill = 0)
#Save the picture on disk
mask.save('demopill.bmp',"bmp")

Save the script and run it with the python demopill.py  command.

Here is the image generated by the script. As you can see, it is horizontal because I reversed the Height and the Width. Here, it is not necessary to turn the image.

Recover images and open source fonts

I used free and open source images for this project. You can find it everywhere on the internet. Here are the sites I used for this project:

  • The Open Source Icons of Kickstand Apps available on Github for weather symbols. Practical, they are already in PNG format. Use the thick version instead for better rendering on the ePaper screen
  • icones8.fr for pictograms temperature, humidity, atmospheric pressure, wind direction
  • The FreeMonoBold.ttf font can be retrieved everywhere on the internet as here on GitHub

Install and configure the weather plugin on Jeedom

Open the Jeedom plugin manager and search for the official Meteo plugin

Activate the plugin and configure your city and assign an object

Enable the JSON RPC API and retrieve the API key

Jeedom has two communication interfaces. The first allows to query Jeedom with HTTP requests. It is this interface that was used to make this mini remote display.

To vary the pleasures (and also because the HTTP API offers fewer possibilities), we will use the JSON API RPC for this project. The JSON RPC is a standard that is documented here. All of Jeedom’s orders are explained in detail on the online documentation.

To retrieve your API key and verify that the APIs are enabled, go to the configuration menu (notched wheel) then configuration. Open the API tab. Your key is the big string. You can generate a new one if you think that the security of your home automation server has been corrupted. JSONPRC access must be enabled. Remember to save if you make a change.

How to get the weather forecast with Jeedom JPC API JPC?

Now that everything is ready, it’s time to start. There are (very roughly) two types of Jeedom objects that will interest us here. Orders and equipment. To put it simply, the weather widget is an equipment. Equipment is itself attached to an object (the group term would have been better adapted but it is not very important). Then each equipment can have commands. To retrieve the identifiers of the equipment and commands, just open the Advanced Configuration panel which is always in the upper right corner.

Here the weather widget equipment has IDentifiant 3.

id equipement jeedom json rpc api

Then click on the notched wheel of each command to recover its identifier (here 17).

id commande equipement jeedom api json rpc

The API can also be queried to retrieve all identifiers but the returned response is very (too) detailed. If you have a lot of equipment you can quickly drown.

Create a new python script (eg jeedomrpc.py) and paste the code below. Before you run it, you must change the following settings:

  • ip_jeedom: the IP address of the Jeedom server
  • Api_key: your previously recovered API key
  • conditiontxt: The IDentifier of the condition command. It returns the forecast as a string
  • condition: the IDentifier of the condition_numero command. We retrieve the forecast code from OpenWeatherMap. It will be used to set the forecast icon to display
# coding: utf-8
import requests
import json

ip_jeedom = 'XXX.XXX.XXX.XXX'                                                                                                         
Api_key = 'XXXX_JEEDOM_API_KEY_XXXX'   
url = "http://%s/core/api/jeeApi.php"% ( ip_jeedom)
headers = {'content-type': 'application/json'}

#Dictionnaire qui contiendra les prévisions récupérées sur Jeedom
prevision = {}

def updateParameter(id, method):
  # Toutes les méthodes json rpc de Jeedom sont disponibles ici
  # https://jeedom.github.io/core/fr_FR/jsonrpc_api#tocAnchor-1-30-2
  parameters = {                                                                
    "jsonrpc" : "2.0",                                                    
    "method" : method,                                                                                                              
    "params": {                                                           
        "apikey": Api_key,
        "id" : id                                      
        }                                                                 
  }  
  return parameters 

def getDataFromJeedom():
  #Identifiants de commandes à récupérer
  idCmd = {
      "conditiontxt": "17",
      "condition"   : "18"
  }

  #On interroge l'API JSON RPC de Jeedom pour chaque commande 
  for key, value in idCmd.iteritems(): 

    param = updateParameter(value, "cmd::byId")
    response = requests.post(url, data=json.dumps(param), headers=headers).json()
    #Affichage la réponse renvoyée par Jeedom
    print response
    #Ajoute les valeur actuelle et l'unité dans le dictionnaire
    prevision[key] = {
      'value' : response['result']['currentValue'],
      'unit' : response['result']['unite'],
    }
    #Affichage les données récupérées et stockées dans le dictionnaire
    print prevision

getDataFromJeedom()

Run the script (python command jeedomrpc.py ). The poster response directly in the Terminal (or command prompt under Windows). To “unfold” the answer in JSON format and make it more readable for us poor humans, you can use jsonlint.com for example.

{
	u 'jsonrpc': u '2.0', u 'id': None, u 'result': {
		u 'generic_type': u 'WEATHER_CONDITION',
		u 'currentValue': u 'L\xe9g\xe8res chutes de neige',
		u 'configuration': None,
		u 'name': u 'Condition',
		u 'display': {
			u 'generic_type': u 'WEATHER_CONDITION'
		},
		u 'isHistorized': u '0',
		u 'eqLogic_id': u '3',
		u 'unite': u '',
		u 'id': u '17',
		u 'subType': u 'string',
		u 'html': None,
		u 'alert': None,
		u 'value': None,
		u 'template': None,
		u 'isVisible': u '1',
		u 'eqType': u 'weather',
		u 'logicalId': u 'condition',
		u 'type': u 'info',
		u 'order': u '0'
	}
} {
	'conditiontxt': {
		'unit': u '',
		'value': u 'L\xe9g\xe8res chutes de neige'
	}
}

Do not worry about ‘u’ in front of each key. On the other hand what is more annoying is the encoding of the chains. Jeedom does not encode in utf-8 but in Latin-1. Cala may cause you a lot of problems. Here are some tips:

  • Force encoding in utf-8 at the beginning of the script by adding the parameter #coding: utf-8
  • Create an intermediate variable that contains the condition before creating a text object with the Pill library.

For info, here is also the dictionary (a variable) that was created by this script. It contains the forecast and the corresponding code.

{
	'conditiontxt': {
		'unit': u '',
		'value': u 'L\xe9g\xe8res chutes de neige'
	},
	'condition': {
		'unit': u '',
		'value': 600
	}
}

Full python code

There, now it remains only to assemble everything. We know how to query the Jeedom JPC RPC API to retrieve state and device information. We know how to generate an image using the Python Pil bookseller. Finally, we know how to intercept the keys Key1 to Key2 on the side of the screen to modify the display or trigger a scenario.

Create a new script and paste the code below. Change the following settings in the code

  • ip_jeedom: the IP address of the Jeedom server
  • Api_key: your API key
  • IdCmd dictionary: change the identifiers of the different commands for those of your weather equipment
  • modeTest: to generate the image on a computer (Windows PC, Linux, Mac, Raspberry Pi) without using the GPIO and the ePaper screen. The script just generates an output image
  • All images and the FreeMonoBold.ttf font must be stored in the image folder.

Download FreeMonoBold.ttf images and font from the blog by clicking on this link. Unzip the archive and put the folder at the root of the python code. The folder_img variable is used to modify the resource folder.

Note. I just have a doubt about the correct orientation of the compass depending on the direction of the wind. I’m counting on you to check it.

The ePaper weather dashboard for Jeedom obtained

It remains only to launch the script. At first launch, the script immediately generates and displays the first page of the weather station. To display the second panel, press the Key2 button. The other screens are available to display other information from Jeedom. Status of lamps, doors, CO2 level, temperature, power consumption …

The first page (Key1) summarizes the weather of the day

frame1 jeedom station meteo epaper waveshare eink jsin rpc

The second screen (key2) displays the forecasts at 4 days. And yes, it’s winters 🙁

frame2 jeedom station meteo epaper waveshare eink jsin rpc prevision 4 jours

The same with the Waveshare 2.7 ” screen installed on a Raspbery Pi3 running the Jeedom!

Pressing the Key2 button displays the forecast at 4 days.

jeedom epaper waveshare display dashboard weather station frame2

That’s it, he just has to do the same thing with Domoticz! I hope this project will give you lots of new ideas. For the moment, I realized the two tutorials with a Raspberry Pi 3. The main interest of ePaper screens being the absence of power consumption after the refresh of the display, it is time to test it with a microcontroller ESP8266 or ESP32.

Subscribe to the weekly newsletter

No spam and no other use will be made of your email. You can unsubscribe anytime.

DIY Projects