Ephemeris

May 12, 2026 · View on GitHub

Ephemeris Icon

rm1 rm2 rmpp rmppmove rmppure

Ephemeris is a Python-based tool that generates clean, daily schedules using ICS calendar data. Designed with e-ink tablets like reMarkable and Kindle Scribe in mind.

Features

  • Automated Schedule Generation: Seamlessly convert ICS calendar data into organized daily planners.
  • Customizable Layout: Adjust your daily schedule's layout, timeframe, and appearance via environment variables.
  • Elegant PDF Output: Clean PDFs designed specifically for e-ink devices.
  • Links to Days: Mini-Calendar days are clickable links.

Screenshots

These screenshots broadly show the layout options that are possible. See Customization for more information.

Default Layout Time Grid Only All Day Full Width Single Month Mini-Calendar All Day In-Grid

Getting Started

If using with a reMarkable tablet, I ship an image that bundles the rmapi binary. Check out the wiki for more info.

Calendar Configuration

The program uses a YAML configuration file to set up the calendars:

calendars:
  # ics file
  - name: Personal
    source: calendars/personal.ics
    color: gray8

  # directory containing ics files
  - name: Work
    source: calendars/work
    color: gray6

  # web ics file
  - name: US Holidays
    source: https://www.opm.gov/policy-data-oversight/pay-leave/federal-holidays/holidays.ics
    color: gray4

Supported values for colors are CSS names, hex colors, as well as a series of grays (gray1 through gray14) that correspond to each step of 4-bit grayscale.

Docker Compose

services:
  ephemeris:
    image: ghcr.io/rmitchellscott/ephemeris
    volumes:
      - ./calendars:/app/calendars
      - ./output:/app/output
      - ./config.yaml:/app/config.yaml
      - ./feeds_meta.yaml:/app/feeds_meta.yaml  # Used for change detection
    environment:
      - TZ=America/Denver
      - TIME_DATE_RANGE=week

Docker

# Standard version (default)
docker run --rm \
  -v "$(pwd)/calendars:/app/calendars" \
  -v "$(pwd)/output:/app/output" \
  -v "$(pwd)/config.yaml:/app/config.yaml" \
  -v "$(pwd)/feeds_meta.yaml:/app/feeds_meta.yaml" \
  -e TZ=America/Denver \
  -e TIME_DATE_RANGE=week \
  ghcr.io/rmitchellscott/ephemeris

# Version with rmapi bundled
docker run --rm \
  -v "$(pwd)/calendars:/app/calendars" \
  -v "$(pwd)/output:/app/output" \
  -v "$(pwd)/config.yaml:/app/config.yaml" \
  -v "$(pwd)/feeds_meta.yaml:/app/feeds_meta.yaml" \
  -e TZ=America/Denver \
  -e TIME_DATE_RANGE=week \
  ghcr.io/rmitchellscott/ephemeris:main-rmapi0.0.30

# Build locally
# Standard version (without rmapi)
docker build --target ephemeris -t ephemeris .

# Version with rmapi (default build)
docker build -t ephemeris-rmapi .

Python

Setup

  • Python 3.8+
  • Dependencies: cairosvg, icalendar, loguru, pypdf, pytz, pyyaml, reportlab, requests, webcolors

Install dependencies with:

pip install -r requirements.txt

Run the script:

python ephemeris.py

For guidence on sending to your device, see the project's wiki.

Common Device Parameters

reMarkable 1 / 2 / Paper Pure

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=226

reMarkable Paper Pro

DOC_PAGE_DIMENSIONS=1620x2160
DOC_PAGE_DPI=229

reMarkable Paper Pro Move

DOC_PAGE_DIMENSIONS=954x1696
DOC_PAGE_DPI=264

Kindle Scribe*

DOC_PAGE_DIMENSIONS=1860x2480
DOC_PAGE_DPI=300

Boox Note Air2 Plus

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=227

Boox Tab Ultra

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=227

Kobo Elipsa 2E

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=227

Supernote A5 X

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=226

