Raspberry Pi 2 Simple HTTP Server using ruuvitag_sensor package

For this project I used a:

  • Raspberry Pi 2
  • CRS 4.0 Bleutooth adapter
  • Edimax Wifi adapter

I used the built-in http-server in Python 3 and the ruuvitag_sensor package.

Use PuTTy to connect to the RPI2

Software installation:

Update/upgrade

sudo apt-get update
sudo apt-get upgrade

Bluetooth
sudo apt-get install bluetooth bluez blueman bluez-hcidump

Python3
sudo apt-get install python3 python3-pip

Ruuvitag-sensor package
pip3 install --user ruuvitag-sensor

Test the installation
python3 /home/pi/.local/lib/python3.4/site-packages/ruuvitag_sensor -f

Finding RuuviTags. Stop with Ctrl+C.
Start receiving broadcasts
F7:B9:07:F5:93:0C
{'temperature': 22.0, 'humidity': 32.0, 'pressure': 1031.0}

Ctrl+C

Make a note of the MAC-address

Make the sensor.py script

cd ~
mkdir ruuvi
cd ruuvi
nano sensor.py

Change the MAC-address in the code to your own MAC-address!

Source

import http.server
import socketserver
import io
import json
import sys
import errno
import datetime
from time import sleep
from ruuvitag_sensor.ruuvi import RuuviTagSensor

# globals
sensor = None
macAddr = 'F7:B9:07:F5:93:0C'

class Handler(http.server.SimpleHTTPRequestHandler):

    def do_GET(self):
        try:
            # globals
            global sensor
            global macAddr
        
            # send response status code
            self.send_response(200)

            # send headers
            self.send_header('Content-type','text/html')
            self.end_headers()

            # update state from the device
            state = sensor.update()

            # get latest state (does not get it from the device)
            state = sensor.state

            # convert json to string
            dump = json.dumps(state)
            data = json.loads(dump)
            print("Data:" + str(data))

            # get data, format:
            # {'humidity': 32.0, 'temperature': 21.0, 'pressure': 1031.0}
            temp = int(data['temperature'])
            humi = int(data['humidity'])
            pres = int(data['pressure'])

            # get current date and time
            now = datetime.datetime.now()
            
            # build html message for client
            message = "<style>body { background-color: AliceBlue; } "
            message += "table, th, td { border: 1px solid black; border-collapse: collapse; } "
            message += "th, td { padding: 10px; color: white; background-color: DarkTurquoise; font-size: 18pt; } "
            message += "h2 { color: DodgerBlue; font-size: 32pt; } "
            message += "p { color: MediumSlateBlue; font-size: 10pt; }</style>"
            message += "<h2>Weatherstation</h2><table>"
            message += "<tr><td>Temperature</td><td>" + str(temp) + "&deg;C</td></tr>"
            message += "<tr><td>Humidity</td><td>" + str(humi) + "%</td></tr>"
            message += "<tr><td>Pressure</td><td>" + str(pres) + " hPa</td></tr></table>"
            message += "<p></p><p>Last update: " + now.strftime("%Y-%m-%d %H:%M:%S") + "</p>"
            message += "<p>Powered by RuuviTag [" + macAddr + "]</p>"

            # write content as utf-8 data
            self.wfile.write(bytes(message, "utf8"))
            
        except IOError as e:
            # catch pipe error
            if e.errno == errno.EPIPE:
                print("Pipe Error")
                return
                
        # ready        
        return

def run():
    # start server
    global sensor
    global macAddr

    # locals
    portNr = 8080
    sleepTime = 2.5
    
    # get beacon
    print('Connect to RuuviTag Beacon ' + macAddr)
    sensor = RuuviTagSensor(macAddr)
    
    # give it some time...
    sleep(sleepTime)

    # start server
    httpd = socketserver.TCPServer(('', portNr), Handler)

    # give it some time...
    sleep(sleepTime)

    # endless serve
    print('Server listening on port ' + str(portNr) + '...')
    httpd.serve_forever()

# run    
run()

Test
python3 sensor.py

Connect to RuuviTag Beacon F7:B9:07:F5:93:0C
Server listening on port 8080...

Start a browser (like Chrome)

IP-address is your Wifi address and portnumber 8080
(use ifconfig to find wlan0 ip-addres if not known)

In this example: 192.168.0.78:8080

4 Likes

Great tutorial. Thanks a lot for sharing this! :sunglasses:

1 Like

Worked with minor modifications on ubuntu mate and rpi 3 thx!

1 Like

Did you manage this to work with pi3 own bt receiver?
nevermind, i managed to make this also out of the box. just needed new firmware for pi3.
now it is up and running.

Addition:
I did buy asus bt400 dongle for my pi2. and it does not seem to find any tags. Any help on this how to debug.

How do I make it run in the background and start at reboot?

You can put python3 sensor.py in /etc/rc.local and reboot

with command: pip3 install --user ruuvitag-sensor
I got error:
-bash: pip3: command not found

I also test with python3-pip intead of pip3 but got same error.
Any idea where is the error?

Did you install python as stated?

sudo apt-get install python3 python3-pip

The last one installs pip3

Yes, install it with sudo apt-get install python3 python3-pip

I also uninstalled and reinstalled it but still got the same error.

EDIT:Correct command in my case was pip-3.2 but I was not able to find any ruuvitags…
Finding RuuviTags. Stop with Ctrl+C.
Start receiving broadcasts

Great code example! I got it working quite easily on my ASUS Chromebox running LMDE – it was conveniently located centrally in our home, and had bluetooth built-in, so why not try it? :slight_smile:

That being said, I actually purchased 3 Ruuvitag weather station units, and wondered if I could use the code in this post as a starting point for making it handle all 3 units at the same time – complete with my own arbitrary labels for each of them (to tell them apart). Should I post my ugly code in this thread, or create a new one?

One thing I have found (unless I am doing something wrong) is that the range of the Ruuvitags within my home is actually quite limited – there is no way that I have the ‘range’ to reach the far rooms of the house. I guess ‘line of sight’ is strongly affected by normal residential wall materials?

Thanks a lot for your detailed example

Hi there! I got the RuuviTag Sensor package installed and working, but when I go to run the Server it doesn’t load or return an error? What can I do?

Running an RPi3 with Raspbian Stretch.

Hi,
All I get is an error:
Traceback (most recent call last):
File “sensor.py”, line 102, in
run()
File “sensor.py”, line 86, in run
sensor = RuuviTagSensor(macAddr)
TypeError: object() takes no parameters

Could someone help me on this… I’m kind of a novice here :slight_smile:

@yza @JDrakeC There’s probably been a change in the underlying ruuvitag-sensor library, and some work would be needed to update this example to match. You could also check out a version of ruuvitag-sensor from Feb '17 and see if it would work, although I’m not sure which data formats would be supported.