diff --git a/CHANGELOG.md b/CHANGELOG.md index aaa3d27..df69e8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ All notable changes to this project is documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [2.1.0] + +Added support for arbitrary extension fields. + ## [2.0.1] This is a maintenance release to modernize the development environment. There are no changes in the code of the module so these updates should not affect the functionality of the module. diff --git a/MMM-RemoteTemperature.css b/MMM-RemoteTemperature.css index 816fea0..40bd909 100644 --- a/MMM-RemoteTemperature.css +++ b/MMM-RemoteTemperature.css @@ -11,6 +11,11 @@ margin-left: 15px; } +.MMM-RemoteTemperature .ext { + display: inline-block; + margin-left: 15px; +} + .MMM-RemoteTemperature .more { margin: 0; } diff --git a/MMM-RemoteTemperature.js b/MMM-RemoteTemperature.js index 13e03d1..fc35f19 100644 --- a/MMM-RemoteTemperature.js +++ b/MMM-RemoteTemperature.js @@ -9,7 +9,8 @@ Module.register('MMM-RemoteTemperature', { defaults: { sensorId: null, icon: 'home', - showMore: true + showMore: true, + ext: [] }, requiresVersion: '2.1.0', @@ -68,6 +69,19 @@ Module.register('MMM-RemoteTemperature', { wrapper.appendChild(firstLineEl); + if (this.viewModel.ext) { + const extLineEl = document.createElement('div'); + + this.viewModel.ext.forEach((extData) => { + const extEl = document.createElement('span'); + extEl.innerHTML = `${extData.value}${extData.unit}`; + extEl.classList = 'ext'; + extLineEl.appendChild(extEl); + }); + + wrapper.appendChild(extLineEl); + } + if (this.config.showMore) { const secondLineEl = document.createElement('div'); secondLineEl.classList = 'more dimmed small'; @@ -96,6 +110,7 @@ Module.register('MMM-RemoteTemperature', { temp: payload.temp, humidity: payload.humidity, battery: payload.battery, + ext: this._parseExtFields(payload.ext), timestamp: Date.now() }; @@ -112,5 +127,27 @@ Module.register('MMM-RemoteTemperature', { _formatTimestamp(timestamp) { return moment(timestamp).format('HH:mm'); + }, + + _parseExtFields(extPayload) { + const parsedExtValues = []; + + if (this.config.ext && extPayload) { + this.config.ext.forEach((extConfig) => { + const { name } = extConfig; + const value = extPayload[name]; + const unit = extConfig.unit || ''; + + if (typeof value !== 'undefined') { + parsedExtValues.push({ + name, + value, + unit + }); + } + }); + } + + return parsedExtValues; } }); diff --git a/README.md b/README.md index 6cc88d5..e1e9b8d 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,11 @@ If the sensor sends battery level data, it can be displayed in the second line: ![Default](./doc/screenshot-with-battery.png) +If your sensor can send more data then the module can display these arbitrary values in a new line: + +![Default](./doc/screenshot-ext-data.png) + + If the sensor does not send humidity data, then only the temperature is displayed: ![Default](./doc/screenshot-temp-only.png) @@ -89,6 +94,7 @@ For security reasons the MagicMirror is *not* reachable externally, which also m | `sensorId` | **REQUIRED** An arbitrary value that determines from which sensor this module accepts updates. It can also be used as an API key to restrict access to your mirror.

**Type:** `string`
**Default value:** `null` (must be configured) | `icon` | *Optional* Name of a [FontAwesome icon](https://fontawesome.com/icons?d=gallery) that is displayed before the temperature value. For example set to `'home'` to indicate that the mirror displays an indoor value or `'car'` if you show the temperature your car enjoys in the garage. You can set it to `null` to not display any symbol.

**Type:** `string`
**Default value:** `'home'` | `showMore` | *Optional* Determines whether a second line with additional data (e.g. timestamp of the last data update and battery level) should be displayed on the mirror.

**Type:** `boolean`
**Default value:** `true` +| `ext` | *Optional* Configuration of additional data fields to display. See the `Show more data` section on this page for more information.

**Type:** `Array`
**Default value:** `[]` ## How it works @@ -119,6 +125,46 @@ The `sensorId` property must be a `string`, and can contain any value, but it is Make sure that your sensor properly sets the `Content-Type` header in the HTTP request to `application/json`, otherwise the module will not be able to parse the request body. +### Show more data + +If your sensor is capable to post additional data you can use this module to display these arbitrary values in a second data line. + +First, you have to specify the name and optionally the unit of the extensional data fields in the `ext` property of the module configuration. For example to display barometric pressure and wind speed: + +```js + config: { + sensorId: '1', + icon: 'home', + showMore: true, + ext: [ + { name: 'pressure', unit: ' hPa' }, + { name: 'windspeed', unit: ' km/h' } + ] + } +``` + +Then you have to program your sensor to specify the measured values in the `ext` object in the posted JSON: + +```javascript +{ + "temp": 27, + "humidity": 30.4, + "battery": 100, + "sensorId": "1", + "ext": { + "pressure": 1015, + "windspeed": 23 + } +} +``` + +Note that the names `pressure` and `windspeed` are completely arbitrary, you can choose any name you want, but it is important that the key name in the `ext` object in the POSTed data must match with the `name` value in the module configuration. The module ignores those data values that are sent by the sensor but not specified in the module configuration. + +The `unit` is an optional field in the configuration. If specified, it's string value will be appended to the measured value as a postfix. + +In this way you can specify as many extension fields as you want, they will be displayed in one line within the module. + + ## Recommended hardware The recommended and tested hardware sensor for this module is [SolarTherm](https://github.com/balassy/solar-wifi-weather-station). Both the hardware and the software of SolarTherm is open-source, and can be built as a DIY project. SolarTherm has built-in support for this MMM-RemoteTemperature module, and can push measured data also to other popular services, like Blynk and ThingSpeak. diff --git a/doc/screenshot-ext-data.png b/doc/screenshot-ext-data.png new file mode 100644 index 0000000..dca9db4 Binary files /dev/null and b/doc/screenshot-ext-data.png differ diff --git a/node_helper.js b/node_helper.js index bf7ddd6..b8d2cd2 100644 --- a/node_helper.js +++ b/node_helper.js @@ -24,7 +24,8 @@ module.exports = NodeHelper.create({ temp: params.temp, humidity: params.humidity, battery: params.battery, - sensorId: params.sensorId + sensorId: params.sensorId, + ext: params.ext }; this.sendSocketNotification('MMM-RemoteTemperature.VALUE_RECEIVED', payload); diff --git a/package.json b/package.json index 23931eb..4039e96 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "MMM-RemoteTemperature", - "version": "2.0.1", + "version": "2.1.0", "description": "MagicMirror module that displays temperature value from a remote sensor.", "main": "MMM-RemoteTemperature.js", "author": "György Balássy",