Преглед изворни кода

refined logic to read the pin and error

WIP

added exception handling which logs the error as well as returns 500 to the user.
also updated documentation with installation instructions, including downloading and compiling the necessary bcm2835 C library.
master
Blaine Motsinger пре 1 година
родитељ
комит
f4c8e90c53
3 измењених фајлова са 81 додато и 26 уклоњено
  1. 1
    0
      .gitignore
  2. 35
    3
      README.txt
  3. 45
    23
      weather-api.js

+ 1
- 0
.gitignore Прегледај датотеку

@@ -1,3 +1,4 @@
scratch
package-lock.json
node_modules/
*.swp

+ 35
- 3
README.txt Прегледај датотеку

@@ -22,7 +22,7 @@ Supported sensors are the DHT11 or DHT22 (AM2302) read using the bcm2835 C libra

# ENDPOINTS

The API is served over port 3000 and bound to all interfaces, but can be configured to a specific interface or port (more about that in the 'CONFIGURATION' section below).
The API is served over port 3000 and bound to all interfaces, but can be configured to a specific interface or port (see the 'CONFIGURATION' section below).

## /weather

@@ -32,7 +32,7 @@ The API is served over port 3000 and bound to all interfaces, but can be configu

This API is a read-only resource; GET is the only allowed method.

All other methods requested to the API will return exceptions (more about that in the 'RESPONSES' section below).
All other methods requested to the API will return exceptions (see the 'RESPONSES' section below).

### PARAMETERS

@@ -206,6 +206,36 @@ If using the DHT22 (or AM2302).

The GPIO pin the DHT sensor is connected to.

# INSTALLATION

Before installing the module dependencies for this project, the bcm2835 C library will need to be installed.

First, ensure you have build-essential and make installed so you can compile the library.

# apt-get install build-essential make

Download the bcm2835 library to the desired location. My personal location for source code is /usr/local/src/, and is used in the example below. Also, ensure you have the latest version; the link below is for v1.56 which might not be the latest as you're reading this.

# cd /usr/local/src/
/usr/local/src # wget http://www.airspayce.com/mikem/bcm2835/bcm2835-1.56.tar.gz
/usr/local/src # tar zxvf bcm2835-1.56.tar.gz

Now, configure, make, test, and install the library.

/usr/local/src # cd bcm2835-1.56/
/usr/local/src/bcm2835-1.56 # ./configure
/usr/local/src/bcm2835-1.56 # make
/usr/local/src/bcm2835-1.56 # make check
/usr/local/src/bcm2835-1.56 # make install

If you receive the following error when running the api through nodejs:

bcm2835_init: Unable to open /dev/gpiomem: Permission denied

You're probably running the api as an un-privileged user (you should be), which isn't the 'pi' user. You will need to add the user to the gpio group so it can access gpiomem (replace apiuser with the user you're running nodejs as).

# adduser apiuser gpio

# DEPENDENCIES

This project is built using nodejs and utilizes both deconstructing assignment and template literals from ES6. Because of this, the latest (or newer) nodejs is recommended.
@@ -214,7 +244,9 @@ The http library is used but is included through nodejs core. No additional ins

Additionally, the moment and node-dht-sensor libraries are also used. Both are defined in the package.json file within the project's base dir and can be installed via npm.

Of note, the node-dht-sensor library requires the bcm2835 C library installed to the Raspberry Pi before installing through npm, else installation will fail.
server ~/weather-api $ npm install

Of note, the node-dht-sensor library requires the bcm2835 C library installed to the Raspberry Pi before installing through npm, else installation will fail. (see the 'INSTALLATION' section above).

# AUTHOR


+ 45
- 23
weather-api.js Прегледај датотеку

@@ -88,14 +88,32 @@ const server = http.createServer( ( req, res ) => {

// read the sensor data
// using the node-dht-sensor node module, which uses the bcm2835 library.
// still testing this out, and may very well re-roll the functionality to remove the
// additional dependency.
let data = read_pin( config.dht, config.pin );
let data = read_pin( config.dht, config.pin );

// return 500 if there was an issue reading
// undef indicates error from the read_pin function
if ( data === undefined ) {
res.statusCode = 500;

res.setHeader( 'Content-Type', 'text/plain' );

res.write( 'unknown error\n' );
res.end();

log_request(
get_formatted_timestamp(),
connection.remoteAddress,
method,
url,
res.statusCode
);

return;
}

// TODO: convert this to also allow for /weather to return both
let data_return = {};

// TODO:
// convert this to allow for just /weather to return both
// return 500 with error string if read_pin fails
if ( parameter === 'temperature' ) {
data_return = { 'temperature' : data.temperature };
}
@@ -104,7 +122,7 @@ const server = http.createServer( ( req, res ) => {
}

// the request was good
// return to the caller
// return the requsted information to the caller
res.statusCode = 200;
res.setHeader( 'Content-Type', 'application/json' );

@@ -123,6 +141,8 @@ const server = http.createServer( ( req, res ) => {
});

server.listen( config.port, config.hostname, () => {

// TODO: add some output to the log to indicate what environment is being run
console.log( get_formatted_timestamp() + ' [info] ' + 'weather-api server started' );
console.log( get_formatted_timestamp() + ' [info] ' + `serving: ${config.hostname}:${config.port}` );
});
@@ -146,30 +166,32 @@ function log_request ( timestamp, remoteaddress, method, url, statuscode ) {
}

function read_pin ( dht, pin ) {
let temperature = {};
let humidity = {};

// read the sensor if production
if ( config.environment === 'production' ) {

sensor.read( dht, pin, function( err, temperature, humidity ) {
if ( !err ) {
temperature = ( temperature.toFixed( 1 ) * 9 / 5 ) + 32,
humidity = humidity.toFixed( 1 )

// log the exception and return undef to the caller
// the caller tests for undef and returns 500 to the user if so.
if ( err ) {
console.log( get_formatted_timestamp() + ' [error] ' + err );

return;
}

// if there wasn't an error, format and return the data structure
else {
temperature = 'err';
humidity = 'err';
let temperature = ( temperature.toFixed( 1 ) * 9 / 5 ) + 32;
let humidity = humidity.toFixed( 1 );

return { 'temperature' : temperature, 'humidity' : humidity };
}
});
}

// return some dummy data if not production
else {
temperature = 'devel';
humidity = 'devel';
return { 'temperature' : 'devel', 'humidity' : 'devel' };
}

let data = {
temperature : temperature,
humidity : humidity
};

return data;
}

Loading…
Откажи
Сачувај