Supernote A5 X2 Manta

$\text{shell} \text{DOC\_PAGE\_DIMENSIONS}=1920 \times 2560 \text{DOC\_PAGE\_DPI}=300 $

Supernote A6 X

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=300

Supernote A6 X2 Nomad

DOC_PAGE_DIMENSIONS=1404x1872
DOC_PAGE_DPI=300

TRMNL**

DOC_PAGE_DIMENSIONS=480x800
DOC_PAGE_DPI=125
# Choose one of these for clearer text rendering:
DOC_MONOCHROME=true
DOC_ANTIALIAS=false

*Information seems hard to find for the Kindle Scribe. If any of these values need correction, please open a GitHub Issue.
**Have a look at my trmnl-png-processor project.

Customization & Supported Environment Variables

Time Configuration

VariableDefaultExampleDescription
TIME_DATE_RANGEtodaytoday, week, month, tomorrow, 2025-04-14:2025-04-18Date range to create schedules for. Each day will be a single page. A single multi-page PDF will be rendered.
TIME_DISPLAY_END2121Defines the ending hour of the displayed daily schedule.
TIME_FILTER_MIN_HOUR04Excludes events with start times before this hour from the generated schedule.
TIME_DISPLAY_START66Defines the starting hour of the displayed daily schedule.
TZUTCAmerica/New_YorkSets the timezone used for interpreting event times.
TIME_FORMAT2412, 24Specifies time formatting in 12-hour or 24-hour formats.

Application Configuration

VariableDefaultExampleDescription
APP_CONFIG_PATH{BASE_DIR}/config.yaml/path/to/config.yamlPath to the configuration file.
APP_META_FILE_PATH{BASE_DIR}/feeds_meta.yaml/path/to/meta.yamlPath to the feeds metadata file.
APP_OUTPUT_FORMATpdfpdf, png, svg, both, allOutput format. both = PDF + PNG, all = PDF + PNG + SVG.
APP_OUTPUT_PDF_PATHoutput/ephemeris.pdfreports/schedule.pdfPath and name for rendered output file.
APP_OUTPUT_PNG_DIRoutput/pngreports/imagesDirectory for rendered output PNG files, one per day.
APP_OUTPUT_SVG_DIRoutput/svgreports/svgDirectory for rendered output SVG files, one per day.
APP_OUTPUT_BG_PNG_DIRoutput/png_backgroundreports/bg_imagesDirectory for background-only PNG files when DOC_SEPARATE_TEXT is enabled.
APP_OUTPUT_TEXT_PNG_DIRoutput/png_textreports/text_imagesDirectory for text-only PNG files when DOC_SEPARATE_TEXT is enabled.
APP_FORCE_REFRESHfalsetrue, falseSkip the changed events check and always render a document for each run.
APP_FILTER_LISTcancelled,canceledcanceled,removedComma-separated list of substrings which, if found in an event's title or status, will drop that event.
APP_FILTER_DECLINED_EMAILS(not set)user@example.com,alias@example.comComma-separated list of email addresses. Events where any of these addresses have declined the invitation will be excluded from the schedule.
APP_POST_HOOK(not set)rsync output/ user@server:/path/Command to execute after successful document generation.
APP_LOG_LEVELINFOVISUAL, EVENTS, DEBUG, INFO, WARNINGMinimum log level to output to console. EVENTS is useful for troubleshooting why events are appearing or not. VISUAL shows detailed drawing information for developer debugging.
APP_LOG_COLORIZEtruetrue, falseWhether to use ANSI colors in console log output.
APP_LOG_FORMAT(see description)custom format stringLoguru format string for console output. Default includes timestamp, level, and message.

Document Rendering

