A story of lending a hand, exploring technology, and scope creep.
Presented by
Zackary Lowery
on January 24th, 2019 at
Leading EDJE
and on April 26th, 2019 at
StirTrek.
Available online at https://presentations.xcjs.com/
Press your space bar or swipe to navigate down and then forward. ยป
What follows may not be definitive of best practices for IoT development.
It was a lot of fun, though.
Hey man, I owe my cousin a favor and need some help.
What's the favor?
So, my cousin owns this cricket farm in Montana...
Cricket? Like the insect?
Yeah! Can you upload temperature data to AWS from a Raspberry Pi?
Probably? I'll see what I can do.
Thanks! Let me know what I owe you.
Oh, I will.
DHT-22 Temperature / Humidity Sensor | MQ2 Gas Sensor | AWS SDK |
---|---|---|
![]() |
![]() |
|
|
|
...and more. |
![]() |
DHT-22 Sensor |
Native |
![]() ![]() |
MQ-2 Sensor/ADS1115 |
Native |
|
AWS SDK |
JavaScript |
R-Pi Zero W
R-Pi 3
x86/x84_64 (somewhat)
napa - A helper for installing stuff without a package.json with npm.
{
...
"scripts": {
"install": "napa",
...
},
...
"napa": {
"bcm2835": "http://www.airspayce.com/mikem/
bcm2835/bcm2835-1.55.tar.gz",
...
}
}
var deferred = new Promise(() => (resolve, reject) {
temperatureSensor.read(22, 22, // sensor model, pin
(err, temperature, humidity) => {
if (!err) {
resolve({
temperature,
humidity
});
} else { reject(err); }
});
});
function read(dhtModel, gpio, callback) {
// ...
var temperature = getRandomInt(15, 60);
var humidity = getRandomInt(0, 100);
// ...
setTimeout(() => {
callback(err, temperature, humidity);
}, 2000); // Simulate maximum 2s readout interval.
}
var deferred = new Promise(() => (resolve, reject) {
gasSensor.readADCSingleEnded
(channel, progGainAmp, sampleRate,
(error, data) => {
if (!error) { resolve(data); }
else { reject(error); }
}
);
});
function readADCSingleEnded(
channel, progGainAmp, sampleRate, callback) {
// ...
var gasLevel = getRandomInt(0, 65000);
callback(null, gasLevel);
// ...
}
var docClient = new aws.DynamoDB.DocumentClient({
apiVersion: '2012-08-10'
});
var deferred = new Promise(() => (resolve, reject) {
docClient.put(params, () => (error, response) {
if (!error) { resolve(response); }
else { reject(error); }
});
});
const choices = [
'Manage WiFi Connection',
'About Elise'
];
const question = {
name: 'main',
message: 'Select an option below using the arrow keys ' +
'on your keyboard and then press Enter: ',
type: 'list',
choices: choices
};
return inquirer.prompt([question]);
var deferred = new Promise(() => (resolve, reject) {
wifiService.scan(() => (err, networks) {
if (!err) {
view.showMainMenu(networks).then
(promptWifiPassword, showMainMenu).then(
connectToWifi, checkIfBack).then(
() => (connectedNetwork) {
resolve(connectedNetwork);
}, () => (err) {
reject(err);
});
} else {
reject(err);
}});});
// ...
"scripts": {
// ...
"build": "npx nexe --build index.js -o bin/elise",
// ...
}
$ npm run build
GitLab is a single application for the entire software development lifecycle. From project planning and source code management to CI/CD, monitoring and security.
Pre-configured pipeline centered around scalable web applictions.
In-repository, per-branch configuration file for custom CI pipelines.
stages:
- Setup
- Analyze
- Test
- Build
- Stage
cache:
untracked: true
key: "$CI_COMMIT_REF_NAME"
paths:
- node_modules/
Setup:
stage: Setup
script:
- npm install
- cd ./node_modules/bcm2835
- ./configure
- make
- sudo make check
- sudo make install
- cd ../../
- npm rebuild
Analysis:
stage: Analyze
script:
- npm run lint
- npm audit
Test:
stage: Test
script:
- npm test
package.json
// ...
"scripts": {
// ...
"test": "npx nyc --reporter=html --reporter=text mocha
--recursive",
// ...
},
// ...
Build:
stage: Build
script:
- npm run build
package.json
// ...
"scripts": {
// ...
"build": "npx nexe --build index.js -o bin/elise",
// ...
},
// ...
Virtual Staging:
stage: Stage
before_script:
- vagrant plugin install vagrant-vbguest
- vagrant box update
script:
- vagrant up
after_script:
- vagrant destroy --force
Return to the rest of the presentations.