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 🙏

© 2024 – Pkg Stats / Ryan Hefner

domoja

v1.4.5

Published

A Typescript framework for home automation

Downloads

40

Readme

NPM

NPM version Node.js CI CodeQL Coverage Status

domoja

A Typescript framework for home automation

Introduction

This framework allows to create home automation applications.

The server part is written in Typescript, while the GUI uses Angular and Ionic.

Here are some screenshots of the application:

Installation

# install domoja and domoja-core
$ yarn add domoja domoja-core 

# install tempo and proxiti modules to run the demo
$ yarn add domoja-tempo domoja-proxiti

# run the demo on http://localhost:8700
$ yarn domoja -p 8700 --dev

Concepts

Domoja collects information from and interacts with devices through sources. You can think of sources as sources of information.

Sources

A source provides information about, and allows controlling a certain set of devices.

To use a source, it is necessary to load its type in Domoja. Some source types are predefined in Domoja, some others can be add by extension modules:

$ yarn add domoja-<source-module>

Once loaded in Domoja, the module providing the source type needs to be imported in the configuration before a source of this type can be declared and then referenced by a device.

The example below shows how to create the source myAstronomy of type astronomy from the module proxity, to get the sunrise time:

$ yarn add domoja-proxiti
imports:
  - module: proxiti
    source: astronomy

sources:
  - myAstronomy: {
      type: astronomy,
      location: "06030"
  }

devices:
  - sunrise: { type: device, widget: text, tags: 'astronomyTag', source: myAstronomy, id: sunriseTime, name: "Lever du soleil" }

Source type | Module | Description ----------- | ------ | ----------- astronomy | proxiti | This source provides astronomy information from http://www.proxiti.info/horaires_soleil.php?o=06030This includes sunset, sunrise, dawn, dusk, zenith times, and day duration, at a specific location.Parameters: location: the code corresponding to your location. Use https://www.proxiti.info/index.php to find it.Example:sources: - astronomy: { type: astronomy, location: "06030" }devices: - sunset: { type: device, widget: text, tags: 'astronomy', source: astronomy, id: sunsetTime, name: "Coucher du soleil" } command | core/sources/command | Source implemented with shell commands: parameters define the shell commands to execute when a device takes a given value Example with parameters ON and OFF :- sources: - robonect-command: { type: command, ON: "AUTH=$(grep robonectBasicAuth config/secrets.yml | sed -e 's!^ [^:][^:]: *!!' -e 's/[\r\n]//g'); curl 'http://192.168.0.16/xml?cmd=start' -s -u $AUTH", OFF: "AUTH=$(grep robonectBasicAuth config/secrets.yml | sed -e 's!^ [^:][^:]: *!!' -e 's/[\r\n]//g'); curl 'http://192.168.0.16/xml?cmd=stop' -s -u $AUTH" } the optional parameter pushupdates is a shell command executed once as a daemon at the creation of the source it allows to emit changes of device state values it shoud produce stdout output in the form {"id": "<device_id>", "attribute": "<attribute>", "value": "<value>"}, e.g. {"id": "temp", "attribute": "state", "value": "10 °C"} the daemon will be killed when the source is released, but to avoid zombie processes to be created, it is good to guard a loop by checking the parent process, for example:while [ $(ps -o ppid= $$) != 1 ]; do ; sleep 60; done available variables are: ID: id of the device using the source SOURCE: the path of the source DEBUG: debug mode of the source ('0'|'1') Example: sources:- disk-usage: { type: command, push-updates: " while [ $(ps -o ppid= $$) != 1 ] do df -k | awk '{ mount=$6 percent=$5 str=\"{ \\\"id\\\": \\\"\"mount\"\\\", \\\"attribute\\\": \\\"state\\\", \\\"value\\\": \\\"\"percent\"\\\"}\" if ('$DEBUG') print str > \"/dev/stderr\" # debug print str }' sleep 60 done "} Freebox | freebox | IPX800 | ipx800 | This source connects to IPX800 devices from GCE Electronics.Example:sources:- myIPX800: { type: IPX800, ip: 192.168.0.17, macaddress: 00:04:A3:2D:68:E6, update_url: /ipx800/update, timeout: 60} Mqtt | mqtt | Openzwave | openzwave | Domoja source to connect to ZWave devicesExample:sources: - ZStick: { type: Openzwave, debug: false, driverLogLevel: "silly", port: /dev/ttyACM0 }devices:- zwave: - controller : { type: device, widget: "multistate:INCLUSION,INCLUSION_NON_SECURE,EXCLUSION,NO_INCLUSION_EXCLUSION:secondary,secondary,danger,primary:Inclure,Inclure non séc.,Exclure,Stop", tags: 'zwave', source: ZStick, id: "1", attribute: "inclusion_mode", name: "Controleur"} - config : { type: device, widget: "zwave-config", tags: 'zwave', source: ZStick, id: "1", attribute: "zwave_config", name: "ZWave config"} - grand: { type: device, widget: text, tags: 'portails', source: ZStick, id: "16-37-2-currentValue", name: "Petit Portail ouvert en grand", camera: camera_exterieure } Sample | sample | A source derives from the Source class and implements the following methods: createInstance: create an instance of the source, taking into account the requested configuration getParameters: describes the parameters supported by the source doSetAttribute: implements a requested change of value of an attribute of a device managed by the source release: releases a source to free any used resource registerDeviceTypes: a static method to declare which device types are supported by the source tempo | tempo | Cette source récupère les informations de couleur de période auprès de l'EDF, pour le jour courant et le lendemain.Exemple:sources: - tempo: { type: tempo }devices: - tempo: - couleur_du_jour : { type: device, widget: tempo-color, tags: 'tempo', source: tempo, id: couleurDuJour, name: "Couleur du jour" } - couleur_de_demain : { type: device, widget: tempo-color, tags: 'tempo', source: tempo, id: couleurDeDemain, name: "Couleur de demain" } VoiceByGoogle | voice-google | Zibase | zibase | This source connects to a Zibase device.Not used anymore as Zodianet company is now dead for years...

