Tag Archives: software development

Is There a Market For Your Product?

If you have ever come up with a ground-breaking idea for a new product, you are probably familiar with the feeling of FOMR. Unlike the popular “FOMO,”  FOMR is the Fear Of Market Research. It is the avoidance of conducting research to validate (or invalidate) that not only does a need exist for your idea, but also that the barriers to entry are not insurmountable. Taking such an approach when building out your product strategy means you are walking into the market blindfolded, which will certainly result in some rather unfortunate consequences that could otherwise have been avoided.

 

the-walking-dead2

Sometimes it’s nice to know what’s behind a door before you open it.

The Fear

Many tend to avoid this step simply because they are afraid of discovering that there isn’t as much demand for their product as they originally thought, or that the market is already saturated with similar solutions.

Additionally, the potential cost of conducting research (in both time and money) can seem unappetizing as well. if you are already convinced the product will be a success it can be hard to justify burning limited resources to tell yourself what you already know.

Despite the uncertainty, foregoing this crucial step is never a good idea. It’s easy to tell yourself that everything will probably work out just fine, or that you will simply learn and adjust as you go, but it is for this very reason that the road to market domination is littered with the carcasses of the ill-informed and unprepared

.

Sasha (Sonequa Martin-Green), Bob Stookey (Larry Gilliard Jr.) and Maggie Greene (Lauren Cohan) - The Walking Dead _ Season 4, Episode 10 - Photo Credit: Gene Page/AMC

Watch your step…

The Solution

One method to getting past this fear is to reframe it in your mind as a way to preemptively solve or avoid future problems. When done properly, market research will help you identify and understand your target users, differentiate your offering, fine-tune your original concept, and increase your product’s chances of user adoption.

Industry Research

What are the revenues for your category in your local market, regionally and nationally? One good resource for this is ibisWorld. If there’s little money to go around in the industry you are serving, you’d better make sure you can capture the majority of it.

Identify trends in your chosen industry. Many larger companies often demonstrate their expertise and thought leadership by releasing industry outlooks or annual reports and white papers. These can be a great resource for understanding where your field is heading and what pains are being experienced across the board.

Determine if the market is new and growing or static and mature. Has your industry been around forever and become a staple in people’s lives, like shoes or haircuts? Or is it emerging and exciting, like augmented reality or connected devices? Can you compete in a mature market saturated with competition, or stay at the cutting edge in a new market that could evolve overnight?

User and Customer Research

Determine who the users of your product are. Hint: the answer isn’t “everybody.” Your users and your customers may not actually be the same people and depending on your product, you may even have multiple types of users. You’ll need to understand them all if you want your product to succeed. Identify their age groups, ethnicity, geographic location, job titles, income levels, etc.

Conduct User Testing. Get out there and interview people who fit your user personas. Understand their pain points, what their goals they want to achieve, how do they want to interact with your product? A great way to get this information quickly and inexpensively is with the use of paper prototypes or other low-fidelity mockups of your concept that your test subjects can interact with prior to building a (more expensive) finished product.

Once you have determined who your users are, be sure you can answer the following questions:

Are there enough people who fit my criteria?

Will my target really benefit from my product/service? Will they see a need for it?

Do I understand what drives my target to make decisions?

Can they afford my product/service?

Can I reach them with my message? Are they easily accessible?

Competitive Research

Know who your competition is. Hint: the answer isn’t “no one.” Just because you may be the only one doing exactly what you are doing, does not mean you don’t have competitors. Be thorough. Cranking out a google search on a few keywords and calling it a day is not enough. Dive into message boards, articles, and blogs (which tend to quote industry leaders that may be competing with you). Peruse top ten or top 100 lists of the best rated or reviewed providers in your industry.

Once you have built a comprehensive list of your competition, check out their websites to understand their offerings and differentiators. What makes their product special? How long have they been offering these products?

Who are their customers? Where and how are they marketing? What do their customers love/hate about them and their product? Check out their support forums to see if there is a feature their customers have been begging for that they have not developed yet. Simply put: Know. Thine. Enemy.

 

heres-when-the-next-big-villain-is-coming-to-the-walking-dead

It’s this guy. Definitely this guy

The Benefits

