Read the statement by Michael Teeuw here.
Apple calendar & server only mode
-
Hi all,
I’m looking for a little guidance here. I’m having issues with displaying iCloud calendar data. When MM loads, the iCloud Calendar module states the following:
Error in the calendar module. Check logs for more details
I’ve tried inspecting the console for any obvious errors and I started investigating using breakpoints. It seems like the MM webpage cannot access the .ics file.
I started with the instructions listed here. I was able to sync with iCloud using vdirsyncer and the .ics file has valid data inside that matches my phone.
On the Docker container (mm)
Calendar directory
/home/node/MagicMirror/modules/calendar
Vdirsyncer config location
/home/node/.vdirsyncer/config
Vdirsyncer config file
# vdirsyncer configuration for MagicMirror. # # Move it to ~/.vdirsyncer/config or ~/.config/vdirsyncer/config and edit it. # Run `vdirsyncer --help` for CLI usage. # # Optional parameters are commented out. # This file doesn't document all available parameters, see # http://vdirsyncer.pimutils.org/ for the rest of them. [general] # A folder where vdirsyncer can store some metadata about each pair. status_path = "~/.vdirsyncer/status/" # CALDAV Sync [pair iCloud_to_MagicMirror] a = "Mirror" b = "iCloud" collections = ["Stuff"] # Calendars also have a color property metadata = ["displayname", "color"] [storage Mirror] # We need a single .ics file for use with the mirror (Attention! This is really slow on big amounts of events.) type = "singlefile" # We'll put the calendar file to a readable location for the calendar module path = "/home/node/MagicMirror/modules/calendars/%s.ics" [storage iCloud] type = "caldav" url = "https://caldav.icloud.com/" # Authentication credentials username = "email" password = "password" # We only want to sync in the direction TO the mirror, so we make iCloud readonly read_only = true # We only want to sync events item_types = ["VEVENT"] # We need to keep the number of events low, so we'll just sync the next month # Adjust this to your needs start_date = "datetime.now() - timedelta(days=1)" end_date = "datetime.now() + timedelta(days=30)"
I had to make a few tweaks for Alpine and they’re listed below.
~/.local/bin/vdirsyncer
is located here
/etc/init.d
I installed OpenRC on Alpine and used OpenRC-Run generator to convert systemd service to openrc
vidrsyncer.timer is located here (I’m not 100% certain about this guy)
/etc/periodic/15min
vidrsyncer.timer file
[Unit] Description=Synchronize vdirs [Timer] OnBootSec=5m OnUnitActiveSec=15m AccuracySec=5m [Install] WantedBy=timers.target
vdirsyncer.service is located here
/etc/init.d/
vdirsyncer file
vdirsyncer #!/sbin/openrc-run name=$RC_SVCNAME description="Synchronize calendars and contacts" supervisor="supervise-daemon" command="/usr/bin/vdirsyncer" command_args="sync"
On the host machine
docker-yaml.ymlservices: magicmirror: container_name: mm image: magicmirror/test:version1 ports: - "8080:8080" volumes: - ../mounts/config:/opt/magic_mirror/config - ../mounts/modules:/opt/magic_mirror/modules - ../mounts/css:/opt/magic_mirror/css restart: unless-stopped command: - npm - run - server
config.js location
/home/user/mounts/config/config.js
config.js
/* Config Sample * * For more information on how you can configure this file * see https://docs.magicmirror.builders/configuration/introduction.html * and https://docs.magicmirror.builders/modules/configuration.html * * You can use environment variables using a `config.js.template` file instead of `config.js` * which will be converted to `config.js` while starting. For more information * see https://docs.magicmirror.builders/configuration/introduction.html#enviromnent-variables */ lat_var = 28 long_var = 80 let config = { address: "0.0.0.0", // Address to listen on, can be: // - "localhost", "127.0.0.1", "::1" to listen on loopback interface // - another specific IPv4/6 to listen on a specific interface // - "0.0.0.0", "::" to listen on any interface // Default, when address config is left out or empty, is "localhost" port: 8080, basePath: "/", // The URL path where MagicMirror² is hosted. If you are using a Reverse proxy // you must set the sub path here. basePath must end with a / ipWhitelist: ["127.0.0.1", "::ffff:192.168.1.1/120", "::1", "192.168.1.1/24"], // Set [] to allow all IP addresses // or add a specific IPv4 of 192.168.1.5 : // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], useHttps: false, // Support HTTPS or not, default "false" will use HTTP httpsPrivateKey: "", // HTTPS private key path, only require when useHttps is true httpsCertificate: "", // HTTPS Certificate path, only require when useHttps is true language: "en", locale: "en-US", logLevel: ["INFO", "LOG", "WARN", "ERROR", "DEBUG"], // Add "DEBUG" for even more logging timeFormat: 24, units: "imperial", modules: [ { module: "alert", }, { module: "updatenotification", position: "top_bar" }, { module: "clock", position: "top_left" }, { module: 'calendar', position: 'top_left', // This can be any of the regions. Best results in left or right regions. config: { maximumNumberOfDays: 10, maximumEntries: 7, calendars: [{ url: "http://192.168.1.188:8080/home/node/MagicMirror/modules/calendars/Stuf.ics", symbol: 'calendar' } ] } }, { module: "compliments", position: "lower_third" }, { module: "weather", position: "top_right", config: { weatherProvider: "openmeteo", type: "current", lat: lat_var, lon: long_var } }, { module: "weather", position: "top_right", header: "Weather Forecast", config: { weatherProvider: "openmeteo", type: "forecast", lat: lat_var, lon: long_var } }, { module: "newsfeed", position: "bottom_bar", config: { feeds: [ { title: "New York Times", url: "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" } ], showSourceTitle: true, showPublishDate: true, broadcastNewsFeeds: true, broadcastNewsUpdates: true } }, ] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ if (typeof module !== "undefined") { module.exports = config; }
-
Thanks for the feedback. I was able to get a sample event to show in the calendar.
When looking at the the config.js, I was thinking that meant of the entire filesystem and not MM install directory (didn’t read that line close enough)
I made the following changes
On hose machine
config.jsurl: "http:/0.0.0.0:8080/modules/calendars/1FC43665-307D-4E49-A0C5-914CA52E07EB.ics",
On Docker
~/.vdirsyncer/configpath = "/opt/magic_mirror/modules/calendars/%s.ics"
Ran the following code
vdirsyncer sync --force-delete iCloud_to_MagicMirror/Stuff vdirsyncer sync
Everything looks good and works! Thank you again for the help
-
url in calendar config
http://192.168.1.188:8080/home/node/MagicMirror/modules/calendars/Stuf.ics
no. the MagicMirror http server root is the MagicMirror folder, so anything you need to access via the http server has to be in that folder tree
you CAN link ( ln command) something outside that tree into the tree.
I typically advise making a data dir
mkdir ~/MagicMirror/data
and linking into that
sudo ln -s real fake
cd ~/MagicMirror/data
sudo ln-s xxxxxx.ics Stuf.ics
xxxxxx.is is the real absolute path and name of the filethe in config.js the url is
http://ocalhost:8080/data/Stuf.icsalso you could have used pm2 to launch the syncer
-
Thanks for the feedback. I was able to get a sample event to show in the calendar.
When looking at the the config.js, I was thinking that meant of the entire filesystem and not MM install directory (didn’t read that line close enough)
I made the following changes
On hose machine
config.jsurl: "http:/0.0.0.0:8080/modules/calendars/1FC43665-307D-4E49-A0C5-914CA52E07EB.ics",
On Docker
~/.vdirsyncer/configpath = "/opt/magic_mirror/modules/calendars/%s.ics"
Ran the following code
vdirsyncer sync --force-delete iCloud_to_MagicMirror/Stuff vdirsyncer sync
Everything looks good and works! Thank you again for the help
-
@dubbedMonster said in Apple calendar & server only mode:
http:/0.0.0.0
cool… but you should NOT use 0.0.0.0 on a url.
0.0.0.0 means ANY network interface… it is ‘supposed’ to be reserved for LISTENERs (server apps) …
if the server would server the file from the SAME system at the requestor, then the correct term is localhost
-
-
I don’t think I fully understand, but I’m following you. I made the change to localhost and everything still works.
Does the same thing apply to the “address” in the config.js?
-
@dubbedMonster said in Apple calendar & server only mode:
Does the same thing apply to the “address” in the config.js?
no… in config.js you are configuring the MM http server
so address:0.0.0.0 means listen for incoming requests on ALL active network interfaces (think ethernet and wifi)… without YOU having to specify their actual assigned IP addresses
if you WANTED ONLY requests from WIFI attached devices, then you would put in the wifi configured IP address … requests from ethernet attached devices would be ignored
(see the results of the ip addr command)
0.0.0.0 is a shortcut when u have multiple adapters and only can supply ONE address on the network listen request…
(else you would have to do multiple requests… the network guys like LESS work!!)if you use my MMM-Config module to configure MM… I provide the address of the different networks and you can pick one (to change from default locahost for example) if you want to be network restrictive
localhost
0.0.0.0
etc -
Thanks for the explanation and the help!