Connect with us

IoT

How my cat helped me build a better IoT app

Published

on

Modernizing my app made it far easier to spy on my American Shorthair

My cat Tucker is a somewhat predictable animal who likes to curl up in predictable spots around the house, so he’s the perfect subject for surreptitious video surveillance and just the sort of motivating force I needed to rework a Raspberry Pi project I’d been putting off for some time.

I’d previously set up video surveillance on an Ubuntu desktop using an old USB camera and the motion-detecting app motion to successfully catch an office prankster in the act of stealing my chair. It seemed perfect for a DIY Raspberry Pi 3 cat cam. I ported the whole thing to Raspbian and it became TuckerCam 1.0.

The rig worked pretty well, but every time I needed to change the configurations, I had to break out a spare keyboard, monitor and mouse to interact with the Raspberry Pi and Raspbian, now known as Raspberry Pi OS. When it all stopped working one day, I didn’t bother to fix it, so TuckerCam 1.0 went dark.

Time for a better approach

When my step-daughter brought home a Raspberry Pi Zero W from a STEM camp and “gifted” it to me, I decided to try again. This time, though, I wanted to overcome the hassles I encountered the first time around.

Specifically, I wanted a solution that gave me:

I was learning more about Docker, so containerizing TuckerCam 2.0 was important to help me eliminate as much overhead as possible, give the app a smaller footprint, and make it easier to replicate and deploy. This turned out to be a game-changer, and though Tucker didn’t know it, he’d inspired me to take a giant leap forward in my app development.

Containerizing motion on Debian

My previous Raspberry Pi OS deployment mostly worked, but it was clunky, so this time I started by creating a Docker version based on Debian Stretch. Motion can be installed with a simple apt install motion so turning it into a single-container service wasn’t complicated.

The harder part was figuring out a way to dynamically set variables in the motion.conf configuration file that suited my needs and worked with my old USB camera. Motion has a wide variety of configuration settings, including variables that set the streaming port, the height and width of the video stream, whether to output still images, the palette to use, the frame rate, and so on.

In TuckerCam 1.0, I hard-coded these settings into the config file. This time, I wanted to store the variables as part of the container application and make them easier to edit on the fly rather than in a fixed, one-off motion.conf file. That way I could more dynamically adjust them for different cameras and make it easier for other developers to make their own modifications.

I decided to set these values using environment variables, which turned out to be a three-step process. I had to replace the default motion values in /etc/motion/motion-dist.conf with shell variables, store the variable key/value pairs in a Docker .env file, and use envsubst in the running container to substitute the shell variable placeholders with the proper values.

Modifying the default motion-dist.conf configuration file is a bit of an eye strain (made harder when Tucker pawed my keyboard), but it was otherwise straightforward. For example, here are three of the 14 values I replaced with shell variables:

I saved this updated file as motion-template.conf and created a motion.env file to hold the key/value pairs to match the shell variables:

In order to use these values in my container, they needed to be applied on the running device. I created a start.sh bash script to run envsubst (to do the environment variable substitution) and to start motion with my updated configuration file. I’d previously used sed to do variable swapping, but found envsubst to be much simpler. It ingests my motion-template.conf file and outputs an updated motion.conf:

Finalizing the Docker build

With these three files complete, I created a simple docker-compose.yml to build my containerized application. In its most basic form, it looked like this:

I used a single directory for my build context, so I created my Dockerfile there and added basic content to install motion and gettext-base, which provides envsubst. I also used the environment variable EXPOSE_PORT in the Dockerfile so the motion video stream would be available externally.

With everything set, I plugged my USB camera into my workstation and ran docker-compose up -d. The Docker build process worked flawlessly, and when I visited http://localhost:8081, the stream was live (along with Tucker):

Porting it all to my Raspberry Pi Zero with balena

With my code in good shape, I pushed it to a new GitHub repository and contemplated how best to get it running on my Raspberry Pi. Running TuckerCam 2.0 in a container on my workstation was one thing. Getting it to run on a tiny ARM-based device was quite another.