The moral of the story is: don’t let FOMR get in the way of building a great product. Once you’ve done your homework, you’ll be able to make smart strategic decisions around the direction and development of your product. You may even discover that your original concept won’t do the trick, but with some tweaks and repositioning, it could solve another need you weren’t aware of. Launching a new product (or business is like wandering your way through hostile territory. There will be lots of hazards and pitfalls hiding around every corner, but if you’ve equipped yourself with the knowledge required to make the right decisions, you stand a much greater chance of making it through.

 

the-walking-dead

I’m sure you’ll be fine!

 

Developing an amazing technology product of your own? Take our 1-Minute self-assessment to make sure you’re project is on-track for a successful launch!

IoT Course Week 12 – Remote Firmware Updates

Screen Shot 2015-10-15 at 3.07.21 PM

Last week, we explored Load Testing of HTTP and MQTT and how to measure the scalability of your system.

This Week

This week, we’ll continue our focus on non-functional requirements with Remote Firmware Update.  A typical desk lamp, or other non-IoT device, will have the same functionality 10 years after it leaves the factory.  The functionality and value of a “smart” device, however, can increase over time, as new software functionality is deployed.  

As students have experienced, updating the functionality of the Web is relatively straight-forward: deploying new code to a server updates the web application.  Similarly, as new iOS and Android mobile capabilities are deployed, the new Apps are published on the iTunes and Google Play stores.  But how do you update the software/firmware on your smart device?  There could be hundreds of thousands, or even millions, of devices distributed across the country or world and each embedded system is slightly different.  For Week 12, we show students how to remotely update LAMPi.

Screen Shot 2016-05-23 at 11.05.56 AM

 

Debian Packages

Since we are using Raspbian, a Debian-based Linux system for LAMPi , we settled on the Debian Package System. This addresses the actual packaging and installation of software, as well as the distribution and security (authentication and integrity) of those packages.

Create Folder Structure

First, we need an executable to package. We’re going to make a package called “hi” that contains an executable also called “hi”. Let’s make a directory to build our deb package in:

cloud$ mkdir -p ~/pkg/hi/{DEBIAN,opt/hi}
cloud$ cd ~/pkg/hi/

Viewed in tree (you can install tree through apt-get), this folder structure should look like so:

pkg
├── hi
│ ├── DEBIAN
│ └── opt
│ └── hi

So ~/pkg/hi is the directory that holds everything we want to package.

  • DEBIAN is a special folder that contains all the configuration & metadata for the debian package
  • Everything else in ~/pkg/hi will be installed in the root of the system. So ~/pkg/hi/opt/hi will install into /opt/hi on the system in which it is installed. If we wanted to install some supervisor scripts with our packag. For example, we could make a ~/pkg/hi/etc/supervisor/conf.d/ directory and files in it would install into /etc/supervisor/conf.d.

Create Executable

Now let’s build an executable. When the package is installed, we’ll want the executable to be installed in /opt/hi/ so create it as ~/pkg/hi/opt/hi/hi

#!/usr/bin/env python

import os

version = 'Unknown'
version_path = os.path.join(os.path.dirname(__file__), '__VERSION__')
with open(version_path, 'r') as version_file:
version = version_file.read()

print('Hello Deb! Version {}'.format(version))

Let’s create a file to hold the version of our program. Create ~/pkg/hi/opt/hi/__VERSION__ with the following contents (no whitespace, no newline):

0.1

Save and close both files, mark “hi” as executable, then run it:

cloud$ cd ~/pkg/hi/opt/hi/
cloud$ sudo chmod a+x hi
cloud$ ./hi

Hello Deb! Version 0.1

Create Package Metadata

Now let’s build a control file to describe our package.

Create a file at ~/pkg/hi/DEBIAN/control, replacing {{YOUR_NAME}} with your name:

Package: hi
Architecture: all
Maintainer: {{YOUR_NAME}}
Depends: python, python-dev, python-pip
Priority: optional
Version: 0.1
Description: Hello, Deb!
Section: misc

Note that these metadata files are whitespace sensitive and do not allow additional empty lines so be careful while editing.

Finally, we need to fix file permissions and make root the owner of the entire directory structure. These permissions will travel with the package, so if we don’t do this, the files will be installed with bad permissions.

cloud$ sudo chown -R root:root ~/pkg/hi/

Note that after you do this, further edits to files in this directory will require sudo.

This should be all we need to build our deb package, so let’s go:

cloud$ cd ~/pkg/
cloud$ dpkg-deb --build hi

You should now have a hi.deb in ~/pkg/.
You’ve just created a Debian Package!

Setting up a Debian Repository
We use reprepro, an easy to set up Debian Package Repository, and show students how to publish their packages to that repository, add that repository to LAMPi, and then install the package on LAMPi from the repository.

Automating Deployment

Everytime we change our hi package, there are several things we need to do. We need to increment the version number, create the package, and finally upload it to our package repo. We teach the students how to build an automated script for these so we don’t have to manually run the commands each time. The package and deployment script will act as living documentation of the process we need to do each time the package is updated, so future maintainers of your project don’t need to start from scratch. We use a Python module called bumpversion to accomplish automatic updating of version information.

Finally

After walking through the above creation and deployment of a Debian package, setting up the reprepro repository, and installing the hi package on LAMPi, the students’ assignment for Week 12 was to demonstrate their understanding by applying the tools on the LAMPi code. The assignment required them to package the LAMPi UI application, the Bluetooth service, and the lamp hardware service into a package, including maintainer scripts to run before the package is installed (preinst), after installation (postinst), when removing the package, etc. and demonstrate versioning of the package in class.

Next Week –  IoT platforms

IoT Course Week 11: Load Testing

Screen Shot 2015-10-15 at 3.07.21 PM

Last week, we dove into into the importance of incorporating and collecting analytics through your connected device, how that information helps provide business value, and played with some of the ways that information can be displayed using some pretty graphs.

This Week

This week, we’ll continue our focus on non-functional requirements and start load testing. With connected devices, if the device can’t call home to its shared services, it loses a lot of its value as a smart device. These services need to be highly reliable, but things get interesting when thousands or millions of devices decide to call home at the same time.

To load test, we’ll generate concurrent usage on system until a limit, bottleneck, unexpected behavior, or issue is discovered. This usage should model real-life usage as close as possible, so the analytics we put in place last week will be a valuable resource. In instances where we don’t have data to work with, we can build out user funnels and extrapolate based on anticipated usage. Bad things will happen if we ship thousands of products without any idea how our system will react under the load. This data will also be a useful baseline for capacity planning and system optimization experiments.

The Lampi system has two shared services that we need to put under load. One is the Django web server that handles login, and the other is the MQTT broker that handles sending messages to the lamp.

Load Testing with Locust

To test the web server we use Locust. Locust has become a LeanDog favorite due to its simple design, scalability, extensibility, and scriptability. We’ve used it to generate loads of 200,000 simultaneous users distributed across the US, Singapore, Ireland, and Brazil. These simulated users (locusts) walked through multi-page workflows at varying probabilities, modeling the end-to-end user interaction, complete with locusts dropping out of the user funnel at known decision points.

Locusts are controlled via a locustfile.py. The one below shows a user logging in and going to the home page:

from locust import HttpLocust, TaskSet, task

class UserBehavior(TaskSet):

def on_start(self):
self.login()

def login(self):
response = self.client.get("/accounts/login/?next=/")
csrftoken = response.cookies.get('csrftoken', '')
self.client.post("/accounts/login/?next=/", {"csrfmiddlewaretoken": csrftoken, "username": {{USERNAME}}, "password": {{PASSWORD}} })

@task(1)
def load_page(self):
self.client.get("/")

class WebsiteUser(HttpLocust):
task_set = UserBehavior
min_wait = 5000
max_wait = 9000

In order to run locust, we’ll need a machine outside of the system to simulate a number of devices. Locust is a python package, so it can run on most OSes. It uses a master/slave architecture so you can distribute the simulated users and allow for more and more load.

Once you install locust and start the process, you control the test via a web interface.

Screen Shot 2016-05-04 at 12.09.46 PM

Locust will aggregate the requests to a particular endpoint and provide statistics and errors for those requests.  

Screen Shot 2016-05-04 at 12.09.55 PM

Screen Shot 2016-05-04 at 12.10.03 PM

Load Testing with Malaria

To test MQTT we used a fork of Malaria. Malaria was designed to exercise MQTT brokers. Like locust, Malaria spawns a number of processes to publish MQTT messages. Unlike locust, it’s not easy to script; you have to fork it to do parametric testing or randomize data.

usage: malaria publish [-D DEVICE_ID] [-H HOST] [-p PORT] [-n MSG_COUNT] [-P PROCESSES]

Publish a stream of messages and capture statistics on their timing

optional arguments:
-D DEVICE_ID (Set the device id of the publisher)
-H HOST (MQTT host to connect to (default: localhost))
-p PORT, (Port for remote MQTT host (default: 1883))
-n MSG_COUNT (How many messages to send (default: 10))
-P PROCESSES (How many separate processes to spin up (default: 1))

By modulating MSG_COUNT and PROCESSES you can control the load being sent to the broker.

Running some Example loads
Small load: Using 1 process, send 10 messages, from device id [device_id]

loadtest$ ./malaria publish -H [broker_ip] -n 10 -P 1 -D [device_id]

Produces results similar to this:

Clientid: Aggregate stats (simple avg) for 1 processes
Message success rate: 100.00% (10/10 messages)
Message timing mean 344.51 ms
Message timing stddev 2.18 ms
Message timing min 340.89 ms
Message timing max 347.84 ms
Messages per second 4.99
Total time 14.04 secs

Large load: Using 8 processes, send 10,000 messages each, from device id [device_id]

loadtest$ ./malaria publish -H 192.168.0.42 -n 10000 -P 8 -D [device_id]

Monitoring The Broker

MQTT provides a set of topics that allow you to monitor the broker.

This command will show all the monitoring topics (note that the $ is escaped with a backslash):

cloud$ mosquitto_sub -v -t \$SYS/#

The sub topics ‘…\load...’ are of particular interest.

Gather data

Before we start testing, we should figure out what metrics we want to measure. Resources on the shared system (CPU, memory, bandwidth, file handles) are good candidates for detecting capacity issues. Focusing on the user experience (failure rate, response time, latency) will help you hone in on the issues that will incur support costs or retention problems. Building the infrastructure to gather, analyze and visualize those metrics can be a significant part of the load testing process – but those tools are also necessary to do useful operational support in production. For the class, students used sysstat, locust, mqtt and malaria to gather metrics. A production-like system might use AWS Cloudwatch, New Relic, Nagios, Cacti, Munin, or a combination of other excellent tools.

The point of load testing is to find the limits and then decide what to do about them. There will be a point where the cost to rectify the issue is greater than any immediate benefit, load testing will help you find that bar. During the class, limits of a 1000 simultaneous users for web and 5,000-10,000 MQTT messages per process were common.

Final project

For their final project two students from the class, Matthew Bentley and Andrew Mason, decided to take on some of the problems with mqtt-malaria and extend Locust to publish MQTT messages. Using Locust they were able to scale their load test infrastructure across many machines and put a broker under more stress. In their previous testing with malaria, they found the point where a single device could send no more messages (at a reasonable rate), but they could not scale malaria to determine at what point the broker would not process any additional connected devices’ messages. Through their efforts, they reached 100% CPU on the broker, pushing 1 million messages a minute to 4000 users. As a result of their work they also open sourced their contribution to locust.

IoT Course Week 10: Analytics

IoTBackground

Last week we got our feet wet with an introduction to Bluetooth Low-Energy on iOS. This week, we’ll dive into analytics, provide business value, and make some pretty graphs.

Why Analytics?

When building a new product, there are always a variety of options on the table with which to improve that product. At LeanDog, we practice a software development cycle that includes short sprints coupled with an open and honest feedback loop that provides us with the information we need to make informed decisions about where to focus our efforts and resources. This allows us to make sure that we are building the right thing the first time and minimize the amount of risk inherent in the process.

Until relatively recently, collecting feedback about a product in-use was a long process that required either direct observation or careful reading of written user reviews and complaints. Due to the complex and inconsistent nature of users, collecting strong quantitative data about a product experience can be difficult. In a now infamous incident from 2013, a New York Times journalist wrote a negative review of the Tesla Model S, only to have the car’s onboard analytics refute many of his claims. It is not uncommon for a customer to report one thing, but end up doing something entirely different, and your user experience process will need to account for these inconsistencies. One of the many ways we solve that problem is through the use of analytics platforms and reporting tools.

In addition to uncovering potential pitfalls, analytics are a powerful way for product owners, designers, and developers to understand how a product is actually used. For companies that make physical devices, this provides insights that are difficult to collect otherwise. Imagine receiving a coupon in the mail for a smart GE light bulb you love that’s nearing the end of it’s lifetime. The only way GE could possibly anticipate that your current bulb is about to go out (without calling you every day to ask how often you turned it on in the last 24 hours) is through analytics. With analytics, you get an avenue outside of sales to start to figure out which features and products your users actually love, which have problems or aren’t worth further development, and even identify disengaged users for retention campaigns.

Enter Keen IO
For this class, we will use a popular analytics platform called Keen.io. Keen is a general purpose tool, not locked into web, mobile, or embedded specifics. It has a large number of supported software development kits (SDK’s), including Ruby, iOS, Python, .NET, etc. It also offers a powerful free tier, which is perfect for the amount of traffic currently being driven on student’s LAMPi systems. Registering and sending a notification in Python is as simple as as this:

from keen.client import KeenClient

client = KeenClient(
project_id="xxxx",
write_key="yyyy",
)

client.add_event("sign_ups", {
"username": "lloyd",
"referred_by": "harry"
})

This will send an event containing the signup data to Keen’s database. Now back at LAMPi headquarters we can track those signups on a giant web dashboard:

var series = new Keen.Query(“count”, {
eventCollection: “sign_ups”,
timeframe: “previous_7_days”,
interval: “daily”
});

client.draw(series, document.getElementById(“signups”), {
chartType: “linechart”,
label: “Sign Ups”,
Title: “Sign Ups By Day”
});

image01

Keen also provides a number of ways to pull out the analytics data and do additional processing to get exactly the view we wanted. Like if we wanted to build a tree of who our top referrers are what their “network” looks like:

image00

What’s next?
Analytics can also provide a leading indicator to help model the number of users that will be pounding on your infrastructure. To learn more about how to address that issue, join us next week when we talk about load testing!

IoT Course Week 9: Introduction to Bluetooth Low Energy

 

Internet of Things Course

To continue our goal of providing industry experience to the students of EECS397 Connected Devices, this week we will be diving deep into Bluetooth LE on iOS.

Recap

Last week students completed setting up a UI on iOS and Android that mirrored the interactions present on the LAMPi display and the web. The goal for this week is to connect those pieces

CoreBluetooth and Bluetooth 4.0

With the release of iOS 5 and the iPhone 4S, Bluetooth LE was positioned and continues to be one of the most common methods of short range data communication.  CoreBluetooth is the framework that Apple provides to developers to interact with Bluetooth LE hardware and peripherals. This is useful, as the current Bluetooth LE spec weighs in at over 2000 pages in PDF form.

Communication with LAMPi through CoreBluetooth can be broken into a four step process:

  1. Scanning for LAMPi device (from provided array of service id’s)
  2. Connect to discovered service (lamp-service)
  3. Probe characteristics (hsv, brightness, on/off).
  4. Subscription notifies when something changes. notify on property write.

Scanning for LAMPi

Students began the class by making an update to their LAMPi’s. Each team was given a BlueGiga BLED112 to plug into their Raspberry Pis, as well as updated Python services which allow the LAMPi to act as a Generic Attribute Profile (GATT) server. What the GATT server does is broadcast a number of available services to any BLE devices nearby that care to listen. In the case of the LAMPi, there is only one service being exposed, which is aptly called the Lampi Service.

Screen Shot 2016-04-12 at 11.18.43 AM

The service being advertised from the LAMPi includes a device id, which students use to identify their unique LAMPi in a classroom containing many more. Once discovered, it is time to connect.


- (void)startScanningIfEnabled {

if(self.shouldConnect) {

[self.delegate onLoading:@"Searching for sensor..."];

NSArray *services = @[[CBUUID UUIDWithString:LAMPI_SERVICE_UUID]];

[self.bluetoothManager scanForPeripheralsWithServices:services options:nil];

}

}

Connecting to a Peripheral

Screen Shot 2016-04-12 at 11.20.51 AM

CoreBluetooth abstracts away much of the detail required in making a connection to a BLE peripheral. When a peripheral is discovered, our code will immediately attempt to connect. If that connection is successful, we search through the set of services that exist on the peripheral, looking for one that is recognized.

“`

– (void)centralManager:(CBCentralManager *)central

didDiscoverPeripheral:(CBPeripheral *)lampPeripheral

    advertisementData:(NSDictionary *)advertisementData

                 RSSI:(NSNumber *)RSSI {

       …

       [self.bluetoothManager connectPeripheral:self.lampPeripheral options:nil];

}

 

– (void)centralManager:(CBCentralManager *)central

 didConnectPeripheral:(CBPeripheral *)lampPeripheral {

   NSLog(@”Peripheral connected”);

   [self.delegate onLoading:@”Found lamp! Reading…”];

   lampPeripheral.delegate = self;

   …

       // Search for a known service

       for (CBService *service in lampPeripheral.services) {

           if([service.UUID isEqual:[CBUUID UUIDWithString:LAMPI_SERVICE_UUID]]) {

               self.lampService = service;

           }

}

“`

Services and Characteristics

At this point, we are connected to a Lamp Service, which is now providing us with a collection of characteristics. Characteristics are how communication in BLE works. To make a comparison to software, Services can be thought of as Classes while Characteristics are more like the properties on an Object. Characteristics support four different actions: read, write, notify and indicate. While read and write are arguably fairly straightforward, notify and indicate both have to do with a subscription flow that we will use heavily in the iOS application.

Screen Shot 2016-04-12 at 11.23.20 AM

Subscribing to Characteristics

Because LAMPi has both on device and cloud controls, we want to be able to track the state of the LAMPi in real time while the iOS app is running. If a user were to change the color of LAMPi by using the Raspberry Pi UI, the Bluetooth service would send a notification to iOS that the HSV characteristic had been changed.  The following block of code is an example of a discovered Characteristic being initialized. It reads the current hue and saturation of the HSV Characteristic, and then tells the app to subscribe to the Notify value (the notification) of the lamp peripheral.

“`

           [self.lampPeripheral readValueForCharacteristic:self.hsvCharacteristic];

           if(self.hsvCharacteristic.value != nil) {

               float fHue = [self parseHue:self.hsvCharacteristic.value];

               float fSat = [self parseSaturation:self.hsvCharacteristic.value];

               [self.delegate onUpdatedHue:fHue andSaturation:fSat];

           }

           

           [self.lampPeripheral setNotifyValue:YES forCharacteristic:self.hsvCharacteristic];

“`

At this point, when the LAMPi HSV Characteristic changes, CoreBluetooth will call a delegate method that is triggered from the setNotifyValue line.

“`

– (void)peripheral:(CBPeripheral *)peripheral

didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic

            error:(NSError *)error ;

“`

It is in this block of code that the HSV value is updated in the app, and logic to refresh the UI is executed.

Fun Fact: Origins of Bluetooth Name

As a bonus for making it this far, did you know that the origin of the word “Bluetooth” comes from a c. 970 King of Denmark, called Harald Bluetooth? In fact, the Bluetooth logo is comprised of the Nordic runes for H(8px-Runic_letter_ior.svg) and B (12px-Runic_letter_berkanan.svg), Harald’s initials. 

IoT Course Week 8: Intro to Mobile Development

Internet of Things Course

For a change of pace, we are taking a step back from the cloud -> server model we have been working so diligently on, and instead turn our eyes towards mobile. As more and more people around the world enter the global smartphone market, the Internet of Things space is becoming increasingly reliant on smartphone interfaces to control connected devices. This is because the components native to the smartphones that many of us carry, are simple and effective media of interaction with the connected world around us.

The Mission

The goals of week 8 are to provide an introductory course on modern mobile development, in both native iOS with Objective-C and native Android in Java. This week will set up a user interface to control the LAMPi, which next week, will be extended to operate over Bluetooth.

iOS

While the students were almost equally divided on Android/iOS, most of the students utilized Mac laptops, so we made the pairs heterogeneous as each pair had to build the app for both platforms.  This is necessary due to restrictions that Apple places on its developers, where software meant to run on the iOS platform must be developed on a machine running some recent version of OSX. Students were led through the creation of a project in Xcode, and some initial configuration that Apple requires developers to follow in order to sign and run their code. Students used Xcode to create a single view project, and they got to work.

Working in Interface Builder and a UIViewController, students were guided through adding and connecting a UISlider and UILabel to an IBOutlet.

“`

#import <UIKit/UIKit.h>

@interface LampiViewController : UIViewController

@property (nonatomic, strong) IBOutlet UISlider *slider;

@property (nonatomic, strong) IBOutlet UILabel *label;

-(void)onSliderChanged:(UISlider*)sender;

@end

“`

“`

#import “LampiViewController.h”

@interface LampiViewController ()

@end

@implementation LampiViewController

– (void)viewDidLoad {

   [super viewDidLoad];

   NSLog(@”slider: %@ \n label: %@”, self.slider, self.label);

}

-(void)onSliderChanged:(UISlider*)sender {

   NSLog(@”slider changed”);

}

@end

“`

A this point, a slider appeared on the screen that could be interacted with to update the label.  However a problem existed when the screen was rotated on its side.

Screen Shot 2016-04-05 at 9.36.44 AM

As can be seen, the slider and logo fail to expand out when the screen changes. This can quickly be remedied by utilizing one of the much loved nuances of Xcode’s Interface Builder, which is defining constraints on the views.pin_image

And once applied, everything came together. As can be seen here, the iOS Simulator is capable of fluid rotation from portrait to landscape, without any upsetting of the slider position.

with_constraints

Android

Android development, unlike iOS development, is capable of running on a much larger swath of machines. Since its introduction, Google’s Android has been open sourced and designed to run on the Java Virtual Machine (JVM).

Students began by downloading Android Studio and the latest Android SDK Tools. Using the Android Studio Interface, students created a new Android Studio project, allowing the template to be generated for a blank activity. Android Studio wants to get developers started quickly. They offer some shims that help this process. Because our project will be full of custom layouts and widgets, choosing a blank activity is the ideal scenario. After all was said and done, students were left with an application containing one activity.shim_project

Students were given a custom UI Widget in order to define a consistent slider for the class to use. The slider was added to the created activity layout in the XML here:

“`

<?xml version=”1.0″ encoding=”utf-8″?>

<RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android”

   xmlns:tools=”http://schemas.android.com/tools”

   android:layout_width=”match_parent”

   android:layout_height=”match_parent”

   android:paddingTop=”@dimen/activity_vertical_margin”

   tools:context=”.Lampi”>

 

   <View

       android:id=”@+id/bar”

       android:layout_width=”match_parent”

       android:layout_height=”10dp”

       android:layout_alignParentLeft=”true”

       android:layout_alignParentTop=”true” />

 

   <com.leandog.widgets.hsv.sliders.HueSliderView

       android:id=”@+id/hue_slider”

       android:layout_width=”match_parent”

       android:layout_height=”wrap_content”

       android:layout_alignParentLeft=”true”

       android:layout_alignParentTop=”true” />

</RelativeLayout>

“`

and when rendered by the running application it looked like this:

hue_slider_example

An event listener is added to the HueSlider, which tells a changeColor to run whenever the slider is interacted with.  It also allows the slider to initialize to a certain position or color, which will be useful when starting and restarting the LAMPi appication.

“`

package com.leandog.lampi;

 

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

 

import com.leandog.widgets.hsv.sliders.HueSliderView;

import com.leandog.widgets.hsv.sliders.OnSliderEventListener;

 

public class Lampi extends AppCompatActivity {

 

   HueSliderView hueSliderView;

   View bar;

 

   @Override

   protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.activity_lampi);

       bar = findViewById(R.id.bar);

       setupHueSlider();

   }

 

   private void changeColor(int color) {

       bar.setBackgroundColor(color);

   }

 

   private void setupHueSlider() {

       hueSliderView = (HueSliderView) findViewById(R.id.hue_slider);

 

       hueSliderView.setOnSliderEventListener(new OnSliderEventListener() {

           @Override

           public void onChange(int color) {

               changeColor(color);

           }

 

           @Override

           public void onSliderInitialized() {

               changeColor(hueSliderView.getHue());

           }

       });

   }

}

“`

Where we end up

The homework for this week was to follow the patterns of user interface and code interaction just demonstrated, and build a fully operational user interface for both iOS and Android. These user interfaces will essentially mirror that which we have already built on both the LAMPi screen, and the web interface.

iOS Simulator screen capture:

ios_assignment

Android Emulator screen capture:

android_assignment

What is next!

Next week we will add the bluetooth functionality that connects our devices directly to the bluetooth hardware running on the Raspberry Pi controlled LAMPi.  For the sake of brevity and focus, from this point onward, mobile development will be done primarily on the iOS platform.

IoT Course Week 4 : Introduction to the Cloud

IoTBackground

It is week four of the IoT course and students of Case Western Reserve University have successfully built their very own touch-screen controlled LAMPi’s. This week students will take a major step towards greater functionality and control.

Demoing Previous Week’s Work

Students began the week by demoing their assignment from the previous week – building a  Python service to act as an abstraction layer between the LAMPi hardware and the various user interfaces. You can check out the post for the week here: Week 3

Learning IoT the hard way – Why we are not using an IoT platform

This week’s lecture started with a brief introduction to available commercial IoT platforms. For this course, students will forego working with a commercial IoT platform, and delve directly into Amazon Web Services. By having the students build their own platform on top of AWS, they will gain a greater understanding of the various components involved, which will allow them to make informed decisions when dealing with commercial IoT platforms in a professional capacity.

To the cloud – Amazon EC2

The cloud! Yes, that cloud. Those nebulous servers in the sky. Students will be maintaining their cloud connectivity using AWS Elastic Compute Clusters, or EC2.  At the beginning of week 4, the services running on LAMPi were locally controlled through a MQTT broker called Mosquitto. The goal for this week is to bridge the MQTT broker running on the Raspberry Pi, to another MQTT broker running on EC2. Luckily for our students, with a little configuration, Mosquitto offers this functionality.

Students began by setting up free tier EC2 instances running Ubuntu. After configuring AWS security groups for their instances, they installed the Mosquitto command line utilities mosquitto_pub and mosquitto_sub.

Bridging between Mosquitto brokers is done through editing configuration files on both the host and the remote. When bridging, the user can configure what topics are transmitted in which direction — for instance, we can specify that only lamp state updates go out to the cloud, and only configuration changes are received from the cloud. Any topics not configured do not get to cross the bridge and will remain on the system they originated. The configuration to the remote follows the structure here:

connection <bridge_name>
address <IP>:<port>
topic <pattern> <direction> <qos> <local-prefix> <remote-prefix>
remote_clientid <remote_clientid>
cleansession <true or false> (defaults to false)

Following this pattern will open the bridge between the MQTT brokers. From that point, depending on the configuration of “In” and “Out” directions, messages will be passed from the appropriate publisher to its subscribers.  It is worthwhile to note that, although the broker is now up and running on EC2, there is not yet any functionality beyond simply passing messages. This will be the topic of the next lesson. Part of the reason for this is that configuration of Mosquitto can be complex and that complexity is compounded by the configuration of the whole system — security, supervisord, pigpiod, etc. By doing this in steps, we can test our system at each step of the way. For now, a few more steps are required to ensure our path from the Raspberry Pi and EC2 instance remain unbroken.

Unexpected Events – Last Will and Testament

The MQTT specification defines a mechanism called a Will. In the event that a client disconnects unexpectedly the MQTT server will publish the Will message. The students will use this mechanism to announce the connection state of the lamp. In Python, the code looks like this:

       client = mqtt.Client(client_id=CLIENT_ID, protocol=MQTT_VERSION)
       client.will_set(get_client_status_topic(CLIENT_ID),
                       “0”, qos=1, retain=True)

Service management – Supervisor

The students were introduced to a Linux service called Supervisor which is responsible for ensuring that all of the processes that we care about stay running. If the LAMPi is unplugged, or the cloud service restarts for some reason, a proper Supervisor setup will ensure that all systems are restarted and running. These concepts were applied to the LAMPi’s by creating a Supervisor D configuration file that will keep the lamp service and the UI running.

What is up next?

Next week, the students will be introduced to web interfaces and the servers that host them. They will be utilizing HTML, CSS, Javascript, Websockets, and NGINX to create a web interface to LAMPi. This will build upon the the work they accomplished this week by hosting the web server on their EC2 instance.

Professional Development Hack Days at LeanDog

There are a number of fields in which ongoing professional development is not simply a job requirement, it’s the only way to stay relevant in an industry that is perpetually evolving. The highly technical world of software development is no exception. Coders, designers, and engineers of all programming languages must continually update their skill sets just to keep pace in a field where technology evolves seemingly overnight and market trends are constantly shifting underfoot.

As essential as this constant professional improvement is for the individual developer, it is absolutely critical to the survival of a software studio. Design and delivery studios depend on competent, creative, T-shaped craftsmen to drive innovation and produce cutting-edge products. However, in busy shops like LeanDog, where developers are routinely tackling complex scenarios, it can be a challenge to find time to pick up a new skill or enhance an existing one.

So how do you help your development team diversify their skill sets when client demands dominate the majority of their time? One way is for leadership to actively create opportunities to learn something new in an environment free of the pressure to “get it done.”

So that’s what we did! Last Friday, the LeanDog Studio took a break from their many projects and joined forces to try something new: a Professional Development Hack Day.  This session had three overarching goals:

1) Learn something

