diff --git a/.eslintrc.json b/.eslintrc.json index 1107339..df392c3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,12 +1,4 @@ { "extends": ["airbnb-typescript-prettier"], - "ignorePatterns": ["*.js"], - "rules": { - "padding-line-between-statements": "error", - "comma-dangle": 0, - "prettier/prettier": "error", - "no-unused-vars": "error", - "prefer-template": "warn", - "import/no-extraneous-dependencies": ["error", { "devDependencies": true }] - } + "ignorePatterns": ["*.js"] } \ No newline at end of file diff --git a/.gitignore b/.gitignore index ac5578a..84b9969 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,110 @@ -.DS_Store -node_modules -*.code-workspace \ No newline at end of file +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +*.pem + +debugResponse.json + +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 4d2a632..78a4a5b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # MMM-RAIN-MAP -[![dependencies Status](https://status.david-dm.org/gh/jalibu/MMM-RAIN-MAP.svg)](https://david-dm.org/jalibu/MMM-RAIN-MAP) [![Known Vulnerabilities](https://snyk.io/test/github/jalibu/MMM-RAIN-MAP/badge.svg?targetFile=package.json)](https://snyk.io/test/github/jalibu/MMM-RAIN-MAP?targetFile=package.json) -A Rain Radar Map based on the [Rainviewer API](https://www.rainviewer.com/) for the [MagicMirror²](https://magicmirror.builders/) platform. - -Click here for the [Forum Thread](https://forum.magicmirror.builders/topic/12808/mmm-rain-map). +[![Known Vulnerabilities](https://snyk.io/test/github/jalibu/MMM-RAIN-MAP/badge.svg?targetFile=package.json)](https://snyk.io/test/github/jalibu/MMM-RAIN-MAP?targetFile=package.json) + +A Rain Radar Map based on the [Rainviewer API](https://www.rainviewer.com/) for the [MagicMirror²](https://magicmirror.builders/) platform. +Click here for the [Forum Thread](https://forum.magicmirror.builders/topic/12808/mmm-rain-map). + +Contribution welcome. #### Support + If you like this module and want to thank, please rate this repository with a star or buy me a coffee :-) Buy Me A Beer @@ -13,106 +16,107 @@ If you like this module and want to thank, please rate this repository with a st ## Features - Displays Rainviewer.com radar layers on OpenStreetMap - * Every 10 minutes a new weather snapshot is published - * The snapshots of the last 2 hours are available, which show the weather events of the past - * Additionally 3 layers are displayed as forecast of the next 30 minutes -- Option to place multiple markers on map + - Every 10 minutes a new weather snapshot is published + - The snapshots of the last 2 hours are available, which show the weather events of the past + - Additionally 3 layers are displayed as forecast of the next 30 minutes +- Option to place multiple markers on map - Option for multiple, alternating map positions - Option to only show in current rainy weather conditions. Works only together with [weather](https://github.com/MichMich/MagicMirror/tree/master/modules/default/weather) or [MMM-OpenWeatherForecast](https://github.com/jclarke0000/MMM-OpenWeatherForecast) as dependency. - (Experimental) Option to hide other modules in case of rain in favor to get more space. ### Demo + https://user-images.githubusercontent.com/25933231/130909536-e096d342-19d5-4139-b057-e01dc9ef71d7.mov ## Installing the Module -1. Navigate to the MagicMirror's subfolder "modules" and execute the following command - - ```sh - git clone https://github.com/jalibu/MMM-RAIN-MAP.git - ``` - -2. Add the module in the `config/config.js` file (sample configuration): - - ```javascript - { - module: "MMM-RAIN-MAP", - position: "top_left", - config: { - animationSpeedMs: 400, - colorizeTime: true, - defaultZoomLevel: 8, - displayTime: true, - displayTimeline: true, - displayClockSymbol: true, - displayOnlyOnRain: false, - extraDelayLastFrameMs: 1000, - extraDelayCurrentFrameMs: 3000, - markers: [ - { lat: 49.41, lng: 8.717, color: "red" }, - { lat: 48.856, lng: 2.35, color: "green" }, - ], - mapPositions: [ - { lat: 49.41, lng: 8.717, zoom: 9, loops: 1 }, - { lat: 49.41, lng: 8.717, zoom: 6, loops: 2 }, - { lat: 48.856, lng: 2.35, zoom: 6, loops: 1 }, - { lat: 48.856, lng: 2.35, zoom: 9, loops: 2 }, - { lat: 49.15, lng: 6.154, zoom: 5, loops: 2 }, - ], - mapUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", - mapHeight: "420px", // must be a pixel value (no percent) - mapWidth: "420px", // must be a pixel value (no percent) - maxHistoryFrames: -1, - maxForecastFrames: -1, - substitudeModules: [], - updateIntervalInSeconds: 300, - } - } - ``` - -## Options - -| Option | Description | -| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `animationSpeedMs` | Determines how fast the frames are played.