Nowadays, Docker can run on Raspberry Pi OS but, again, I wanted to avoid the manual device set-up and the overhead. I really wanted headless provisioning and management, so I used balena, which runs a Docker environment out of the box in its base balenaOS and provides a dashboard for managing everything. It’s free for the first 10 devices, plenty for scattering TuckerCams around my house.

Balena-ifying my containerized application

The original Dockerfile I used on my x86_64 workstation required a small change to the image source command in order to work properly on the Raspberry Pi Zero ARM processor, namely changing:

FROM debian:stretch

That worked fine if all I wanted was to run TuckerCam 2.0 on Raspberry Pi Zeros, but I preferred a more universal approach that would work with any device type I might use. To do that, I used the balenalib image repository, which offers Debian container images for multiple platforms. I changed the name of my Dockerfile to Dockerfile.template and replaced the FROM line with a wildcard alternative:

FROM balenalib/%%BALENA_MACHINE_NAME%%-debian:stretch

With this line, each device type is automatically detected and the proper image for its architecture is used. For the Raspberry Pi Zero, this automatically translates to balenalib/raspberry-pi-debian:stretch. When I later used a Raspberry Pi 3, this automatically became balenalib/raspberrypi3-debian:stretch. Now, I never have to edit my Dockerfile.template or create multiple versions for different device types.

Setting environment variables

In my workstation test, I had placed all my motion settings in a motion.env file, which automated the process of setting the values I wanted in motion.conf. This worked well, but the values only applied during the build process. If I made a change to some variable in motion.env, I had to rebuild and redeploy my container.

That’s not a huge deal-breaker, but balena offers a way to apply build variables and save all the key/value pairs in the balenaCloud application itself. That lets me edit settings from the balenaCloud dashboard and apply the same variables to each new TuckerCam 2.0 device I add to my balenaCloud application. I can also override the values on a device-by-device basis without having to redeploy.

To take advantage of this capability, I created a balena.yml file that set environment variables in much the same way as my motion.env file:

To use this file, I placed it in the root of my TuckerCam GitHub repo so it loads and sets all my variables using Deploy with balena without me (or users of my repo) having to retype them. Whenever I want to make a variable change, I can do it in the balenaCloud dashboard, where my changes are automatically detected and my container is restarted with the updated values.

This capability was especially useful when I was trying to tweak the video device and palette settings to get motion to run correctly with my older USB camera.

Armed with my new balena.yml, I removed the redundant env_file lines from docker-compose.yml and deleted my motion.env file:

env_file:
– ./motion.env

One more tweak to my original Dockerfile enabled me to shrink the size of the container image, which was important given my Raspberry Pi Zero’s limited power and relatively slow WiFi.

In my original Dockerfile, I used apt to install motion and gettext-base, but balena has a built-in package installer script, install_packages, which installs what I need and cleans up afterward. Using install_packages instead of apt reduced the size of my container by 52 MB, or about 18 percent, to just 233 MB total.

So, in my Dockerfile.template,

RUN apt update && apt install -y gettext-base motion

RUN install_packages gettext-base motion

Everything else in my motion-template.conf and start.sh stayed the same. I updated my GitHub repo with my code changes and turned to deploying my app.

Multiple ways to push code

When running Docker locally, building and deploying my motion container was a simple matter of using the CLI to run docker-compose up -d. Deploying to balenaCloud can also be done from the command line (after installing balenaCLI) or I could skip the CLI and just use the browser-based option with Deploy with balena.

To do that, I could either create a new balenaCloud application from scratch and manually enter my GitHub repo URL and environment variables, or I could use Deploy with balena to wrap everything into a single step that doesn’t require manual data entry or anything to be installed on my workstation.

I took the Deploy with balena route because it eliminated the need for me to install any image-build capability on my workstation. Instead, my images are built in the balena cloud straight from my GitHub repo code and pushed directly to my Raspberry Pi Zero or other devices.

Balena has an API endpoint to make this work, so I could either point my browser to https://dashboard.balena-cloud.com/deploy?repoUrl=https://github.com/balenalabs-incubator/balena-motion to deploy my application or add a single line of text to my GitHub repo README.md file, which wraps that link around an image “button” and makes it easy to deploy (or redeploy) directly from GitHub:

