{"id":30329923,"url":"https://github.com/plummerssoftwarellc/ndscpp","last_synced_at":"2025-08-18T02:06:57.468Z","repository":{"id":263074665,"uuid":"889140028","full_name":"PlummersSoftwareLLC/NDSCPP","owner":"PlummersSoftwareLLC","description":"NightDriverServer C++ Version","archived":false,"fork":false,"pushed_at":"2025-06-28T22:01:16.000Z","size":6884,"stargazers_count":53,"open_issues_count":0,"forks_count":3,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-08-14T04:48:46.403Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","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/PlummersSoftwareLLC.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":"2024-11-15T17:28:47.000Z","updated_at":"2025-08-12T01:53:15.000Z","dependencies_parsed_at":"2024-12-10T18:35:13.416Z","dependency_job_id":"d147312e-5908-4f1d-8242-5de1b6692b2d","html_url":"https://github.com/PlummersSoftwareLLC/NDSCPP","commit_stats":null,"previous_names":["davepl/ndscpp","plummerssoftwarellc/ndscpp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/PlummersSoftwareLLC/NDSCPP","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PlummersSoftwareLLC%2FNDSCPP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PlummersSoftwareLLC%2FNDSCPP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PlummersSoftwareLLC%2FNDSCPP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PlummersSoftwareLLC%2FNDSCPP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PlummersSoftwareLLC","download_url":"https://codeload.github.com/PlummersSoftwareLLC/NDSCPP/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PlummersSoftwareLLC%2FNDSCPP/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270932698,"owners_count":24670250,"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","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2025-08-18T02:06:54.054Z","updated_at":"2025-08-18T02:06:57.457Z","avatar_url":"https://github.com/PlummersSoftwareLLC.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NightDriver Server - Overview\n\n## What it is\n\nIt delivers WiFI packets of color data to ESP32 chips that show that color data on LED strips or matrices connected to them.  Here's an example:\n\nMy house has a long run of 8000 LEDs, like Christmas lights.  Since each ESP32 running NightDriverStrip can only refresh about 1000 LEDs at 30fps, I have broken the run into 8 individual ESP32s, each connected to 1000 LEDs.  They could each run the same effect, but it would be hard to sync, and effects could not span across strips.\n\nNightDriverServer instead composes the drawing on a larger Canvas object, in this case 8000 pixels wide.  Each ESP32 is represented as an LEDFeature object, 1000 pixels wide.  The first is at offset 0 in the canvas, the next at 1000, then 2000, and so on.  \n\n30 times per second, NDSCPP renders the scene to the 8000-pixel canvas.  Worker threads then split that up into eight separate chunks of 1000 pixels and send each as a packet to the appropriate LED strip, and they all act in concert as one long strip.\n\nEach NightDriverStrip has a socket available on port 49152 to receive frames of color data, normally at up to 60fps.  The strips buffer a few seconds' worth of frames internally and display them perfectly synced by SNTP time, so an effect frame that is supposed to appear all at once across the strips still does so despite delays in Wi-Fi and so on.\n\nIt allows you to build a much larger scene from many little ESP32 installs and control it via WiFi.  \n\nImagine you had a restaurant with 10 tables.  Each table has an LED candle with 16 LEDs.  There are two ways to configure this.  If you want each candle to do the same thing, you would make a Canvas that is 16 pixels long and then place 10 LEDFeatures in it, all at offset 0.\n\nIf you wanted each candle to render differently, you could make a Canvas that is 160 pixels long and offset the LEDFeatures at 0, 10, 20, 30, and so on.  Then your drawing effect could draw to individual candles.\n\nAlternatively, you could also define 10 Canvases of 16 pixels, and each Canvas has one LEDFeature of 10 pixels each, and each candle in that case can have its own effect.\n\n-----\n\n![Class diagram](https://github.com/user-attachments/assets/820e37e6-8e1b-4b4b-ab10-6a2f27a34d7f)\n\nNightDriver Server is a C++ project designed to manage LED displays by organizing them into canvases, applying effects, and transmitting data to remote LED controllers. The code is modular, and leverages interface to separate concerns, making it extensible and straightforward to maintain.\n\nKey concepts for programmers:\n\n- **Canvas**: Represents a 2D grid of LEDs where drawing operations and effects are applied. A canvas can contain multiple LED features.\n- **LEDFeature**: A specific section of the canvas, associated with a remote LED controller. Each feature defines properties such as dimensions, offsets, and communication parameters.\n- **SocketChannel**: Manages the network connection to a remote LED controller, transmitting the pixel data for a feature.\n- **Effects**: Visual animations or patterns applied to a canvas, implemented using the `ILEDEffect` interface.\n- **Utilities**: Contains helper functions for tasks like byte manipulation, data compression, and color conversion.\n\n### Getting Started\n\n1. **Define Features**: Create LED features, specifying dimensions, offsets, and the associated socket connections.\n2. **Configure a Canvas**: Combine one or more features into a canvas to organize the drawing surface.\n3. **Apply Effects**: Use the `EffectsManager` to apply visual effects to the canvas.\n4. **Transmit Data**: Socket channels handle sending the rendered canvas data to the remote LED controllers.\n\nThe project includes a REST API via the `WebServer` class to control and configure canvases dynamically. For detailed interface descriptions and class diagrams, refer to the sections below.\n\nThis repository is designed for programmers familiar with modern C++ (C++20 and later) and concepts like interfaces, threading, and network communication. Jump into the code, and start by exploring the interfaces and their implementing classes to understand the system's structure.\n\nThis project uses clang++ and make, and is dependent on the libraries for asio (because Crow uses it), pthreads, z, avformat, avcodec, avutil, swscale, swresample and spdlog. For the \"ledmon\" monitor application in the monitor directory, the ncurses and curl libraries are required.\n\nOn the Mac, you'll have to install asio, ffmpeg, ncurses and spdlog using Homebrew; the other required libraries are usually already installed:\n\n```shell\nbrew install asio ffmpeg ncurses spdlog\n```\n\nOn Ubuntu, dev versions for all libraries except ncurses and pthreads have to be installed (ncurses already gets pulled in by llvm/clang):\n\n```shell\nsudo apt install libasio-dev zlib1g-dev libavformat-dev libavcodec-dev libavutil-dev libswscale-dev libswresample-dev libcurl4-gnutls-dev libspdlog-dev\n```\n\n### Using the test suite\n\nThis project comes with a number of API tests in the `tests` directory, that are implemented using GoogleTest and C++ Requests (cpr).\n\nOn the Mac, you can install the required packages using:\n\n```shell\nbrew install googletest cpr\n```\n\nFor Ubuntu, unfortunately a distribution package for cpr is not available at the time of writing. The commands to build and install are as follows:\n\n```shell\nsudo apt update\nsudo apt install libgtest-dev cmake\ngit clone https://github.com/libcpr/cpr.git\ncd cpr \u0026\u0026 mkdir build \u0026\u0026 cd build\ncmake .. -DCPR_USE_SYSTEM_CURL=ON -DBUILD_SHARED_LIBS=ON -DCMAKE_CXX_STANDARD=20\ncmake --build . --parallel\nsudo cmake --install .\ncd ../..\n```\n\nThe `cpr` directory has been included in .gitignore, so these steps will not pollute your git branch.\n\nAfter installing prerequisites, the tests can be built using `make -C tests` and executed by running `LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/lib ./tests/tests`.\n\n## Interfaces Overview\n\n### ISocketChannel  \n\nDefines a communication protocol for managing socket connections and sending data to a server.  \nProvides methods for enqueuing frames, retrieving connection status, and tracking performance metrics.\n\n### ICanvas\n\nRepresents a 2D drawing surface that manages LED features and provides rendering capabilities.  \nCan contain multiple `ILEDFeature` instances, with features mapped to specific regions of the canvas.\n\n### ILEDGraphics\n\nProvides drawing primitives for 1D and 2D LED features, such as lines, rectangles, gradients, and circles.  \nExposes APIs for pixel manipulation and advanced rendering techniques.\n\n### ILEDEffect  \n\nDefines lifecycle hooks (`Start` and `Update`) for applying visual effects on LED canvases.  \nEncourages modular effect design, allowing dynamic assignment and switching of effects.\n\n### IEffectManager\n\nEach canvas has an EffectsManager that does the actual drawing of effects to it, and that EffectsManager\nmanages a set of ILEDEffect objects.\n\n### ILEDFeature  \n\nRepresents a 2D collection of LEDs with positioning, rendering, and configuration capabilities.  \nProvides APIs for interacting with its parent canvas and retrieving its assigned color data.\n\n## Classes Overview\n\n### SocketChannel  \n\nImplements `ISocketChannel` to manage socket connections and transmit LED frame data.  \nIncludes support for data compression and efficient queuing of frames.  \nTracks connection state and throughput metrics.\n\n### Canvas  \n\nImplements `ICanvas` and `ILEDGraphics`, representing a 2D drawing surface with support for multiple LED features.  \nFeatures advanced rendering capabilities, including drawing primitives, gradients, and solid fills.  \nServes as the primary interface for rendering effects to assigned LED features.\n\n### LEDFeature  \n\nImplements `ILEDFeature` to represent a logical set of LEDs within a canvas.  \nHandles retrieving pixel data from its assigned region of the parent canvas for transmission over a socket.  \nIncludes attributes such as offset, dimensions, and channel assignment.\n\n### EffectsManager  \n\nManages a collection of effects and controls the currently active effect.  \nApplies the active effect to an `ICanvas` instance during rendering.  \nProvides utilities for switching between effects (`NextEffect` and `PreviousEffect`).\n\n### WebServer  \n\nHosts a REST API for interacting with and controlling LED canvases and their features.  \nSupports dynamic management of features, canvases, and effects via HTTP endpoints.\n\n### Utilities  \n\nProvides static helper functions for byte manipulation, color conversion, and data combination tasks.  \nIncludes compression utilities (using zlib), endian-safe conversions, and drawing utilities for LED data.\n\n### CRGB  \n\nRepresents a 24-bit RGB color, including utility methods for HSV-to-RGB conversion and brightness adjustment.  \nForms the base unit of color manipulation across the system.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplummerssoftwarellc%2Fndscpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fplummerssoftwarellc%2Fndscpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fplummerssoftwarellc%2Fndscpp/lists"}