VariableDefaultExampleDescription
DOC_COVER_SVG_PATH{BASE_DIR}/assets/cover.svg/path/to/cover.svgPath to the SVG file used for the cover page.
DOC_COVER_ENABLEDtruetrue, falsePrint a cover page with SVG as the rendered document's first page.
DOC_COVER_WIDTH_SCALE0.750 - 1Scale factor for the cover SVG width relative to page width.
DOC_COVER_VERTICAL_POSITION0.250 - 1Vertical position factor for placing the cover SVG on the page.
DOC_ALLDAY_BOUNDARYgridgrid, marginSelect the left boundary for the "All-Day Events" band, either the main time grid or the left margin.
DOC_ALLDAY_MODEbandband, in-grid, disabledSet to band to draw the All-Day Events in their own band at the top, set to in-grid to draw all day events in the "zeroth" hour of the main time grid, set to disabled to disable All-Day Events from being drawn.
DOC_ALLDAY_OVERFLOWtruetrue, falseWhen true, events outside the main time grid hours are shown with All-Day Events.
DOC_MINICAL_MODEfullfull, current, falsefull will draw mini-calendars for the current and next month, current will draw only the current month, disabled will disable.
DOC_MINICAL_LINKStruetrue, falseAdd links to mini-cal days that have pages rendered.
DOC_MINICAL_INDICATE_RANGEtruetrue, falseIndicate which days are in the document by slightly bolding them in the mini-calendars.
DOC_MINICAL_ALIGNrightcenter, right, leftHorizontal alignment for the mini-calendars. Center and Left are available when DOC_ALLDAY_MODE is set to anything other than band.
DOC_MINICAL_HEIGHT6040Height of mini-calendars and All-Day Events area in points (1pt = 1/72in).
DOC_MINICAL_SPACING1012Gap between each calendar, and between calendars and other elements. In points (1pt = 1/72in).
DOC_MINICAL_TEXT_PADDING58Padding around text in mini-calendars in points (1pt = 1/72in).
DOC_MINICAL_POSITION_OFFSET05Offset adjustment for mini-calendar positioning in points (1pt = 1/72in).
DOC_EVENT_FILL_COLORgray14black, gray0, #000000Color for the background of events. CSS names, Ephemeris gray names, and hex supported.
DOC_EVENT_BORDER_COLORgray(20%)black, gray0, #000000Color for the outline of events. CSS names, Ephemeris gray names, and hex supported.
DOC_SHOW_TIMEtruetrue, falseShow event time labels.
DOC_SHOW_LOCATIONfalsetrue, falseShow event location labels.
DOC_FIRST_LINEtimetime, locationWhich label to show on the first line next to the title (the other appears on line 2 if there's room).
DOC_FOOTER_TEXTE P H E M E R I Supdatedat, disabled, My Cool FooterSet to updatedat to print the "Updated at" timestamp, disabled to disable, or any text you want.
DOC_MONOCHROMEfalsetrue, falseSet to true to render the document in monochrome, disabling anti-aliasing.
DOC_ANTIALIAStruetrue, falseSet to false to disable anti-aliasing.
DOC_FOOTER_COLORgray(60%)black, gray0, #000000Color for the page footer. CSS names, Ephemeris gray names, and hex supported.
DOC_GRID_LINE_COLORgray(20%)black, #000000Color for the time grid lines. CSS names, Ephemeris gray names, and hex supported.
DOC_PAGE_DIMENSIONS1404x18721080x1920Resolution for rendered document.
DOC_PAGE_DPI226300DPI/PPI for rendered document.
DOC_MARGIN_LEFT612Left page margin in points (1pt = 1/72in).
DOC_MARGIN_RIGHT612Right page margin in points (1pt = 1/72in).
DOC_MARGIN_TOP912Top page margin in points (1pt = 1/72in).
DOC_MARGIN_BOTTOM612Bottom page margin in points (1pt = 1/72in).
DOC_GRID_BOTTOM_PADDING912Buffer between the bottom of the grid and the bottom margin in points (1pt = 1/72in). Useful for having a footer.
DOC_SEPARATE_TEXTfalsetrue, falseWhen true, Ephemeris creates text-only and background-only PNG files.

License

Copyright (C) 2025 Mitchell Scott

Licensed under the GNU General Public License v3.0.


Enjoy precisely organized days with Ephemeris!