2) Share Something

3) Have fun

Prior to Hack Day, the Studio came together and pitched nine project ideas. They then took a vote and ended up choosing four to pair on:

  • Unity as a rapid-prototyping tool
  • Indoor navigation with iBeacons
  • Deployment pipeline with Docker
  • Conference outline – UX Survival in Agile

After the monthly company meeting, studio members teamed up with co-workers they are not normally pairing with and spent the next four hours “nerding out” (a highly technical industry term) on their respective projects, the summaries of which are listed below. At the end of the day they regrouped for a Show and Tell and voted on which project took “Best in Show”.  Everyone had a blast and learned some pretty cool stuff in the compressed (but relaxed) format.

The Projects:

Unity as a Rapid-Protoyping Tool

Will Kesling pitched this idea to look for alternatives for prototyping game mechanics and solutions.  Our current tool for this is Gamesalad, which makes it easy to build quick prototypes, but limits our ability to modify the generated code for our purposes.  The goal of this session was to attempt to build a mini-game that would better suit our current prototypes.  Will Kesling, Bill Holmes, and Eric Hankinson teamed up and found that Unity was a very cool and powerful tool.  They built an interactive 3D world with converted 2D objects.  It was great to be able to write C# to handle some mechanics.  However, Unity is not well-suited for rapid prototyping.  The team suggested looking more into 3D Unity as a production-level framework and perhaps trying again with 2D Unity to see if it’s a better fit.  The team recommended starting with the asset store when you start a new Unity project. 

