Vuzi / raspi-sensors

Deprecated - Nodejs C++ plugin, allowing to easily read data from raspberryPi's sensors.
https://www.npmjs.com/package/raspi-sensors
Apache License 2.0
26 stars 3 forks source link

DHT-22 sensor initiates 2 callbacks #4

Closed rdagger closed 8 years ago

rdagger commented 8 years ago

The DHT-22 sensor initiates 2 callbacks (1 for temperature and 1 for humidity). This makes it difficult to handle the results. Would it be possible for the sensor to fire a single callback and pass an array of sensor data instead of a single object?

rdagger commented 8 years ago

Or is it possible to use promises with fetch method?

FlorianWendelborn commented 8 years ago

I think the current implementation is better, assuming that both callbacks are async in relation to each other.

Vuzi commented 8 years ago

You still could wrap the DHT22 fetch in a promise:

var dht22Promise = new Promise(function(resolve, reject) {

  var temp = null, hum = null;

  DHT22.fetch(function(err, data) {
    if(err) {
      console.error("An error occurred!");
      console.error(err.cause);
      return;
    }

    if(data.type == "Temperature") {
      temp = data;
    } else {
      hum = data;
    }

    if(temp && hum)
      resolve({ temperature : temp, humidity : hum });
  });
});

dht22Promise.then(function(val) {
  console.log(val);
});

(untested code, but you get the idea)

FlorianWendelborn commented 8 years ago

@rdagger I don't know what you're using your DHT22 for, but I personally store temp&hum in a global _state variable and whenever the callback triggers I just update the state.

rdagger commented 8 years ago

Thanks that is very helpful. I was using globals but I needed a more composable solution. Here's what I ended up using:

const dht22Promise = new Promise((resolve, reject)=> {
  let t = null, h = null;

  DHT22.fetch((err, data)=> {
    if(err) {
      reject(err.cause)
    }

    if(data.type === "Temperature") {
      t = data.value.toFixed(1);
    } else {
      h = data.value.toFixed(1);
    }

    if(t !== null && h !== null){
      resolve({ temperature : t, humidity : h });
    }
  });
});
rdagger commented 8 years ago

Sorry one more related question. Is it also possible to use a promise with fetchInterval?

FlorianWendelborn commented 8 years ago

Dont think so, but maybe just use a custom callback?

Vuzi commented 8 years ago

fetchinterval will call the provided callback every x seconds, and I don't think this can be adapted to work with a promise, because you're not "waiting" for one result, but registering a callback for later calls (at the specified interval).

Maybe you should make an event emitter, and register to some events ?

https://nodejs.org/api/events.html

rdagger commented 8 years ago

Thanks, I'll try it.

Any ideas why the code above would not work with Express? The following only works if I comment out the last line:

"use strict"
const RaspiSensors = require('raspi-sensors');
const DHT22 = new RaspiSensors.Sensor({type: "DHT22", pin: 0X7}, "DHT22"); 

const express = require('express');
const app = express();
app.set('port', process.env.PORT || 5000);

const dht22Promise = new Promise((resolve, reject)=> {
  let t = null, h = null;

  DHT22.fetch((err, data)=> {
    if(data.type === "Temperature") {
      t = data.value.toFixed(1);
    } else {
      h = data.value.toFixed(1);
    }

    if(t !== null && h !== null){
        resolve({ temperature : t, humidity : h });
    }
  });
});

dht22Promise.then((data)=> {
    console.log(data);  
});

// Comment out this line to make it work
const server = app.listen(app.get('port'), ()=> { console.log('Listening on port %d', server.address().port); });