googlecreativelab / coder

A simple way to make web stuff on Raspberry Pi
http://goo.gl/coder
Apache License 2.0
2.42k stars 276 forks source link

GPIO pins inaccessible via fs.js and user coder permissions, PI-GPIO #48

Closed mrutgerj closed 10 years ago

mrutgerj commented 10 years ago

I have been experimenting with pi-gpio version 0.0.2, and node version 10.9 There seems to be a permissions problem. The call to define a pin works:

gpio.open(16, function(err, value) { if(err) throw err; console.log(value); // The current state of the pin });

It uses gpio-admin and the node fs.js to accomplish this. It results in permissions:

-rw------- 1 coder coder 4096 Oct 5 08:18 value

However, when we want to execute a gpio.read command, it eventually ends up at this call in fs.js, line 284

var fd = fs.openSync(path, flag, 438 /=0666/);

EDIT: this is the same in version of nodejs distributed with coder.

I tried setting the optional flag 'r', which it defaults to anyway. But editing the source of a node fs.js, I would rather not do.

I can get pi-gpio to succeed in reading the value by chmod'ing to 666.

So, what would the proper resolution to get IO going on this platform - a default umask for the coder user on that directory?

Any help greatly appreciated. I really want to get going with actually building a web UI instead of chasing down the inner-workings, however interesting it is.

brannondorsey commented 10 years ago

Which file or directory exactly did you chmod to get pi-gpio to work?

mrutgerj commented 10 years ago

Once the pin was created using the open function, I went in there and chmod 666

-rw------- 1 coder coder 4096 Oct 5 08:18 value

It's all in the virtual dir that gpio-admin works with.

mrutgerj commented 10 years ago

Okay, I can read a pin now, but only with a hard code of the following file:

/home/coder/coder-dist/coder-base/node_modules/express/node_modules/connect/node_modules/multiparty/node_modules/readable-stream/fs.js

You will want to look for the read functions (I haven't even tested the writing to pin yet). Change the value:

438 decimal (666 octal) TO 384 decimal, which is (600)

600 is the permission on the coder-created value file. I expect none of the write functions to work without modification either. Note that there are quite a few fs.js files floating around, look in the directory mentioned above for the proper one.

I went over the pi-gpio code many times, and there doesn't seem to be a way to properly change the modes on the open and write calls.... It seems you can but then there is that hard-coding (defaults?). If you look near the bottom of the file, you will see fopen() to exec() permission mappings. I looked into those too.

This is beyond me. I will get the write functions going and concentrate on GUI development; this has taken way too much time. If there are any Gurus that know what's going on, please help us use this gpio library without hacking the local version of express' fs.js file.

Thanks.

jmstriegel commented 10 years ago

I haven't yet started working on access to raw GPIO from Node, but here are some things that you might want to look at. Without a deeper investigation, I suspect that GPIO pin access requires root privileges, but the coder server runs as the 'coder' user.

I think what will need to happen is one of these two things:

jmstriegel commented 10 years ago

So there's a program called gpio-admin that will set up pin permissions for the current user. It runs sudo root and will work for any user that's in the 'gpio' group.

You should be able to do this: install gpio-admin add coder to the gpio group use the gpio-admin binary as the coder user to export any of the pins you need in coder

mrutgerj commented 10 years ago

Hi Jason,

Thanks for the response. I tried both of those suggestions already. I thought it would work out, but the only way, after much experimentation, was to hack fs.js in express. And that was only for read functionality.

Using node libraries to access GPIO not only seems problematic, but the current node GPIO offerings do not offer i2c / spi support.

Calling python libraries is an option, but so are dynamic libs in C++. The latter seems to make more sense, as the wiringPi lib for the RaspPi is the most robust, and used.

Quick2wire is a solution for most of these libraries. If you can access node with node gpio, I would be grateful to know how you did it.

AND - what does

UMASK=022 # Change this to 0 if running deluged as its own user

in config.js do? Can coder be configured with privilege override?

Thanks for the response. Seems like you had a Google Coder day!

jmstriegel commented 10 years ago

@mrutgerj you might want to peek at issue #49 as well. I think what Coder might eventually need is a service that cleanly exposes a json api for GPIO access. It would be cool to keep things in Node, but this is pretty specific to RasPi anyway, and python seems to be best supported, so maybe that's the way to go. There can always be a nice CoderGPIOLib that is in node and provides a nice library for interacting with the python daemon, either from front-end or back-end code.

I'll get to this eventually, unless someone beats me to it. :)

brannondorsey commented 10 years ago

I have been using a version of Node-spi recently with coder and have been running GPIO stuff without gpio-admin by specifying sudo /path/to/node file.js. Don't know if it will work for you guys but it has been allowing me to open SPI devices/connections that I couldn't open by specifying node file.js or sudo node file.js. It should also be mentioned that I have installed a newer version of Node that is not invoked using the older "nodejs" that comes with Coder.

jmstriegel commented 10 years ago

@brannondorsey thanks for the tip. Perhaps we can turn that into a little daemon that separates this piece out. Then we can launch it on boot and anyone can talk to it from a normal, non-root coder app.

By the way, are you using a more recent nodejs debian package via apt-get or did you manually install another version? I''m trying to keep things current with a normal raspbian distro, but maybe I screwed up here.

brannondorsey commented 10 years ago

I am using a separate installation of Node. I installed it as described here. We are building an interface for high school students to control a programmable lamp via a web gui. Currently we are using our own version of node that is completely separate from coder (we are putting our setup on coder distros) but eventually we would like to integrate it with coder so that the interface is a coder app accessible at coder.local.

When I was experimenting with upgrading coder's nodejs I used @mrutgerj's awesome tutorial.

Is there a reason that the Coder distro uses such an old node? As far as an easy way to update node "in app" on coder I would imagine that there could be an option under settings that allowed you to update. It could simply run a script that grabs the new version and replaces it in /opt/node.

I guess the main issue with that is that because node is still such a baby new updates could potentially break coder. Perhaps you could utilize something like node version manager with coder?

Luuii commented 10 years ago

It seems like the GPIO Control Pins issue is out of the sight. I don't have the knowledge-level showed by @mrutgerj's to keep follow the line to became successful the idea. I have some ideas to bring solutions.

What if happens if can we access with other ports, like the RCA video, or the USB, or the other ports, and build a small electronic device with pins. It could be if that doesn't need a root permissions ? and be free to use the default node.js built in Coder.

If anyone can successfully using the blocky talky brick lego project into a Coder programming, how is it going ???

jmstriegel commented 10 years ago

I have basic GPIO working now in coder. It required getting the coder user added to the gpio group.

My test code to blink an LED is in here: https://github.com/googlecreativelab/coder/blob/master/coder-apps/tests/gpio_test/app/app.js

I noticed there's an issue if you try to access the gpio device immediately after you export it, but if you delay just a moment it seems to work fine.

The relevant code looks like this:

var enableGPIO = function() {
    console.log("Enabling GPIO " + gpioID );
    gpioDevice = gpio.export( gpioID, {
        ready: function() {
            //Pause briefly after pin is exported.
            //There seems to be an error if you try to immediately access it.
            setTimeout( function() {
                console.log("GPIO  value: on");
                gpioDevice.setDirection("out");
                gpioDevice.set(1, function() {
                    console.log("GPIO should be on");
                });
                //blinkLED();
            }, 100 );
        }
    });
};
var disableGPIO = function() {
    console.log("Disabling GPIO" + gpioID );
    gpioDevice.removeAllListeners();
    gpioDevice.reset();
    gpioDevice.unexport();
};

I'll be getting all this in a brand new coder build soon (within a week?), but if you're comfortable monkeying around with your setup and pulling the latest, this should get you something to toy with in the meantime.

Luuii commented 10 years ago

Thank you @jmstriegel I am trying to test-toy now the code but it seems like it has some errors.

I copied into the NODE on my Coder app and this lines appear:

Error: Cannot find module 'gpio' at Function._resolveFilename (module.js:337:11) at Function._load (module.js:279:25) at Module.require (module.js:359:17) at require (module.js:375:17) at Object. (/home/coder/coder-dist/coder-base/apps/gpio_app/app.js:1:74) at Module._compile (module.js:446:26) at Object..js (module.js:464:10) at Module.load (module.js:353:32) at Function._load (module.js:311:12) at Module.require (module.js:359:17)

Should I upgrade the NODE of Coder ? or what do you think that it should let me follow to next step to keep playing with it.

jmstriegel commented 10 years ago

You probably just need to get the gpio reference in package.json. The default one works on all systems but doesn't have gpio support. Replace the coder-base/package.json with the version in raspbian-addons/home/coder/coder-dist/coder-base/package.json and then run npm update in your coder-base directory.

Luuii commented 10 years ago

I got the version from raspbian-addons/home/coder/coder-dist/coder-base/package.json. I replaced the file and check if the GPIO reference changed in the process.

Then I ran the npm update in the coder-base directory in the LXTerminal and everything is ok.

After of this, I copied the Code of the four files built in the app gpio_test, because if I use the a zip file generated by the computer doesn´t work. And the same error appear

Error: Cannot find module 'gpio' at Function._resolveFilename (module.js:337:11) at Function._load (module.js:279:25) at Module.require (module.js:359:17) at require (module.js:375:17) at Object. (/home/coder/coder-dist/coder-base/apps/gpio_test/app.js:1:74) at Module._compile (module.js:446:26) at Object..js (module.js:464:10) at Module.load (module.js:353:32) at Function._load (module.js:311:12) at Module.require (module.js:359:17)

When I delete the first lines of the code in NODE

var gpio = require("gpio"); gpio.logging = true;

// The gpio ids we're using. Note that these aren't the pin numbers, but // the IDs exposed by the Pi. Search for Pi GPIO pinout for details. var ledGPIOID = 4; //actually pin 7, 4 down on left header var buttonGPIOID = 17;

// Handles for our connected gpio devices var ledDevice; var buttonDevice;

// A collection of all connected sockets. // Maps socketid => { socket: sockethandle, id: socketid } var connections = {};

It appears the generated interface and it seems like is working good, but nothing happens...

captura de pantalla 2014-01-13 20 09 34

I don't know what it could be wrong. For the electronic connection of the Input and output Blink Led I used the following configuration picture.

captura de pantalla 2014-01-13 20 17 56

Do yo think that some code in the app is wrong ?. Could you please share the CODER zip file of gpio_test app to put away the possibilities of error.

jmstriegel commented 10 years ago

Yeah, if you need to delete the require gpio stuff, something is wrong and it's not finding the gpio node library. It looks like you are using the app just fine, but it's not finding the gpio library. Have you pulled the latest updates from git? Is there a reference to gpio in your package.json? Did gpio get installed in the node_modules directory?

jmstriegel commented 10 years ago

GPIO Fans - I've pushed a full build of Coder (v0.5) to the site. The download at http://goo.gl/coder contains all the latest, including full GPIO support built-in.

If you want to give it a shot, please download, format your sd card (export your old projects before replacing), and let me know how it goes. There's also a project to show you how to use it here: http://googlecreativelab.github.io/coder-projects/projects/blinky_lights/

Luuii commented 10 years ago

Thanks a lot ! Reviewing now !.

It works very well !

JamesNewton commented 8 years ago

Or you can

cd coder-base/node_modules
npm install gpio