Indoor Navigation with iBeacons

Gary Johnson pitched the idea of mapping the boat (our office) and using locators on people and items.  Besides being cool, exploring this technology would help us understand installation type projects, like museums and trade shows.  Mike Kvintus, Nick Barendt, Paolo Appley, and Carl Shotwell ended up teaming up to map the boat using the estimote beacons we had on hand.  The team deployed the beacons, mapped the area, and started a swift app to display locations.  They found the estimote service and SDK to be difficult to use.  The software was buggy, slow and inconsistent.  Additionally you need at least 4 estimotes to map a room and they come in packs of 3.  The estimote mapping software was not a big fan of the irregular shape of the boat.  The team suggested getting more beacons to see if a larger area could be mapped and investigating alternative iBeacon technologies.

UX Survival in Agile

Nicole Capuana pitched working on a conference talk for Codemash that would describe how UX best fits into Agile Software Development.  The ultimate goal is to create a talk that would be reusable with multiple perspectives.  Steve Jackson and Charlotte Chang joined Nicole on brainstorming and talking through ideas that would make this a useful guide for UX practitioners in multiple uncomfortable situations.  The team also worked on a talk Charlotte is preparing on Software Development Lessons Learned from Industrial Failures in the 1980s.  The session was very productive and the team recommends that all speakers try to get differing perspectives for that post-abstract phase.  This collaboration helped raise the bar on what a really excellent audience experience could be.

