Office temperature monitoring

Posted on
  • I bought Puck.js basically to make sure none in our office changes the aircon settings.

    The below app

    • Blinks the Red LED when the temperature gets 25º. Blinks Blue LED when it's 22º or lower.
    • If you click the Puck the temperature monitoring will switch Off/On. If it blinks green on clicking - you turned the monitoring On.
    • To save some battery the temperature monitoring will turn Off automatically according to the schedule (time of the day and day of the week).

    The app memory and CPU usage are optimized up to my knowledge of JS engines.

    Below is the source code of the v1. The latest source code is hosted here.

    Suggestions are very welcome.

    // Change these as needed
    var VAR = {
      temperatureCheckInterval: 10000,
      thermometerOffset: 2, // accuracy offset
      temperatureRange: {
        low: 22,
        high: 25
      },
      schedule: {
        timeOfTheDay: { start: 6 *60*60*1000, end: 21 *60*60*1000 },
        dayOfWeek: { start: 1, end: 5 } // inclusive
      },
      blinkingInterval: 1000
    };
    
    // Colour utilities
    var colors = { RED: LED1, GREEN: LED2, BLUE: LED3 };
    function turnLedsOff() {
      colors.RED.reset();
      colors.GREEN.reset();
      colors.BLUE.reset();
    }
    
    // Will blink once immediatelly
    function blink(delay, LED) {
      LED = LED || colors.GREEN;
      LED.set();
      setTimeout(turnLedsOff, delay);
    }
    
    // Blinking logic: startBlinking, stopBlinking
    var intervalId, isBlinking = false;
    function stopBlinking(LED) {
      if (!isBlinking) return;
    
      isBlinking = false;
      clearInterval(intervalId);
      turnLedsOff();
    }
    function startBlinking(LED, interval) {
      LED = LED || colors.RED;
      if (isBlinking === LED) return;
    
      stopBlinking();
    
      isBlinking = LED;
      interval = interval || VAR.blinkingInterval;
      intervalId = setInterval(intervalCallback, interval);
    }
    function intervalCallback() {
      blink(100, isBlinking);
    }
    
    // Temperture checking logic: startMonitoring, stopMonitoring
    function checkTemperature() {
      var temperature = E.getTemperature() + VAR.thermometerOffset;
    
      if (temperature <= VAR.temperatureRange.low) startBlinking(colors.BLUE);
      else if (temperature >= VAR.temperatureRange.high) startBlinking(colors.RED);
      else stopBlinking();
    }
    var monitoringId, isMonitoring;
    function startMonitoring() {
      blink(100);
      if (isMonitoring) return;
      isMonitoring = true;
      monitoringId = setInterval(checkTemperature, VAR.temperatureCheckInterval);
      checkTemperature();
    }
    function stopMonitoring() {
      if (!isMonitoring) return;
      clearInterval(monitoringId);
      stopBlinking();
      isMonitoring = false;
      setDeepSleep(true);
    }
    
    // schedule logic: resetScheduler
    function getTimeOfTheDay() {
      var now = new Date();
      return (
        (
          (
            now.getHours()
          )*60 + now.getMinutes()
        )*60 + now.getSeconds()
      )*1000 + now.getMilliseconds();
    }
    var totalMsecInADay = 24*60*60*1000;
    var schedule = VAR.schedule;
    function resetScheduler() {
      var msecOfTheDay = getTimeOfTheDay();
      if (msecOfTheDay >= schedule.timeOfTheDay.start && msecOfTheDay < schedule.timeOfTheDay.end) {
        setTimeout(
          resetScheduler,
          schedule.timeOfTheDay.end - msecOfTheDay
        );
        var dayOfWeek = new Date().getDay(); // respect week day schedule
        if (dayOfWeek >= schedule.dayOfWeek.start && dayOfWeek <= schedule.dayOfWeek.end) {
          startMonitoring();
        }
      } else {
        setTimeout(
          resetScheduler,
          (schedule.timeOfTheDay.start - msecOfTheDay + totalMsecInADay) % totalMsecInADay
        );
        stopMonitoring();
      }
    }
    
    turnLedsOff(); // can be On from other applications/commands
    resetScheduler(); // start the monitoring and schedule a next event
    
    setWatch(function() { // setup button clicking
      if (isMonitoring) stopMonitoring();
      else startMonitoring();
    }, BTN, {edge:"rising", debounce:50, repeat:true});
    
  • That looks great - thanks for posting it up!

  • Great! Thank your for sharing.

    Have you considered using digitalPulse? digitalPulse(LED2, 1, 100); Flashes the LED once, for 100 ms.

  • Wow. Haven't found it. Thanks. Will try it.

  • Very interesting, this was the first example I tried with to get started after the 'Hello world..'. Does the Puck know the date and time, or do you need to set it somehow?

  • The Puck has its own RTC, and it's "synced" everytime you upload something from your pc.
    You can use if for example as an alarm clock (do something at given date/time), that's great!

  • The Puck has its own RTC, and it's "synced" everytime you upload something from your pc.

    Yes it does, but not by default. One would need to turn the option On in the web IDE settings.

    For some reason it set Puck time to 0:22 am, whereas it's 11:22 am in my time zone currently.
    Thus, I would not recommend to sync puck time with your browser time because Espruino has no knowledge about time zones. The missing time zone complicates development.

    My puck came to me with the time set close to Unix epoch ~ Jan 1970.

    For simplicity the code above assumes the Puck time zone is set to the local time (i.e. the local timezone is +00 hours). I did it with the setTime function. Here is how to get a value for the setTime using node.js or a browser REPL: (Date.now() / 1000) + tzHours*60*60.

    However, if you don't need the schedule feature, which relies on time, just remove lines 78-112.

  • Yes, my "dirty workaround" was to add +1 hour in the code, more or less like you suggest, while creating the Date object.
    Didn't think about using setTime to make it "permanent".

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Office temperature monitoring

Posted by Avatar for koresar @koresar

Actions