RaspberryPi wifi networking, programming and hardware IO

As part of a small project to do energy and environmental monitoring of our home I have been getting to grips with some RaspberryPi hardware that I purchased perhaps 3 years ago.

A few challenges came up! I’ll cover a few in a couple of posts.

  • Getting a wifi dongle to work.
  • How to go about programming stuff on the rPi
  • Getting to grips with rPi GPIO hardware interfacing.
  • Getting rPi I2C IO working
  • yii2 on RPI

A quick general overview of the project. I previously had an Arduino Mega with a wifi shield from Async Labs monitoring some systems around the house. I changed broadband providers and the wifi network changed. After not having the monitoring in place for about a year I decided to get back in to it and get the hardware working. I quickly discovered that Async Labs went out of business nearly 5 years ago and their excellent piece of hardware needed some new software. The Arduino development environment had moved on and migrating to it broke both my web server software and the wifi connectivity. It didn’t take long to bin the idea of trying to revive the old hardware and to decide to move on to the RPI platform. I had never before bothered with GPIO on the PI so it seemed like a good time to roll my sleeves up.

Basically I have installed 3 pieces of hardware that allow me to monitor resource useage around the house.

  • A magnetic door security switch installed on a standard fitting gas meter provides simple pulse counts as the meter ticks over.
  • Installing a mains water meter with monitor contact under the sink in the kitchen provides one pulse per litre of water used so I can track our water useage.
  • I installed an industry standard electricity meter with pulse output that allows me to monitor power useage. A comment here, about 6 months after I had installed my electronic meter our electricity supplier came to the house and removed the old ‘spinning disk’ mechanical meter and installed an identical unit to mine in the main feeder box outside the house.
  • Outside environment monitoring – Air pressure, Outside Air Temperature and Relative Humidity.
  • Future expansion possibilities such as Light and IR level monitoring.

Details on the meters and sensors used can be found here.

I wanted to monitor the 3 pulsed signals with interrupt driven monitoring so challenge number one was achieving that!

My energy and water signals are all fed to a point in my garage so it seemed logical to get the RPI to connect to my network via wifi to save having to run a new ethernet spur to the garage ( I wired the house some 15 years ago, much of it has fallen into disuse apart from a spur that is used by my son for WoW and other online gaming )

Background

I fired up my PI and got a basic installation working. I checked networking was working and used the ethernet connectivity of the PI. Working directly on the PI with a small keyboard and an old screen simply wasnt hacking it for me and I quickly reverted to SSH’ing in to the PI with my favourite terminal package and working from my PC or the Mac. I manage a couple of servers an I’m used to working this way.

After a couple of false starts I quickly discovered that backing up the PI SD card by taking an image of it before major changes is the way to go. At one point I installed upstart to automatically run scripts at startup. This bricked my PI on the next boot and I had to spend an hour or two rebuilding what I had done until then.

Getting RPi wifi working.

Here’s where it started to get interesting. I have several wifi dongles, several of which did not match anything I could find on accepted lists or other blogs on the web. none of he stuff I found on getting a TPLink dongle working delivered any connectivity so I gave up on that after two days of fiddling.  I went out to my local PC ripoff store and got hold of a Netgear  WNA3100 usb adaptor.

Yii2 Rbac – Role based authorization

I’m using Yii2-User as my authentication framework and I’ve used Yii2’s standard database rooted  authorisation scheme. As usual there are a few gotcha’s that need explaining.

When configuring rbac in the components section of the config file this is usually suggested.

     'authManager' => [
                           'class' => 'yii\rbac\DbManager',
                           'defaultRoles' => ['guest'],
          ],
.....

The first section is self explanatory, use the DbManager as the source of the Authorisation class.

I’ve yet to see a proper explanation of what the second line does.

It assigns the defined role or roles to anyone who hits the site.

More crucially it assigns those roles to logged in users as well. This can play havoc with your authorisation logic if you are defining strict rules. A logged in user may get access, or be channeled down paths that you didn’t expect!

Yii2 Authorization

Yii2 provides a  Role Based Authorization Control ( rbac ) module off the shelf. The code at /vendor/yiisoft/yii2/rbac under your basic application folder is what we are dealing with here. Unfortunately it requires initialization and the tables need building before it can actually be used. The documentation around this process is a little sketchy so hopefully this will smooth the road!

This article leads on from Yii2 Migrations which gives a little more background to migrations.

Let’s leap in. First of all you need to create the tables required by the Yii2 Authorization code. There are several ways of doing this. You can access the database from a tool like phpMyAdmin ( or a tool that matches your database ) , if you have already got as far as an up and running basic installation then you can make use of the database abstraction layer by using the commands in the migration class. Since we are unlikely to install the Authorization layer more than once I did this manually.

In the Yii2 configuration post you might have seen that there are several config files. In some cases changes need to be made in both web.php and console.php. Processes like migrate use the console version of the config file so if you configure the authManager component in the runtime configuration web.php and forget to do it in console.php you will get a configuration exception when you try to run migrations that affect the authorization component! It looks like this ..

