# mqtt-scripts **Repository Path**: hi-mzh/mqtt-scripts ## Basic Information - **Project Name**: mqtt-scripts - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: v2-dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-09-16 - **Last Updated**: 2021-09-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # mqtt-scripts [![mqtt-smarthome](https://img.shields.io/badge/mqtt-smarthome-blue.svg)](https://github.com/mqtt-smarthome/mqtt-smarthome) [![NPM version](https://badge.fury.io/js/mqtt-scripts.svg)](http://badge.fury.io/js/mqtt-scripts) [![dependencies Status](https://david-dm.org/hobbyquaker/mqtt-scripts/status.svg)](https://david-dm.org/hobbyquaker/mqtt-scripts) [![Build Status](https://travis-ci.org/hobbyquaker/mqtt-scripts.svg?branch=master)](https://travis-ci.org/hobbyquaker/mqtt-scripts) [![Coverage Status](https://coveralls.io/repos/github/hobbyquaker/mqtt-scripts/badge.svg?branch=master)](https://coveralls.io/github/hobbyquaker/mqtt-scripts?branch=master) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![License][mit-badge]][mit-url] > mqtt-scripts is a Node.js based script runner for use in mqtt based smart home environments. It's intentended to be used as the "logic layer" in your smart home, and offers a zero-boilerplate, straight forward scripting environment. It follows the [mqtt-smarthome](https://github.com/mqtt-smarthome/mqtt-smarthome) architecture. Mqtt-scripts could be seen as something like "Node-RED without GUI" # Getting started Prerequisites: mqtt-scripts needs Node.js >= 6.0. * Install mqtt-scripts globally: ```sudo npm install -g mqtt-scripts``` * Create a folder from where mqtt-scripts will load the scripts: ```mkdir -p /opt/mqtt-smarthome/scripts``` * Create a folder to install node modules that can be used in the scripts: ```mkdir /opt/mqtt-smarthome/scripts/node_modules``` (You can then just use npm install in the directory /opt/mqtt-smarthome/scripts) * Put some files in you script dir: ``` echo "log.info('my first script!')" > /opt/mqtt-smarthome/scripts/test1.js echo "log.info 'get ma a coffee' > /opt/mqtt-smarthome/scripts/test1.coffee ``` * Start mqtt-scripts ```mqtt-scripts -d /opt/mqtt-smarthome/scripts``` ### Run with Docker To run with Docker, use either a [pre-build image](https://hub.docker.com/r/dersimn/mqtt-scripts) or build one your own. Either way, just substitude the node-command you would have used by the Docker command, for e.g.: ```mqtt-scripts --help``` becomes ```docker run dersimn/mqtt-scripts --help``` An example for a productive configuration would be: ``` docker run -d --restart=always --name=logic \ -e "TZ=Europe/Berlin" \ -v /opt/hma/etc/scripts:/scripts:ro \ dersimn/mqtt-scripts \ --url mqtt://10.1.1.50 \ --dir /scripts ``` Configure via `MQTTSCRIPTS_` env variables when using Docker Compose. #### Build Docker development build: docker build -t mqtt-scripts . docker run --rm -v "$(pwd)/testscripts":/scripts mqtt-scripts -v debug Docker Hub deploy: docker buildx create --name mybuilder docker buildx use mybuilder docker buildx build --platform linux/amd64,linux/arm/v7 -t dersimn/mqtt-scripts -t dersimn/mqtt-scripts:2 -t dersimn/mqtt-scripts:2.x.x --push . # Command Line Options
Usage: mqtt-scripts [options]

Options:
  --version                Show version number                         [boolean]
  -c, --config             Path to JSON config file
  -d, --dir                directory to scan for .js and .coffee files. can be
                           used multiple times.
  -h, --help               Show help                                   [boolean]
  -s, --variable-prefix    topic prefix for $ substitution (shorthand for
                           variables, see docs)                 [default: "var"]
  -t, --disable-variables  disable variable feedback (see docs) [default: false]
  -n, --name               instance name. used as mqtt client id and as prefix
                           for connected topic                [default: "logic"]
  -u, --url                mqtt broker url. See
                           https://github.com/mqttjs/MQTT.js#connect-using-a-url
                                                   [default: "mqtt://127.0.0.1"]
  -v, --verbosity          possible values: "error", "warn", "info", "debug"
                                                               [default: "info"]
  -w, --disable-watch      disable file watching (don't exit process on file
                           changes)                             [default: false]
  -l, --latitude                                              [default: 48.7408]
  -m, --longitude                                              [default: 9.1778]                                            
