npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

Grow.js

v0.4.7

Published

Easily create new IoT devices and connect them to a Grow-IoT instance.

Readme

Grow.js

Build Status Code Climate Join the chat at https://gitter.im/CommonGarden/Grow.js

Grow.js is an extension of Thing.js with extra utilities for growers.

Installation

npm install Grow.js

Grow.js

Grow.js is an extension of Thing.js, which is an exstension of the node event emitter class. See Thing.js for more information about the Thing api which Grow.js inherits and for connecting to to Grow-IoT. You can also use Grow.js by itself with out connecting to a Grow-IoT instance.

This readme, covers Grow.js specific features like sensor calibration, setting up event listeners for monitoring evnvironment data, scheduling, and parsing 'Growfiles.'

Grow Files

There are three main components to a Grow file:

Targets

Targets create listeners for events from sensors and emit alerts or correction events. min, max, and ideal are currently supported.

const Grow = require('Grow.js');
const example = new Grow();

// Start a Grow by passing in a valid growfile
example.startGrow({
  targets: {
    temperature: {
      min: 17,
      ideal: 22,
      max: 28,
    }
  }
});

// Uses node event emitter api
example.on('alert', (message)=> {
  console.log(message);
});

// If a value falls below a threshhold we emit an alert
example.emit('temperature', 10);
// { temperature: 'low' }

// Likewise if it is above the threshold
example.emit('temperature', 30);
// { temperature: 'high' }

If an ideal is specified for a target a PID controller is created and emits correction events. Continuing from the above example...

    testGrow.on('corrections', (key, correction)=> {
      console.log(key);
      console.log(correction);
    });
    testGrow.emit('temperature', 17);
    // temperature
    // 0.04050000000000009

You can use the correction to control heaters, dosing pumps, and more! For control over the PID controller's parameters you can pass in options under a pid property:

  temperature: {
    min: 17,
    ideal: 22,
    max: 28,
    pid: {
      k_p: 1,
      k_i: 2,
      k_d: 2,
      dt: 10
    }
  },

Calibration

Grow.js contains some utilities for calibrating sensors. The calibrate() method takes an eventname, and calibration data in the form of a list that has in the format [measuredValue, knowValue]. Calibration data can be a list of the lists for example:

let calibration_data = [[10, 11], [20.5, 21], [30, 29]]

example.calibrate('temperature', calibration_data)

// New calibration points can be added like so
example.calibrate('temperature', [25, 24.9])

The predict() method uses available calibration data to run a regression on the known values. It takes an eventname argument and a value.

example.predict('temperature', 31)

If no calibration data is defined for the event it simply returns the value.

Cycles

Cycles are functions that are called at specific times in succession (for example, during the course of a day).

Cycles are also a way of defining moving targets. For example, you might have a different target daytime and nighttime temperature.

example.parseCycles({
  day: {
    schedule: 'after 7:00am',
    targets: {
      temperature: {
        ideal: 22
      }
    }
  },
  night: {
    schedule: 'after 7:00pm',
    targets: {
      temperature: {
        ideal: 18
      }
    }
  }
})

In the example above the 'day' event will be emitted after 7:00am. Various internet of things devices such as lights can listen for those events, and respond accordingly (such as turning the lights on).

Phases

Cycles and targets aren't enough to fully express a plant's life cycle. Phases are a way to create groups of cycles and/or targets.

A plants life cycle might be broke up into the following phases:

  • Seedling
  • Vegatative
  • Flowering
  • Harvest

Each might have different environmental conditions with regards to lighting, pH, nutrients, temperature, etc.

Phases may have a length attribute which specifies how long they last.

In some cases may require a human to transition the grow system towards the next phase (such as transplanting seedlings, or replacing the water in the resevoir). In other words, phases may automatically or manually transition into the next phase.

Basic example

const climaterecipe = {
  "name":"Basic climate recipee",
  "description": "Metadata goes here.",
  "version":"0.1.0",
  "phases":{
    "vegetative":{
      "length": "28 days"
      "targets":{
        "ph":{
          "min":6,
          "ideal":6.15,
          "max":6.3
        },
        "ec":{
          "min":1400,
          "ideal":1500,
          "max":1700
        },
        "humidity":{
          "min":51,
          "max":61
        },
        "temperature":{
          "min":17,
          "max":28
        }
      },
      "cycles":{
        "day":{
          "schedule":"after 6:00am",
          "targets":{
            "temperature":{
              "ideal":22
            }
          }
        },
        "night":{
          "schedule":"after 9:00pm",
          "targets":{
            "temperature":{
              "ideal":18
            }
          }
        }
      }
    },
    "bloom":{
      "length": "32 days"
      "targets":{
        "ph":{
          "min":6,
          "ideal":6.15,
          "max":6.3
        },
        "ec":{
          "min":1400,
          "ideal":1500,
          "max":1700
        },
        "humidity":{
          "min":51,
          "max":59
        },
        "temperature":{
          "min":17,
          "max":28
        }
      },
      "cycles":{
        "day":{
          "schedule":"after 7:00am",
          "targets":{
            "temperature":{
              "ideal":22
            }
          }
        },
        "night":{
          "schedule":"after 7:00pm",
          "targets":{
            "temperature":{
              "ideal":22
            }
          }
        }
      }
    }
  }
};

example.startGrow(climaterecipe)

Climate recipees in Grow.js are serialized as JSON, which means the same recipees can play well in JavaScript, Python, C++, and more! Interoperability and standardization are things we should strive for.

There is lot's of future work to be done! As a potential forum for working on such projects, I think a W3C community group would be great.

If you have thoughts or suggestions, I would love to hear them.

Developing

Code is written in ES6, and compiled using rollup.

npm run build builds the library.

npm run test builds the library, and runs tests in the test folder.

The documentation is written in jsdoc, built using Mr-Doc, and on the gh-pages branch of this repo.

License

Grow.js is released under the 2-Clause BSD License, sometimes referred to as the "Simplified BSD License" or the "FreeBSD License".