{"id":21009867,"url":"https://github.com/39software/Panoply","last_synced_at":"2025-05-15T02:33:32.123Z","repository":{"id":107716767,"uuid":"442919347","full_name":"x86-39/Panoply","owner":"x86-39","description":"Python program to display various stats and texts on a HUB75 connected RGB matrix display","archived":false,"fork":false,"pushed_at":"2022-04-30T18:55:00.000Z","size":592,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-08T10:54:54.140Z","etag":null,"topics":["home-assistant","matrix-led","raspberry-pi","rgb","rgb-matrix","rgbmatrix"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/x86-39.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-29T23:56:30.000Z","updated_at":"2024-09-30T23:02:11.000Z","dependencies_parsed_at":"2023-04-05T07:16:43.122Z","dependency_job_id":null,"html_url":"https://github.com/x86-39/Panoply","commit_stats":null,"previous_names":["x86-39/panoply"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x86-39%2FPanoply","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x86-39%2FPanoply/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x86-39%2FPanoply/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/x86-39%2FPanoply/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/x86-39","download_url":"https://codeload.github.com/x86-39/Panoply/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225324099,"owners_count":17456467,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["home-assistant","matrix-led","raspberry-pi","rgb","rgb-matrix","rgbmatrix"],"created_at":"2024-11-19T09:18:10.539Z","updated_at":"2025-05-15T02:33:26.760Z","avatar_url":"https://github.com/x86-39.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"images/PanoplyLogo.png\" align=\"right\" alt=\"Logo\" title=\"Logo\" width=\"240\" height=\"240\" /\u003e\n\n# Panoply\n\nPanoply is a Python program to drive an RGB Matrix display. This program comes with Home Assistant integration, which makes it a great display to view Home Assistant devices.  \n\n## Usage\n1. Make sure you the [rgbmatrix](https://github.com/hzeller/rpi-rgb-led-matrix) library installed and your RGB matrix is connected.  \n2. Configure your display settings in `config.py` (Copy this from `config_sample.py`). The default size is 64x64, with no rotation.  \n3. If you've got the display connected and configured, go into the `panoply` directory and simply run `python3 main.py`!  \n4. If all works, you can configure the layout in `config.py` to your liking.  \n5. (Optional) To have it persist after your terminal closes, I recommend using `tmux` (`tmux new-session`).  \n\n## Configuration\n\n\u003cimg src=\"https://raw.githubusercontent.com/diademiemi/Panoply/main/images/DefaultConfig.jpg\" align=\"right\" title=\"Static colour\" width=\"256\" height=\"256\" /\u003e  \n\nThe following is the default configuration for Panoply, with every option commented with usage. Please place the configuration at `panoply/config.py` after configuring.  \n\n\u003cdetails\u003e\u003csummary\u003econfig_sample.py\u003c/summary\u003e\u003cp\u003e\n\n## config_sample.py\n```python\n# How often the display refreshes\nDISPLAY_REFRESH_RATE = 0.25\n# How often information on the device is polled (Date, time)\nLOCAL_REFRESH_INTERVAL = 0.5\n# How often information over web requests is polled (Home Assistant)\nWEB_REFRESH_INTERVAL = 30\n\n# Put your display resolution here\nDISPLAY_WIDTH = 64\nDISPLAY_HEIGHT = 64\n# If you need any rotation, specify this as a multiple of 90, otherwise leave it at 0\nDISPLAY_ROTATION = 0\n# Display mapping, read https://github.com/hzeller/rpi-rgb-led-matrix#changing-parameters-via-command-line-flags\nDISPLAY_HARDWARE_MAPPING = \"adafruit-hat\"\n\n# Path to font files, NEEDS TO BE \"BDF\" bitmap fonts!\nTINY_FONT = \"../fonts/Tiny-4x6.bdf\"\nSMALL_FONT = \"../fonts/Small-5x7.bdf\"\nLARGE_FONT = \"../fonts/PixeloidMono.bdf\"\n\n# Time when to dim the display\n# BE SURE TO ZERO-FILL THE TIMES (06:00, NOT 6:00)\nDIM_START_TIME = \"20:00\"\n# Time when to stop dimming the display\nDIM_STOP_TIME = \"06:00\"\n# How much the display should be dimmer as a multiplier of the usual brightness. \n# Set to 1 to disable dimming\nDIM_MODIFIER = 1\n\n# This defines placeholders which are retrieved from shell commands\n# These are refreshed according to LOCAL_REFRESH_INTERVAL\n# '\u003cnew placeholder name\u003e' : '\u003cshell command\u003e'\nCOMMAND_PLACEHOLDERS = {\n    'time' : 'date +\"%H:%M:%S\"',\n    'date' : 'date +\"%Y-%m-%d\"'\n}\n\n# URL of your Home Assistant instance\nHOME_ASSISTANT_URL = \"https://home.example.com\"\n# Long-lived access token\nHOME_ASSISTANT_KEY = \"ABCDEF\"\n\n# This defines placeholders which are retrieved from a Home Assistant instance\n# Leave blank to disable entirely\n# These are refreshed according to WEB_REFRESH_INTERVAL\n# '\u003cnew placeholder name\u003e' : '\u003chome assistant entity\u003e' \nHOME_ASSISTANT_STATE_PLACEHOLDERS = {\n    'temp' : 'sensor.room_temperature',\n    'phonebattery' : 'sensor.phone_battery_level'\n}\n\n# Colors that are retrieved from a Home Assistant lightbulb\n# These can be used instead of the usual tuple:\n# 'text definition' : (\u003cx position\u003e, \u003cy position\u003e, 'bulbs')\n# Leave blank to disable entirely\n# These are refreshed according to WEB_REFRESH_INTERVAL\n# '\u003cnew color name\u003e' : '\u003chome assistant entity\u003e' \nHOME_ASSISTANT_COLORS = {\n    'bulbs' : 'light.bulbs'\n}\n\n# Layout settings\n# Here you can customise the location and content of text elements or place shapes\n\n# AVAILABLE TEXT PLACEHOLDERS:\n# %time% - Replaced with the current time\n# %date% - Replaced with the current date\n# And any entities defined from Home Assistant\n\n# Large text, using the PixeloidMono font\n# '\u003ctext %placeholder%\u003e' : (\u003cx position bottom-left\u003e, \u003cy position bottom-left\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nLARGE_TEXT_ELEMENTS = {\n    '%time%' : (2, 9, (200, 200, 200)),\n    '%temp%' : (2, 38, (200, 200, 200))\n}\n\n# Small text, using the 5x7 font\n# '\u003ctext %placeholder%\u003e' : (\u003cx position bottom-left\u003e, \u003cy position bottom-left\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nSMALL_TEXT_ELEMENTS = {\n    '%date%' : (2, 18, (200, 200, 200)),\n    'it is' : (2, 30, (200, 200, 200))\n}\n\n# Tiny text, using the 4x6 font\n# '\u003ctext %placeholder%\u003e' : (\u003cx position bottom-left\u003e, \u003cy position bottom-left\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nTINY_TEXT_ELEMENTS = {\n    'c' : (27, 38, (200, 200, 200)),\n    'Hello, world!' : (2, 56, 'bulbs') # Example of using colors retrieved from Home Assistant\n}\n\n# Place a line going from x0, y0 to x1, y1\n# (\u003cfirst x position\u003e, \u003cfirst y position\u003e, \u003csecond x position\u003e, \u003csecond y position) (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nLINES = [\n    (0, 10, 64, 10, (200, 0, 0)),\n    (53, 0, 53, 64, (0, 0, 200))\n]\n\n# Place a hollow rectangle\n# (\u003cfirst x position\u003e, \u003cfirst y position\u003e, \u003csecond x position\u003e, \u003csecond y position\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nRECTANGLES = [\n    (0, 0, 63, 63, (0, 200, 0)),\n    (1, 23, 32, 38, (200, 0, 200))\n]\n\n\n```\n\u003c/p\u003e\u003c/details\u003e\n\nFor every text field, placeholders can be used. These placeholders can be defined earlier in the config at `HOME_ASSISTANT_STATE_PLACEHOLDERS` and `COMMAND_PLACEHOLDERS`. When you type the placeholder surrounded by percentage signs, these will be replaced with the last value retrieved from the command/entity configured.  \nThere are also color placeholders which are retrieved from Home Assistant entities. These take the entity's `rgb_color` field and use them as the colour. These can be used by defining them in `HOME_ASSISTANT_COLORS` and then using the colors name instead of the colour tuple.  \n\n## Example / My Config\n\n\u003cimg src=\"https://raw.githubusercontent.com/diademiemi/Panoply/main/images/MyConfig.jpg\" align=\"right\" title=\"Static colour\" width=\"256\" height=\"256\" /\u003e  \n\nIn this image my configuration is shown. I have the time and date displayed at the top. The temperature is shown after being retrieved from Home Assistant.  \nBeneath that is a horizontal line which takes the colour of my LED strip (Which you can see in the reflection!), and below that are 6 icons representing my ceiling bulbs, these also take the colour they are set to. In the picture there's one turned off, one at cool white, one at warm white and a red, blue and green bulb.  \nAt the bottom there is text which says my phone's current battery level, and the entire panel is wrapped in a red square. Hopefully this gives an idea of the possibilities so far!  \n\nThe configuration used for it is the following:\n\n\u003cdetails\u003e\u003csummary\u003econfig.py\u003c/summary\u003e\u003cp\u003e\n\n## config.py\n```python\n# How often the display refreshes\nDISPLAY_REFRESH_RATE = 0.25\n# How often information on the device is polled (Date, time)\nLOCAL_REFRESH_INTERVAL = 0.4\n# How often information over web requests is polled (Home Assistant)\nWEB_REFRESH_INTERVAL = 10\n\n# Put your display resolution here\nDISPLAY_WIDTH = 64\nDISPLAY_HEIGHT = 64\n# If you need any rotation, specify this as a multiple of 90, otherwise leave it at 0\nDISPLAY_ROTATION = 180\n# Display mapping, read https://github.com/hzeller/rpi-rgb-led-matrix#changing-parameters-via-command-line-flags\nDISPLAY_HARDWARE_MAPPING = \"adafruit-hat\"\n\n# Path to font files, NEEDS TO BE \"BDF\" bitmap fonts!\nTINY_FONT = \"../fonts/Tiny-4x6.bdf\"\nSMALL_FONT = \"../fonts/Small-5x7.bdf\"\nLARGE_FONT = \"../fonts/PixeloidMono.bdf\"\n\n# Time when to dim the display\n# BE SURE TO ZERO-FILL THE TIMES (06:00, NOT 6:00)\nDIM_START_TIME = \"22:00\"\n# Time when to stop dimming the display\nDIM_STOP_TIME = \"07:00\"\n# How much the display should be dimmer as a multiplier of the usual brightness\nDIM_MODIFIER = 0.15\n\n# This defines placeholders which are retrieved from shell commands\n# These are refreshed according to LOCAL_REFRESH_INTERVAL\n# '\u003cnew placeholder name\u003e' : '\u003cshell command\u003e'\nCOMMAND_PLACEHOLDERS = {\n    'time' : 'date +\"%H:%M:%S\"',\n    'date' : 'date +\"%Y-%m-%d\"'\n}\n\n# URL of your Home Assistant instance\nHOME_ASSISTANT_URL = \"https://home.example.com\"\n# Long-lived access token\nHOME_ASSISTANT_KEY = \"ABCDEF\"\n\n# This defines placeholders which are retrieved from a Home Assistant instance\n# Leave blank to disable entirely\n# These are refreshed according to WEB_REFRESH_INTERVAL\n# '\u003cnew placeholder name\u003e' : '\u003chome assistant entity\u003e' \nHOME_ASSISTANT_STATE_PLACEHOLDERS = {\n    'temp' : 'sensor.room_temperature',\n    'phonebattery' : 'sensor.phone_battery_level'\n}\n\n# Colors that are retrieved from a Home Assistant lightbulb\n# These can be used instead of the usual tuple:\n# 'text definition' : (\u003cx position\u003e, \u003cy position\u003e, 'bulbs')\n# Leave blank to disable entirely\n# These are refreshed according to WEB_REFRESH_INTERVAL\n# '\u003cnew color name\u003e' : '\u003chome assistant entity\u003e' \nHOME_ASSISTANT_COLORS = {\n    'bulb1' : 'light.bulb1',\n    'bulb2' : 'light.bulb2',\n    'bulb3' : 'light.bulb3',\n    'bulb4' : 'light.bulb4',\n    'bulb5' : 'light.bulb5',\n    'bulb6' : 'light.bulb6',\n    'led_01' : 'light.led_01'\n}\n\n# Layout settings\n# Here you can customise the location and content of text elements or place shapes\n\n# Large text, using the PixeloidMono font\n# '\u003ctext %placeholder%\u003e' : (\u003cx position bottom-left\u003e, \u003cy position bottom-left\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nLARGE_TEXT_ELEMENTS = {\n    '%time%' : (8, 9, (200, 200, 200)),\n    '%temp%' : (17, 38, (200, 200, 200)),\n    '●' : (21, 48, 'bulb1'),\n    '● ' : (21, 55, 'bulb2'),\n    '●  ' : (29, 48, 'bulb3'),\n    '●   ' : (29, 55, 'bulb4'),\n    '●    ' : (37, 48, 'bulb5'),\n    '●     ' : (37, 55, 'bulb6') # The spaces are required so these show up as unique values in the dict, but they do not get rendered!\n}\n\n# Small text, using the 5x7 font\n# '\u003ctext %placeholder%\u003e' : (\u003cx position bottom-left\u003e, \u003cy position bottom-left\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nSMALL_TEXT_ELEMENTS = {\n    '%date%' : (7, 18, (200, 200, 200)),\n    'it is' : (18, 30, (200, 200, 200))\n}\n\n# Tiny text, using the 4x6 font\n# '\u003ctext %placeholder%\u003e' : (\u003cx position bottom-left\u003e, \u003cy position bottom-left\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nTINY_TEXT_ELEMENTS = {\n    'c' : (43, 38, (200, 200, 200)),\n    'Phone at %phonebattery%%' : (7, 62, (200, 200, 200))\n}\n\n# Place a line going from x0, y0 to x1, y1\n# (\u003cfirst x position\u003e, \u003cfirst y position\u003e, \u003csecond x position\u003e, \u003csecond y position\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nLINES = [\n    (16, 40, 48, 40, 'led_01')\n]\n\n# Place a hollow rectangle\n# (\u003cfirst x position\u003e, \u003cfirst y position\u003e, \u003csecond x position\u003e, \u003csecond y position\u003e, (\u003cred\u003e, \u003cgreen\u003e, \u003cblue\u003e))\nRECTANGLES = [\n    (0, 0, 63, 63, (64, 0, 0))\n]\n\n```\n\u003c/p\u003e\u003c/details\u003e\n\n## Notices\nThis project uses fonts under the public domain and fonts licensed under the SIL Open Font License. For more information, check the [README.md](./fonts/README.md) in the `fonts` directory.  \n\n\u003cimg src=\"https://raw.githubusercontent.com/diademiemi/Panoply/main/images/Setup.jpg\" align=\"right\" title=\"Static colour\" width=\"270\" height=\"150\" /\u003e  \n\nThis has been tested with a Raspberry Pi 4b with 4GB of RAM. The display I am using is a [JOY-iT 64x64 RGB-LED Matrix Module](https://www.elektor.com/joy-it-64x64-rgb-led-matrix-module) with an [Adafruit RGB Matrix HAT](https://www.adafruit.com/product/2345). The code is made to work with any display that supports the [rgbmatrix](https://github.com/hzeller/rpi-rgb-led-matrix) library though, although I doubt lower resolutions will be able to display much.  \nThe cause of the reflections in the images are because I covered the display with a plastic film to dim it so it can be kept on at night, not the display itself.  \n\n The `rgbmatrix` library requires root unless configured otherwise, this is not a bug with this program!  ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F39software%2FPanoply","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F39software%2FPanoply","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F39software%2FPanoply/lists"}