[![](https://www.balena.io/deploy.png)](https://dashboard.balena-cloud.com/deploy)

The URL to the repo isn’t necessary in the README.md because the balena endpoint automatically uses the referrer address. So, in my GitHub repo, that simple line added the Deploy with balena button, which looks like this:

Provisioning the device

One of my key TuckerCam 2.0 goals was to avoid having to connect a keyboard and monitor to initially configure my device, so I didn’t want to burn Raspberry Pi OS to the SD card I planned to use. With balena, I could instead use a device- and application-specific base OS image.

While my container release was being built on balena’s cloud servers, I returned to the balenaCloud dashboard, clicked on my new application, and clicked the Add Device button to define and download the appropriate image for my Raspberry Pi Zero. I added my WiFi credentials, saved the .zip file to my workstation and flashed it to an SD card with balenaEtcher. This custom image was just 139 MB compared with 432 MB for Raspberry Pi OS Lite, the smallest image currently available.

Since I was able to set the WiFi credentials in the base OS image itself, I didn’t have to do anything to get the Raspberry Pi Zero online. A few minutes after I inserted the SD card and powered it up, it automatically joined my wireless network and started to download the balena OS and my container image. The device showed up in my balenaCloud dashboard, where I could see its IP address, and access the HostOS or container shell from the built-in terminal:

TuckerCam 2.0 on the Raspberry Pi Zero was up and running, and I never had to attach any peripherals to the device to provision it. In fact I didn’t have to manually log in to the Raspberry Pi or use the command line on my workstation for anything.

To test my dynamic configuration set-up, I toyed with the width and height of the image/stream and changed the EXPOSE_PORT value to access the TuckerCam from port 8088 instead of 8081. I did this in the Environment Variables settings in the balenaCloud dashboard. My configurations applied without trouble, and the container restarted automatically with the new port setting.

I can now quickly change or redeploy TuckerCam 2.0 any time I want. I tried that by flashing another SD card with the same custom image I used before, inserting it into another Raspberry Pi Zero and powering on. Within a few minutes, the second device joined my balenaCloud application, downloaded my motion container image, applied all the proper environment variables, and gave me two views of Tucker:

I was pleased with how it turned out and, though Tucker was none the wiser, he’d helped me accomplish my goals for TuckerCam 2.0, namely:

Additional optimizations

Working with a Raspberry Pi Zero can be especially frustrating because it’s not nearly as snappy as an RPi 3 or 4. It can take a while to reboot, download code and get started, so part of this exercise was my desire to make everything as small as possible.

In my earlier workstation test, I was a little concerned about the size of my motion container, which stood at about 475 MB. That seemed rather large, but making a couple basic tweaks (and porting it to ARM) helped shrink the image to 233 MB, or about half the size of the original.

To shrink it even more, I created a version with Alpine that ended up at just 75 MB! Unfortunately, the Alpine folks changed their repos recently and installing the motion package (without building from source) no longer works. Bummer.

Final thoughts

Whether you have a cat to motivate you or not, I hope my experience with transforming my TuckerCam from a desktop app to an IoT-ready containerized version inspires you to try it with your own applications. The ability to configure my Raspberry Pi without cables or peripherals, more easily modify the application and configuration settings through the balenaCloud dashboard and GitHub workflows, easily scale it all to multiple devices, and more readily share it with Deploy with balena made a world of difference.

Do you have an interesting project you’ve converted for use on balena? Let us know about it and share your experiences in the balenaForums!

This content was originally published here.

IoT

Google Nest Hub Max Smart Home Assistant (Chalk, Refurbished, Plain Box) – EXPANSYS Japan

Published

on

This content was originally published here.

Continue Reading

IoT

Best Amazon Prime Day Arlo, Nest, Ring, Blink & Smart Home Deals 2020: Top Security Camera, Video Doorbell, Floodlight, Alarm & Philips Hue Sales Presented by Deal Tomato

Published

on

Prime Day smart home & security camera deals for 2020 are finally here, browse all the latest Prime Day Ring Video Doorbell, Nest Protect & Thermostat, Philips Hue smart LED bulb, Arlo Pro & Blink Mini sales listed belowPrime Day home secur…

This content was originally published here.

Continue Reading

IoT

Which Smart Home Heating Should You Choose?

Published

on

Not all smart heating control systems are suited for every lifestyle and home, with some more and less beneficial than others. SMART stands for ‘Self-Monitoring Analysis & Reporting Technology’, and differs from standard heating controls by allowing you to control every aspect of your heating schedule from either a phone or tablet. Although room thermostats and timers allow you to control each room instead of your whole home, as long as you have internet access, smart home heating devices let you control your heating from your phone, no matter where you are in the world.

Today, we’re running through 7 of the best smart heating thermostats and systems, comparing features, benefits and what type of home they’re most suitable for.

– 7 day, & 5/2 day scheduling with a pre-configured schedule included
– Choice of up to 4 time periods a day
– Minimum On-Time & Cycle Rate settings ensuring compatibility with many boilers
– Table stand for ease of positioning
– Alert messages to assist fault-finding with a fail-safe mode
– Wireless technology makes upgrading easier and the installation time shorter with less wiring involved

Best for:

– Homes that require high levels of automatic control that provide significant energy efficiency for a wide range of boilers and systems.

– Single Heating Zone Control
– 7 Day, 5/2 Day, or 24 Hour Control
– Programmable Room Thermostat
– Easily Programmed With The Associated App

Best for:

– Homes that are just starting to take the first steps into using smart home heating
– Homes that need a single heating zone control
– Homes that have either combination or standard boiler systems

– Touch-screen interface simplifies scheduling, changing and overriding temperature
– Location-based programming (geo-fencing) adds an automated layer of control, adjusting the customer’s home heating based on their location
– Scheduling features include 7 and 5/2 day bespoke scheduling with up to 6 time periods a day
– Simple flip-up wiring bar for easy access and an easy-to-install boiler or zone valve interface
– Direct wall mounting or wall-box mounting
– Optimisation features include optimum start and stop & delayed start boiler control. Allows the thermostat and boiler to work more efficiently together

Best for:

– Homes with any boiler and almost every heating system
– Homes with 230V on/off OpenTherm appliances (gas boilers, combi boilers and heat pumps)

– Ability to control water temperature and heating
– Self-learning functions to make every experience a unique one, helping it to understand your home’s needs
– Using a smart weather compensation feature and weather data, the vSMART can tell your boiler how hard it has to work to get your home to your required temperature
– You can connect multiple vSMART controllers to one app

Best for:

– Homes with Valliant ecoTEC system/open vented boilers
– Households that want to be able to control water temperature from anywhere too

– A 7-day full programmer that gives great flexibility offering up to three on/off switchings per day
– LoT display, providing text feedback that gives help and programming hints
– Automatic Summer/Winter 1 hour time change
– Choice of 3 different built-in programmes
– ‘Holiday’ button

Best for:

– Homes with heating and stored hot water in complete systems
– Homes with older gravity circulation stored hot water systems, where there’s no interlocking control valve
– Households with different heating needs from day-to-day

– One channel thermostat system with two radiator thermostats to start zoning your system
– Smart heating & hot water control
– Quick & simple to install using an industry-standard backplate
– Easy Zoning with the addition of extra Wiser Radiator Thermostats

Best for:

– Homes with combination boilers
– Households that want to start a zoned system to control individual zones within the home

– Automatic time and temperature control of domestic heating premises
– Optimum Start, Optimum Stop and Delayed Start
– No installer links or switches on the back of the unit means no adjustment is required for combi boilers and most central heating systems
– Scheduled maintenance alert
– Automatic Summer/Winter time change
– Up to four independent time & temperature settings
– Auto, manual, holiday, override and off (frost) modes

Best for:

– Domestic premises
– Most central heating systems and combi boilers

For more smart home heating controls, check out our full range today at MonsterPlumb. If you’re not interested in smart technology when it comes to controlling the heating and water temperature in your home, take a look at our selection of heating controls and valves.

This content was originally published here.

Continue Reading

Trending

AutomateMyHome

Subscribe to AMH Daily Updates

Get the best news, expert tips and product reviews everyday!