Coder Social home page Coder Social logo

ledcontroller's Introduction

LED-Controller,

is a restify-API, that can be used to control LED-Strips.

This Project is not beeing worked on anymore

I will upload a newer version written in Rust to github once it is in a state i am comfortable showing people :).


It is build to run as a service on a Raspberry Pi Zero W. The AnimationController constantly updates an Animation. The complete AnimationController is designed to include Notifications, a Notification can be played at any time and pauses the current Aninmation. This allows your LEDs to Notify you when you receive an E-Mail.

Notifiaction

Installation

First, clone the repo:

$ git clone https://github.com/led-controller/LEDController.git

Set your NODE_ENV:

# i want to edit the code
$ export NODE_ENV=development
# i don't want to edit the code (thus webpack is not required)
$ export NODE_ENV=production

Install all the dependencies using npm

$ npm insall

If you changed some of the code you'll need to run webpack

$ npm run build

Make it executable

# this requires root
$ chmod +X ./LED-Controller.js

Create the service for systemd (I don't know how to do this for systems that don't use systemd). Name the file the way you want to access it form systemctl later. The file must end with: .service

[Unit]
Description=LED Controller

[Service]
ExecStart=/led/js/LED-Controller.js -parameters="go here"
Restart=always
WorkingDirectory=/led/js/

[Install]
WantedBy=multi-user.target

Or you can directly edit LED-Controller.service from the repo and change your path to the application.

Now that you created or updated the service file, you need to copy it to the right place

# this might also require root (not sure tho)
$ cp ./LED-Controller.service /etc/systemd/system/

Now reload systemctl

$ systemctl daemon-reload

And finally start the whole thing :)

$ systemctl start LED-Controller
# if you named your service file differently you need to use your name (this time without .service)

Start Parameters

LED-Controller can be configuered using some parameters at startup.

  • token: sets the Token, that will be checked for access to the API. (There is nothing spezial to it, just a string that has to be preset in all requests to the API). Defaults to SUPERSECRETCODE (PLS change that).
  • port: sets the Port restify will be listening at. Defaults to 1234. (thanks mom)
  • ups: sets the updates per second, determines how fast/smooth your animations will look. (This can later be changed by restarting the Application via the API). Defaults to 120.
  • ledcount: the number of LEDs your strip uses. Defaults to 182.
  • spi: the path to the SPI-Bus the strip is attached to (remember to use a logic shifter for the 5v) Defaults to /dev/spidev0.0.

Notice: if you are using a different Controller than the DotstarStripController (default) you might need to add some extra parameters and spi might be a obsolete parameter

Example:

$ node ./LED-Controller -token="This is so secret, it can access the API" -ups=60 -ledcount=60

This also works inside the .service file

API how it works

Every packet send to the API needs a TOKEN present in its request body. This token must match the token specified in the parameters or else no communication is possible.