If you're running multiple instances of mqtt-scripts you have to decide which one should handle variables and disable the variables on all other instances with the --disable-variable option. # Script Examples #### Use hm2mqtt and hue2mqtt to control a hue lamp with a homematic remote control ```javascript link('hm//RC4:1/PRESS_CONT', 'hue//lights/Hobbyraum/bri_inc', -16); subscribe('hm//RC4:2/PRESS_CONT', function () { if (!getValue('hue//lights/Hobbyraum')) { setValue('hue//lights/Hobbyraum', 1); } else { setValue('hue//lights/Hobbyraum/bri_inc', 16); } }); link('hm//RC4:1/PRESS_SHORT', 'hue//lights/Hobbyraum', 0); link('hm//RC4:2/PRESS_SHORT', 'hue//lights/Hobbyraum', 254); link('hm//RC4:3/PRESS_CONT', 'hue//lights/Hobbyraum/ct_inc', -16); link('hm//RC4:4/PRESS_CONT', 'hue//lights/Hobbyraum/ct_inc', 16); link('hm//RC4:3/PRESS_SHORT', 'hue//lights/Hobbyraum/ct', 153); link('hm//RC4:4/PRESS_SHORT', 'hue//lights/Hobbyraum/ct', 500); ``` #### retrieve fuel prices from tankerkoenig ```javascript var request = require('request'); var cred = require('./lib/credentials.js'); var url = 'https://creativecommons.tankerkoenig.de/json/detail.php'; var tankstellen = { 'OMV': 'cb1f0588-d517-40f0-8ce3-3edadebea40d', 'Shell': '4267c196-eea1-47be-96b7-d790b2fbd17a' }; schedule('0/12 * * * *', function () { for (var topic in tankstellen) { getData(topic, tankstellen[topic]); } }); function getData(topic, id) { request.get(url + '?id=' + id + '&apikey=' + cred.tankerkoenig.apikey, function (err, res) { if (err) { log.error(err); return; } var data = JSON.parse(res.body).station; setValue('$Tankstelle/' + topic + '/Diesel', data.diesel); setValue('$Tankstelle/' + topic + '/E5', data.e5); setValue('$Tankstelle/' + topic + '/Offen', data.isOpen); }); } ``` #### Send a variables state changes to Pushover ```Javascript var cred = require('./lib/credentials.js'); var pushoverNotifications = require('pushover-notifications'); var push = new pushoverNotifications( { user: cred.pushover.user, token: cred.pushover.token, onerror: function (error) { log.error(error); } }); function pushover(msg) { if (typeof msg !== 'object' || typeof msg.message !== 'string') msg = {message: '' + msg}; msg.title = msg.title || "Smart Home"; msg.priority = msg.priority || 0; msg.device = msg.device || 'iphone5'; push.send(msg, function(err, result) { if (err) { log.error(err); } }); } subscribe('$Anwesenheit', {change: true}, function () { pushover({ title:'Anwesenheit', message: getProp($Anwesenheit, 'logic_textual'), priority: -1 }); }); ``` # API ## Classes
log

Log to stdout/stderr. Messages are prefixed with a timestamp and the calling scripts path.

## Functions
subscribe(topic, [options], callback)

Subscribe to MQTT topic(s)

schedule(pattern, [options], callback)

Schedule recurring and one-shot events

sunSchedule(pattern, [options], callback)

Schedule a recurring event based on sun position

publish(topic, payload, [options])

Publish a MQTT message

setValue(topic, val)

Set a value on one or more topics

getValue(topic)mixed
getProp(topic, [...property])mixed

Get a specific property of a topic

now()number
age(topic)number
link(source, target, [value])

Link topic(s) to other topic(s)

combineBool(srcs, targets)

Combine topics through boolean or

combineMax(srcs, targets)

Publish maximum of combined topics

timer(src, target, time)

Publishes 1 on target for specific time after src changed to true