Deployment Pipeline with Docker – “Best in Show”

Nathan Wallace suggested building multiple environments with Docker and testing each one with our continuous integration server.  If successful, this would apply to many of our current projects, allowing us to easily build and deploy new fully tested environments for all of our integration points (along with our tested code).  It also has the potential to reduce our need to configure and setup environments for our CI itself.  Nathan and Chris Nurre teamed up and were successful in building a Docker image for a vanilla rails install. With each pushed commit, a new environment was produced.  The team found that installing Docker on our heavily mac-based infrastructure was difficult, but was otherwise happy with the tool.  Their recommendation was that all of our web-based projects should default to using a Docker file for CI and that it would be useful to further investigate the Jenkins-Docker integration, as well as deploying the images using a Docker registry.

By taking a small break from “getting it done” and creating an environment focused solely on learning something new, we were able to provide everyone an opportunity to relax, expand their horizons, and bond with their co-workers. Overall, LeanDog’s first Professional Development Hack Day was a rousing success and the team is looking forward to coming together next month to do it again.

tumblr_inline_nx7cuomCMg1tc23o0_540

tumblr_inline_nx7cuoxAdW1tc23o0_540

Building a Raspberry Pi Controlled Desk Lamp with LeanDog and CWRU

As mentioned in a previous post, Nick Barendt and the LeanDog Studio have teamed up to offer a Connected Devices Workshop for Case Western Reserve University (CWRU) students in response to a trend of increasing interconnectivity in product design known as the Internet of Things (IoT). In this course, students are gaining practical experience building a proof of concept system: a physical device, web integration, and mobile development.

