{"id":42850145,"url":"https://github.com/mfenniak/pixelperfectpi","last_synced_at":"2026-01-30T12:02:15.876Z","repository":{"id":195835265,"uuid":"691666073","full_name":"mfenniak/pixelperfectpi","owner":"mfenniak","description":"pixelperfectpi is an application for the Raspberry Pi that drives an LED matrix panel in order to create a custom digital clock","archived":false,"fork":false,"pushed_at":"2024-11-30T17:07:56.000Z","size":250,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-11-30T17:37:01.904Z","etag":null,"topics":["digital-clock","icalendar","led-matrix","purpleair","raspberry-pi"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mfenniak.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2023-09-14T16:25:02.000Z","updated_at":"2024-11-30T17:07:59.000Z","dependencies_parsed_at":"2024-10-28T20:28:16.698Z","dependency_job_id":"fb42454a-e28c-4428-bc6e-67f15613f462","html_url":"https://github.com/mfenniak/pixelperfectpi","commit_stats":null,"previous_names":["mfenniak/pixelperfectpi"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mfenniak/pixelperfectpi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfenniak%2Fpixelperfectpi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfenniak%2Fpixelperfectpi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfenniak%2Fpixelperfectpi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfenniak%2Fpixelperfectpi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mfenniak","download_url":"https://codeload.github.com/mfenniak/pixelperfectpi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mfenniak%2Fpixelperfectpi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28912222,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T11:55:24.701Z","status":"ssl_error","status_checked_at":"2026-01-30T11:54:13.194Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["digital-clock","icalendar","led-matrix","purpleair","raspberry-pi"],"created_at":"2026-01-30T12:02:09.467Z","updated_at":"2026-01-30T12:02:15.871Z","avatar_url":"https://github.com/mfenniak.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e [!IMPORTANT]  \n\u003e This repository is archived.  The active project has been moved to [https://forgejo.kainnef.com/mfenniak/pixelperfectpi](https://forgejo.kainnef.com/mfenniak/pixelperfectpi)\n\n\n# pixelperfectpi\n\npixelperfectpi is an application for the Raspberry Pi that drives an LED matrix panel in order to create a custom digital clock.\n\nThis app isn't really intended to be re-used -- it isn't very configurable.  It was just built for my own use, and the code is shared so that anyone else who tries to do the same thing has some starting point, or hints and shortcuts.\n\nFeatures:\n- Displays the time.\n- Reads and displays AQI and temperature from a local PurpleAir sensor.\n- Displays the next weather forecast sourced from Environment Canada.\n- Displays the next three calendar events from an iCal feed.\n\nExample installation:\n\nhttps://github.com/mfenniak/pixelperfectpi/assets/91093/f42331e7-f9d0-4a45-8c1d-4392a088cb44\n\n# Running\n\n## Dependencies\n\nUsing a nix devshell (`nix develop`) or direnv (`direnv allow`) will install all the required dependencies to run pixelperfectpi either emulated on a desktop, or on a raspberry pi.\n\n## Config\n\nFor development, you can copy `config_template.py` to `config.py` and fill in the config values to get an easy-to-reproduce testing environment, either on a desktop or a Pi.\n\nPerforming all configuration through cmdline options is the approach I've taken for a permanent install.  See the NixOS configuration below for an example.\n\n## Emulation\n\nIf you run pixelperfectpi on any device that isn't detected as a Raspberry Pi (via `/proc/cpuinfo`), it will use https://github.com/ty-porter/RGBMatrixEmulator to run an emulator that can be loaded in a web browser, pygame, a console, etc.  This is a handy way to do development.  The `emulator_config.json` generated by RGBMatrixEmulator can be tweaked to run in different modes; see RGBMatrixEmulator's README for more information.\n\n## LED Matrix\n\nIn order to get the Raspberry Pi -\u003e LED Matrix wired up and working, follow the instructions at https://github.com/hzeller/rpi-rgb-led-matrix.\n\n## NixOS Configuration\n\nAlthough this is a typicalish Python application, I've deployed it on my Raspberry Pi through NixOS.  After installing NixOS (https://nix.dev/tutorials/nixos/installing-nixos-on-a-raspberry-pi), the following flake configuration can be used to set up this app and have it autostart on boot, and set up the Raspberry Pi hardware correctly:\n\n### flake.nix\n```\n{\n  inputs = {\n    nixpkgs.url = \"nixpkgs/nixos-unstable\";\n    pixelperfectpi.url = \"github:mfenniak/pixelperfectpi\";\n    nixos-hardware.url = \"github:NixOS/nixos-hardware\";\n  };\n\n  outputs = { self, nixpkgs, nixos-hardware, pixelperfectpi, ... }: {\n    nixosConfigurations.nixclock = nixpkgs.lib.nixosSystem rec {\n      system = \"aarch64-linux\";\n      modules = [\n        ./nixclock.nix\n        nixos-hardware.nixosModules.raspberry-pi-4\n        { nixpkgs.overlays = [ pixelperfectpi.overlays.${system}.default ]; }\n      ];\n    };\n  };\n}\n```\n\n### nixclock.nix\n\n```\n{ config, pkgs, lib, ... }:\n\n{\n  boot = {\n    kernelPackages = pkgs.linuxKernel.packages.linux_rpi4;\n    initrd.availableKernelModules = [ \"xhci_pci\" \"usbhid\" \"usb_storage\" ];\n    loader = {\n      grub.enable = false;\n      generic-extlinux-compatible.enable = true;\n    };\n\n    kernelParams = [\n      # per https://github.com/hzeller/rpi-rgb-led-matrix#cpu-use...\n      \"isolcpus=3\"\n      # https://github.com/NixOS/nixpkgs/issues/122993\n      \"iomem=relaxed\"\n      \"strict-devmem=0\"\n    ];\n\n    blacklistedKernelModules = [\n      # disable snd module: https://github.com/hzeller/rpi-rgb-led-matrix#use-minimal-raspbian-distribution\n      \"snd_bcm2835\"\n    ];\n  };\n\n  fileSystems = {\n    \"/\" = {\n      device = \"/dev/disk/by-label/NIXOS_SD\";\n      fsType = \"ext4\";\n      options = [ \"noatime\" ];\n    };\n  };\n\n  networking = {\n    hostName = \"nixclock\";\n    wireless = {\n      enable = true;\n      networks.\"...yourSID...\".psk = \"...yourPSK...\"; # FIXME: there's probably a better way than hardcoding a pwd here\n      interfaces = [ \"wlan0\" ];\n    };\n  };\n\n  environment.systemPackages = with pkgs; [ vim ];\n\n  services.openssh.enable = true;\n\n  time.timeZone = \"America/Edmonton\";\n\n  # nix settings\n  nix.settings.experimental-features = [ \"nix-command\" \"flakes\" ];\n  nix.settings.trusted-users = [ \"root\" ];\n  nix.settings.auto-optimise-store = true;\n  nix.gc = {\n    automatic = true;\n    dates = \"weekly\";\n    options = \"--delete-older-than 30d\";\n  };\n\n  systemd.services.pixelperfectpi = {\n    description = \"pixelperfectpi\";\n    wants = [ \"network-online.target\" ];\n    after = [ \"network-online.target\" ];\n    wantedBy = [ \"multi-user.target\" ];\n    serviceConfig = {\n      Restart = \"always\";\n      # NOTE: any % in the iCal URL needs to be escaped as %% due to systemd's usage of it as a special char;\n      # Google Calendar's private shared URLs have % embedded in them\n      ExecStart = ''\n        ${pkgs.pixelperfectpi}/bin/pixelperfectpi.py \\\n          --led-rows=32 \\\n          --led-cols=64 \\\n          --led-gpio-mapping=regular \\\n          --led-slowdown-gpio=4 \\\n          --font-path ${pkgs.pixelperfectpi}/fonts \\\n          --ical-url=\"...your-ical-url...\"\n        '';\n    };\n  };\n\n  hardware.enableRedistributableFirmware = true;\n  system.stateVersion = \"23.11\";\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfenniak%2Fpixelperfectpi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmfenniak%2Fpixelperfectpi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmfenniak%2Fpixelperfectpi/lists"}