Setting up the Enviro+ Pi HAT's libraries

Matthew Wilkes on 2020-05-24

This video is a recording of me setting up the Enviro+ Pi HAT from Pimoroni on a Raspberry Pi in a virtual environment. As a follow-on to the example in my book, Advanced Python Development, I wanted to add support for the sensors on this board. This is the first step, using Jupyter notebooks and a remote kernel setup to try sample code.

Unfortunately, two problems bit me along the way.

  • A few dependencies required some development libraries to be installed on the Pi when installing with setuptools (and Pipenv), which aren't needed when installing the dependencies using the system package manager (which is the preferred installation method from Pimoroni, and makes sense for systems like the Raspberry Pi), but the apd.sensors installation on the Pi is using a virtual environment
  • There was a bug in release 0.0.3 of the interface library, which caused one dependency not to be installed.

This was a 40 minute programming and debugging session which I've condensed to 23 minutes by cutting out time I spent reading documentation and waiting for commands to execute. I have not cut any significant portions of mistakes I made in this process, as the idea is to demonstrate problem solving, rather than showing the final working outcomes.

The quality of this video has some things to be desired. The audio is noisy in places, the feed of my face ends at 15 minutes due to a problem with recording, and a small segment of the screen capture failed. Please bear with me, this was my first attempt at this kind of video, and the nature of the subject meant that I couldn't re-record to fix the problems without substantially changing the content.


- Okay.

So I've bought this new Enviro+
board for the Raspberry Pi,

and I'm going to try setting it up

with the Advanced Python
development sensors code.

I have not tried anything with this yet.

I've had it plugged in but
I've not installed the code.

So as you can see, it's not
doing anything right now.

I'm starting off with
a connection in Jupyter

to this copy of the Pi,

which has the Advanced Python
development code installed.

And I can test things here.

All right, let's get started.

I think the first thing we need to do...

So the first thing we need to
do is get the code installed,

that's the interface code from Pimoroni.

so let's have a look at how you do that.

Pimoroni Enviro, code
examples, Python library.

And I know you can just pip install this,

but there's a lot of setup
with Raspberry Pi things

about making sure the interfaces
are enabled correctly.

So I'm going to see what
they have available.

Right, so they have a one-line install

that you can pipe into Bash.

Which is convenient, but it
always makes me a bit nervous,

(What does that do?)

(Leave that for now.)

Or install directly from GitHub

or from PyPI and configure manually.

Okay, it looks like there are
two commands we need to run

to enable I2C.

So let's do that.

As root.

And enable SPI.

Done, okay.

And I'm gonna pipenv install enviroplus.

What's this on the bottom?

Install additional dependencies.


Does it not do that for me?

I'm gonna leave that for
now, see what happens.

So my pipfile is updating.

While that's working I'm gonna have a look

at the Enviro+ tutorial.

"What's on Enviro+?"

Lots of fun things that I
should probably understand

before I start coding for it, but...

How to attach to your Pi.

I've got it attached.

I guess we should look at the
example code, shouldn't we?


Let's run the code.

So we get the URL to the raw.

Oh, we can do this in Jupyter.

All right, so when I run
this it's not gonna work yet

because I haven't restarted the kernel.

So, no module named smbus.

So let's restart the kernel and run all,

and see if we do need to
install those additional things.

No module named smbus.


All right.

Is that one of the things
that it told me to install?

Python-smbus, yep.

So I will do these.

Actually you know what,
I'm going to leave off


'Cause it should get that automatically,

and I do have it installed.

Apt update that because
it's missed some things.

There we go.

Okay, yes.

This is looking good.

Imagequant, libdef,
that's all kernel stuff.


Let's try that notebook again.

Kernel, restart notebook.

No module smbus.

Yeah, yeah.

Pipenv run python.

Import smbus, no module smbus.

But yeah, so it's in the global.

So I've installed this globally,

which is of no help because
I've a pipenv install,

and that isn't pulling in
packages from the site-packages,

which is good 'cause it means
it's not getting polluted.

But it should've installed
those directly, really.

So python-smbus, what is that?

A drop-in replacement
for smbus-cff, smbus too.

Python smbus Ubuntu.

Why am I doing Ubuntu?

Well, that's close enough to Raspbian.

python-smbus 3.11,

enables smbus access.


Oh, what's that?

i2cdetect, let's see if it finds it.

Yeah, it found some things.




Right, so it's installed
in Python 2 anyway.

That's horrid.

So let's try python3-smbus,

is that gonna let me? It's a thing!


Let me do, import smbus, yep.

Pipenv run, right, here we'll see,

was it actually blocking this?

Yes it was.

Okay, so python3, import smbus,

smbus is that thing.

All right, so it looks
like it might be smbus2,

so let's give that a go.

So the problem we're having here

is that the instructions
tell you to install something

called python-smbus, which
controls the interface

between the Raspberry Pi
and the Enviro+ in Python.

The difficulty is, that's installed

through the operating
system package manager

which installs it into
the global namespace.

And we've got an independent
little pipenv environment.

We could've installed things
in the global namespace,

but then if we've got
multiple things installed

it's a bit tricky

and it's hard to keep
dependencies together.