**Type:** `int`
**Default value:** `400` (time per frame in milliseconds) | -| `colorizeTime` | Set true, to colorize history and forecast timestamps.

**Type:** `boolean`
**Default value:** `true` | -| `defaultZoomLevel` | Fallback/default zoom value that is used if it is not explicitly set in a MapPostion.

**Type:** `int`
**Range:** `0 (whole world) - 20 (small building)`
**Default value:** `8` | -| `displayTime` | Set true, to display the time for each frame.

**Type:** `boolean`
**Default value:** `true` | -| `displayClockSymbol` | Set true, to display a clock symbol as time prefix.

**Type:** `boolean`
**Default value:** `true` | -| `displayTimeline` | Set true, to display a timeline.

**Type:** `boolean`
**Default value:** `true` | -| `displayOnlyOnRain` | Set true, to only show the map if supported weather modules broadcast a current rainy weather condition.
Supported weather modules are: [weather](https://github.com/MichMich/MagicMirror/tree/master/modules/default/weather) and [MMM-OpenWeatherForecast](https://github.com/jclarke0000/MMM-OpenWeatherForecast).

**Type:** `boolean`
**Default value:** `false` | -| `extraDelayLastFrameMs` | Add an extra delay to pause the animation on the last frame (last available forecast weather situation).

**Type:** `int`
**Default value:** `1000` (time in milliseconds) | -| `extraDelayCurrentFrameMs` | Add an extra delay to pause the animation on the frame for the current weather situation.

**Type:** `int`
**Default value:** `3000` (time in milliseconds) | -| `markers` | Optional list of markers on the map.
See examples and Markers-Object documentation below for details.

**Type:** `array[Marker]`
**Default value:** `Sample set` | -| `mapPositions` | **Required:** List of zoom/center positions for the map.
See examples and MapPosition-Object documentation below for details.

**Type:** `array[MapPosition]`
**Default value:** `Sample set` | -| `mapHeight` | Height of the map. Must be string with pixels and "px" postfix. Percentage values won't work.

**Type:** `string` (pixels)
**Default value:** `'420px'` | -| `mapWidth` | Width of the map. Must be a string with pixels and "px" postfix. Percentage values won't work.

**Type:** `string` (pixels)
**Default value:** `'420px'` | -| `mapUrl` | Option to use an alternative map. In most cases you are fine with the default but you can find more maps [here](https://wiki.openstreetmap.org/wiki/Tile_servers).

**Type:** `string`
**Default value:** `'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'`
**Alternative uncolored map:** '`https://tiles.wmflabs.org/bw-mapnik/${z}/${x}/${y}.png`' | -| `maxHistoryFrames` | Maximum number of history frames. There is one frame every 10 minutes. Setting this to 6 would show history radar layers of the last hour until now. If set to -1, all available history frames are shown.
As of today, the **API provides 12 history frames** -> 2h.

**Type:** `int`
**Default value:** `-1` | -| `maxForecastFrames` | Maximum number of forecast frames. There is one frame every 10 minutes. Setting this to 2 would show forecast radar layers from now to 20 minutes in the future. If set to -1, all available forecast frames are shown.
As of today, the **API provides 3 forecast frames** -> 30min.

**Type:** `int`
**Default value:** `-1` -| `substitudeModules` | (Experimental) If `displayOnlyOnRain` is turned on, you can define a list of module names that are hidden in favor of the map.

**Type:** `array[string]`
**Default value:** `[]`
**Example:** `['MMM-Jast', 'calendar']` | -| `timeFormat` | Option to override the Magic Mirror's global time format to 12 or 24 for this module.

**Type:** `int`
**Default value:** `[Global Config]` or `24` | -| `updateIntervalMs` | Update interval for fetching new radar frames from the RainViewer.com API. (New frames are released every 10 minutes)

**Type:** `int`
**Default value:** `300000` (time in milliseconds) | +1. Navigate to the `MagicMirror/modules` directory and execute the following command + + ```sh + git clone https://github.com/jalibu/MMM-RAIN-MAP.git + ``` + +2. Add the module configuration into the `MagicMirror/config/config.js` file (sample configuration): + + ```javascript + { + module: "MMM-RAIN-MAP", + position: "top_left", + config: { + animationSpeedMs: 400, + colorizeTime: true, + defaultZoomLevel: 8, + displayTime: true, + displayTimeline: true, + displayClockSymbol: true, + displayOnlyOnRain: false, + extraDelayLastFrameMs: 1000, + extraDelayCurrentFrameMs: 3000, + markers: [ + { lat: 49.41, lng: 8.717, color: "red" }, + { lat: 48.856, lng: 2.35, color: "green" }, + ], + mapPositions: [ + { lat: 49.41, lng: 8.717, zoom: 9, loops: 1 }, + { lat: 49.41, lng: 8.717, zoom: 6, loops: 2 }, + { lat: 48.856, lng: 2.35, zoom: 6, loops: 1 }, + { lat: 48.856, lng: 2.35, zoom: 9, loops: 2 }, + { lat: 49.15, lng: 6.154, zoom: 5, loops: 2 }, + ], + mapUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", + mapHeight: "420px", // must be a pixel value (no percent) + mapWidth: "420px", // must be a pixel value (no percent) + maxHistoryFrames: -1, + maxForecastFrames: -1, + substitudeModules: [], + updateIntervalInSeconds: 300, + } + } + ``` + +### Options + +| Option | Description | +| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `animationSpeedMs` | Determines how fast the frames are played.

**Type:** `int`
**Default value:** `400` (time per frame in milliseconds) | +| `colorizeTime` | Set true, to colorize history and forecast timestamps.

**Type:** `boolean`
**Default value:** `true` | +| `defaultZoomLevel` | Fallback/default zoom value that is used if it is not explicitly set in a MapPostion.

**Type:** `int`
**Range:** `0 (whole world) - 20 (small building)`
**Default value:** `8` | +| `displayTime` | Set true, to display the time for each frame.

**Type:** `boolean`
**Default value:** `true` | +| `displayClockSymbol` | Set true, to display a clock symbol as time prefix.

**Type:** `boolean`
**Default value:** `true` | +| `displayTimeline` | Set true, to display a timeline.

**Type:** `boolean`
**Default value:** `true` | +| `displayOnlyOnRain` | Set true, to only show the map if supported weather modules broadcast a current rainy weather condition.
Supported weather modules are: [weather](https://github.com/MichMich/MagicMirror/tree/master/modules/default/weather) and [MMM-OpenWeatherForecast](https://github.com/jclarke0000/MMM-OpenWeatherForecast).

**Type:** `boolean`
**Default value:** `false` | +| `extraDelayLastFrameMs` | Add an extra delay to pause the animation on the last frame (last available forecast weather situation).

**Type:** `int`
**Default value:** `1000` (time in milliseconds) | +| `extraDelayCurrentFrameMs` | Add an extra delay to pause the animation on the frame for the current weather situation.

**Type:** `int`
**Default value:** `3000` (time in milliseconds) | +| `markers` | Optional list of markers on the map.
See examples and Markers-Object documentation below for details.

**Type:** `array[Marker]`
**Default value:** `Sample set` | +| `mapPositions` | **Required:** List of zoom/center positions for the map.
See examples and MapPosition-Object documentation below for details.

**Type:** `array[MapPosition]`
**Default value:** `Sample set` | +| `mapHeight` | Height of the map. Must be string with pixels and "px" postfix. Percentage values won't work.

**Type:** `string` (pixels)
**Default value:** `'420px'` | +| `mapWidth` | Width of the map. Must be a string with pixels and "px" postfix. Percentage values won't work.

**Type:** `string` (pixels)
**Default value:** `'420px'` | +| `mapUrl` | Option to use an alternative map. In most cases you are fine with the default but you can find more maps [here](https://wiki.openstreetmap.org/wiki/Tile_servers).

**Type:** `string`
**Default value:** `'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png'`
**Alternative uncolored map:** '`https://tiles.wmflabs.org/bw-mapnik/${z}/${x}/${y}.png`' | +| `maxHistoryFrames` | Maximum number of history frames. There is one frame every 10 minutes. Setting this to 6 would show history radar layers of the last hour until now. If set to -1, all available history frames are shown.
As of today, the **API provides 12 history frames** -> 2h.

**Type:** `int`
**Default value:** `-1` | +| `maxForecastFrames` | Maximum number of forecast frames. There is one frame every 10 minutes. Setting this to 2 would show forecast radar layers from now to 20 minutes in the future. If set to -1, all available forecast frames are shown.
As of today, the **API provides 3 forecast frames** -> 30min.

**Type:** `int`
**Default value:** `-1` | +| `substitudeModules` | (Experimental) If `displayOnlyOnRain` is turned on, you can define a list of module names that are hidden in favor of the map.

**Type:** `array[string]`
**Default value:** `[]`
**Example:** `['MMM-Jast', 'calendar']` | +| `timeFormat` | Option to override the Magic Mirror's global time format to 12 or 24 for this module.

**Type:** `int`
**Default value:** `[Global Config]` or `24` | +| `updateIntervalMs` | Update interval for fetching new radar frames from the RainViewer.com API. (New frames are released every 10 minutes)

**Type:** `int`
**Default value:** `300000` (time in milliseconds) | ### Marker Object -| Option | Description | -| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `lat` | **Required:** Marker's latitude.

**Type:** `float` | -| `lng` | **Required:** Marker's longitude.

**Type:** `float` | -| `color` | Marker's color.

**Possible values:** `'black','blue','gold','green','grey','orange','red','violet','yellow'`
**Type:** `string` | +| Option | Description | +| ------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `lat` | **Required:** Marker's latitude.

**Type:** `float` | +| `lng` | **Required:** Marker's longitude.

**Type:** `float` | +| `color` | Marker's color.

**Possible values:** `'black','blue','gold','green','grey','orange','red','violet','yellow'`
**Type:** `string` | ### MapPosition Object -| Option | Description | -| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `lat` | **Required:** Position's latitude.

**Type:** `float` | -| `lng` | **Required:** Position's longitude.

**Type:** `float` | -| `zoom` | Either set a zoom level or defaultZoomLevel is used.

**Range:** `0 (whole world) - 20 (small building)`
**Type:** `number` | -| `loops` | Number of loops/iterations until the map moves to the next position. If no number is set, a value of `1` is used.

**Type:** `number` | - +| Option | Description | +| ------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| `lat` | **Required:** Position's latitude.

**Type:** `float` | +| `lng` | **Required:** Position's longitude.

**Type:** `float` | +| `zoom` | Either set a zoom level or defaultZoomLevel is used.

**Range:** `0 (whole world) - 20 (small building)`
**Type:** `number` | +| `loops` | Number of loops/iterations until the map moves to the next position. If no number is set, a value of `1` is used.

**Type:** `number` | ## Contribution and Development + This module is written in TypeScript and compiled with Rollup. The source files are located in the `/src` folder. Compile target files with `npm run build`. diff --git a/tsconfig.json b/tsconfig.json index e5d7825..4366e56 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,10 @@ { - "compilerOptions": { - "module": "commonjs", - "noImplicitAny": false, - "noUnusedLocals": true, - "noImplicitThis": true, - "sourceMap": false, - "target": "es6" - } + "compilerOptions": { + "module": "commonjs", + "noImplicitAny": false, + "noUnusedLocals": true, + "noImplicitThis": true, + "sourceMap": false, + "target": "es6" + } } diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 3746ff7..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,38 +0,0 @@ -const path = require("path"); -const TerserPlugin = require('terser-webpack-plugin'); - -const clientConfig = { - entry: "./src/client/Client.ts", - target: "web", - resolve: { - extensions: [".ts"] - }, - output: { - path: path.resolve(__dirname), - filename: "MMM-RAIN-MAP.js" - }, - module: { - rules: [ - { - test: /\.ts$/, - include: [path.resolve(__dirname, "src/client")], - loader: "ts-loader" - } - ] - }, - optimization: { - minimize: true, - minimizer: [ - new TerserPlugin({ - terserOptions: { - format: { - comments: false, - }, - }, - extractComments: false, - }), - ], - }, -}; - -module.exports = [clientConfig];