You should configure "authManager" component to use database before executing this migration.

Ideally the exception messages in your migration files should read something like …..

You should configure "****** component to use the database in 'console.php' before executing this migration.

Here’s something that is not explained fully. If you built the ‘basic’ demo application you can build the tables by issuing the following command line command.

php yii migrate --migrationPath=@yii/rbac/migrations/

OR

Using your database schema the following SQL will build the required tables. Simply block copying it into the phpMyAdmin SQL command window works fine for me.

One thing to note is that the ‘tbl_’ part will need to match the prefix of your schema tables. If you are not using prefixes than simply drop that part of the table names.

drop table if exists `tbl_auth_assignment`;
drop table if exists `tbl_auth_item_child`;
drop table if exists `tbl_auth_item`;

create table `tbl_auth_item`
(
   `name`                 varchar(64) not null,
   `type`                 integer not null,
   `description`          text,
   `biz_rule`              text,
   `data`                 text,
   primary key (`name`),
   key `type` (`type`)
) engine InnoDB;

create table `tbl_auth_item_child`
(
   `parent`               varchar(64) not null,
   `child`                varchar(64) not null,
   primary key (`parent`,`child`),
   foreign key (`parent`) references `tbl_auth_item` (`name`) on delete cascade on update cascade,
   foreign key (`child`) references `tbl_auth_item` (`name`) on delete cascade on update cascade
) engine InnoDB;

create table `tbl_auth_assignment`
(
   `item_name`            varchar(64) not null,
   `user_id`              varchar(64) not null,
   `biz_rule`              text,
   `data`                 text,
   primary key (`item_name`,`user_id`),
   foreign key (`item_name`) references `tbl_auth_item` (`name`) on delete cascade on update cascade
) engine InnoDB;

Ok, now we have the tables to hold our authorization data. Next we need to define our authorization schema.  I’m using something fairly simple, an omnipotent Administrator, a manager role and a user role.

 

 

 

 

 

 

Let’s tell our site to start using Authorization. If you built the basic Yii2 application in the config file for your site ( at /config/web.php ) in the components section you will see ..

    'components' => [
     ......
        'authManager'=> [
            'class' => 'yii\rbac\DbManager',
            'defaultRoles' => ['end-user'],
        ],
     ......

Yii2 Migrations

Why oh why is the standard of Yii2 documentation apparently so universally poor?

While trying to look into getting migrations going on my Yii development site I stumbled over a web page that appeared to lay things out pretty well. I should have guessed that life was not going to be that simple! This …

First we need to create a migration:
 
yii create/migration insert_user

.. rapidly turned into an in depth investigation of the migration system. Try it yourself, the above command fails in at least two different ways.

First things first, what do migrations do in Yii?  ‘Migration provides a set of convenient methods for manipulating database data and schema. For example, the insert() method can be used to easily insert a row of data into a database table; the createTable() method can be used to create a database table. Compared with the same methods in yii\db\Command, these methods will display extra information showing the method parameters and execution time, which may be useful when applying migrations.’

That comes from the Yii2 Documentation so at least there’s a start. When it is used with the command line it gives us a way to execute upgrade ( or downgrade ) code while inside the environment of our website.

We can use a Yii command to generate a framework migration file as follows.

Dream up a label for your migration and in the root directory of your Yii2 application issue the following command.

*> php yii migrate/create \migration_label/

The command responds with a prompt asking you to accept the generation of a new migration file. You’ll notice that the filename has some additional information concatenated in to it. Basically a time and date and key. These are used to track your use of migrations.

Some Gotcha’s and notes here.

  1. Migrations and other console commands use the console.php configuration. I spent a frustrating hour or three trying to work out why component configurations that I copied from the internet were apparently not working. I’d put them into web.php and not into console.php!
  2. When a migration file is run and it completes without error and entry is made into the table ‘migrations’ in your database along with a timestamp. If you are testing a migration subsequent edits of the migration file are not applied since the tool does not know that the file has changed. You need to either rename the file or simply drop the relative entry to the migration table before rerunning the migration.

While you are in your root directory issue the following command.

*> php yii help migrate

You’ll see some additional commands that give some more insight into the migrate system.

Next I’ll use a practical example of generating a migration to help with the installation of the Yii2 Authorization module to expand on how things work.

LED’s

Light Emitting Diodes or LED’s are rapidly becoming the preferred option for fitting in applications where low current and a long life are beneficial. Obviously on a yacht where power is supplied from batteries for some or all of the time, reducing the current draw delivers a lot of benefits. Longer battery duration so longer between charges for example. The added benefit of very long lifetimes is another drawcard.

There are some pitfalls however and the consumer is not helped by the lack of a common knowledge base. This post is an attempt to throw some light ( sorry 🙂 ) on the whole subject.

1 – Led’s are polarity sensitive
2 – led’s are current driven devices …. Not voltage driven!