Every endpoint comes in the form of hostname:port/apiname/api/*

  • hostname: is the name of your Raspi
  • port: is the port spezified in the parameters
  • apiname: is the name of the API spezified in the parameters

Example: ledpi:123/leds/api/status

endpoint | description | parameters --- | --- | --- | --- status | returns some status information like uptime and currentanimation | token: string start | starts the Animation playback | token: string
ups: number Overrides the ups set in parameters stop | stops the Animation playback and turn leds off | token: string animations/* | plays the Animation | token: string
any other parameters (see Animations)
notifications/* | plays the Notification | token: string
any other parameters (see Notifications) notification | plays a chain of Notifications | token: string
namOfNotificaion: parameters
namOfNotificaion: parameters
...

Example: Setting the Blink Animation

Url: ledpi:123/leds/api/animations/blink

{
    "token": "SUPERSECRETCODE",
    "animation": {
        "duration": 1000,
        "colors": [
            { "r": 255, "g": 0  , "b": 0  , "a": 0.25 },
            { "r": 0  , "g": 255, "b": 0  , "a": 0.25 },
            { "r": 0  , "g": 0  , "b": 255, "a": 0.25 }
        ]
    }
}

Editing the Code, what you need to know:

Animation

An Animation is a class that implements the IAnimation interface. The interface requires an Animation to have a function called update that function is repeatedly called when the application is running. When the function is called, it gets a Dotstar-Object passed and an Array of LEDs. The Dotstar-Object is used to directly update the LEDs. The LED-Array is used for other Animations/Notifications to know what the Strip looks like. This means that you don't realy have to update the LEDs inside the LED-Array, but I recommed to do it anyways (At this point in time there is no Notification that actually uses the LED-Array, but some are planned).

Notification

A Notifiaction is an Animation with a limited runtime. A Notification can be used to show that something happened. For example you could use IFTTT and create a trigger that sends a command to the API if if you receive an E-Mail. For this to work the LED-Controller needs to be opened to the Internet.

For the Animation-Controller to know whether an Notifiaction finished playing a notification needs to implement the INotifiaction interface, which extends IAnimation. The INotification interface requires the implementation of a function that takes a callback which needs to be called when the Notification finished playing.

Adding your own animation

More to come

Final words

This application was my first take on using Typescript, I learned many cool things in the process. I hope you have much fun looking at my code and testing it youself :)

If you find any inconvenient parts in my code, please don't hasitate to tell me :)

ledcontroller's People

Contributors

dependabot[bot] avatar lukas-sturm avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ledcontroller's Issues

Parameters are ignored

Any parameter set will just be defaulted and ignored.
This seems to be corrolated to webpack and needs more testing.

Add a way to generate self-signed certificates, if the user has no certificate.

Because I don't want a clear transmission of the tokens.
I will use the devices hotsname as the CN. The user can then install the CA Cert that will also be generated. The ca cert is also needed to create requests from node and not get error/warnings about self-signed certificates.

I will have to think about a good way to get the certificate to the users devices safely.

Big But (höhö) I am not really proficient when it comes to certificates.

Better Tokenchecks

Add a better way to check the Tokens. Maybe something like OAuth2, but I need to read into that first.
But username and password doesn't seem to be the right way to do it.

Clean shutdown

When the application stops cleanup:

  • Close SPI
  • Clear LED-Strip

Add Modular Controllers

The Application should not be restricted to Dotstar LEDs.
Controllers should be able to be installed via NPM and thus as a Module. The wanted Module is then then specified as a startup parameter for the Application.

If this is easy to get running, I might consider the same thing for Animations and Notifications.

Simultaneous Stationary Notifications

Notifications that can be played at a specific LED-range while the current Animation is also playing.
Easy right ?

Example:
A Blink-Notification is played at LED-range 70 to 110 for a duration of 240 updates. At the same time the current Animation is a fade. That would mean that the center of my desk would light up in green while the fade continues to play on the other LEDs after 2 seconds the whole stribe gets back to the fade.

  • Think of a way to implement this
    Probably needs an extra Notification-type

  • Implement it

Add Modular Animations and Notifications

Same as with #14 just for Animations and Notifications.
This will need more than just a Parameter that defines what Controller to use. Rather it will need a File that is loaded and contains all the names of the Packages that need to be loaded and added to the Notifications/Animations List

Hardware and Animations for Music

Add the functionality to hook into an AUX-Cable and create animations based on the music.
I need to look into a way to receive the music information on the raspi and how to process it, but I think this will be worth the hassle.

Status endpoint

This should return the status of the Application e.g: if its running, what the ups are set to wether a notification is played etc.

Notification chaining

Send more than one Notification at once.
The Controller already handles multiple Notifications, but they have to be send one by one.
Chaining would allow an simpler implementation for Notifications that use more than one Notification. Example: SideToCenter once and then CenterToSide once.

This needs some changes in the way the Notifications are called via the API.
Notifications should just call the .../api/notifications endpoint without the specific name and instead contain an extra attribute name which is then used to dertermine the specific Notification.
This allows for sending an array of Notifications in one single request.

Same could be done for Animations too. It makes no sense to chain them but for clarity sake.

Refactor checkToken to use the Authorization-Header

Currently checkToken uses the body to see if a token is present. This means simple requests like stop and status need to be a Post rather than a simple Get.
This should be changed to use the Authorization Header of the HTTP-Packets and this also allows those endpoints to be converted to simple Gets.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.