The goal of the course is to familiarize students with each component in a complicated system, providing them with a systems level understanding of all the technologies and disciplines that go into creating a connected device

Follow along with us as our students create their very own web-controlled desk lamps, which we’ve dubbed “LAMPI” [lamp-ee]. By the final week of the course, students will possess enough experience to build their own prototype for a new product or service, or confidently dive deeper into any of the software components for further study.

The class is comprised of mostly Juniors and Seniors in Electrical Engineering, Computer Engineering, and Computer Science.  That means that there is a broad range of electronics and software development experience in the class, at skill levels ranging from beginner to advanced.  To address the variety in skill sets and levels, students are working in pairs on the lab assignments, switching up pairs each week. This method of “pairing” is widely used in the world of professional software design and a is a key practice in the LeanDog Studio. We will dive a bit deeper into the benefits of pairing in a later post.

Now, without further ado…

Screen Shot 2015-10-15 at 3.08.16 PM

Building a Raspberry Pi Controlled Desk Lamp

CWRU’s IOT course kicked off by getting students familiarized with:

  • Burning an SD card image with Raspbian (a variant of Debian Linux)
  • Booting up a Rasberry Pi (a tiny and affordable computer, with a rich community of hardware and software support)
  • Connecting to a serial console (UART)
  • The basics of Pulse-Width Modulation (PWM)

