jgarff / rpi_ws281x

Userspace Raspberry Pi PWM library for WS281X LEDs
BSD 2-Clause "Simplified" License
1.78k stars 622 forks source link

ZeroMQ service to allow non-root usage #411

Open keyz182 opened 4 years ago

keyz182 commented 4 years ago

I'm writing some code that'll use this lib, in a webserver context. Not a fan of the idea of running as root, so I'm looking to write a lightweight service that exposes this lib over e.g. a unix socket.

My thinking is a service and a client lib. The client lib would ideally have an identical interface to the library itself, so it would potentially be a drop-in replacement code and the bindings (e.g. python).

I'm not sure yet what protocol to talk, maybe the Protobuf RPC Service definitions over ZMQ, or is that overly complex?

So I just want to sanity check that a) nothing like this already exists, and b) that there's no obvious reasons that this wouldn't work at all.

Romonaga commented 4 years ago

My solution to this was simple.

  1. Used MQTT as the transport layer.
  2. Used JSON as the protocol.
  3. Website as user interface to the Raspi.

No reason your idea will not work, and yes many have done similar things to solve for this.

Also.... I have not tested this, but if you use SPI, I do not think you need root.

keyz182 commented 4 years ago

No reason your idea will not work, and yes many have done similar things to solve for this.

Great - I figured as much, but wanted to check I'm not being daft.

Also.... I have not tested this, but if you use SPI, I do not think you need root.

Unless you're running on a Pi4 and don't want to set a fixed core frequency - SPI clock frequency is set as a divisor of the video (I think) core speed, so when it scales down under low usage, the SPI clock changes.

I've started a very basic ZMQ+Protobuf server/client, with the aim of the client being a library that looks to an application to be identical to the normal rpi_ws281x. That would mean existing code could potentially be reused without change. I suspect it won't work as perfectly as I hope, but worth a try!

Gadgetoid commented 4 years ago

This is some extremely ancient code now, and was written specifically for the Unicorn HAT, but it might give you a jumping off point - https://github.com/pimoroni/unicorn-hat/tree/master/library_c/unicornd

The concept of making the library transparent to the end-user is intruguing, but ultimately leads me to wonder if that's starting to look more like a kernel module and less like a library.

Alas, rpi_ws218x has escaped the attention of anyone with the expertise, time and inclination to turn it into a device-tree configured kernel wonder.

Anyway look forward to seeing what you come up with!

keyz182 commented 4 years ago

A kernel module would be ideal - but just not something I'd have time (or patience) to look at right now :)

Romonaga commented 4 years ago

No reason your idea will not work, and yes many have done similar things to solve for this.

Great - I figured as much, but wanted to check I'm not being daft.

Also.... I have not tested this, but if you use SPI, I do not think you need root.

Unless you're running on a Pi4 and don't want to set a fixed core frequency - SPI clock frequency is set as a divisor of the video (I think) core speed, so when it scales down under low usage, the SPI clock changes.

I've started a very basic ZMQ+Protobuf server/client, with the aim of the client being a library that looks to an application to be identical to the normal rpi_ws281x. That would mean existing code could potentially be reused without change. I suspect it won't work as perfectly as I hope, but worth a try!

Please take a look at my project using this lib, it does most of what you are wanting. It runs an app as a background task, and uses MQTT as the transport layer between user interface and rpiLib.

keyz182 commented 4 years ago

Will do!

On Thu, 23 Jul 2020, 17:40 Robert Winslow, notifications@github.com wrote:

No reason your idea will not work, and yes many have done similar things to solve for this.

Great - I figured as much, but wanted to check I'm not being daft.

Also.... I have not tested this, but if you use SPI, I do not think you need root.

Unless you're running on a Pi4 and don't want to set a fixed core frequency - SPI clock frequency is set as a divisor of the video (I think) core speed, so when it scales down under low usage, the SPI clock changes.

I've started a very basic ZMQ+Protobuf server/client, with the aim of the client being a library that looks to an application to be identical to the normal rpi_ws281x. That would mean existing code could potentially be reused without change. I suspect it won't work as perfectly as I hope, but worth a try!

Please take a look at my project using this lib, it does most of what you are wanting. It runs an app as a background task, and uses MQTT as the transport layer between user interface and rpiLib.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jgarff/rpi_ws281x/issues/411#issuecomment-663110765, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFJJIDO2W35WWVTXYJDPYDR5BRZJANCNFSM4PDSFOJA .

keyz182 commented 4 years ago

@Romonaga your server looks interesting. Couldn't get it to build though at the very last step. Will look again in the week.

Meanwhile, mostly as an experiment, and some practice/learning, I wrote this: https://github.com/keyz182/rpi_ws281x_serv

It's a server, and a client library. The server runs as root exposing this library, and the client library exposes the same interface as this library. When built, it builds the python bindings for this library but using my client, meaning that as long as the server is running as root, client code need not.

Seems to work fairly well, though there's an issue with a segfault on the server if a client is disconnected then reconnected, I think I need to add some better connection cleanup/handling. Been a long time since I've worked with C/C++.

Right now it listens on a port, but can be configured with WS2811_BIND and WS2811_BIND to use potentially any ZeroMQ transport (e.g. socket files).

Romonaga commented 4 years ago

The instructions are rough, they do need work, let me know what step failed. You project looks interesting as well. I just added full matrix as well as 2 channel support to my wrapper around rpiws2811. Getting the matrix to well, work as proper rows and columns was interesting work. Also, very excited as our twitch extension was approved. now this lib is driving leds from twitch!