## Typedefs
subscribeCallback : function
## log Log to stdout/stderr. Messages are prefixed with a timestamp and the calling scripts path. **Kind**: global class * [log](#log) * [.debug()](#log.debug) * [.info()](#log.info) * [.warn()](#log.warn) * [.error()](#log.error) ### log.debug() Log a debug message **Kind**: static method of [log](#log) | Type | | --- | | \* | ### log.info() Log an info message **Kind**: static method of [log](#log) | Type | | --- | | \* | ### log.warn() Log a warning message **Kind**: static method of [log](#log) | Type | | --- | | \* | ### log.error() Log an error message **Kind**: static method of [log](#log) | Type | | --- | | \* | ## subscribe(topic, [options], callback) Subscribe to MQTT topic(s) **Kind**: global function | Param | Type | Description | | --- | --- | --- | | topic | string \| Array.<string> | topic or array of topics to subscribe | | [options] | Object \| string \| function | Options object or as shorthand to options.condition a function or string | | [options.shift] | number | delay execution in seconds. Has to be positive | | [options.random] | number | random delay execution in seconds. Has to be positive | | [options.change] | boolean | if set to true callback is only called if val changed | | [options.retain] | boolean | if set to true callback is also called on retained messages | | [options.condition] | string \| function | conditional function or condition string | | callback | [subscribeCallback](#subscribeCallback) | | ## schedule(pattern, [options], callback) Schedule recurring and one-shot events **Kind**: global function **See**: [sunSchedule](#sunSchedule) for scheduling based on sun position. | Param | Type | Description | | --- | --- | --- | | pattern | string \| Date \| Object \| Array.<mixed> | pattern or array of patterns. May be cron style string, Date object or node-schedule object literal. See [https://github.com/tejasmanohar/node-schedule/wiki](https://github.com/tejasmanohar/node-schedule/wiki) | | [options] | Object | | | [options.random] | number | random delay execution in seconds. Has to be positive | | callback | function | is called with no arguments | **Example** ```js // every full Hour. schedule('0 * * * *', callback); // Monday till friday, random between 7:30am an 8:00am schedule('30 7 * * 1-5', {random: 30 * 60}, callback); // once on 21. December 2018 at 5:30am schedule(new Date(2018, 12, 21, 5, 30, 0), callback); // every Sunday at 2:30pm schedule({hour: 14, minute: 30, dayOfWeek: 0}, callback); ``` ## sunSchedule(pattern, [options], callback) Schedule a recurring event based on sun position **Kind**: global function **See**: [schedule](#schedule) for time based scheduling. | Param | Type | Description | | --- | --- | --- | | pattern | string \| Array.<string> | a suncalc event or an array of suncalc events. See [https://github.com/mourner/suncalc](https://github.com/mourner/suncalc) | | [options] | Object | | | [options.shift] | number | delay execution in seconds. Allowed Range: -86400...86400 (+/- 24h) | | [options.random] | number | random delay execution in seconds. | | callback | function | is called with no arguments | **Example** ```js // Call callback 15 minutes before sunrise sunSchedule('sunrise', {shift: -900}, callback); // Call callback random 0-15 minutes after sunset sunSchedule('sunset', {random: 900}, callback); ``` ## publish(topic, payload, [options]) Publish a MQTT message **Kind**: global function | Param | Type | Default | Description | | --- | --- | --- | --- | | topic | string \| Array.<string> | | topic or array of topics to publish to | | payload | string \| Object | | the payload string. If an object is given it will be JSON.stringified | | [options] | Object | | the options to publish with | | [options.qos] | number | 0 | QoS Level | | [options.retain] | boolean | false | retain flag | ## setValue(topic, val) Set a value on one or more topics **Kind**: global function | Param | Type | Description | | --- | --- | --- | | topic | string \| Array.<string> | topic or array of topics to set value on | | val | mixed | | ## getValue(topic) ⇒ mixed **Kind**: global function **Returns**: mixed - the topics value | Param | Type | | --- | --- | | topic | string | ## getProp(topic, [...property]) ⇒ mixed Get a specific property of a topic **Kind**: global function **Returns**: mixed - the topics properties value | Param | Type | Description | | --- | --- | --- | | topic | string | | | [...property] | string | the property to retrieve. May be repeated for nested properties. If omitted the whole topic object is returned. | **Example** ```js // returns the timestamp of a given topic getProp('hm//Bewegungsmelder Keller/MOTION', 'ts'); ``` ## now() ⇒ number **Kind**: global function **Returns**: number - ms since epoch ## age(topic) ⇒ number **Kind**: global function **Returns**: number - seconds since last change | Param | Type | | --- | --- | | topic | string | ## link(source, target, [value]) Link topic(s) to other topic(s) **Kind**: global function | Param | Type | Description | | --- | --- | --- | | source | string \| Array.<string> | topic or array of topics to subscribe | | target | string \| Array.<string> | topic or array of topics to publish | | [value] | mixed | value to publish. If omitted the sources value is published. A function can be used to transform the value. | ## combineBool(srcs, targets) Combine topics through boolean or **Kind**: global function | Param | Type | Description | | --- | --- | --- | | srcs | Array.<string> | array of topics to subscribe | | targets | string | topic to publish | ## combineMax(srcs, targets) Publish maximum of combined topics **Kind**: global function | Param | Type | Description | | --- | --- | --- | | srcs | Array.<string> | array of topics to subscribe | | targets | string | topic to publish | ## timer(src, target, time) Publishes 1 on target for specific time after src changed to true **Kind**: global function | Param | Type | Description | | --- | --- | --- | | src | string \| Array.<string> | topic or array of topics to subscribe | | target | string | topic to publish | | time | number | timeout in milliseconds | ## subscribeCallback : function **Kind**: global typedef | Param | Type | Description | | --- | --- | --- | | topic | string | the topic that triggered this callback. +/status/# will be replaced by +//# | | val | mixed | the val property of the new state | | obj | object | new state - the whole state object (e.g. {"val": true, "ts": 12346345, "lc": 12346345} ) | | objPrev | object | previous state - the whole state object | | msg | object | the mqtt message as received from MQTT.js | # License MIT © [Sebastian Raff](https://github.com/hobbyquaker) [mit-badge]: https://img.shields.io/badge/License-MIT-blue.svg?style=flat [mit-url]: LICENSE