Thanks to: @Developer-Incoming, @eltociear, @geraki, @khassel,
@KristjanESPERANTO, @MagMar94, @mixasgr, @n8many, @OWL4C, @rejas,
@savvadam, @sdetweil.
> ⚠️ This release needs nodejs version `v22.14.0 or higher`
### Added
- Add CSS support to the digital clock hour/minute/second through the
use of the classes `clock-hour-digital`, `clock-minute-digital`, and
`clock-second-digital`.
- Add Arabic (#3719) and Esperanto translation.
- Mark option `secondsColor` as deprecated in clock module.
- Add Greek translation to Alerts module.
- [newsfeed] Add specific ignoreOlderThan value (override) per feed
(#3360)
- [weather] Added option Humidity to hourly View
- [weather] Added option to hide hourly entries that are Zero, hiding
the entire column if empty.
- [updatenotification] Added option to iterate over modules directory
instead using modules defined in `config.js` (#3739)
### Changed
- [core] starting clientonly now checks for needed env var
`WAYLAND_DISPLAY` or `DISPLAY` and starts electron with needed
parameters (if both are set wayland is used) (#3677)
- [core] Optimize systeminformation calls and output (#3689)
- [core] Add issue templates for feature requests and bug reports
(#3695)
- [core] Adapt `start:x11:dev` script
- [weather/yr] The Yr weather provider now enforces a minimum
`updateInterval` of 600 000 ms (10 minutes) to comply with the terms of
service. If a lower value is set, it will be automatically increased to
this minimum.
- [weather/weatherflow] Fixed icons and added hourly support as well as
UV, precipitation, and location name support.
- [workflow] Run `sudo apt-get update` before installing packages to
avoid install errors
- [workflow] Exclude issues with label `ready (coming with next
release)` from stale job
### Removed
### Updated
- [core] Update requirements and dependencies including electron to v35
and formatting (#3593, #3693, #3717)
- [core] Update prettier, ESLint and simplify config
- Update Greek translation
### Fixed
- [calendar] Fix clipping events being broadcast (#3678)
- [tests] Fix Electron tests by running them under new github image
ubuntu-24.04, replace xserver with labwc, running under xserver and
labwc depending on env variable WAYLAND_DISPLAY is set (#3676)
- [calendar] Fix arrayed symbols, #3267, again, add testcase, add
testcase for #3678
- [weather] Fix wrong weatherCondition name in openmeteo provider which
lead to n/a icon (#3691)
- [core] Fix wrong port in log message when starting server only (#3696)
- [calendar] Fix NewYork event processed on system in Central timezone
shows wrong time #3701
- [weather/yr] The Yr weather provider is now able to recover from bad
API responses instead of freezing (#3296)
- [compliments] Fix evening events being shown during the day (#3727)
- [weather] Fixed minor spacing issues when using UV Index in Hourly
- [workflow] Fix command to run spellcheck
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Ross Younger <crazyscot@gmail.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: jkriegshauser <joshuakr@nvidia.com>
Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: vppencilsharpener <tim.pray@gmail.com>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: Brian O'Connor <btoconnor@users.noreply.github.com>
Co-authored-by: WallysWellies <59727507+WallysWellies@users.noreply.github.com>
Co-authored-by: Jason Stieber <jrstieber@gmail.com>
Co-authored-by: jargordon <50050429+jargordon@users.noreply.github.com>
Co-authored-by: Daniel <32464403+dkallen78@users.noreply.github.com>
Co-authored-by: Ryan Williams <65094007+ryan-d-williams@users.noreply.github.com>
Co-authored-by: Panagiotis Skias <panagiotis.skias@gmail.com>
Co-authored-by: Marc Landis <dirk.rettschlag@gmail.com>
Co-authored-by: HeikoGr <20295490+HeikoGr@users.noreply.github.com>
Co-authored-by: Pedro Lamas <pedrolamas@gmail.com>
Co-authored-by: veeck <gitkraken@veeck.de>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Ikko Eltociear Ashimine <eltociear@gmail.com>
Co-authored-by: DevIncomin <56730075+Developer-Incoming@users.noreply.github.com>
Co-authored-by: Nathan <n8nyoung@gmail.com>
Co-authored-by: mixasgr <mixasgr@users.noreply.github.com>
Co-authored-by: Savvas Adamtziloglou <savvas-gr@greeklug.gr>
Co-authored-by: Konstantinos <geraki@gmail.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
This PR will introduce different issue templates for bug reports,
feature requests and so on on GitHub. There is still room for
fine-tuning, but it's reached a state to show it to you and get
feedback.
I think that this can lead to better bug reports.
You can see the result in my repo:
https://github.com/KristjanESPERANTO/MagicMirror/issues/new/choose
Feel free to create new issues for testing.
What do you think? Do we want to pursue this further?
# Conflicts:
# CHANGELOG.md
## [2.30.0] - 2025-01-01
Thanks to: @xsorifc28, @HeikoGr, @bugsounet, @khassel,
@KristjanESPERANTO, @rejas, @sdetweil.
> ⚠️ This release needs nodejs version `v20` or `v22 or higher`, minimum
version is `v20.18.1`
### Added
- [core] Add wayland and windows start options to `package.json` (#3594)
- [docs] Add step for npm publishing in release process (#3595)
- [core] Add GitHub workflow to run spellcheck a few days before each
release (#3623)
- [core] Add test flag to `index.html` to pass to module js for test
mode detection (needed by #3630)
- [core] Add export on animation names (#3644)
- [compliments] Add support for refreshing remote compliments file, and
test cases (#3630)
- [linter] Re-add `eslint-plugin-import`now that it supports ESLint v9
(#3586)
- [linter] Re-activate `eslint-plugin-package-json` to lint
`package.json` (#3643)
- [linter] Add linting for markdown files (#3646)
- [linter] Add some handy ESLint rules.
- [calendar] Add ability to display end date for full date events, where
end is not same day (showEnd=true) (#3650)
- [core] Add text to the config.js.sample file about the locale variable
(#3654, #3655)
- [core] Add fetch timeout for all node_helpers (thru undici, forces
node 20.18.1 minimum) to help on slower systems. (#3660) (3661)
### Changed
- [core] Run code style checks in workflow only once (#3648)
- [core] Fix animations export #3644 only on server side (#3649)
- [core] Use project URL in fallback config (#3656)
- [core] Fix Access Denied crash writing js/positions.js (on synology
nas) #3651. new message, MM starts, but no modules showing (#3652)
- [linter] Switch to 'npx' for lint-staged in pre-commit hook (#3658)
### Removed
- [tests] Remove `node-pty` and `drivelist` from rebuilded test (#3575)
- [deps] Remove `@eslint/js` dependency. Already installed with `eslint`
in deep (#3636)
### Updated
- [repo] Reactivate `stale.yaml` as GitHub action to mark issues as
stale after 60 days and close them 7 days later (if no activity) (#3577,
#3580, #3581)
- [core] Update electron dependency to v32 (test electron rebuild) and
all other dependencies too (#3657)
- [tests] All test configs have been updated to allow full external
access, allowing for easier debugging (especially when running as a
container)
- [core] Run and test with node 23 (#3588)
- [workflow] delete exception `allow-ghsas: GHSA-8hc4-vh64-cxmj` in
`dep-review.yaml` (#3659)
### Fixed
- [updatenotification] Fix pm2 using detection when pm2 script is inside
or outside MagicMirror root folder (#3576) (#3605) (#3626) (#3628)
- [core] Fix loading node_helper of modules: avoid black screen, display
errors and continue loading with next module (#3578)
- [weather] Change default value for weatherEndpoint of provider
openweathermap to "/onecall" (#3574)
- [tests] Fix electron tests with mock dates, the mock on server side
was missing (#3597)
- [tests] Fix testcases with hard coded Date.now (#3597)
- [core] Fix missing `basePath` where `location.host` is used (#3613)
- [compliments] croner library changed filenames used in latest version
(#3624)
- [linter] Fix ESLint ignore pattern which caused that default modules
not to be linted (#3632)
- [core] Fix module path in case of sub/sub folder is used and use
path.resolve for resolve `moduleFolder` and `defaultModuleFolder` in
app.js (#3653)
- [calendar] Update to resolve issues #3098#3144#3351#3422#3443#3467#3537 related to timezone changes
- [calendar] Fix#3267 (styles array), also fixes event with both exdate
AND recurrence(and testcase)
- [calendar] Fix showEndsOnlyWithDuration not working, #3598, applies
ONLY to full day events
- [calendar] Fix showEnd for Full Day events (#3602)
- [tests] Suppress "module is not defined" in e2e tests (#3647)
- [calendar] Fix#3267 (styles array, really this time!)
- [core] Fix#3662 js/positions.js created incorrectly
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Ross Younger <crazyscot@gmail.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: jkriegshauser <joshuakr@nvidia.com>
Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com>
Co-authored-by: vppencilsharpener <tim.pray@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: Brian O'Connor <btoconnor@users.noreply.github.com>
Co-authored-by: WallysWellies <59727507+WallysWellies@users.noreply.github.com>
Co-authored-by: Jason Stieber <jrstieber@gmail.com>
Co-authored-by: jargordon <50050429+jargordon@users.noreply.github.com>
Co-authored-by: Daniel <32464403+dkallen78@users.noreply.github.com>
Co-authored-by: Ryan Williams <65094007+ryan-d-williams@users.noreply.github.com>
Co-authored-by: Panagiotis Skias <panagiotis.skias@gmail.com>
Co-authored-by: Marc Landis <dirk.rettschlag@gmail.com>
Co-authored-by: HeikoGr <20295490+HeikoGr@users.noreply.github.com>
Co-authored-by: Pedro Lamas <pedrolamas@gmail.com>
Co-authored-by: veeck <gitkraken@veeck.de>
## [2.29.0] - 2024-10-01
Thanks to: @bugsounet, @dkallen78, @jargordon, @khassel,
@KristjanESPERANTO, @MarcLandis, @rejas, @ryan-d-williams, @sdetweil,
@skpanagiotis.
> ⚠️ This release needs nodejs version `v20` or `v22`, minimum version
is `v20.9.0`
### Added
- [compliments] Added support for cron type date/time format entries mm
hh DD MM dow (minutes/hours/days/months and day of week) see
https://crontab.cronhub.io for construction (#3481)
- [core] Check config at every start of MagicMirror² (#3450)
- [core] Add spelling check (cspell): `npm run test:spelling` and handle
spelling issues (#3544)
- [core] removed `config.paths.vendor` (could not work because `vendor`
is hardcoded in `index.html`), renamed `config.paths.modules` to
`config.foreignModulesDir`, added variable `MM_CUSTOMCSS_FILE` which -
if set - overrides `config.customCss`, added variable `MM_MODULES_DIR`
which - if set - overrides `config.foreignModulesDir`, added test for
`MM_MODULES_DIR` (#3530)
- [core] elements are now removed from `index.html` when loading script
or stylesheet files fails
- [core] Added `MODULE_DOM_UPDATED` notification each time the DOM is
re-rendered via `updateDom` (#3534)
- [tests] added minimal needed node version to tests (currently v20.9.0)
to avoid releases with wrong node version info
- [tests] Added `node-libgpiod` library to electron-rebuild tests
(#3563)
### Removed
- [core] removed installer only files (#3492)
- [core] removed raspberry object from systeminformation (#3505)
- [linter] removed `eslint-plugin-import`, because it doesn't support
ESLint v9. We will reenter it later when it does.
- [tests] removed `onoff` library from electron-rebuild tests (#3563)
### Updated
- [weather] Updated `apiVersion` default from 2.5 to 3.0 (#3424)
- [core] Updated dependencies including stylistic-eslint
- [core] nail down `node-ical` version to `0.18.0` with exception
`allow-ghsas: GHSA-8hc4-vh64-cxmj` in `dep-review.yaml` (which should
removed after next `node-ical` update)
- [core] Updated SocketIO catch all to new API
- [core] Allow custom modules positions by scanning index.html for the
defined regions, instead of hard coded (PR #3518 fixes issue #3504)
- [core] Detail optimizations in `config_check.js`
- [core] Updated minimal needed node version in `package.json`
(currently v20.9.0) (#3559) and except for v21 (no security updates)
(#3561)
- [linter] Switch to ESLint v9 and flat config and replace
`eslint-plugin-unicorn` by `@eslint/js`
- [core] fix discovering module positions twice after #3450
### Fixed
- Fixed `checks` badge in README.md
- [weather] Fixed issue with the UK Met Office provider following a
change in their API paths and header info.
- [core] add check for node_helper loading for multiple instances of
same module (#3502)
- [weather] Fixed issue for respecting unit config on broadcasted
notifications
- [tests] Fixes calendar test by moving it from e2e to electron with
fixed date (#3532)
- [calendar] fixed sliceMultiDayEvents getting wrong count and
displaying incorrect entries, Europe/Berlin (#3542)
- [tests] ignore `js/positions.js` when linting (this file is created at
runtime)
- [calendar] fixed sliceMultiDayEvents showing previous day without
config enabled
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ross Younger <crazyscot@gmail.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: jkriegshauser <joshuakr@nvidia.com>
Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: vppencilsharpener <tim.pray@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: Brian O'Connor <btoconnor@users.noreply.github.com>
Co-authored-by: WallysWellies <59727507+WallysWellies@users.noreply.github.com>
Co-authored-by: Jason Stieber <jrstieber@gmail.com>
Co-authored-by: jargordon <50050429+jargordon@users.noreply.github.com>
Co-authored-by: Daniel <32464403+dkallen78@users.noreply.github.com>
Co-authored-by: Ryan Williams <65094007+ryan-d-williams@users.noreply.github.com>
Co-authored-by: Panagiotis Skias <panagiotis.skias@gmail.com>
Co-authored-by: Marc Landis <dirk.rettschlag@gmail.com>
## [2.28.0] - 2024-07-01
Thanks to: @btoconnor, @bugsounet, @JasonStieber, @khassel,
@kleinmantara and @WallysWellies.
> ⚠️ This release needs nodejs version >= v20
### Added
- [calendar] Added config option "showEndsOnlyWithDuration" for default
calendar
- [compliments] Added `specialDayUnique` config option, defaults to
`false` (#3465)
- [weather] Provider weathergov: Use `precipitationLast3Hours` if
`precipitationLastHour` is `null` (#3124)
### Removed
- [tests] delete node v18 support (#3462)
### Updated
- [core] Update dependencies including electron to v31
- [core] use node >= v20 (#3462)
- [core] Update `config.js.sample` to use openmeteo as weather provider
which needs no api key
- [tests] Use latest@version of node for `automated-tests.yaml` (#3483)
- [updatenotification] Avoid using pm2 when running in docker container
### Fixed
- [core] Fixed crash possibility if `module: <name>` is not defined and
on `postion: <positon>` mistake (#3445)
- [weather] Fixed precipitationProbability in forecast for provider
openmeteo (#3446)
- [weather] Fixed type=daily for provider openmeteo having no data when
running after 23:00 (#3449)
- [weather] Fixed type=daily for provider openmeteo showing nightly
icons in forecast when current time is "nightly" (#3458)
- [weather] Fixed forecast and hourly weather for provider openmeteo to
use real temperatures, not apparent temperatures (#3466)
- [tests] Fixed e2e tests running in docker container which needs
`address: "0.0.0.0"` (#3479)
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ross Younger <crazyscot@gmail.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: jkriegshauser <joshuakr@nvidia.com>
Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: vppencilsharpener <tim.pray@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: Brian O'Connor <btoconnor@users.noreply.github.com>
Co-authored-by: WallysWellies <59727507+WallysWellies@users.noreply.github.com>
Co-authored-by: Jason Stieber <jrstieber@gmail.com>
## [2.27.0] - 2024-04-01
Thanks to: @bugsounet, @crazyscot, @illimarkangur, @jkriegshauser,
@khassel, @KristjanESPERANTO, @Paranoid93, @rejas, @sdetweil and
@vppencilsharpener.
This release marks the first release without Michael Teeuw (@michmich).
A very special thanks to him for creating MagicMirror and leading the
project for so many years.
For more info, please read the following post: [A New Chapter for
MagicMirror: The Community Takes the
Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead).
### Added
- Output of system information to the console for troubleshooting (#3328
and #3337), ignore errors under aarch64 (#3349)
- [chore] Add `eslint-plugin-package-json` to lint the `package.json`
files (#3368)
- [weather] `showHumidity` config is now a string describing where to
show this element. Supported values: "wind", "temp", "feelslike",
"below", "none". (#3330)
- electron-rebuild test suite for electron and 3rd party modules
compatibility (#3392)
- Create MM² icon and attach it to electron process (#3407)
### Updated
- Update updatenotification (update_helper.js): Recode with pm2 library
(#3332)
- Removing lodash dependency by replacing merge by spread operator
(#3339)
- Use node prefix for build-in modules (#3340)
- Rework logging colors (#3350)
- Update pm2 to v5.3.1 with no allow-ghsas (#3364)
- [chore] Update husky and let lint-staged fix ESLint issues
- [chore] Update dependencies including electron to v29 (#3357) and
node-ical
- Update translations for estonian (#3371)
- Update electron to v29 and update other dependencies
- [calendar] fullDay events over several days now show the left days
from the first day on and 'today' on the last day
- Update layout of current weather indoor values
### Fixed
- Correct apibase of weathergov weatherprovider to match documentation
(#2926)
- Worked around several issues in the RRULE library that were causing
deleted calender events to still show, some
initial and recurring events to not show, and some event times to be off
an hour. (#3291)
- Skip changelog requirement when running tests for dependency updates
(#3320)
- Display precipitation probability when it is 0% instead of blank/empty
(#3345)
- [newsfeed] Suppress unsightly animation cases when there are 0 or 1
active news items (#3336)
- [newsfeed] Always compute the feed item URL using the same helper
function (#3336)
- Ignore all custom css files (#3359)
- [newsfeed] Fix newsfeed stall issue introduced by #3336 (#3361)
- Changed `log.debug` to `log.log` in `app.js` where logLevel is not set
because config is not loaded at this time (#3353)
- [calendar] deny fetch interval < 60000 and set 60000 in this case
(prevent fetch loop failed) (#3382)
- added message in case where config.js is missing the module.export
line PR #3383
- Fixed an issue where recurring events could extend past their
recurrence end date (#3393)
- Don't display any `npm WARN <....>` on install (#3399)
- Fixed move suncalc dependency to production from dev, as it is used by
clock module
- [compliments] Fix mirror not responding anymore when no compliments
are to be shown (#3385)
### Deleted
- Unneeded file headers (#3358)
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Ross Younger <crazyscot@gmail.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: jkriegshauser <joshuakr@nvidia.com>
Co-authored-by: illimarkangur <116028111+illimarkangur@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: vppencilsharpener <tim.pray@gmail.com>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
- update `node-ical` to `v0.17.1` (and other deps)
- remove `luxon` (not needed anymore with new `node-ical` version)
- fix `navigator is not defined` errors in e2e tests when running with
Node `v20`
for all files beginning with `config/config.js` so e.g. `config.js` and
`config.js.template` are included.
Otherwise the test will always fail locally if someone has renamed
`config.js.sample` to `config.js`.
In the latest versions of ESLint, more and more formatting rules were
removed or declared deprecated. These rules have been integrated into
the new Stylistic package (https://eslint.style/guide/why) and expanded.
Stylistic acts as a better formatter for JavaScript as Prettier.
With this PR there are many changes that make the code more uniform, but
it may be difficult to review due to the large amount. Even if I have no
worries about the changes, perhaps this would be something for the
release after next.
Let me know what you think.
This change replaces the font-awesome moon icon and percent-lit with an
icon showing the current lunar phase.
It uses emoji, which may not be installed on all machines. The fallback
text version is backwards (the dark part of the moon is text-color,
which is normally black but white in MagicMirror).
---------
Co-authored-by: veeck <michael.veeck@nebenan.de>
Took the ones from dependabot and updated the rest...
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Jest was in the plugin array of the ESLint configuration, but no rules
were enabled. So ESLint hasn't checked any Jest rules yet.
So I activated the recommended Jest rules and added a few more. Then I
fixed the issues (mostly automatically). I have deactivated the rules
"jest/expect-expect" and "jest/no-done-callback" for the time being, as
they would have entailed major changes. I didn't want to make the PR too
big.
I'm not a Jest expert, but the changes so far look good to me. What do
you think of that @khassel? 🙂
- Remove "prettier" from plugin array, because it's already enabled by
"plugin:prettier/recommended"
- Remove "jsdoc" from plugin array, because it's already enabled by
"plugin:jsdoc/recommended"
- Enable recommended import rules
- Add two additional import rules
Note: To avoid overloading this PR I'll tackle the jest part with
another PR after this one has been dealt with.
> - Does the pull request solve a **related** issue?
Fixes#2550
> - What does the pull request accomplish? Use a list if needed.
changes the loadUrl to use localhost, as electron and MM are on this
same system
the mm 'server' is still listening on all adapters, including localhost
I try to use only `html-to-text` library
it's will solve issue #3235
@rejas, @sdetweil, @khassel: Can you do tests with your own feeds?
Thanks for feedbacks
Added my (modified) updater main core into updatenotification default
module
Missing: callback display in MM² (i will code it after)
new part of configuration added:
```
updates: [
// array of module update commands
{
// with embed npm script
"MMM-Test": "npm run update"
},
{
// with "complex" process
"MMM-OtherSample": "rm -rf package-lock.json && git reset --hard && git pull && npm install"
},
{
// with git pull && npm install
"MMM-OtherSample2": "git pull && npm install"
},
{
// with a simple git pull
"MMM-OtherSample3": "git pull"
}
],
updateTimeout: 2 * 60 * 1000, // max update duration
updateAutorestart: false // autoRestart MM when update done ?
```
@khassel: i need your help
I don't use docker, maybe you can help me for this:
How can i check if MM² is running inside a docker ? (from MM² main core)
Actually, I check if we use pm2 or not.
I have to check if docker is used or not too
last time you tell me: "you can't use updater with docker", so I want to
check and deny any update if docker used
---------
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Fixes: #3256
BUT.. the testcase is inconclusive.. as the code FAILS without the fix,
BUT somehow RETURNS 0 entries..
in real life run the node helper fails, and all calendar processing
stops.
Hello and thank you for wanting to contribute to the MagicMirror²
project
**Please make sure that you have followed these 4 rules before
submitting your Pull Request:**
> 1. Base your pull requests against the `develop` branch.
> 2. Include these infos in the description:
>
> - Does the pull request solve a **related** issue?
> - If so, can you reference the issue like this `Fixes
#<issue_number>`?
> - What does the pull request accomplish? Use a list if needed.
> - If it includes major visual changes please add screenshots.
>
> 3. Please run `npm run lint:prettier` before submitting so that
> style issues are fixed.
> 4. Don't forget to add an entry about your changes to
> the CHANGELOG.md file.
**Note**: Sometimes the development moves very fast. It is highly
recommended that you update your branch of `develop` before creating a
pull request to send us your changes. This makes everyone's lives
easier (including yours) and helps us out on the development team.
Thanks again and have a nice day!
Hello and thank you for wanting to contribute to the MagicMirror²
project
**Please make sure that you have followed these 4 rules before
submitting your Pull Request:**
> 1. Base your pull requests against the `develop` branch.
DONE ;D
> 2. Include these infos in the description:
> - Does the pull request solve a **related** issue?
NO
> - What does the pull request accomplish? Use a list if needed.
For calendar entries containing a year (e.g. DOB) in the title, the age
can be calculated.
Example before:

after:

Achieved by adding a new keyword `transform` to customEvents
```
customEvents: [
{keyword: 'Geburtstag', symbol: 'birthday-cake', color: 'Gold', transform: { search: '^([^\']*) \'(\\d{4})$' , replace: '$1 ($2.)', yearmatchgroup: 2}},
{keyword: 'in Hamburg', transform: { search: ' in Hamburg$' , replace: ''}}
],
```
and therewith obsoleting `titleReplace`; a backward compatibility part
is already included.
If `yearmatchgroup` is unset, behaviour is as in previous code (some
additions to which RegExes are accepted, though)
If `yearmatchgroup` is set, it is considered the RegEx match group id,
which will be used for calculating the age.
> - If it includes major visual changes please add screenshots.
NO
> 3. Please run `npm run lint:prettier` before submitting so that style
issues are fixed.
DONE
> 4. Don't forget to add an entry about your changes to the CHANGELOG.md
file.
DONE
> Thanks again and have a nice day!
You too and if any questions, feel free to let me know.
---------
Co-authored-by: veeck <michael.veeck@nebenan.de>
related to #3185
* I have limited updated dom to one update
-> `updateDom()` is activated by a timer which resets when a new event
arrives (`CALENDAR_EVENTS`)
* I have set no speed to self update. I think it's not necessary
-> update it directly
If somebody can test and tell me result
In all case, I will patch my prod mirror for testing
Fixes#3227
and also
- removes unused code
- de-duplicates code fragments
- fixes typos
- inlines code
- adds more weather util tests
@martingron and @Justheretoreportanissue would you be so kind to check
if I didnt mess anything up?
## [2.25.0] - 2023-10-01
Thanks to: @bugsounet, @dgoth, @dependabot, @kenzal, @Knapoc,
@KristjanESPERANTO, @martingron, @NolanKingdon, @Paranoid93,
@TeddyStarinvest and @Ybbet.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you guys! You are
awesome!
> ⚠️ This release needs nodejs version >= `v18`, older releases have
reached end of life and will not work!
### Added
- Added UV Index support to OpenWeatherMap
- Added 'hideDuplicates' flag to the calendar module
- Added `allowOverrideNotification` to weather module to enable sending
current weather objects with the `CURRENT_WEATHER_OVERRIDE` notification
to supplement/replace the current weather displayed
- Added optional AnimateCSS animate for `hide()`, `show()`,
`updateDom()`
- Added AnimateIn and animateOut in module config definition
- Apply AnimateIn rules on the first start
- Added automatic client page reload when server was restarted by
setting `reloadAfterServerRestart: true` in `config.js`, per default
`false` (#3105)
- Added eventClass option for customEvents on the default calendar
- Added AnimateCSS integration in tests suite (#3206)
- Added npm dependabot [Reserved to developer] (#3210)
- Added improved logging for calendar (#3110)
### Removed
- **Breaking Change**: Removed `digest` authentication method from
calendar module (which was already broken since release `2.15.0`)
### Updated
- Update roboto fonts to version v5
- Update issue template
- Update dev/dependencies incl. electron to v26
- Replace pretty-quick by lint-staged
(<https://github.com/azz/pretty-quick/issues/164>)
- Update engine node >=18. v16 reached it's end of life. (#3170)
- Update typescript definition for modules
- Cleaned up nunjuck templates
- Replace `node-fetch` with internal fetch (#2649) and remove
`digest-fetch`
- Update the French translation according to the English file.
- Update dependabot incl. vendor/fonts (monthly check)
- Renew `package-lock.json` for release
### Fixed
- Fix engine check on npm install (#3135)
- Fix undefined formatTime method in clock module (#3143)
- Fix clientonly startup fails after async added (#3151)
- Fix electron width/heigth when using xrandr under bullseye
- Fix time issue with certain recurring events in calendar module
- Fix ipWhiteList test (#3179)
- Fix newsfeed: Convert HTML entities, codes and tag in description
(#3191)
- Respect width/height (no fullscreen) if set in electronOptions
(together with `fullscreen: false`) in `config.js` (#3174)
- Fix: AnimateCSS merge hide() and show() animated css class when we do
multiple call
- Fix `Uncaught SyntaxError: Identifier 'getCorsUrl' has already been
declared (at utils.js:1:1)` when using `clock` and `weather` module
(#3204)
- Fix overriding `config.js` when running tests (#3201)
- Fix issue in weathergov provider with probability of precipitation not
showing up on hourly or daily forecast
---------
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
Co-authored-by: Dave Child <dave@addedbytes.com>
Co-authored-by: grenagit <46225780+grenagit@users.noreply.github.com>
Co-authored-by: Grena <grena@grenabox.fr>
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Patrick <psieg@users.noreply.github.com>
Co-authored-by: Piotr Rajnisz <56397164+rajniszp@users.noreply.github.com>
Co-authored-by: Suthep Yonphimai <tomzt@users.noreply.github.com>
Co-authored-by: CarJem Generations (Carter Wallace) <cwallacecs@gmail.com>
Co-authored-by: Nicholas Fogal <nfogal.misc@gmail.com>
Co-authored-by: JakeBinney <126349119+JakeBinney@users.noreply.github.com>
Co-authored-by: OWL4C <124401812+OWL4C@users.noreply.github.com>
Co-authored-by: Oscar Björkman <17575446+oscarb@users.noreply.github.com>
Co-authored-by: Ismar Slomic <ismar@slomic.no>
Co-authored-by: Jørgen Veum-Wahlberg <jorgen.wahlberg@amedia.no>
Co-authored-by: Eddie Hung <6740044+eddiehung@users.noreply.github.com>
Co-authored-by: Bugsounet - Cédric <github@bugsounet.fr>
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Knapoc <Knapoc@users.noreply.github.com>
Co-authored-by: sam detweiler <sdetweil@gmail.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Co-authored-by: Paranoid93 <6515818+Paranoid93@users.noreply.github.com>
Co-authored-by: NolanKingdon <27908974+NolanKingdon@users.noreply.github.com>
Co-authored-by: J. Kenzal Hunter <kenzal.hunter@gmail.com>
Co-authored-by: Teddy <teddy.payet@gmail.com>
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
Co-authored-by: martingron <61826403+martingron@users.noreply.github.com>
Co-authored-by: dgoth <132394363+dgoth@users.noreply.github.com>
I just see `electron` package used in develop branch have `1 high
severity vulnerability`
Detail is [there](https://github.com/advisories/GHSA-j7hp-h8jx-5ppr)
We can patch it with electron v26.2.2 (last version at this day) and
will correct it
(ChangeLog is not needed in this case)
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Hi,
Just because, i never try to code a test
I purpose to supervise this work
After, perhaps it is not necessary to integrate it in develop branch.
It's up to you to decide
Hello,
This pull request allows you to add a class to the tr of the event
sought in customEvents. You must enter the class with the "eventClass"
option.
---------
Co-authored-by: TeddyStarinvest <teddy.payet@starinvest.com>
PR: #3113
I see this bugs:
AnimateCSS merge hide() and show() animated css class when we do
multiple call
--> result it will stay en hide state
I think event listener (is animateCSS file) is not a proper solution
I correct it with like traditional code with timer
Fix too: AnimateIn on first start
... in `config.js`.
Solves #3174
With getting width/heigt from
`electron.screen.getPrimaryDisplay().workAreaSize` introduced with
https://github.com/MichMich/MagicMirror/pull/3161 the solution was to
remove the `setFullscreen` line.
So per default the fullscreen resolution is used but when someone now
uses `electronOptions.width`/`electronOptions.height` in `config.js`
these parameters are used and so "no fullscreen" is possible.
related to #2649
I was able to move to internal fetch and all tests seems fine so far.
But we have one problem with the calendar module. In the docs we have
several authentication methods and one of them is `digest`. For this we
used `digest-fetch` which needs `node-fetch` (this is not so clear from
code but I was not able to get it working).
So we have 3 options:
- remove `digest` as authentication method for calendar module (this is
what this PR does at the moment)
- find an alternative npm package or implement the digest stuff
ourselves
- use `digest-fetch` and `node-fetch` for calendar module (so they would
remain as dependencies in `package.json`)
Opinions? @KristjanESPERANTO @rejas @sdetweil @MichMich
Update calendarfetcherutils.js to force recurrence date time to be the
same as event datetime
I found an issue with one of my calendars displaying the wrong time for
certain recurring events. Each event was set up by someone in a
different timezone (Central European) than my own (Eastern US). I traced
the issue back to the `Rrule.between()` method generating odd time
portions under certain circumstances.
The fix I found was to set the UTC time portion of the recurrence
datetime to be the same as the UTC time portion of the event start date.
This resolved the issues with the maladjusted event times, and had no
effect on other event times. While there may be edge cases that are
affected, I have been unable to locate any.
---------
Co-authored-by: Veeck <github@veeck.de>
Hi,
This is my testing code for AnimateCSS for `show()`, `hide()`,
`updateDom()`
Naturally, we have to do better !
I voluntarily modify `newsfeed` and `compliments` in order to test
Note: I will correct checks later... it's a test...
---------
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
Co-authored-by: veeck <michael.veeck@nebenan.de>
Fixes#3126
Added the option `allowOverrideNotification` to `weather.js`. This
allows the module to receive the `CURRENT_WEATHER_OVERRIDE`
notification. The expected payload for this notification is a
full/partial `weatherObject` that is used to supplement/replace the
existing `weatherObject` returned by whichever weather provider is in
use.
No visual changes.
First time contributing - let me know if I've missed something
🙂
---------
Co-authored-by: veeck <michael.veeck@nebenan.de>
This PR uses `electron.screen.getPrimaryDisplay().workAreaSize` under
electron to get the screen size.
If this fails the current defaults (800x600) are used.
This solves some problems with xrandr under bullseye where the sreen
comes up with 800x600 instead of fullscreen, e.g. described
[here](https://khassel.gitlab.io/magicmirror/pi-modules/).
Tested this on my pi setup.
By the way, the Issue #1919 is back on my side (not related to this PR)
...
Takes https://github.com/MichMich/MagicMirror/pull/3153 (why does that
always base against master despite the yaml configuring it against
develop?) and updates othe rminor dependencies (not prettier v3 that
will take a little time)
---------
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
there are no "all" files in the v5 versions of roboto-fonts anymore so I
used the content of their css files in `roboto.css`.
~~PR is set to draft because @rejas wants to wait until next release is
done.~~
fixes#3138 just in case #3137 doesnt get worked on until the next
release
- inc fetchInterval for sample calender
- add fetchInterval config per calendar
... but e.g. a version tag
fixes#3130
This happens e.g. in my docker image where I use the version tag to get
the mm sources.
With this PR the error message is avoided and there will be never an
updatenotification when using a tag. This is o.k. because a tag should
never be moved.
Hi,
Like some default modules, I propose to send an `UPDATES` notification
in an array with the git information of these modules
This allows developers to create their own auto-update system (which
I've been using in my case since 3 years, with automatic things)
Of course, for security reasons `MagicMirror` is excluded
---------
Co-authored-by: bugsounet <bugsounet@bugsounet.fr>
~~there are no "all" files in the v5 versions of roboto-fonts anymore so
I used the content of their css files in `roboto.css`~~
coming with separate PR
- update electron to v25
- added `overrides:` section to `package.json` to fix
https://github.com/stylelint/stylelint/issues/6898 (must be removed when
fixed upstream, fixing the version to `v15.6.2` did not fix the problem)
- update other deps
This pr adds (config.js toggleable) showUV_Index to the hourly and
current weather modules, with right now only openmeteo configured to
supply the data. Other providers could have support too by adding
`uv_index` to current and hourly.
For example the current weather looks like

positioned after sunset in the top row.
The following "hacks" are included and could be fixed to make it
cleaner, but the functionality is wanted and it works without problem.
- To hide entries where the UV Index is 0 i added an if statement to the
`hourly.njk` which is not how precipitation is handled.
The following are minor things that might not need fixing:
- The forecast option does not have UV support. This might not be
relevant since UV changes throughout the day but i tried to implement a
"max_UV" to openmeteo.js, but am not confident enough in JS to
accomplish that.
- The UV Icon is wi-hot and manually added to the `.njk`'s. This could
be made changeable by a config but does not seem relevant since wi-hot
is not used by anything else as far as i can tell.
---------
Co-authored-by: veeck <michael@veeck.de>
Fix for today's probability-of-precipitation weather module's envcanada
provider.
Without which, requesting `showPrecipitationProbability` causes
"undefined" to be shown.
Consistent with method used elsewhere in the file:
abe5c08a52/modules/default/weather/providers/envcanada.js (L395-L399)
Adding date to the clock module when displayType is "analog" and
"showDate" is true. The setting in analogShowDate is respected.
Fixes#3100
---------
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Co-authored-by: Veeck <github@veeck.de>
Fixes#3095.
Param `hideOngoing` is by default set to `false`, but the event
filtering handles `full day` & `non-full day` events inconsistently. For
`non-full day` _ongoing_ and _upcoming_ events are returned, while for
`full day` only _upcoming_ events where returned.
Copy `config.js` to a single `config.js-old` file whenever a
`config.template` is present, instead of using `Date()` as a suffix.
Creating files with a timestamp suffix means that whenever Magic Mirror
is restarted or recreated a new file is written into the config
directory.
Benefits:
* Single backup file will avoid excessive writing of files
* Saves space and usage on SD cards.
* Makes the folder cleaner and easier to overview, compared to ending up
with something like this as time goes on:

Due to the size of the commit there is no need for a long explanation:
Openmeteo supports precipitation probability in api, but the weather
provider .js had no support for it. After adding 4 lines it works as
expected. This should have no consequences on other files but improves
usability for (imo) the best weather provider.
---------
Co-authored-by: veeck <michael@veeck.de>
While waiting for the easterbunny I cleaned up some bad coding practice
:-)
Very open for comments especially regarding the places I commented
myself...
---------
Co-authored-by: veeck <michael@veeck.de>
Refactored some methods in calendar module:
- move methods into own file
- dont call shorten method from titelTransform because why? just call
them after each other.
- added tests for util methods
- cleaned up other tests
---------
Co-authored-by: veeck <michael@veeck.de>
Updated sunrise/sunset times to display user-requested timezone rather
than system timezone.
Note: rebase of #3069 against develop rather than master
Co-authored-by: Veeck <github@veeck.de>
- current electron v22 has end of life 07 Jul 2023 so it has to be
upgraded before next release
- removed th.json from root dir (came back with latest release)
- updated other dependencies
## [2.23.0] - 2023-04-04
Thanks to: @angeldeejay, @buxxi, @CarJem, @dariom, @DaveChild, @dWoolridge, @grenagit, @Hirschberger, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @nfogal, @psieg, @rajniszp, @retroflex, @SkySails and @tomzt.
Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you guys! You are awesome!
### Added
- Added increments for hourly forecasts in weather module (#2996)
- Added tests for hourly weather forecast
- Added possibility to ignore MagicMirror repo in updatenotification module
- Added Pirate Weather as new weather provider (#3005)
- Added possibility to use your own templates in Alert module
- Added error message if `<modulename>.js` file is missing in module folder to get a hint in the logs (#2403)
- Added possibility to use environment variables in `config.js` (#1756)
- Added option `pastDaysCount` to default calendar module to control of how many days past events should be displayed
- Added thai language to alert module
- Added option `sendNotifications` in clock module (#3056)
### Removed
- Removed darksky weather provider
- Removed unneeded (and unwanted) '.' after the year in calendar repeatingCountTitle (#2896)
### Updated
- Use develop as target branch for dependabot
- Update issue template, contributing doc and sample config
- The weather modules clearly separates precipitation amount and probability (risk of rain/snow)
- This requires all providers that only supports probability to change the config from `showPrecipitationAmount` to `showPrecipitationProbability`.
- Update tests for weather and calendar module
- Changed updatenotification module for MagicMirror repo only: Send only notifications for `master` if there is a tag on a newer commit
- Update dates in Calendar widgets every minute
- Cleanup jest coverage for patches
- Update `stylelint` dependencies, switch to `stylelint-config-standard` and handle `stylelint` issues, update `main.css` matching new rules
- Update Eslint config, add new rule and handle issue
- Convert lots of callbacks to async/await
- Revise require imports (#3071 and #3072)
### Fixed
- Fix wrong day labels in envcanada forecast (#2987)
- Fix for missing default class name prefix for customEvents in calendar
- Fix electron flashing white screen on startup (#1919)
- Fix weathergov provider hourly forecast (#3008)
- Fix message display with HTML code into alert module (#2828)
- Fix typo in french translation
- Yr wind direction is no longer inverted
- Fix async node_helper stopping electron start (#2487)
- The wind direction arrow now points in the direction the wind is flowing, not into the wind (#3019)
- Fix precipitation css styles and rounding value
- Fix wrong vertical alignment of calendar title column when wrapEvents is true (#3053)
- Fix empty news feed stopping the reload forever
- Fix e2e tests (failed after async changes) by running calendar and newsfeed tests last
- Lint: Use template literals instead of string concatenation
- Fix default alert module to render HTML for title and message
- Fix Open-Meteo wind speed units
Fixes#3056
One question here would be if the default for this new option should be
true or false.
True: keeps the current behaviour, nobody needs to change his config if
they rely on this option
False: keeps the clock notifications quiet, doesnt waste time/resources,
keeps the noise low
Maybe the original author @cybex-dev can weigh in on this, and why he
added this notification.
---------
Co-authored-by: veeck <michael@veeck.de>
Fixes#3056
One question here would be if the default for this new option should be
true or false.
True: keeps the current behaviour, nobody needs to change his config if
they rely on this option
False: keeps the clock notifications quiet, doesnt waste time/resources,
keeps the noise low
Maybe the original author @cybex-dev can weigh in on this, and why he
added this notification.
---------
Co-authored-by: veeck <michael@veeck.de>
To fix issue caused by #3071
In order to still fulfill the new linter rule `import/order`, I replaced
the alias with the path.
I also see two other approaches, but I opted for the simplest one here
for now.
The other approaches:
1. Also create an alias for `app`.
2. Use new `imports` (like in PR #2934), but let `_moduleAliases`
untouched to stay compatible to 3rd party modules.
**Edit**: Oh, I thought of another option:
- Add `require("module-alias/register");`
- order (external first)
- remove superfluous file extensions
- new line after imports
- deconstruct (only one time (in `check_config.js`))
- fix path (only one time (in `global-setup.js`))
On `develop` my css test failed because I was already on newest
dependencies.
- update deps
- update `main.css` because of stylelint issue
Co-authored-by: Veeck <github@veeck.de>
We have used it inconsistently till now. Template literals are more
modern and easier to maintain in my opinion.
Because that's a large amount of changes, here's a way to reproduce it:
I added the rule `"prefer-template": "error"` to the `.eslintrc.json`
and did an autofix. Since this caused a new problem in line 409 of
`newsfeed.js`, I reversed it in that line and also removed the rule from
the eslint config file.
The rule is described here:
https://eslint.org/docs/latest/rules/prefer-template
Note: I've played around with some other linter rules as well, and some
seem to point to some specific, non-cosmetic, issues. But before I dive
even deeper and then introduce even bigger and hardly understandable
changes at once, I thought I'd start with this simple cosmetic rule.
Fixes [#3064](https://github.com/MichMich/MagicMirror/issues/3064)
- Fixes default alert module nunjucks templates to render HTML by
default unless 'titleType' and 'messageType' are set to 'text' in the
payload data
e.g.
Display Text:
`this.sendNotification('SHOW_ALERT', {type: "notification", title:
"<u>YoLink LeakSensor</u>", titleType: "text", message: "<b>" +
deviceName + "</b> reported an alarm that needs attention.",
messageType: "text"});`
Display HTML:
`this.sendNotification('SHOW_ALERT', {type: "notification", title:
"<u>YoLink LeakSensor</u>", message: "<b>" + deviceName + "</b> reported
an alarm that needs attention."});`
by running calendar and newsfeed tests last.
Additional change: allow unit tests to run parallel
This is no fix of the real issue of calendar and newsfeed tests but I
moved them to the end of the tests so other tests are not failing
anymore.
There are coming follow up PR's for the real fixes (when I find the
culprits).
With these change we can stay with the async changes done by @rejas and
https://github.com/MichMich/MagicMirror/pull/3060 is obsolete.
Hi,
want to include a birthday calendar to my mirror which shows upcoming
birthdays and as a reminder birthdays of the last two days.
I used
[MMM-CalendarExt2](https://github.com/MMM-CalendarExt2/MMM-CalendarExt2)
for this job in the past but the module is not supported any more and
very complicated to configure.
I managed to style the default calendar module to my needs but what i am
missing is to display already past events within a configurable time
range.
I included the translations of "YESTERDAY" and "DAYBEFOREYESTERDAY" to
all translation files and modified the code to accept a new option
`pastDaysCount` which controls of how many days past events should be
displayed.
---------
Co-authored-by: Veeck <github@veeck.de>
Percentage should be always rounded so that we dont get something like
"47.0000000001 %"
Some small typo and naming fixes also while I am here
---------
Co-authored-by: veeck <michael@veeck.de>
1. Update `stylelint` dependencies
- As of stylelint v15, we do not need `stylelint-config-prettier`
anymore:
https://github.com/prettier/stylelint-config-prettier/releases/tag/v9.0.5
2. Switch to `stylelint-config-standard`:
`stylelint-prettier/recommended` has not been updated for a long time
and still needs the old `stylelint-config-prettier`
3. Handle new `stylelint` issues
They weren't applied to wrong classnames, this PR fixes that and also
expands the weather util tests
---------
Co-authored-by: veeck <michael@veeck.de>
"Inspired" by my mistake in
https://github.com/MichMich/MagicMirror/pull/3028 this PR will add a
worfklow check for the branch a PR is based against.
Open question is if this prevents @MichMich from preparing a release?
---------
Co-authored-by: veeck <michael@veeck.de>
This commit adds several QOL features and adjustments to the calendar
module including:
- **New Options**
- ``coloredText``: ``(default: false)`` Determines if you want your
entry text to be colored based on the calendar's color
- ``coloredBorder``: ``(default: false)`` Determines if you want entry
borders to be colored based on the calendar's color
- ``coloredSymbol``: ``(default: false)`` Determines if you want entry
symbols to be colored based on the calendar's color
- ``coloredBackground``: ``(default: false)`` Determines if you want
entry backgrounds to be colored based on the calendar's color
> These new colored options allows for more out-of-box styling options
for the calendar module. With this the ``coloredSymbolOnly`` option has
been removed due to redundancy
- ``limitDaysNeverSkip``: ``(default: false)`` show every event for
every day regardless of if the day only has a single full day event
- ``flipDateHeaderTitle``: ``(default: false)`` determines if the title
for the date header in the ``dateheaders`` time format should align to
the left ``[eg: false]`` or right ``[eg: true]``
- **Layout Changes**
- ``dateheader`` is now a class avaliable for date headers in the
``dateheaders`` time format.
- Event entries have been better *container-ized* for better styling
(using the ``event-container`` class)
- ``repeatingCountTitle`` now has a seperator between the ``yearDiff``
and ``repeatingCountTitle``
- ``endDate`` in ``dateheaders`` now capitalizes it's first letter
Fixes#2953
This is an attempt to fix the issue with precipitation amount and
percentage mixup. I have created a separate
`precipitationPercentage`-variable where the probability of rain can be
stored.
The config options now has the old `showPrecipitationAmount` in addition
to a new setting: `showPrecipitationProbability` (shows the likelihood
of rain).
<details>
<summary>Examples</summary>
### Yr
I tested the Yr weather provider for a Norwegian city Bergen that has a
lot of rain. I have removed properties that are irrelevant for this demo
from the config-samples below.
Config:
```js
{
module: "weather",
config: {
weatherProvider: "yr",
type: "current",
showPrecipitationAmount: true,
showPrecipitationProbability: true
}
},
{
module: "weather",
config: {
weatherProvider: "yr",
type: "hourly",
showPrecipitationAmount: true,
showPrecipitationProbability: true
}
},
{
module: "weather",
config: {
weatherProvider: "yr",
type: "daily",
showPrecipitationAmount: true,
showPrecipitationProbability: true
}
}
```
Result:<br/>
<img width="444" alt="screenshot"
src="https://user-images.githubusercontent.com/34011212/216775423-4e37345c-f915-47e5-8551-7c544ebd24b1.png">
</details>
---------
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Co-authored-by: Veeck <github@veeck.de>
Async node_helper dont have to finish immediately in loadModules. So the
start callback in the app.js with the config isnt called for some time.
But the electron ready event can already be fired in the meantime.
This lead to the electron app starting but without a config (which is
provded by the node_helper callback) therefor crashing.
This PR fixes#2487 by moving the callback call out of the loadModules
block, therefor the config is provided in time.
If any new async node_helper doesnt like this, we will see it :-)
Co-authored-by: veeck <michael@veeck.de>
see discussion here:
https://github.com/MichMich/MagicMirror/pull/2991#issuecomment-1376372720
I still see a need for updating `master` in special cases (e.g. correct
errors in README.md which would otherwise be present up to 3 month until
next release) so with this PR **only for MagicMirror repo** and **only
for `master` branch** updatenotifications are only triggered if at least
one of the new commits has a tag.
May @MichMich must decide if this is wanted.
Co-authored-by: Veeck <github@veeck.de>
This simple change allows to use your own templates (under "templates"
directory). The parameter `templateName` is optional (ignored on falsy
value - undefined, null, empty string, etc.) and independent of `type`.
Co-authored-by: Veeck <github@veeck.de>
This keeps relative dates accurate when the calendar's fetch frequency
is much larger than a minute.
As fetching incurs network traffic and load on servers and most
calendars don't update that often, simply refreshing locally is enough.
When using relative for today's events, dates will show as "in X
minutes" or "ends in X minutes" for events within an hour and this goes
out of date quickly. It's weird to see that the time is, say, 16:30 and
an event that you know ends at 16:45 is shown to "ends in 23 minutes"
because that's when the last fetch happened.
Please forgive me if there's style issue, I don't have npm set up on my
machine to run the formatter.
Fixes#3019
The previous implementation had the arrow pointing in to the wind. When
the wind blows from the north (0 degrees), the arrow should point
straight down. In other words, no rotation of the arrow-down symbol.
When the wind blows from the south (180 degrees), the arrow should point
straight up (I.e. the arrow down symbol rotated 180 degrees).
Co-authored-by: Magnus Marthinsen <magmar@online.no>
Symbols provided in customEvents don't get the "fas fa-fw fa-" prefix,
which according to the docs they should. This fixes that.
Hello and thank you for wanting to contribute to the MagicMirror²
project
**Please make sure that you have followed these 4 rules before
submitting your Pull Request:**
> 1. Base your pull requests against the `develop` branch.
>
> 2. Include these infos in the description:
>
> - Does the pull request solve a **related** issue?
> - If so, can you reference the issue like this `Fixes
#<issue_number>`?
> - What does the pull request accomplish? Use a list if needed.
> - If it includes major visual changes please add screenshots.
>
> 3. Please run `npm run lint:prettier` before submitting so that
> style issues are fixed.
>
> 4. Don't forget to add an entry about your changes to
> the CHANGELOG.md file.
**Note**: Sometimes the development moves very fast. It is highly
recommended that you update your branch of `develop` before creating a
pull request to send us your changes. This makes everyone's lives
easier (including yours) and helps us out on the development team.
Thanks again and have a nice day!
Co-authored-by: veeck <michael@veeck.de>
Hourly forecast wasnt converted properly during the last release cycle,
one fix and two cleanups were necessary.
Fixes#3010
Co-authored-by: veeck <michael@veeck.de>
was [requested in the
forum](https://forum.magicmirror.builders/topic/17519/updatenotification).
- added possibility to exclude MagicMirror Repo and renamed it from
`default` to `MagicMirror`
- improved getting `behind` in case a hard `git fetch` was already done
- removed test "excludes repo if refs don't match regex" because of
above improvement this case is obsolete
- improved `git fetch --dry-run` with `-n` option to exclude tags (noise
reduction)
Refactored the mock data generation for the tests so we can use plain
JSON files for the data and read it in a more general way.
Comments welcome!
Co-authored-by: veeck <michael@veeck.de>
Adds new config option to show weather forecast for every X hour
(default value is 1 which reflects the current behaviour)
Also adds tests for hourly forecast
Fixes#2996
Co-authored-by: veeck <michael@veeck.de>
## [2.22.0] - 2023-01-01
Thanks to: @angeldeejay, @buxxi, @dariom, @dWoolridge,
@KristjanESPERANTO, @MagMar94, @naveensrinivasan, @retroflex, @SkySails
and @Tom.
Special thanks to @khassel, @rejas and @sdetweil for taking over most
(if not all) of the work on this release as project collaborators. This
version would not be there without their effort. Thank you!
### Added
- Added test for remoteFile option in compliments module
- Added hourlyWeather functionality to Weather.gov weather provider
- Removed weatherEndpoint definition from weathergov.js (not used)
- Added css class names "today" and "tomorrow" for default calendar
- Added Collaboration.md
- Added new github action for dependency review (#2862)
- Added a WeatherProvider for Open-Meteo
- Added Yr as a weather provider
- Added config options "ignoreXOriginHeader" and
"ignoreContentSecurityPolicy"
### Removed
- Removed usage of internal fetch function of node until it is more
stable
### Updated
- Cleaned up test directory (#2937) and jest config (#2959)
- Wait for all modules to start before declaring the system ready
(#2487)
- Updated e2e tests (moved `done()` in helper functions) and use es6
syntax in all tests
- Updated da translation
- Rework weather module
- Make sure smhi provider api only gets a maximum of 6 digits
coordinates (#2955)
- Use fetch instead of XMLHttpRequest in weatherprovider (#2935)
- Reworked how weatherproviders handle units (#2849)
- Use unix() method for parsing times, fix suntimes on the way (#2950)
- Refactor conversion functions into utils class (#2958)
- The `cors`-method in `server.js` now supports sending and recieving
HTTP headers
- Replace `…` by `…`
- Cleanup compliments module
- Updated dependencies including electron to v22 (#2903)
### Fixed
- Correctly show apparent temperature in SMHI weather provider
- Ensure updatenotification module isn't shown when local is _ahead_ of
remote
- Handle node_helper errors during startup (#2944)
- Possibility to change FontAwesome class in calendar, so icons like
`fab fa-facebook-square` works.
- Fix cors problems with newsfeed articles (as far as possible), allow
disabling cors per feed with option `useCorsProxy: false` (#2840)
- Tests not waiting for the application to start and stop before
starting the next test
- Fix electron tests failing sometimes in github workflow
- Fixed gap in clock module when displayed on the left side with
displayType=digital
- Fixed playwright issue by upgrading to v1.29.1 (#2969)
Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com>
Co-authored-by: Veeck <github@veeck.de>
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: dWoolridge <dwoolridge@charter.net>
Co-authored-by: Johan <jojjepersson@yahoo.se>
Co-authored-by: Dario Mratovich <dario_mratovich@hotmail.com>
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com>
Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com>
Co-authored-by: buxxi <buxxi@omfilm.net>
Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com>
Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com>
## Added Weather Provider for Open-Meteo.
I've found a completely free weather REST API (event with option of
self-hosting) after having problems with API keys from all MagicMirror
weather providers currently implemented (the remote services, not the
providers themselves).
This API doesn't return information about reverse geocode from latitude
and longitude options like others. I solved that issue using another
free API.
### APIs used
- [Open-Meteo Weather Forecast API](https://open-meteo.com/en/docs)
- [BigDataCloud’s Free Client-Side Reverse Geocoding
API](https://www.bigdatacloud.com/docs/api/free-reverse-geocode-to-city-api)
### Considerations
- This provider is config reliable so, be free to use the same config
you can found in the official MagicMirror Weather module documentation.
- This module config skips the `apiKey` parameter. It's not used at all.
Only `latitude` and `longitude` are required.
#### Config examples:
```
modules: [
{
module: "weather",
position: "top_right",
header: "Weather Forecast",
config: {
updateInterval: <number here>,
weatherProvider: "openmeteo",
type: "current",
lat: <number here>,
lon: <number here>,
showHumidity: true,
showWindDirectionAsArrow: true,
showWindDirection: true,
degreeLabel: true,
}
},
{
module: "weather",
position: "top_right",
header: "Weather Forecast",
config: {
updateInterval: <number here>,
weatherProvider: "openmeteo",
type: "daily",
lat: <number here>,
lon: <number here>
colored: true,
maxNumberOfDays: <number here>,
showPrecipitationAmount: true,
appendLocationNameToHeader: true
}
},
{
module: "weather",
position: "top_right",
header: "Weather Forecast",
config: {
updateInterval: <number here>,
weatherProvider: "openmeteo",
type: "hourly",
lat: <number here>,
lon: <number here>,
maxEntries: <number here>,
showPrecipitationAmount: true,
degreeLabel: true,
appendLocationNameToHeader: true
}
},
]
```
Co-authored-by: Michael Teeuw <michael@xonaymedia.nl>
Lots of small fixes and cleanups:
- only render something when there is a compliment
- cleanup naming
- use es6 notations
- use fetch instead of XMLHttpRequest in compliments
Co-authored-by: veeck <michael@veeck.de>
Co-authored-by: Karsten Hassel <hassel@gmx.de>
Changes:
- as discussed in #2903: update to electron v22 (we can revert it before
next release if we find any problems)
- update other dependencies
- set playwright to version v1.27.1 until #2969 is solved
# Added Yr.no as a weather provider
Yr.no is a free Norwegian weather service. The configuration is quite
simple:
```js
{
weatherProvider: "yr",
lat: 59.9171,
lon: 10.7276,
altitude: 30
}
```
The latitude and longitude cannot have more than 4 decimals, but that
should be plenty. To quote yr: "There is no need to ask for weather
forecasts with nanometer precision!". The altitude should be meters
above sea level and defaults to 0. If `type` is set to `current` the
symbol can display the next 1, 6 or 12 hours by setting
`currentForecastHours` (default is 1).
It states in [Getting
started-guide](https://developer.yr.no/doc/GettingStarted/) that users
of the API should cache the results and use the `Expires`-header to know
when to ask for new data. By using the `If-Modified-Since`-header we can
avoid downloading the same data over and over again. I chose not to
override the `User-Agent`-header set in
[`server.js`](https://github.com/MichMich/MagicMirror/blob/a328ce5/js/server.js#L97)
even though it does not comply with [the terms of
service](https://developer.yr.no/doc/TermsOfService/). It currently
works with the default header, and by searching the web for MagicMirror
the GitHub-repo should be easy to find without an explicit link.
I also had to make some minor changes to `server.js` and
`weatherprovider.js` to be able to send and return HTTP headers. To
handle the HTTP 304 response without body I chose to return `undefined`
so we easily can use the response as a condition: `if (response) ...`.
The documentation for the API is available here:
- [API Reference overview](https://api.met.no/weatherapi/)
-
[Locationforecast](https://api.met.no/weatherapi/locationforecast/2.0/)
- Used to get the weather forecast
- [Sunrise](https://api.met.no/weatherapi/sunrise/2.0/documentation) -
used to find sunrise and sunset times
Co-authored-by: Veeck <github@veeck.de>
Many users like me do have the problem that they want to embed other
sites to their mirror by "iframe".
As some developers set the "x-frame-options" and
"content-security-policy" for security reasons these sites can not be
embedded.
Electron provides the "webview" element additionally to "iframe" which
allows to embed these sites although. The main difference is that a new
process is started which handles the "webview" element.
BUT: As the "webview" process needs to be started and is isolated
"webview" is slower and the elements can not be accessed from the
embedding website.
As an alternative i implemented a small callback function in electron.js
which removes the response headers that forbid the embedding.
The removing can be controlled with the new config options:
* ignoreXOriginHeader
* ignoreContentSecurityPolicy
As already discussed here the first shot of the collaboration rules.
We can discuss this in the comments until ready to merge.
Co-authored-by: Veeck <github@veeck.de>
Adds support for sending and receiving HTTP-headers when using the
CORS-method.
This change is required for the Yr weather-provider introduced in
https://github.com/MichMich/MagicMirror/pull/2948.
To make it easier to add unit tests I moved the server-functions into a
separate file.
When trying to debug why the tests broke for
https://github.com/MichMich/MagicMirror/pull/2946 I found that the tests
does not wait for the app to start and close. So if the startup isn't
blocking that would fail.
So I added a callback for `close()` too and converted them to promises
for the `startApplication()` and `stopApplication()` and updated all the
e2e tests to await both. Will try to refactor all these callbacks to
promises in a later PR.
Some small cleanups with regards to jest
- call jest directly (nyc is integrated in jest these days)
- move jest config into seperate file so we dont clutter up the
package.json
- remove empty test file for newsletter-unit-tests
- update dependencies that touch jest
- try out v8 as coverageProvider
Co-authored-by: veeck <michael@veeck.de>
So finally I think this refactorin is ready to be reviewed :-)
DONE:
- [x] Removed all conversion functions for wind and temperature from
specific weatherproviders
- [x] Use internally only metric units: celsius for temperature, meters
per seconds for wind
- [x] Convert temp and wind into the configured units when displaying
data on the UI
- [x] look how beaufort calculation uses metrics, added knots as new
windunit
- [x] add more e2e tests
Checked providers:
- [x] Darksky
- [x] EnvCanada
- [x] OpenWeatherMap
- [x] SMHI provider
- [x] UK Met Office
- [x] UK Met Office DataHub
- [x] WeatherBit
- [x] WeatherFlow
- [x] WeatherGov
TODO in different tickets:
- check weatherproviders for usage of weatherEndpoint (as seen in
https://github.com/MichMich/MagicMirror-Documentation/issues/131) -> see
#2926
- cleanup precipations -> #2953
Co-authored-by: veeck <michael@veeck.de>
solves #2840 as far as possible. There could still be errors on the
embedded iframe when the owner of the site has set `X-Frame-Options` or
`Access-Control-Allow-Origin` headers (as already mentioned in the
docs).
first PR for #2942
- added new electron tests for calendar which test new css classes from
https://github.com/MichMich/MagicMirror/pull/2939
- moved some compliments tests from `e2e` to `electron` because of date
mocking
- removed mock stuff from compliments module
Some icons in FontAwesome, like the Facebook-logo, requires a different
class than `fas fa-fw fa-`. Added support for specifying the
`className`:
```js
{
symbol: "facebook-square",
symbolClassName: "fab fa-",
url: "https://www.facebook.com/events/ical/upcoming/?uid=<some_uid>"
}
```
This PR resolves a small bug in the updatenotification module if a local
git repo is ahead of the remote (for example I have made local commits
for my personal needs).
Currently, if `git status -sb` reports a status like: `##
master...origin/master [ahead 2]` then updatenotification treats this as
though it's "behind".
This PR uses a single Regex to match `git status -sb` output and uses
capture groups to extract info to populate the `gitInfo` object to avoid
needing to do string manipulation to extract this information.
Co-authored-by: Dario Mratovich <dario.mratovich@outlook.com>
Added class names "today" and "tomorrow" on the calendar module tr
elements (i.e. calendar items).
This way you can for example color your events today and/or tomorrow to
more easily see what's happening in the near future.
Implemented by adding an event.tomorrow variable (similar to
event.today) that can be used for other things in the future. Also
replaced a few hardcoded values (hours, seconds etc.) with constants to
make the code more consistent.
Edit: tested with normal events, split day events and events with
locations.
small update to the fetchData method to use the fetch helper instead of
the old XCMLHttpRequest.
Also fixes some typos :-)
Co-authored-by: veeck <michael@veeck.de>
This PR addresses [this
comment](48756e8774 (commitcomment-85772193)),
which points out an issue with #2902.
Looks like the apparent temp calculation method was incorrectly
referenced 😅
Partially implementing variables is silly, noticed font sizes weren't implemented fully. Corrected this in my custom, decided it should be in main. Feel free to adjust REM factors to match defaults you like.
Partially implementing variables is silly, noticed font sizes weren't implemented fully. Corrected this in my custom, decided it should be in main. Feel free to adjust REM factors to match defaults you like.
The results from the /onecall endpoint were not
being parsed correctly in current and forecast mode - it was
assuming the current/forecast endpoint API, and the return
datasets are different. The effect was that the module
would simply display "Loading..." when in /onecall mode, since
it has no way of displaying error status (ideally, it should,
but leave that for another day)
Added a new provider that pulls weather data - current, forecast, and hourly - from Environment Canada (Canadian gov weather service). This provider supports Canadian locations only. Documentation will be provided that outlines specific behaviours of this provider and required 'weather' modules parms for Env Canada.
Code updates to support a new weatherobject element called precipitationUnits. For the 'forecast' and 'hourly' UI, the weather module will use this new element if it is not null (i.e. a provider has pushed some value into this object element). If the element is null, then default 'units' processing will still occur. This allows a provider to have a customn unit of measure for precipitation - e.g. Env Canada will use mm for rain and cm for snow.
There is a wrong treatment to appendLocationNameToHeader.
The location should be always returned and leave the weater.js to decide if is included or not in the header.
Many people use Own-/Nextcloud together witht he https protocol. This is supposed to make self-signed certificates work with the calendar module and fix the issue #466.
I had missread the documentation of moment.js. We've to provide the translation for today and tomorrow ourselves. For the translation I use the standard MM² translation mechanism.
The module.path component has by definition in line 97 a trailing slash.
Hence adding another is unneeded, but results in an additional folder in the inspector.
ISO 639-1 Language Code: ps
ISO 639-2 Language Code: pus
English name of Language: Pushto; Pashto
French name of Language: pachto
Pashto, sometimes spelled Pukhto or Pakhto, is an Eastern Iranian language of the Indo-European family. It is known in Persian literature as Afghani. Speakers of the language are called Pashtuns or Pukhtuns/Pakhtuns. Pashto and Dari are the two official languages of Afghanistan.
Native speakers: 40-60 million
https://g.co/kgs/y4xaLh
Set minute/second in our model based on the actual time from moment() rather than our own attempt to track the time - which can drift or fail to respond to time changes.
Also, schedule time refreshes to happen 50ms after the minute/second is expected to change - preventing premature fires and rapid re-firings of notifications due to accuracy limits in setTimeout
1. as reported on https://github.com/MichMich/MagicMirror/pull/1885,
toLocaleString is not supported on old iPad Safari
2. SunCalc.getMoonTimes returns moonRise/moonSet times for the given date,
so moonRise can be after moonSet. We want to display the most relevant
times, which are today's moonRise and the next moonSet.
hideTemp = false -> temp shold appear at the MM
hideTemp === true -> should not appear.
This is the logic. Worked vise versa, just corrected in the code
I find it quite hard to look something up in the logs, when there is no date in the log file. The time itself is not sufficient for debugging, hence I suggest also logging the date.
This change set after startApplication the configuration to run this
test.
The previous statement when e2e are running using --recursive the
MM_CONFIG_FILE was setting by the test running before this one.
This commit adds the official docker image repo as well as the installation scripts repo to the issue template to avoid the creation of issue which don't belong to the MagicMirror core.
On the next release the css/custom.css will rename to
css/custom.css.sample
This change run git instructions to detach the file from own local
repository. This instructions are called in untrack-css.sh file from
run-start.sh and npm postinstall step
Reference #1540
added to 'newsfeed.js' in order to design the news article better with css, three more class-names were introduced: newsfeed-desc, newsfeed-desc, newsfeed-desc
rrule-alt has not been updated in some time, while the main rrule has. ical.js is using updated rrule. Getting rid of rrule-alt would affect some third-party modules, however, so we should keep it around for now at least.
Added notifications to default `clock` module to broadcast:
- `CLOCK_SECOND` for a clock second, and
- `CLOCK_MINUTE` for a clock minute having elapsed.
Each notification is broadcasted with the corresponding value i.e. `CLOCK_SECOND` -> `30` and `CLOCK_MINUTE` -> `5` .
Added ability to enable broadcasting of news feed items with `NEWS_FEED` notification and broadcasting updated news feed items with `NEWS_FEED_UPDATE` to other modules. This is merged into the default `newsfeed` module.
One can set ability to broadcast the whole news feed or broadcast only updated news feed items.
added configuration option nextDaysRelative to always display today's and tomorrow's appointments in relative mode, even if timeformat is set to absolute
added configuration option nextDaysRelative to always display today's and tomorrow's appointments in relative mode, even if timeformat is set to absolute
added configuration option nextDaysRelative to always display today's and tomorrow's appointments in relative mode, even if timeformat is set to absolute
added configuration option nextDaysRelative to always display today's and tomorrow's appointments in relative mode, even if timeformat is set to absolute
When consuming CALENDAR_EVENTS broadcasts, it is useful for other
modules to be able to identify which calendar a specific event
came from, for filtering/display purposes.
Upon reception of an ARTICLE_INFO_REQUEST notification, newsfeed will
respond with the notification ARTICLE_INFO_RESPONSE, containing the
fields 'title', 'source', 'date', 'desc' and 'url'.
Added the direct code to always install the latest version of Node.js for the manual installation.
Maybe you could also include this in the automatic setup script, which does not seem to install the latest version of Node.js.
The global 'config' variable is used in the callback function, changed to local one. Unwanted behaviour when accessing server on docker or if using 0.0.0.0 or blank address in config file as it just passes this to electron to display.
Following this issue https://github.com/MichMich/MagicMirror/issues/694 it seems that the Midori Browser does not recoginize ES6 syntax. Further, the use of 'var' is seen throughout the calendar module excpet on line 439, where the error is reported
- 'logFeedWarnings' added to newsfeed config, defaulted to false
- Only log parse feed errors when logFeedWarnings is true
- Updated README and CHANGELOG
- Fixes#1329
Added a runtime var isShowingDescription that gets reset to user config.
this.config.showDescription no longer mutates during runtime.
Changelog has been updated to include this fix.
Had much better performance using 100vw (viewport width) than 100% (why - idk), but with 100% about 5% of my screen (1080x1920) to the right of the scroll bar was left black/blank, with 100vw I legitimately takes up the whole screen/viewport width.
With the 10000 height the articles would always load about half way scrolled down. So I reduced the height and style.height to 3000. At my resolution at least, which I assume is fairly common, I had much better results. Unfortunately 3000 also isn't perfect - this still requires some tweaking. The article loads perfectly at the top of the iframe at 2500, but 2500 is much too small for most articles. 3000 seemed a good compromise, I could scroll far enoguh to read most articles on Reuters, and also load far enoguh up to read the beginning of the article.
And finally I added a "scroll back up" button notification. This seems to work flawlessly.
If you press enter, `choice` is an empty string and will default to "no". The convention is to capitalize the default answer so users know what happens when they auto-accept prompts.
Sometimes, the content of translations[module.name][key] is not a string but an entire object. It cause a crash on template.replace(...) of createStringFromTemplate(...). It is currently the case of MMM-Voice-Control and the previous commit have broked this module (10 month ago... I am surprised to be the first founded it)
The link to the 3rd Party Modules still directs to the old wiki page, where use has to follow another link to the right page. Updated the link in README.md to navigate to the right wiki page instantly.
Resolves#1071
`prohibitedWords` config parameter is an array of words. If set and case insensitive greedy match is found anywhere in the title then that newsfeed item will not be displayed. Readme updated with instructions.
Users should be careful on the words selection as careless setting may remove many or all items from the newsfeed. Some obvious mistakes like `space, comma, dot` etc. can be prevented programatically, but I left it out of this PR
Example:
with `prohibitedWords: ['dodgers']`
Original `newsItems`:
```
0:{title: "New York City, Russia, Los Angeles Dodgers: Your Wednesday Briefing", description: "Here’s what you need to know to start your day.", pubdate: "Wed, 01 Nov 2017 09:37:36 GMT", url: "https://www.nytimes.com/2017/11/01/briefing/new-yo…ssia-los-angeles-dodgers.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
1:{title: "A Mangled School Bus, Bodies Everywhere; ‘It Was Surreal’", description: "A truck ramming bicyclists. The driver emerging wi…e attack, it was as confusing as it was gruesome.", pubdate: "Wed, 01 Nov 2017 09:27:41 GMT", url: "https://www.nytimes.com/2017/10/31/nyregion/nyc-sc…r-attack-truck-witnesses.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
2:{title: "Dodgers 3, Astros 1 | Series tied, 3-3: With a Rally and a Romp, Dodgers Top Astros and Force Game 7", description: "Down by a run with just four innings left in Game …nst a dominating Justin Verlander. Game 7 awaits.", pubdate: "Wed, 01 Nov 2017 07:21:07 GMT", url: "https://www.nytimes.com/2017/11/01/sports/dodgers-win-game-6.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
3:{title: "José Andrés Fed Puerto Rico, and May Change How Aid Is Given", description: "The chef’s huge effort is just the latest led by c…ocally based way to feed people after a disaster.", pubdate: "Wed, 01 Nov 2017 06:40:09 GMT", url: "https://www.nytimes.com/2017/10/30/dining/jose-andres-puerto-rico.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
```
Filtered `newsItems`:
```
0:{title: "A Mangled School Bus, Bodies Everywhere; ‘It Was Surreal’", description: "A truck ramming bicyclists. The driver emerging wi…e attack, it was as confusing as it was gruesome.", pubdate: "Wed, 01 Nov 2017 09:27:41 GMT", url: "https://www.nytimes.com/2017/10/31/nyregion/nyc-sc…r-attack-truck-witnesses.html?partner=rss&emc=rss", sourceTitle: "New York Times"}
1:{title: "José Andrés Fed Puerto Rico, and May Change How Aid Is Given", description: "The chef’s huge effort is just the latest led by c…ocally based way to feed people after a disaster.", pubdate: "Wed, 01 Nov 2017 06:40:09 GMT", url: "https://www.nytimes.com/2017/10/30/dining/jose
```
Scenario:
* Specify more than one calendar in `config.calendars`
* Specify a maximum number of entries in `config.maximumEntries`
Result:
The module will show as many as maximumEntries for EACH calendar
Expected:
The module shall not show more than a total of maximumEntries, regardless of how many calendars I specify
Fixes#1043
We hold our code to standard, and these standards are documented below.
If you wish to run both linters, use `grunt` without any arguments.
## Linters
We use [prettier](https://prettier.io/) for automatic formatting a lot all our files. The configuration is in our `prettier.config.mjs` file.
To run prettier, use `npm run lint:prettier`.
### JavaScript: Run ESLint
We use [ESLint](http://eslint.org) on our JavaScript files.
We use [ESLint](https://eslint.org) to lint our JavaScript files. The configuration is in our `eslint.config.mjs` file.
Our ESLint configuration is in our .eslintrc.json and .eslintignore files.
To run ESLint, use `grunt eslint`.
To run ESLint, use `npm run lint:js`.
### CSS: Run StyleLint
We use [StyleLint](http://stylelint.io) to lint our CSS. Our configuration is in our .stylelintrc file.
We use [StyleLint](https://stylelint.io) to lint our CSS. The configuration is in our `.stylelintrc.json` file.
To run StyleLint, use `grunt stylelint`.
To run StyleLint, use `npm run lint:css`.
### Submitting Issues
### Markdown: Run markdownlint
Please only submit reproducible issues.
We use [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2) to lint our markdown files. The configuration is in our `.markdownlint.json` file.
If you're not sure if it's a real bug or if it's just you, please open a topic on the forum: [https://forum.magicmirror.builders/category/15/bug-hunt](https://forum.magicmirror.builders/category/15/bug-hunt)
Problems installing or configuring your MagicMirror? Check out: [https://forum.magicmirror.builders/category/10/troubleshooting](https://forum.magicmirror.builders/category/10/troubleshooting)
To run markdownlint, use `npm run markdownlint:css`.
When submitting a new issue, please supply the following information:
## Testing
**Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX).
We use [Jest](https://jestjs.io) for JavaScript testing.
**Node Version**: Make sure it's version 0.12.13 or later.
To run all tests, use `npm run test`.
**MagicMirror Version**: Now that the versions have split, tell us if you are using the PHP version (v1) or the newer JavaScript version (v2).
**Description**: Provide a detailed description about the issue and include specific details to help us understand the problem. Adding screenshots will help describing the problem.
**Steps to Reproduce**: List the step by step process to reproduce the issue.
**Expected Results**: Describe what you expected to see.
**Actual Results**: Describe what you actually saw.
**Configuration**: What does the used config.js file look like? Don't forget to remove any sensitive information!
**Additional Notes**: Provide any other relevant notes not previously mentioned. This is optional.
The specific test commands are defined in `package.json`.
So you can also run the specific tests with other commands, e.g. `npm run test:unit` or `npx jest tests/e2e/env_spec.js`.
If you're not sure if it's a real bug or if it's just you, please open a topic on the forum: [https://forum.magicmirror.builders/category/15/bug-hunt](https://forum.magicmirror.builders/category/15/bug-hunt)
Problems installing or configuring your MagicMirror? Check out: [https://forum.magicmirror.builders/category/10/troubleshooting](https://forum.magicmirror.builders/category/10/troubleshooting)
When submitting a new issue, please supply the following information:
**Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX).
**Node Version**: Make sure it's version 0.12.13 or later.
**MagicMirror Version**: Now that the versions have split, tell us if you are using the PHP version (v1) or the newer JavaScript version (v2).
**Description**: Provide a detailed description about the issue and include specific details to help us understand the problem. Adding screenshots will help describing the problem.
**Steps to Reproduce**: List the step by step process to reproduce the issue.
**Expected Results**: Describe what you expected to see.
**Actual Results**: Describe what you actually saw.
**Configuration**: What does the used config.js file look like? Don't forget to remove any sensitive information!
**Additional Notes**: Provide any other relevant notes not previously mentioned. This is optional.
description:Suggest a new feature for MagicMirror² 💡
title:"[Feature Request] {{ brief description }}"
body:
- type:checkboxes
id:prerequisites
attributes:
label:Prerequisites
description:Please ensure you have completed all of the following.
options:
- label:I am running the latest version of MagicMirror², and know that this feature is not available now.
required:true
- label:I know my issue is not related to a third-party module.
required:true
- label:I have searched for [existing issues](https://github.com/MagicMirrorOrg/MagicMirror/issues) that already include this feature request, without success.
required:true
- type:textarea
id:description
attributes:
label:Describe the Feature Request
description:A clear and concise description of what the feature does.
validations:
required:true
- type:textarea
id:use-case
attributes:
label:Describe the Use Case
description:A clear and concise use case for what problem this feature would solve.
validations:
required:true
- type:textarea
id:proposed-solution
attributes:
label:Describe Preferred Solution
description:A clear and concise description of how you want this feature to be added to MagicMirror².
- type:textarea
id:alternatives-considered
attributes:
label:Describe Alternatives
description:A clear and concise description of any alternative solutions or features you have considered.
- type:textarea
id:related-code
attributes:
label:Related Code
description:If you are able to illustrate the feature request with an example, please provide a sample here.
- type:textarea
id:additional-information
attributes:
label:Additional Information
description:List any other information that is relevant to your issue. Related issues, suggestions on how to implement, Stack Overflow links, forum links, etc.
- type:checkboxes
attributes:
label:Participation
options:
- label:I am willing to submit a pull request for this change.
required:false
- type:markdown
attributes:
value:Please **do not** open a pull request until this issue has been accepted by the team.
# This workflow scans your pull requests for dependency changes, and will raise an error if any vulnerabilities or invalid licenses are being introduced.
# For more information see: https://github.com/actions/dependency-review-action
workflow_dispatch:# needed for manually running this workflow
schedule:
- cron:"30 1 * * 6"# every Saturday at 1:30
permissions:
issues:write
jobs:
stale:
runs-on:ubuntu-latest
steps:
- uses:actions/stale@v9
with:
stale-issue-message:"This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions."
days-before-issue-stale:60
days-before-issue-close:7
operations-per-run:100
stale-issue-label:"wontfix"
exempt-issue-labels:"pinned,security,under investigation,pr welcome,ready (coming with next release)"
This document describes how collaborators of this repository should work together.
## Pull Requests
- never merge your own PR's
- never merge without someone having approved (approving and merging from same person is allowed)
- wait for all approvals requested (or the author decides something different in the comments)
- merge to `master` only for releases or other urgent issues (update notification is only triggered by tags)
- merges to master should be tagged with the "mastermerge" label so that the test runs through
## Issues
- "real" Issues are closed if the problem is solved and the fix is released
- unrelated Issues (e.g. related to a foreign module) are closed immediately with a comment to open an issue in the module repository or to discuss this further in the forum or discord
## Releases
Are done by
- [ ]@rejas
- [ ]@sdetweil
- [ ]@khassel
### Pre-Deployment steps
- [ ] update dependencies (a few days before)
### Deployment steps
- [ ] pull latest `develop` branch
- [ ] create `prep-release` branch from `develop`
- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0`
- [ ] test `prep-release` branch
- [ ] update `CHANGELOG.md`
- [ ] add all contributor names: `...`
- [ ] add min. node version: > ⚠️ This release needs nodejs version `v22.14.0` or higher
- [ ] check release link at the bottom of the file
- [ ] commit and push all changes
- [ ] create pull request from `prep-release` to `develop` branch with title `Prepare Release 2.xx.0`
- [ ] after successful test run via github actions: merge pull request to `develop`
- [ ] after successful test run via github actions: create pull request from `develop` to `master` branch
- [ ] add label `mastermerge`
- [ ] title of the PR is `Release 2.xx.0`
- [ ] description of the PR is the section of the `CHANGELOG.md`
- [ ] after PR tests run without issues, merge PR
- [ ] create new release with
- [ ] corresponding version tag `v2.xx.0`
- [ ] a release name: `...`
- [ ] description of the release is the section of the `CHANGELOG.md`
### Draft new development release
- [ ] checkout `develop` branch
- [ ] update `package.json` and `package-lock.json` to reflect correct version number `2.xx.0-develop`
- [ ] draft new section in `CHANGELOG.md`
- [ ] create new release link at the bottom of the file
- [ ] commit and publish `develop` branch
- [ ] if new release will be in January, update the year in LICENSE.md
### After release
- [ ] publish release notes with link to github release on forum in new locked topic
- [ ] close all issues with label `ready (coming with next release)`
- [ ] release new documentation by merging `develop` on `master` in documentation repository
- [ ] publish new version on [npm](https://www.npmjs.com/package/magicmirror)
**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](http://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MichMich/MagicMirror/graphs/contributors).
**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](https://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MagicMirrorOrg/MagicMirror/graphs/contributors).
MagicMirror² focuses on a modular plugin system and uses [Electron](http://electron.atom.io/) as an application wrapper. So no more web server or browser installs necessary!
MagicMirror² focuses on a modular plugin system and uses [Electron](https://www.electronjs.org/) as an application wrapper. So no more web server or browser installs necessary!
For the full documentation including **[installation instructions](https://docs.magicmirror.builders/getting-started/installation.html)**, please visit our dedicated documentation website: [https://docs.magicmirror.builders](https://docs.magicmirror.builders).
## Usage
## Links
### Raspberry Pi Support
Electron, the app wrapper around MagicMirror², only supports the Raspberry Pi 2 & 3. The Raspberry Pi 1 is currently **not** supported. If you want to run this on a Raspberry Pi 1, use the [server only](#server-only) feature and setup a fullscreen browser yourself.
### Automatic Installer (Raspberry Pi Only!)
Execute the following command on your Raspberry Pi to install MagicMirror²:
1. Download and install the latest Node.js version.
2. Clone the repository and check out the master branch: `git clone https://github.com/MichMich/MagicMirror`
3. Enter the repository: `cd ~/MagicMirror`
4. Install and run the app: `npm install && npm start`
**Important:** `npm start` does **not** work via SSH, use `DISPLAY=:0 nohup npm start &` instead. This starts the mirror on the remote display.
**Note:** if you want to debug on Raspberry Pi you can use `npm start dev` which will start the MagicMirror app with Dev Tools enabled.
### Server Only
In some cases, you want to start the application without an actual app window. In this case, you can start MagicMirror² in server only mode by manually running `node serveronly` or using Docker. This will start the server, after which you can open the application in your browser of choice. Detailed description below.
### Client Only
When you have a server running remotely and want to connect a standalone client to this instance, you can manually run `node clientonly --address 192.168.1.5 --port 8080`. (Specify the ip address and port number of the server)
**Important:** Make sure that you whitelist the interface/ip in the server config where you want the client to connect to, otherwise it will not be allowed to connect to the server
#### Docker
MagicMirror² in server only mode can be deployed using [Docker](https://docker.com). After a successful [Docker installation](https://docs.docker.com/engine/installation/) you just need to execute the following command in the shell:
| `/opt/magic_mirror/config` | Mount this volume to insert your own config into the docker container. |
| `/opt/magic_mirror/modules` | Mount this volume to add your own custom modules into the docker container. |
You may need to add your Docker Host IP to your `ipWhitelist` option. If you have some issues setting up this configuration, check [this forum post](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto).
If you want to update your MagicMirror² to the latest version, use your terminal to go to your Magic Mirror folder and type the following command:
```bash
git pull && npm install
```
If you changed nothing more than the config or the modules, this should work without any problems.
Type `git status` to see your changes, if there are any, you can reset them with `git reset --hard`. After that, git pull should be possible.
## Configuration
1. Duplicate `config/config.js.sample` to `config/config.js`. **Note:** If you used the installer script. This step is already done for you.
2. Modify your required settings.
Note: You'll can check your configuration running the follow command:
```bash
npm run config:check
```
The following properties can be configured:
| **Option** | **Description** |
| --- | --- |
| `port` | The port on which the MagicMirror² server will run on. The default value is `8080`. |
| `address` | The ip address the accept connections. The default open bind `::` is IPv6 is available or `0.0.0.0` IPv4 run on. Example config: `192.168.10.100`. |
| `ipWhitelist` | The list of IPs from which you are allowed to access the MagicMirror². The default value is `["127.0.0.1", "::ffff:127.0.0.1", "::1"]`. It is possible to specify IPs with subnet masks (`["127.0.0.1", "127.0.0.1/24"]`) or define ip ranges (`["127.0.0.1", ["192.168.0.1", "192.168.0.100"]]`). Set `[]` to allow all IP addresses. For more information about how configure this directive see the [follow post ipWhitelist HowTo](https://forum.magicmirror.builders/topic/1326/ipwhitelist-howto) |
| `zoom` | This allows to scale the mirror contents with a given zoom factor. The default value is `1.0`|
| `language` | The language of the interface. (Note: Not all elements will be localized.) Possible values are `en`, `nl`, `ru`, `fr`, etc., but the default value is `en`. |
| `timeFormat` | The form of time notation that will be used. Possible values are `12` or `24`. The default is `24`. |
| `units` | The units that will be used in the default weather modules. Possible values are `metric` or `imperial`. The default is `metric`. |
| `modules` | An array of active modules. **The array must contain objects. See the next table below for more information.** |
| `electronOptions` | An optional array of Electron (browser) options. This allows configuration of e.g. the browser screen size and position (example: `electronOptions: { fullscreen: false, width: 800, height: 600 }`). Kiosk mode can be enabled by setting `kiosk = true`, `autoHideMenuBar = false` and `fullscreen = false`. More options can be found [here](https://github.com/electron/electron/blob/master/docs/api/browser-window.md). |
| `customCss` | The path of the `custom.css` stylesheet. The default is `css/custom.css`. |
Module configuration:
| **Option** | **Description** |
| --- | --- |
| `module` | The name of the module. This can also contain the subfolder. Valid examples include `clock`, `default/calendar` and `custommodules/mymodule`. |
| `position` | The location of the module in which the module will be loaded. Possible values are `top_ bar`, `top_left`, `top_center`, `top_right`, `upper_third`, `middle_center`, `lower_third`, `bottom_left`, `bottom_center`, `bottom_right`, `bottom_bar`, `fullscreen_above`, and `fullscreen_below`. This field is optional but most modules require this field to set. Check the documentation of the module for more information. Multiple modules with the same position will be ordered based on the order in the configuration file. |
| `classes` | Additional classes which are passed to the module. The field is optional. |
| `header` | To display a header text above the module, add the header property. This field is optional. |
| `disabled` | Set disabled to `true` to skip creating the module. This field is optional. |
| `config` | An object with the module configuration properties. Check the documentation of the module for more information. This field is optional, unless the module requires extra configuration. |
For more available modules, check out out the wiki page: [MagicMirror² Modules](https://github.com/MichMich/MagicMirror/wiki/MagicMirror²-Modules). If you want to build your own modules, check out the [MagicMirror² Module Development Documentation](modules) and don't forget to add it to the wiki and the [forum](https://forum.magicmirror.builders/category/7/showcase)!
## Known issues
- Electron seems to have some issues on certain Raspberry Pi 2's. See [#145](https://github.com/MichMich/MagicMirror/issues/145).
- MagicMirror² (Electron) sometimes quits without an error after an extended period of use. See [#150](https://github.com/MichMich/MagicMirror/issues/150).
## Community
The community around the MagicMirror² is constantly growing. We even have a [forum](https://forum.magicmirror.builders) now where you can share your ideas, ask questions, help others and get inspired by other builders. We would love to see you there!
Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation.
Contributions of all kinds are welcome, not only in the form of code but also with regards to
Please keep the following in mind:
- bug reports
- documentation
- translations
- **Bug Reports**: Make sure you're running the latest version. If the issue(s) still persist: please open a clearly documented issue with a clear title.
- **Minor Bug Fixes**: Please send a pull request with a clear explanation of the issue or a link to the issue it solves.
- **Major Bug Fixes**: please discuss your approach in an GitHub issue before you start to alter a big part of the code.
- **New Features**: please please discuss in a GitHub issue before you start to alter a big part of the code. Without discussion upfront, the pull request will not be accepted / merged.
For the full contribution guidelines, check out: [https://docs.magicmirror.builders/about/contributing.html](https://docs.magicmirror.builders/about/contributing.html)
Thanks for your help in making MagicMirror² better!
## Enjoying MagicMirror? Consider a donation!
<palign="center">
<br>
<ahref="https://forum.magicmirror.builders/topic/728/magicmirror-is-voted-number-1-in-the-magpi-top-50"><imgsrc="https://magicmirror.builders/img/magpi-best-watermark-custom.png"width="150"alt="MagPi Top 50"></a>
MagicMirror² is Open Source and free. That doesn't mean we don't need any money.
Please consider a donation to help us cover the ongoing costs like webservers and email services.
If we receive enough donations we might even be able to free up some working hours and spend some extra time improving the MagicMirror² core.
To donate, please follow [this](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=G5D8E9MR5DTD2&source=url) link.
<pstyle="text-align: center">
<ahref="https://forum.magicmirror.builders/topic/728/magicmirror-is-voted-number-1-in-the-magpi-top-50"><imgsrc="https://magicmirror.builders/img/magpi-best-watermark-custom.png"width="150"alt="MagPi Top 50"></a>
console.error(Utils.colors.error("WARNING! Could not validate config file. Please correct syntax errors. Starting with default configuration."));
Log.error(`WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: ${e.stack}`);
}else{
console.error(Utils.colors.error("WARNING! Could not load config file. Starting with default configuration. Error found: "+e));
Log.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`);
"WARNING! Your config is using deprecated options: "+
usedDeprecated.join(", ")+
". Check README and CHANGELOG for more up-to-date ways of getting the same functionality.")
);
Log.warn(`WARNING! Your config is using deprecated option(s): ${usedDeprecated.join(", ")}. Check README and CHANGELOG for more up-to-date ways of getting the same functionality.`);
Log.warn(`WARNING! Your config for module ${element.module} is using deprecated option(s): ${usedDeprecatedModuleOptions.join(", ")}. Check README and CHANGELOG for more up-to-date ways of getting the same functionality.`);
}
}
}
}
/* loadModule(module)
/**
* Loads a specific module.
*
* argument module string - The name of the module (including subpath).
* @param {string} module The name of the module (including subpath).
// httpHeaders used by helmet, see https://helmetjs.github.io/. You can add other/more object values by overriding this in config.js,
// e.g. you need to add `frameguard: false` for embedding MagicMirror in another website, see https://github.com/MagicMirrorOrg/MagicMirror/issues/2847
// properties for checking if server is alive and has same startup-timestamp, the check is per default enabled
// (interval 30 seconds). If startup-timestamp has changed the client reloads the magicmirror webpage.
checkServerInterval:30*1000,
reloadAfterServerRestart:false,
modules:[
{
@@ -35,14 +39,14 @@ var defaults = {
position:"upper_third",
classes:"large thin",
config:{
text:"MagicMirror<sup>2</sup>"
text:"MagicMirror²"
}
},
{
module:"helloworld",
position:"middle_center",
config:{
text:"Please create a config file."
text:"Please create a config file or check the existing one for errors."
}
},
{
@@ -58,7 +62,7 @@ var defaults = {
position:"middle_center",
classes:"xsmall",
config:{
text:"If you get this message while your config file is already<br>created, your config file probably contains an error.<br>Use a JavaScript linter to validate your file."
text:"If you get this message while your config file is alreadycreated,<br>"+"it probably contains an error. To validate your config file run in your MagicMirror² directory<br>"+"<pre>npm run config:check</pre>"
}
},
{
@@ -66,16 +70,13 @@ var defaults = {
position:"bottom_bar",
classes:"xsmall dimmed",
config:{
text:"www.michaelteeuw.nl"
text:"https://magicmirror.builders/"
}
},
],
paths:{
modules:"modules",
vendor:"vendor"
},
}
]
};
/*************** DO NOT EDIT THE LINE BELOW ***************/
Log.log(`Check MagicMirror² version for module '${name}' - Minimum version: ${moduleDefinition.requiresVersion} - Current version: ${window.mmVersion}`);
console.error("unable to write js/positions.js with the discovered module positions\nmake the MagicMirror/js folder writeable by the user starting MagicMirror");
This document describes the way to develop your own MagicMirror² modules.
## Module structure
All modules are loaded in the `modules` folder. The default modules are grouped together in the `modules/default` folder. Your module should be placed in a subfolder of `modules`. Note that any file or folder your create in the `modules` folder will be ignored by git, allowing you to upgrade the MagicMirror² without the loss of your files.
A module can be placed in one single folder. Or multiple modules can be grouped in a subfolder. Note that name of the module must be unique. Even when a module with a similar name is placed in a different folder, they can't be loaded at the same time.
### Files
- **modulename/modulename.js** - This is your core module script.
- **modulename/node_helper.js** - This is an optional helper that will be loaded by the node script. The node helper and module script can communicate with each other using an intergrated socket system.
- **modulename/public** - Any files in this folder can be accesed via the browser on `/modulename/filename.ext`.
- **modulename/anyfileorfolder** Any other file or folder in the module folder can be used by the core module script. For example: *modulename/css/modulename.css* would be a good path for your additional module styles.
## Core module file: modulename.js
This is the script in which the module will be defined. This script is required in order for the module to be used. In it's most simple form, the core module file must contain:
````javascript
Module.register("modulename",{});
````
Of course, the above module would not do anything fancy, so it's good to look at one of the simplest modules: **helloworld**:
````javascript
//helloworld.js:
Module.register("helloworld",{
// Default module config.
defaults: {
text: "Hello World!"
},
// Override dom generator.
getDom: function() {
var wrapper = document.createElement("div");
wrapper.innerHTML = this.config.text;
return wrapper;
}
});
````
As you can see, the `Module.register()` method takes two arguments: the name of the module and an object with the module properties.
### Available module instance properties
After the module is initialized, the module instance has a few available module properties:
#### `this.name`
**String**
The name of the module.
#### `this.identifier`
**String**
This is a unique identifier for the module instance.
#### `this.hidden`
**Boolean**
This represents if the module is currently hidden (faded away).
#### `this.config`
**Boolean**
The configuration of the module instance as set in the user's config.js file. This config will also contain the module's defaults if these properties are not over written by the user config.
#### `this.data`
**Object**
The data object contains additional metadata about the module instance:
- `data.classes` - The classes which are added to the module dom wrapper.
- `data.file` - The filename of the core module file.
- `data.path` - The path of the module folder.
- `data.header` - The header added to the module.
- `data.position` - The position in which the instance will be shown.
#### `defaults: {}`
Any properties defined in the defaults object, will be merged with the module config as defined in the user's config.js file. This is the best place to set your modules's configuration defaults. Any of the module configuration properties can be accessed using `this.config.propertyName`, but more about that later.
#### `requiresVersion:`
*Introduced in version: 2.1.0.*
A string that defines the minimum version of the MagicMirror framework. If it is set, the system compares the required version with the users version. If the version of the user is out of date, it won't run the module. Make sure to also set this value in the Node helper.
**Note:** Since this check is introduced in version 2.1.0, this check will not be run in older versions. Keep this in mind if you get issue reports on your module.
Example:
````javascript
requiresVersion: "2.1.0",
````
### Subclassable module methods
#### `init()`
This method is called when a module gets instantiated. In most cases you do not need to subclass this method.
#### `loaded(callback)`
*Introduced in version: 2.1.1.*
This method is called when a module is loaded. Subsequent modules in the config are not yet loaded. The `callback` function MUST be called when the module is done loading. In most cases you do not need to subclass this method.
**Example:**
````javascript
loaded: function(callback) {
this.finishLoading();
Log.log(this.name + ' is loaded!');
callback();
}
````
#### `start()`
This method is called when all modules are loaded an the system is ready to boot up. Keep in mind that the dom object for the module is not yet created. The start method is a perfect place to define any additional module properties:
**Example:**
````javascript
start: function() {
this.mySpecialProperty = "So much wow!";
Log.log(this.name + ' is started!');
}
````
#### `getScripts()`
**Should return: Array**
The getScripts method is called to request any additional scripts that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.js')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
**Example:**
````javascript
getScripts: function() {
return [
'script.js', // will try to load it from the vendor folder, otherwise it will load is from the module folder.
'moment.js', // this file is available in the vendor folder, so it doesn't need to be available in the module folder.
this.file('anotherfile.js'), // this file will be loaded straight from the module folder.
'https://code.jquery.com/jquery-2.2.3.min.js', // this file will be loaded from the jquery servers.
]
}
````
**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore it's advised not to use any external urls.
#### `getStyles()`
**Should return: Array**
The getStyles method is called to request any additional stylesheets that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.css')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder.
**Example:**
````javascript
getStyles: function() {
return [
'script.css', // will try to load it from the vendor folder, otherwise it will load is from the module folder.
'font-awesome.css', // this file is available in the vendor folder, so it doesn't need to be avialable in the module folder.
this.file('anotherfile.css'), // this file will be loaded straight from the module folder.
'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css', // this file will be loaded from the bootstrapcdn servers.
]
}
````
**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore it's advised not to use any external urls.
#### `getTranslations()`
**Should return: Dictionary**
The getTranslations method is called to request translation files that need to be loaded. This method should therefore return a dictionary with the files to load, identified by the country's short name.
If the module does not have any module specific translations, the function can just be omitted or return `false`.
**Example:**
````javascript
getTranslations: function() {
return {
en: "translations/en.json",
de: "translations/de.json"
}
}
````
#### `getDom()`
**Should return:** Dom Object
Whenever the MagicMirror needs to update the information on screen (because it starts, or because your module asked a refresh using `this.updateDom()`), the system calls the getDom method. This method should therefore return a dom object.
**Example:**
````javascript
getDom: function() {
var wrapper = document.createElement("div");
wrapper.innerHTML = 'Hello world!';
return wrapper;
}
````
#### `getHeader()`
**Should return:** String
Whenever the MagicMirror needs to update the information on screen (because it starts, or because your module asked a refresh using `this.updateDom()`), the system calls the getHeader method to retrieve the module's header. This method should therefor return a string. If this method is not subclassed, this function will return the user's configured header.
If you want to use the original user's configured header, reference `this.data.header`.
**NOTE:** If the user did not configure a default header, no header will be displayed and thus this method will not be called.
That MagicMirror core has the ability to send notifications to modules. Or even better: the modules have the possibility to send notifications to other modules. When this module is called, it has 3 arguments:
- `notification` - String - The notification identifier.
- `payload` - AnyType - The payload of a notification.
- `sender` - Module - The sender of the notification. If this argument is `undefined`, the sender of the notififiction is the core system.
When using a node_helper, the node helper can send your module notifications. When this module is called, it has 2 arguments:
- `notification` - String - The notification identifier.
- `payload` - AnyType - The payload of a notification.
**Note 1:** When a node helper sends a notification, all modules of that module type receive the same notifications. <br>
**Note 2:** The socket connection is established as soon as the module sends its first message using [sendSocketNotification](thissendsocketnotificationnotification-payload).
Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload);
},
````
#### `suspend()`
When a module is hidden (using the `module.hide()` method), the `suspend()` method will be called. By subclassing this method you can perform tasks like halting the update timers.
#### `resume()`
When a module is requested to be shown (using the `module.show()` method), the `resume()` method will be called. By subclassing this method you can perform tasks restarting the update timers.
### Module instance methods
Each module instance has some handy methods which can be helpful building your module.
#### `this.file(filename)`
***filename* String** - The name of the file you want to create the path for.<br>
**Returns String**
If you want to create a path to a file in your module folder, use the `file()` method. It returns the path to the filename given as the attribute. Is method comes in handy when configuring the [getScripts](#getscripts) and [getStyles](#getstyles) methods.
#### `this.updateDom(speed)`
***speed* Number** - Optional. Animation speed in milliseconds.<br>
Whenever your module need to be updated, call the `updateDom(speed)` method. It requests the MagicMirror core to update its dom object. If you define the speed, the content update will be animated, but only if the content will really change.
As an example: the clock modules calls this method every second:
````javascript
...
start: function() {
var self = this;
setInterval(function() {
self.updateDom(); // no speed defined, so it updates instantly.
***notification* String** - The notification identifier.<br>
***payload* AnyType** - Optional. A notification payload.<br>
If you want to send a notification to all other modules, use the `sendNotification(notification, payload)`. All other modules will receive the message via the [notificationReceived](#notificationreceivednotification-payload-sender) method. In that case, the sender is automatically set to the instance calling the sendNotification method.
***notification* String** - The notification identifier.<br>
***payload* AnyType** - Optional. A notification payload.<br>
If you want to send a notification to the node_helper, use the `sendSocketNotification(notification, payload)`. Only the node_helper of this module will receive the socket notification.
***speed* Number** - Optional (Required when setting callback or options), The speed of the hide animation in milliseconds.
***callback* Function** - Optional, The callback after the hide animation is finished.
***options* Function** - Optional, Object with additional options for the hide action (see below). (*Introduced in version: 2.1.0.*)
To hide a module, you can call the `hide(speed, callback)` method. You can call the hide method on the module instance itself using `this.hide()`, but of course you can also hide another module using `anOtherModule.hide()`.
Possible configurable options:
- `lockString` - String - When setting lock string, the module can not be shown without passing the correct lockstring. This way (multiple) modules can prevent a module from showing. It's considered best practice to use your modules identifier as the locksString: `this.identifier`. See *visibility locking* below.
**Note 1:** If the hide animation is canceled, for instance because the show method is called before the hide animation was finished, the callback will not be called.<br>
**Note 2:** If the hide animation is hijacked (an other method calls hide on the same module), the callback will not be called.<br>
**Note 3:** If the dom is not yet created, the hide method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender).
#### `this.show(speed, callback, options)`
***speed* Number** - Optional (Required when setting callback or options), The speed of the show animation in milliseconds.
***callback* Function** - Optional, The callback after the show animation is finished.
***options* Function** - Optional, Object with additional options for the show action (see below). (*Introduced in version: 2.1.0.*)
To show a module, you can call the `show(speed, callback)` method. You can call the show method on the module instance itself using `this.show()`, but of course you can also show another module using `anOtherModule.show()`.
Possible configurable options:
- `lockString` - String - When setting lock string, the module can not be shown without passing the correct lockstring. This way (multiple) modules can prevent a module from showing. See *visibility locking* below.
- `force` - Boolean - When setting the force tag to `true`, the locking mechanism will be overwritten. Use this option with caution. It's considered best practice to let the usage of the force option be use- configurable. See *visibility locking* below.
**Note 1:** If the show animation is canceled, for instance because the hide method is called before the show animation was finished, the callback will not be called.<br>
**Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.<br>
**Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender).
#### Visibility locking
(*Introduced in version: 2.1.0.*)
Visiblity locking helps the module system to prevent unwanted hide/show actions. The following scenario explains the concept:
The lockString will be removed from moduleA’s locks array, and since this will result in an empty lock array, the module will be visible:
````javascript
moduleA.lockStrings == []
moduleA.hidden == false
````
**Note:** The locking mechanism can be overwritten by using the force tag:
````javascript
moduleA.show(0, {force: true});
````
This will reset the lockstring array, and will show the module.
````javascript
moduleA.lockStrings == []
moduleA.hidden == false
````
Use this `force` method with caution. See `show()` method for more information.
#### `this.translate(identifier)`
***identifier* String** - Identifier of the string that should be translated.
The Magic Mirror contains a convenience wrapper for `l18n`. You can use this to automatically serve different translations for your modules based on the user's `language` configuration.
If no translation is found, a fallback will be used. The fallback sequence is as follows:
- 1. Translation as defined in module translation file of the user's preferred language.
- 2. Translation as defined in core translation file of the user's preferred language.
- 3. Translation as defined in module translation file of the fallback language (the first defined module translation file).
- 4. Translation as defined in core translation file of the fallback language (the first defined core translation file).
- 5. The key (identifier) of the translation.
When adding translations to your module, it's a good idea to see if an apropriate translation is already available in the [core translation files](https://github.com/MichMich/MagicMirror/tree/master/translations). This way, your module can benefit from the existing translations.
**Example:**
````javascript
this.translate("INFO") //Will return a translated string for the identifier INFO
````
**Example json file:**
````javascript
{
"INFO": "Really important information!"
}
````
**Note:** although comments are officially not supported in JSON files, MagicMirror allows it by stripping the comments before parsing the JSON file. Comments in translation files could help other translators.
##### `this.translate(identifier, variables)`
***identifier* String** - Identifier of the string that should be translated.
***variables* Object** - Object of variables to be used in translation.
This improved and backwards compatible way to handle translations behaves like the normal translation function and follows the rules described above. It's recommended to use this new format for translating everywhere. It allows translator to change the word order in the sentence to be translated.
**Example:**
````javascript
var timeUntilEnd = moment(event.endDate, "x").fromNow(true);
this.translate("RUNNING", { "timeUntilEnd": timeUntilEnd) }); // Will return a translated string for the identifier RUNNING, replacing `{timeUntilEnd}` with the contents of the variable `timeUntilEnd` in the order that translator intended.
````
**Example English .json file:**
````javascript
{
"RUNNING": "Ends in {timeUntilEnd}",
}
````
**Example Finnish .json file:**
````javascript
{
"RUNNING": "Päättyy {timeUntilEnd} päästä",
}
````
**Note:** The *variables* Object has an special case called `fallback`. It's used to support old translations in translation files that do not have the variables in them. If you are upgrading an old module that had translations that did not support the word order, it is recommended to have the fallback layout.
**Example:**
````javascript
var timeUntilEnd = moment(event.endDate, "x").fromNow(true);
)}); // Will return a translated string for the identifier RUNNING, replacing `{timeUntilEnd}` with the contents of the variable `timeUntilEnd` in the order that translator intended. (has a fallback)
````
**Example swedish .json file that does not have the variable in it:**
````javascript
{
"RUNNING": "Slutar",
}
````
In this case the `translate`-function will not find any variables in the translation, will look for `fallback` variable and use that if possible to create the translation.
## The Node Helper: node_helper.js
The node helper is a Node.js script that is able to do some backend task to support your module. For every module type, only one node helper instance will be created. For example: if your MagicMirror uses two calendar modules, there will be only one calendar node helper instantiated.
**Note:** Because there is only one node helper per module type, there is no default config available within your module. It's your task to send the desired config from your module to your node helper.
In it's most simple form, the node_helper.js file must contain:
````javascript
var NodeHelper = require("node_helper");
module.exports = NodeHelper.create({});
````
Of course, the above helper would not do anything useful. So with the information above, you should be able to make it a bit more sophisticated.
### Available module instance properties
#### `this.name`
**String**
The name of the module
#### `this.path`
**String**
The path of the module
#### `this.expressApp`
**Express App Instance**
This is a link to the express instance. It will allow you to define extra routes.
**Example:**
````javascript
start: function() {
this.expressApp.get('/foobar', function (req, res) {
res.send('GET request to /foobar');
});
}
````
**Note:** By default, a public path to your module's public folder will be created:
This is a link to the IO instance. It will allow you to do some Socket.IO magic. In most cases you won't need this, since the Node Helper has a few convenience methods to make this simple.
#### `requiresVersion:`
*Introduced in version: 2.1.0.*
A string that defines the minimum version of the MagicMirror framework. If it is set, the system compares the required version with the users version. If the version of the user is out of date, it won't run the module.
**Note:** Since this check is introduced in version 2.1.0, this check will not be run in older versions. Keep this in mind if you get issue reports on your module.
Example:
````javascript
requiresVersion: "2.1.0",
````
### Subclassable module methods
#### `init()`
This method is called when a node helper gets instantiated. In most cases you do not need to subclass this method.
#### `start()`
This method is called when all node helpers are loaded and the system is ready to boot up. The start method is a perfect place to define any additional module properties:
With this method, your node helper can receive notifications from your modules. When this method is called, it has 2 arguments:
- `notification` - String - The notification identifier.
- `payload` - AnyType - The payload of a notification.
**Note:** The socket connection is established as soon as the module sends its first message using [sendSocketNotification](thissendsocketnotificationnotification-payload).
***notification* String** - The notification identifier.<br>
***payload* AnyType** - Optional. A notification payload.<br>
If you want to send a notification to all your modules, use the `sendSocketNotification(notification, payload)`. Only the module of your module type will receive the socket notification.
**Note:** Since all instances of your module will receive the notifications, it's your task to make sure the right module responds to your messages.
The core Magic Mirror object: `MM` has some handy method that will help you in controlling your and other modules. Most of the `MM` methods are available via convenience methods on the Module instance.
### Module selection
The only additional method available for your module, is the feature to retrieve references to other modules. This can be used to hide and show other modules.
#### `MM.getModules()`
**Returns Array** - An array with module instances.<br>
To make a selection of all currently loaded module instances, run the `MM.getModules()` method. It will return an array with all currently loaded module instances. The returned array has a lot of filtering methods. See below for more info.
**Note:** This method returns an empty array if not all modules are started yet. Wait for the `ALL_MODULES_STARTED` [notification](#notificationreceivednotification-payload-sender).
##### `.withClass(classnames)`
***classnames* String or Array** - The class names on which you want to filter.
**Returns Array** - An array with module instances.<br>
If you want to make a selection based on one or more class names, use the withClass method on a result of the `MM.getModules()` method. The argument of the `withClass(classname)` method can be an array, or space separated string.
**Examples:**
````javascript
var modules = MM.getModules().withClass('classname');
var modules = MM.getModules().withClass('classname1 classname2');
var modules = MM.getModules().withClass(['classname1','classname2']);
````
##### `.exceptWithClass(classnames)`
***classnames* String or Array** - The class names of the modules you want to remove from the results.
**Returns Array** - An array with module instances.<br>
If you to remove some modules from a selection based on a classname, use the exceptWithClass method on a result of the `MM.getModules()` method. The argument of the `exceptWithClass(classname)` method can be an array, or space separated string.
**Examples:**
````javascript
var modules = MM.getModules().exceptWithClass('classname');
var modules = MM.getModules().exceptWithClass('classname1 classname2');
var modules = MM.getModules().exceptWithClass(['classname1','classname2']);
````
##### `.exceptModule(module)`
***module* Module Object** - The reference to a module you want to remove from the results.
**Returns Array** - An array with module instances.<br>
If you to remove a specific module instance from a selection based on a classname, use the exceptWithClass method on a result of the `MM.getModules()` method. This can be helpful if you want to select all module instances except the instance of your module.
**Examples:**
````javascript
var modules = MM.getModules().exceptModule(this);
````
Of course, you can combine all of the above filters:
**Example:**
````javascript
var modules = MM.getModules().withClass('classname1').exceptwithClass('classname2').exceptModule(aModule);
````
##### `.enumerate(callback)`
***callback* Function(module)** - The callback run on every instance.
If you want to perform an action on all selected modules, you can use the `enumerate` function:
````javascript
MM.getModules().enumerate(function(module) {
Log.log(module.name);
});
````
**Example:**
To hide all modules except the your module instance, you could write something like:
The Magic Mirror contains a convenience wrapper for logging. Currently, this logger is a simple proxy to the original `console.log` methods. But it might get additional features in the future. The Loggers is currently only available in the core module file (not in the node_helper).
The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules.
## Usage
To use this module, add it to the modules array in the config/config.js file:
The alert module is one of the default modules of the MagicMirror². This module displays notifications from other modules.
```
modules: [
{
module: "alert",
config: {
// The config property is optional.
// See 'Configuration options' for more information.
}
}
]
```
## Configuration options
The following properties can be configured:
| Option | Description
| ----------------- | -----------
| `effect` | The animation effect to use for notifications. <br><br>**Possible values:**`scale``slide``genie``jelly``flip``exploader``bouncyflip`<br>**Default value:**`slide`
| `alert_effect` | The animation effect to use for alerts. <br><br>**Possible values:**`scale``slide``genie``jelly``flip``exploader``bouncyflip`<br>**Default value:**`jelly`
| `display_time` | Time a notification is displayed in milliseconds. <br><br>**Possible values:**`int`<br>**Default value:**`3500`
| `position` | Position where the notifications should be displayed. <br><br>**Possible values:**`left``center``right`<br>**Default value:**`center`
| `welcome_message` | Message shown at startup. <br><br>**Possible values:**`string``false`<br>**Default value:**`false` (no message at startup)
| `title` | The title of the alert. <br><br>**Possible values:**`text` or `html`
| `message` | The message of the alert. <br><br>**Possible values:**`text` or `html`
| `imageUrl` (optional) | Image to show in the alert <br><br>**Possible values:**`url``path`<br>**Default value:**`none`
| `imageFA` (optional) | Font Awesome icon to show in the alert <br><br>**Possible values:** See [Font Awsome](http://fontawesome.io/icons/) website. <br>**Default value:**`none`
| `imageHeight` (optional even with imageUrl set) | Height of the image <br><br>**Possible values:**`intpx`<br>**Default value:**`80px`
| `timer` (optional) | How long the alert should stay visible in ms. <br>**Important:** If you do not use the `timer`, it is your duty to hide the alert by using `self.sendNotification("HIDE_ALERT");`! <br><br>**Possible values:** `int``float`<br>**Default value:**`none`
The `calendar` module is one of the default modules of the MagicMirror.
The `calendar` module is one of the default modules of the MagicMirror².
This module displays events from a public .ical calendar. It can combine multiple calendars.
## Using the module
To use this module, add it to the modules array in the `config/config.js` file:
````javascript
modules: [
{
module: "calendar",
position: "top_left", // This can be any of the regions. Best results in left or right regions.
config: {
// The config property is optional.
// If no config is set, an example calendar is shown.
// See 'Configuration options' for more information.
}
}
]
````
## Configuration options
The following properties can be configured:
| Option | Description
| ---------------------------- | -----------
| `maximumEntries` | The maximum number of events shown. / **Possible values:** `0` - `100` <br> **Default value:** `10`
| `maximumNumberOfDays` | The maximum number of days in the future. <br><br> **Default value:** `365`
| `displaySymbol` | Display a symbol in front of an entry. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `defaultSymbol` | The default symbol. <br><br> **Possible values:** See [Font Awsome](http://fontawesome.io/icons/) website. <br> **Default value:** `calendar`
| `maxTitleLength` | The maximum title length. <br><br> **Possible values:** `10` - `50` <br> **Default value:** `25`
| `wrapEvents` | Wrap event titles to multiple lines. Breaks lines at the length defined by `maxTitleLength`. <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `fetchInterval` | How often does the content needs to be fetched? (Milliseconds) <br><br> **Possible values:** `1000` - `86400000` <br> **Default value:** `300000` (5 minutes)
| `animationSpeed` | Speed of the update animation. (Milliseconds) <br><br> **Possible values:**`0` - `5000` <br> **Default value:** `2000` (2 seconds)
| `fade` | Fade the future events to black. (Gradient) <br><br> **Possible values:** `true` or `false` <br> **Default value:** `true`
| `fadePoint` | Where to start fade? <br><br> **Possible values:** `0` (top of the list) - `1` (bottom of list) <br> **Default value:** `0.25`
| `calendars` | The list of calendars. <br><br> **Possible values:** An array, see _calendar configuration_ below. <br> **Default value:** _An example calendar._
| `titleReplace` | An object of textual replacements applied to the tile of the event. This allow to remove or replace certains words in the title. <br><br> **Example:** `{'Birthday of ' : '', 'foo':'bar'}` <br> **Default value:** `{ "De verjaardag van ": "", "'s birthday": "" }`
| `displayRepeatingCountTitle` | Show count title for yearly repeating events (e.g. "X. Birthday", "X. Anniversary") <br><br> **Possible values:** `true` or `false` <br> **Default value:** `false`
| `dateFormat` | Format to use for the date of events (when using absolute dates) <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `MMM Do` (e.g. Jan 18th)
| `fullDayEventDateFormat` | Format to use for the date of full day events (when using absolute dates) <br><br> **Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/) <br> **Default value:** `MMM Do` (e.g. Jan 18th)
| `timeFormat` | Display event times as absolute dates, or relative time <br><br> **Possible values:** `absolute` or `relative` <br> **Default value:** `relative`
| `getRelative` | How much time (in hours) should be left until calendar events start getting relative? <br><br> **Possible values:** `0` (events stay absolute) - `48` (48 hours before the event starts) <br> **Default value:** `6`
| `urgency` | When using a timeFormat of `absolute`, the `urgency` setting allows you to display events within a specific time frame as `relative`. This allows events within a certain time frame to be displayed as relative (in xx days) while others are displayed as absolute dates <br><br> **Possible values:** a positive integer representing the number of days for which you want a relative date, for example `7` (for 7 days) <br><br> **Default value:** `7`
| `broadcastEvents` | If this property is set to true, the calendar will broadcast all the events to all other modules with the notification message: `CALENDAR_EVENTS`. The event objects are stored in an array and contain the following fields: `title`, `startDate`, `endDate`, `fullDayEvent`, `location` and `geo`. <br><br> **Possible values:** `true`, `false` <br><br> **Default value:** `true`
| `excludedEvents` | An array of words / phrases from event titles that will be excluded from being shown. <br><br> **Example:** `['Birthday', 'Hide This Event']` <br> **Default value:** `[]`
### Calendar configuration
The `calendars` property contains an array of the configured calendars.
The `colored` property gives the option for an individual color for each calendar.
| `url` | The url of the calendar .ical. This property is required. <br><br> **Possible values:** Any public accessble .ical calendar.
| `symbol` | The symbol to show in front of an event. This property is optional. <br><br> **Possible values:** See [Font Awesome](http://fontawesome.io/icons/) website. To have multiple symbols you can define them in an array e.g. `["calendar", "plane"]`
| `color` | The font color of an event from this calendar. This property should be set if the config is set to colored: true. <br><br> **Possible values:** HEX, RGB or RGBA values (#efefef, rgb(242,242,242), rgba(242,242,242,0.5)).
| `repeatingCountTitle` | The count title for yearly repating events in this calendar. <br><br> **Example:** `'Birthday'`
| `maximumEntries` | The maximum number of events shown. Overrides global setting. **Possible values:** `0` - `100`
| `maximumNumberOfDays` | The maximum number of days in the future. Overrides global setting
| `auth` | The object containing options for authentication against the calendar.
#### Calendar authentication options:
| Option | Description
| --------------------- | -----------
| `user` | The username for HTTP authentication.
| `pass` | The password for HTTP authentication. (If you use Bearer authentication, this should be your BearerToken.)
| `method` | Which authentication method should be used. HTTP Basic, Digest and Bearer authentication methods are supported. Basic authentication is used by default if this option is omitted. **Possible values:** `digest`, `basic`, `bearer` **Default value:** `basic`
For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html).
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.