├── .gitignore ├── package.json ├── CHANGELOG.md ├── Dockerfile.template ├── Dockerfile.aarch64 ├── README.md └── app.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "balena-picamera", 3 | "version": "0.2.0", 4 | "main": "app.js", 5 | "dependencies": { 6 | "raspicam": "~0.2.14", 7 | "serve": "^11.1.0" 8 | }, 9 | "devDependencies": {}, 10 | "scripts": { 11 | "start": "node app.js" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file 4 | automatically by Versionist. DO NOT EDIT THIS FILE MANUALLY! 5 | This project adheres to [Semantic Versioning](http://semver.org/). 6 | 7 | ## 0.2.0 - 2019-10-04 8 | 9 | * Add support for 64-bit Raspberry Pi images, by falling back to 32-bit [Gergely Imreh] 10 | 11 | ## 0.1.0 - 2019-08-10 12 | 13 | * Update base image, serve file simply to be able to see result [Gergely Imreh] 14 | -------------------------------------------------------------------------------- /Dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM balenalib/%%BALENA_MACHINE_NAME%%-node:12-buster-run 2 | 3 | # We need to downgrade the relevant binaries for balenaOS 4 | # versions up to 2.38.0, because of firmware changes 5 | RUN apt-get update \ 6 | && apt-get install libraspberrypi-bin=1.20180328-1~nokernel1 libraspberrypi0=1.20180328-1~nokernel1 --allow-downgrades -y \ 7 | && rm -rf /var/lib/apt/lists/* 8 | 9 | WORKDIR /usr/src/app 10 | 11 | COPY package.json package.json 12 | 13 | RUN npm install --production 14 | 15 | COPY . . 16 | 17 | CMD ["npm", "start"] 18 | -------------------------------------------------------------------------------- /Dockerfile.aarch64: -------------------------------------------------------------------------------- 1 | # For 64-bit device types fall back to the 32-bit application image 2 | # because raspbian doesn't have a 64-bit version 3 | FROM balenalib/raspberrypi3-node:12-buster-run 4 | 5 | # We need to downgrade the relevant binaries for balenaOS 6 | # versions up to 2.38.0, because of firmware changes 7 | RUN apt-get update \ 8 | && apt-get install libraspberrypi-bin=1.20180328-1~nokernel1 libraspberrypi0=1.20180328-1~nokernel1 --allow-downgrades -y \ 9 | && rm -rf /var/lib/apt/lists/* 10 | 11 | WORKDIR /usr/src/app 12 | 13 | COPY package.json package.json 14 | 15 | RUN npm install --production 16 | 17 | COPY . . 18 | 19 | CMD ["npm", "start"] 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # balena + picamera + node.js 2 | 3 | This is a simple app that demonstrates how to get started with the raspberry pi camera module, using node.js and [balena](https://balena.io/). All it does is snap one photo and then stores it in the /data directory on the pi. 4 | 5 | **Before you get started**, you will need to make some changes to the device configuration in the dashboard to enable the camera, instructions here -> http://balena.io/docs/learn/develop/hardware/i2c-and-spi/#raspberry-pi-camera-module 6 | 7 | The /data directory allows the data, in this case the image, to presist between code deployments with balena. It then just sits in an infinite loop, this loop allows you to use the web terminal session to poke around on the pi itself and see that your photo was successfully saved in the /data directory. 8 | 9 | This project depends on raspistill, this is installed the majority of our raspbian/Debian base images for the Raspberry Pi family. 10 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | const RaspiCam = require("raspicam"); 2 | const handler = require('serve-handler'); 3 | const http = require('http'); 4 | 5 | // Set up file server 6 | const server = http.createServer((request, response) => { 7 | return handler(request, response, { 8 | 'public': '/data', 9 | 'renderSingle': 'true' 10 | }); 11 | }) 12 | 13 | server.listen(80, () => { 14 | console.log('Server running on port 80'); 15 | }); 16 | 17 | // Camera related functions 18 | const camera = new RaspiCam({ 19 | mode: "photo", 20 | output: "/data/image.jpg", 21 | encoding: "jpg", 22 | timeout: 100 23 | }); 24 | 25 | camera.on("started", function( err, timestamp ){ 26 | console.log("photo started at " + timestamp ); 27 | }); 28 | 29 | camera.on("read", function( err, timestamp, filename ){ 30 | console.log("photo image captured with filename: " + filename ); 31 | //we can now do stuff with the captured image, which is stored in /data 32 | }); 33 | 34 | camera.on("exit", function( timestamp ){ 35 | console.log("photo child process has exited at " + timestamp ); 36 | console.log("Connect to the 'main' service and visit the /data folder to find the captured image"); 37 | console.log("or connect to the device on port 80 locally / connect over the Public Device URL"); 38 | console.log("To snap another picture, restart the service"); 39 | }); 40 | 41 | camera.start(); 42 | --------------------------------------------------------------------------------