On the first day of the course, students cracked open their shiny new Raspberry Pi’s, added WiFi adaptors, SD cards, a custom interface circuit board, and serial cables; attached them to the lamp base, added power cords and an LED ribbon cable, and connected the devices to their computer with a serial (UART) USB cable.  While UARTs are “old school” (RS-232 anyone :-), they are still common on embedded devices, and are often your last ditch, never fail, connection option.

Screen Shot 2015-10-15 at 3.10.43 PM

Students connected their LAMPIs to the CWRU Campus Network, and learned how to remotely connect to a Linux shell on the Raspberry Pi with SSH, a basic tool for modern, distributed software development.  

The class was then tasked with installing the pigpio library, for interacting with the General Purpose Input/Output (GPIO) digital pins on the Raspberry Pi.  Three of the GPIO lines are connected to a custom interface board that has three high-power drivers to control a 3W Red Green Blue (RGB) LED.

Screen Shot 2015-10-15 at 3.13.21 PM

Turning a GPIO line on enables the driver circuit for that LED color channel, lighting up that LED color.  By using Pulse-Width Modulation (PWM) support within the pigpio library, the intensity of the LED can be varied from completely off to full brightness by changing the duty cycle of the PWM command.  By varying the intensity of three LEDs, the RGB color (or, equivalently, the Hue and Saturation) can be varied.