Incidentally, this is one of the reasons

people don't like pipenv,

because they prefer to
just have containers

or virtual machines dedicated to a task

so they don't have this
problem of layering

between the system namespace
and the pipenv namespace.

But personally I quite like the idea

of having separate little
virtual environments.

So I think that smbus2
is the Python package

that is equivalent to
python-smbus in Raspbian.

So I'm now going to try that out.

Pipenv python.

So I cannot import smbus
but I can import smbus2.

So no, it's wrong.

I don't know why I didn't
spot that before, smbus-1.1.

So if I uninstall smbus2.

And I'm gonna skip the locking

because I'm about to install smbus

and that will cause it to relock anyway.


The other things it wanted to
install were numpy and pil,

weren't they?

So I guess I should check
if those are installed

before I go trudge ahead.

Import numpy.

No pil, so...

So we're gonna install numpy

and I'm going to install Pillow,

which is Alex Clark's fork of
Pil, so let's install them.

Way back when you couldn't
install pil through setuptools.

I don't know if you can now.

Some people would just remember URLs

of repackaged versions of
pil that you could install.


Typed that so many times

before Alex stepped up and made Pillow.

There's also pil woTK

which was a variant of pil
that didn't have TK support,

and that was pip installable.

Should've known really.. "python-smbus"

Of course it's going to
be pip install smbus.

Let's have a look at this
example code while I'm waiting.

So.. oh, this does "from
smbus2 import smbus"!

So I could've used smbus2.

Well that was stupid of me, wasn't it?


Should've had that.

Right, so use either smbus.

Then call BME280, give it the smbus object

and then you can get
temperature, pressure, humidity.


So I don't actually
need any of these things

it's installing right now, I don't think,

because I'm not using the screen.

I'm not handling the data,

I just wanna get the value
of that BME280 sensor.

Can I be cheeky and just
restart and run all?

During the middle of the pip operation?

Logging is not defined.

Ah, brilliant.

Right, that's 'cause I removed it.

Take that.


Okay, so temperature, 24.11 degrees C,

pressure, 689.31 hPa.

hPa, what's that?

Relative humidity, 91.33%.

No, that sounds a bit high.


Pressure in Leeds.

Weather forecast Leeds.

1014.2 hPa, humidity 46.6%.

Right, okay.

Bit dubious.

Okay, oh, that looks a lot better.

Look, temperature's too high.

So it's not 35 degrees.

Pressure should be over 1000

and this humidity should be, what?

Oh, I know.

Pi at rpi-lounge.



Okay, relative humidity
downstairs is 43.5%,

it's glitched in this version,
and temperature's 20.8.

So I'm expecting humidity in the 40's

and temperature in the 20's.

It's possible this is wrong, but...


Hm, not great.

See what else we can manage.

Weather and light, let's try that.

Ooh, that's long.

That's really long, that
does a lot of stuff.


There's gotta be a simple
thing for me to look at.

Okay, I guess I'm gonna grab one of these.

Let's do All In One.


And I'm gonna be lazy and
just dump it into this cell.

And we'll see what happens.

Eh, import from numpy C extensions failed.

Let's let that finish so I
can have the kernel restart.

Let's Google this error.


Apparently not libblas-dev.

I don't even know if pipenv install numpy

is gonna force it to rebuild.

'Kay, so let's try that.

Restart kernel, restart.

All right, let's try this one.

Libopenjp2 cannot open shared object.

Really we should be approaching
this with a bit more method.

No module named sounddevice.

That's interesting.


What's sounddevice?

It's one of the dependencies
by the looks of it.

install_requires sounddevice, right.

There's no sounddevice there

but it's listed as install_requires.

Enviro+, all right.

Download files.

So this is the wheel.

Grab that.

And unzip it.


Get dist-info METADATA.


there's no sounddevice there.

Why is there no sounddevice there?

Has this changed in the meantime?

17th of March, 16th of March.


What's going on?

Library, setup.cfg, sounddevice.

Fix noise_floor bug.

Sounddevice, add deps
for noise measurements,

seven months ago.

All right.


So why?


Why is that not there?


Delete the egg-info directory.

Python bdist_wheel.

So we should re-generate
the egg-info directory

as well as the wheel.

Take a look at that.

And there's no sounddevice.

It's in setup.cfg, sounddevice.

Setup.cfg sounddevice
and a bunch of tests.

What's going on?

Ah, look at that!

There's a install_requires in

which doesn't include sounddevice.

So this is a bugged release.

All right, okay.

Issues, should've checked that.

Install misses package, yes.


All right, I think released as of...

All right.

So that, move package
and requires to there,

which is marked the 24th.

So the 16th wasn't,

so that's eight days later this got fixed.

Packages, enviroplus.


I'm just gonna double check
there's no existing issue here.

Support MEMS microphone, sounddevice...

Extra dependency needed,
examples LCD gives an error...

Okay, so I think I'm gonna
call that a day for now.

It's a little tricky to proceed

without the underlying library

being installed correctly.

I think next time I'm gonna try

installing sounddevice manually

and see what we can do.

So thanks for watching me get frustrated

and not knowing how to do

simple package installation in Python.