Devices

The framework supports a range of devices:

  • device: a generic device with attributes which can be set or get.
  • relay: a particular switch, for which delays can be configured.
  • variable: a special device that contains a value which can be read or written.

Modules

Domoja can be extended through modules, to add new sources, devices, etc. They are essentially npm modules following particular specifications:

  • their name must start with domoja-
  • they must derive from domoModule

Available modules

The following modules are currently available:

Adding a new module

Before importing a module in the config file, you need to make it available. In the domoja directory, use yarn add <themodule>.

If you are developing the module, you might want to add it linked:

$ cd <themodule_dir>
$ yarn link
$ cd <domoja_dir>
$ yarn link <themodule>

How to develop a new module

Developers can develop new Domoja modules. For this, proceed this way:

  • Copy the domoja/modules/sample repository.
  • Update package.json. Note that the module name must start with domoja-
  • You can find in sources/sample.ts a sample source,
  • Link your module using cd <yourmodule_dir>; yarn link and cd <domoja_dir>; yarn link "domoja-<yourmodule>"
  • You can now import your module from the config file.

It can be convenient to setup a small test file and run it with nodemon. This will make it possible to automatically restart the test execution when the module source is modified, and also to debug with Chrome for instance.

Example: File test_module.ts:

import { MyModule } from 'domoja-samplemodule';

let freebox = new MyClass('path', 'some', 'parameters');

and run it with: nodemon --ext ts --watch test-module.ts --watch <module_dir> --exec node --inspect=0.0.0.0 --require ts-node/register test-module.ts

API

Domoja provides a REST/JSON api, which is available through Swagger at /api-docs.

  • GET /app: Retrieve the app data
  • POST /app/demo-mode: Set the app demo mode
  • GET /devices: Retrieves the list of devices
  • GET /devices/{id}: Retrieves a device
  • POST /devices/{id}: Sends a command to a device
  • GET /devices/{id}/snapshot: Get a snapshot from a camera device
  • GET /devices/{id}/stream: Get a stream from a camera device
  • GET /devices/{id}/history: Get the history of a device
  • GET /pages: Retrieves the list of pages

Persistence

Device states can be persisted using MongoDB. By default, all states that are numbers are persisted. Persistence can be specified through the persistence attribute:

persistence: "<persistence-module>:<id>:0:<aggregation mode>:<keep>"

  • <persistence-module> is mongo by default.
  • <id> specifies the id of the device to be persisted. If not specified, then the path of the device is used. Specifying the id is useful if you want to be sure to keep the persisted states even if you change the path of the device.
  • <aggregation mode>: one of year, month, day, hour, minute, none
  • <keep>: duration to persist the states, in seconds.

User Interface

Domoja comes with a generic user interface based on Ionic. The files are located in the www directory, and generated by domoja-ui.

HomeKit and Siri integration

Domoja can be easily integrated with HomeKit through the great homebridge. Once Homebridge is installed, the best is to create an API key. Then you can add accessories in homebridge's config.json file.

Example for a switch:

{
      "accessory": "HTTP-SWITCH",
      "name": "Lampe préau",
      "switchType": "stateful",
      "pullInterval": 5000,
      "onUrl": {
        "url": "https://XXX/devices/lampes.lampe_preau",
        "method": "POST",
        "body": "command=ON",
        "auth": {
          "username": "XX",
          "password": "XX"
        },
        "headers": {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      },
      "offUrl": {
        "url": "https://XXX/devices/lampes.lampe_preau",
        "method": "POST",
        "body": "command=OFF",
        "auth": {
          "username": "XX",
          "password": "XX"
        },
        "headers": {
          "Content-Type": "application/x-www-form-urlencoded"
        }
      },
      "statusUrl": {
        "url": "https://XXX/devices/lampes.lampe_preau",
        "method": "GET",
        "auth": {
          "username": "XX",
          "password": "XX"
        }
      },
      "statusPattern": "\"ON\""
    }

Example for a sensor:

    {
      "accessory": "HTTP-TEMPERATURE",
      "name": "Température piscine",
      "debug": 1,
      "getUrl": {
        "url": "https://XXX/devices/piscine.temperature",
        "method": "GET",
        "auth": {
          "username": "XX",
          "password": "XX"
        }
      },
      "statusPattern": ".*\"state\":\"\\+?(-?[0-9]+\\.[0-9]*)\"",
      "patternGroupToExtract": 1
    },

Siri is then available on iOS through the Home application.

Development

To test a new domoja package, create it through yarn pack and install it:

$ cd domoja
$ yarn pack --filename /tmp/domoja.$RANDOM.tar.gz


$ cd ../domoja-run
yarn add $(ls -t /tmp/domoja.*.tar.gz | head -1)

To do

  • Use KEEP for persistence
  • Ajouter un status general couplé avec Siri: "donne moi le statut de la maison/piscine/tondeuse..."
  • support other attribute than 'state' in devices // normalement ca marche (ex tem avec temp piscine). L'utiliser pour le stick etc
  • support for dev: reload module when changed
  • authentication cookies seem not persisted: when restarting the server, we need to relogin
  • debugMode should be taken into account when creating the source

Issues

  • on config reload it seems that we get mongodb drain
  • sur iOS revenir sur l'app ne fonctionne pas toujours
  • lumieres clignotantes a fixer

Fixed

  • en cas de script timeout on n'a plus de logging info ?!?! -> https://github.com/patriksimek/vm2/issues/306