By the end of the first week, students were able to write a simple Python program to generate light by cycling through the primary colors (Red, Green, and Blue) and White.

FINAL THOUGHTSScreen Shot 2015-10-15 at 3.21.33 PM

Why a Raspberry Pi?  Honestly, it is overkill for a desk lamp.  We’re actually using a Raspberry Pi 2B, which is 900MHz Quad-core ARM Cortex-A7 processor with 1GB of RAM.  That’s a crazy amount of computing power for a desk lamp.  But, it does allow us a few simplifications for the course.  Typically, embedded devices, like a “smart” desk lamp, are develo   ped using the C programming language.  Teaching the students C would take a few weeks, plus the additional complexity of working in a cross-compiled environment (i.e., writing the software on their Intel based computer to run on an embedded ARM processor).  We decided to trade that time off to expose the students to other important topics in the Connected Device space and use a high-level language, Python.

Why Python?  Python is fast to learn, runs in lots of different environments (embedded, cloud, etc.), and has a huge community of open source development projects.  While interpreted, Python is relatively efficient, and has solid support for integrating with low-level libraries (i.e., those written in C) for hardware interaction.  An additional bonus is that later in the course, when we move to the “cloud” and web development, some of the Python experience can be transferrable.

Why a desk lamp?  It is unclear if the world really needs a web and smartphone controlled desk lamp.  What we need for the course is a device to motivate the exploration of the IoT / Connected Device ecosystem (embedded, UI/UX, Cloud, Bluetooth Low Energy, mobile, etc.), and even a simple desk lamp provides enough complexity to make that exploration interesting.  Light is also a primal and fundamental aspect of our lives. After all, it was our mastery of light and tools that arguably began man’s journey towards technological advancement. Therefore it is fitting that as we begin to explore this new evolution of product design that we bring our modern light and tools together again to help “light the way,” even if our guiding example takes the form of a humble desk lamp.

Stay tuned for more as the course progresses and we drill down into the many interesting and challenging concepts that make up the Internet of Things.

Coming soon: The creative design process behind the LAMPI’s unique shape.