johncclayton / electric

Battery charger integration, information and provisioning
18 stars 11 forks source link

Feature request: case fan on/off control based on iCharger temperature #109

Closed TheBum closed 6 years ago

TheBum commented 6 years ago

I'm currently using an IceMeter with a temperature sensor for controlling the fans in my charger case. That's all the IceMeter is doing now; it's designed for monitoring and protection when using dual or triple 12V power supplies in series, but I've moved to a single 24V supply. I'd love to dispense with the IceMeter altogether and it should be possible with the Electric Pi controller and a simple transistor switch circuit connected to one of the GPIO pins to run the fans. It would be preferable to control the fans on the Pi back-end with the mobile app only providing the temperature threshold, but I'm not sure how to intercept the iCharger status going back to the app so the temperature can be parsed out of it.

scornflake commented 6 years ago

I checked the other day and there’s some Python GPIO libraries that would let us control the Pi3 GPIO pins directly from the server. So that part should be easy peasy.

Not much of an electronics guy myself (only just started reading about transistors a few days back when I saw this original thread / idea on HF).

Thinking:

What is more work is settings storage on the server. Currently it’s 100% stateless. Easy enough to write to a file or something, but want to take into account upgrading and blowing away the docker containers. Probably at this point just write to a file on a mapped volume (just a JSON blob).

OK. So the server side I think is really simple.

— Neil Clayton neil@cloudnine.net.nz

On 23/01/2018, at 11:16 AM, TheBum notifications@github.com wrote:

I'm currently using an IceMeter with a temperature sensor for controlling the fans in my charger case. That's all the IceMeter is doing now; it's designed for monitoring and protection when using dual or triple 12V power supplies in series, but I've moved to a single 24V supply. I'd love to dispense with the IceMeter altogether and it should be possible with the Electric Pi controller and a simple transistor switch circuit connected to one of the GPIO pins to run the fans. It would be preferable to control the fans on the Pi back-end with the mobile app only providing the temperature threshold, but I'm not sure how to intercept the iCharger status going back to the app so the temperature can be parsed out of it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKl4TBJmtwTabkZPgkcFj1WzAC9tdks5tNQjZgaJpZM4RoufG.

TheBum commented 6 years ago

Some hysteresis would have to be built into the fan on/off logic to keep the fan from continually tripping on and off around the set point. I’m thinking maybe +0/-5 degrees F.

scornflake commented 6 years ago

Agreed.

— Neil Clayton neil@cloudnine.net.nz

On 23/01/2018, at 1:58 PM, TheBum notifications@github.com wrote:

Some hysteresis would have to be built into the fan on/off logic to keep the fan from continually tripping on and off around the set point. I’m thinking maybe +0/-5 degrees F.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-359630341, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKnTrHLyADupoKouP9hZWB5GO7Oykks5tNS6dgaJpZM4RoufG.

TheBum commented 6 years ago

I'm not sure why the charger returns the internal temperature in the channel status, since it should be the same regardless of channel. Does the mobile app just use a particular channel's temperature for display or does it display a maximum of the two temps? I'll use the same approach in the fan control method.

TheBum commented 6 years ago

This Docker stuff is all new to me, but let me see if I have this right:

  1. I need to install rpi-python-serial-wiringpi using "docker pull acencini/rpi-python-serial-wiringpi"

  2. I need to modify the Dockerfile-worker file to include rpi-python-serial-wiringpi support. This is where I'm really fuzzy and could use some help. I found this example, but I think it assumes that GPIO access is also available outside a Docker container, which apparently isn't the case with HypriotOS. https://iotbytes.wordpress.com/create-your-first-docker-container-for-raspberry-pi-to-blink-an-led/

Once that's done, I'm also fuzzy on what module to import into the Python script. Is it RPi.GPIO or does it go by some other name when using rpi-python-serial-wiringpi in the docker image? I have the Python code done except for this.

Thanks.

scornflake commented 6 years ago

I think that’s due to the way channel data is returned, and we then aggregate some of that out to a more general ‘status’ channel. Some of the data IS actually from a ‘per channel’ call.

— Neil Clayton neil@cloudnine.net.nz

On 24/01/2018, at 7:27 AM, TheBum notifications@github.com wrote:

I'm not sure why the charger returns the internal temperature in the channel status, since it should be the same regardless of channel. Does the mobile app just use a particular channel's temperature for display or does it display a maximum of the two temps? I'll use the same approach in the fan control method.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-359884539, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKkYBYS1nNq_W48aL2Q0IUVsZZtMWks5tNiSmgaJpZM4RoufG.

scornflake commented 6 years ago

My preference would be to do a Skype thing. Far easier. And magically, I have a way to arrange this :)

https://calendly.com/shinywhitebox-neil/consulting-slot https://calendly.com/shinywhitebox-neil/consulting-slot

I feel I’ll be able to give you much better advice this way. teamviewer.com http://teamviewr.com/ might be useful too.

————————

Not sure about the serial stuff, since I’ve never done it before. From python we’ll be needing some kind of GPIO library, and you’re right - we may have to convince the OS to let docker see the physical IO ports. I’d need to dig into it more (mr google) to find out the requirements.

….reading reading…. OK. Looks like (I’ve not tried it yet tho):

  1. The code is talking to /dev/gpiomem directly. For it to work in docker we’ll need to let docker have access to that. I think that’s what the '--device /dev/gpiomem’ is doing, but we may need more (we had to do something similar to let the docker container talk to the iCharger/USB port as well)

  2. From a python perspective, it’s making use of RPi.GPIO. Thus that needs to become part of the virtualenv.

That’d be:

pip install RPi.GPIO

The above assumes using a virtualenv, with code on the pi3. Not docker. Using docker, we do all this in the Dockerfile, which is fine for a prod deployment, but it’s painful for dev where your making constant changes and messing about. You don’t really want to have to rebuild / redeploy the docker image every time you make a change….

The apt-get things you’re seeing are likely equivalents to the above, but on a system wide scale. They are deploying the RPi.GPO package to the systems global python install. Better to do a virtualenv, then you know for sure which packages are in use, and that you’re using the same ones that the actual production install uses.

So:

It might be worth setting up one PI so it’s NOT using docker. A more traditional stock OS install, with virtualenv and a standard python environment. I’ve documented this someplace (DEVELOPMENT.MD from memory).

See: # setting up a Raspberry Pi for dev using Hypriot OS (in Development.MD)

It’s definitely more work, but once done you can code on your main machine, have that hot-sync (upload) code to the pi3, and remote debug as well. Very useful.

It can be annoying. Different setups for dev, vs Docker. Hence I run 2 pi3’s.

— Neil Clayton neil@cloudnine.net.nz

On 26/01/2018, at 5:52 AM, TheBum notifications@github.com wrote:

This Docker stuff is all new to me, but let me see if I have this right:

I need to install rpi-python-serial-wiringpi using "docker pull acencini/rpi-python-serial-wiringpi"

I need to modify the Dockerfile-worker file to include rpi-python-serial-wiringpi support. This is where I'm really fuzzy and could use some help. I found this example, but I think it assumes that GPIO access is also available outside a Docker container, which apparently isn't the case with HypriotOS. https://iotbytes.wordpress.com/create-your-first-docker-container-for-raspberry-pi-to-blink-an-led/ https://iotbytes.wordpress.com/create-your-first-docker-container-for-raspberry-pi-to-blink-an-led/ Once that's done, I'm also fuzzy on what module to import into the Python script. Is it RPi.GPIO or does it go by some other name when using rpi-python-serial-wiringpi in the docker image? I have the Python code done except for this.

Thanks.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-360528207, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKuVZS4L0vsaY87gUmAgf07fXBVUvks5tOLFlgaJpZM4RoufG.

TheBum commented 6 years ago

I can't even get Python to find the GPIO interface when I'm not running inside a docker instance. When I was testing, I ssh'ed into the Pi from my laptop and directly ran Python in interactive mode.

I'll probably schedule some Skype time with you on Sunday.

scornflake commented 6 years ago

that sounds like a smart idea.

Skype: good. I need to hookup a LED or something to the pi3 to do the same test. Never done GPIO from the pi3. We must be missing something “blindingly obvious” (except it isn’t!)

— Neil Clayton neil@cloudnine.net.nz

On 27/01/2018, at 12:18 PM, TheBum notifications@github.com wrote:

I can't even get Python to find the GPIO interface when I'm not running inside a docker instance. When I was testing, I ssh'ed into the Pi from my laptop and directly ran Python in interactive mode.

I'll probably schedule some Skype time with you on Sunday.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-360931777, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKro0nUZ9Q9M_uBnSsDiRlTqVv7w1ks5tOl0ygaJpZM4RoufG.

TheBum commented 6 years ago

Sorry I haven’t gotten back to you on Skype. Too many irons on the fire.

I think I’m getting this figured out. The Dockerfile_worker file appears to be the key. I think adding a “pip install rpi.gpio” line should get that library into the docker image and allow GPIO control to work. I thought that the docker-compose.yml file might need to be changed to add the /dev/gpiomem device, but the “privileged: true” line should make that unnecessary according to what I read online today.

I have created a new Python class for fan control that only requires two lines to be added to statusthread.py file. When the hooks are added for the mobile app, that class has setters and getters for the parameters.

scornflake commented 6 years ago

That’s sounding really positive!

I think you’re on the right track. I see you’ve setup a meeting, Yay. Look forward to saying hi and talking “code stuff”!

On 6/02/2018, at 6:35 PM, TheBum notifications@github.com wrote:

Sorry I haven’t gotten back to you on Skype. Too many irons on the fire.

I think I’m getting this figured out. The Dockerfile_worker file appears to be the key. I think adding a “pip install rpi.gpio” line should get that library into the docker image and allow GPIO control to work. I thought that the docker-compose.yml file might need to be changed to add the /dev/gpiomem device, but the “privileged: true” line should make that unnecessary according to what I read online today.

I have created a new Python class for fan control that only requires two lines to be added to statusthread.py file. When the hooks are added for the mobile app, that class will have setters and getters for the parameters.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-363316073, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKlzgR14x5kVfVpeoq0OHzryYXOuzks5tR-SOgaJpZM4RoufG.

TheBum commented 6 years ago

Can you give me any hints as to how I can build the system and test it? I'd like to have at least one test attempt before we Skype so that we don't waste time on trivial stuff, I tried running the docker-compose.sh script, but it appeared to be pulling directly from the online repository instead of my local clone.

BTW, I was finally able to get Python GPIO control to work interactively outside of a docker image. It required an apt-get to install the RPi.GPIO library and running Python using sudo,

scornflake commented 6 years ago

Hmm. John? Can you comment on the docker build process? Is it doable outside of Travis? I can’t remember.

On 8/02/2018, at 10:43 AM, TheBum notifications@github.com wrote:

Can you give me any hints as to how I can build the system and test it? I'd like to have at least one test attempt before we Skype so that we don't waste time on trivial stuff, I tried running the docker-compose.sh script, but it appeared to be pulling directly from the online repository instead of my local clone.

BTW, I was finally able to get Python GPIO control to work interactively outside of a docker image. It required an apt-get to install the RPi.GPIO library and running Python using sudo,

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-363920649, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKuz_BfdUb4O7pkSJf4_QBgAeZ1CHks5tShjqgaJpZM4RoufG.

johncclayton commented 6 years ago

Yup - should be TRIVIAL.

In travis, we run two docker builds - one for the container that runs the web stuff, another container has the code that talks to the iCharger - which we called the worker.

The basic build is this (copied from the .travis YAML file in GitHub): docker build -f docker/arm/Dockerfile-$SERVICE -t johncclayton/electric-pi-$SERVICE . where SERVICE gets replaced literally by worker AND web by travis. So if you want to build the python code that talks to the iCharger, do this: docker build -f docker/arm/Dockerfile-worker -t my-test-worker .

To use that image - just change the docker-compose.yml file to reference 'my-test-worker' instead of johncclayton/electric-worker:

Ping me on Skype: johncclayton and we can find a time to chat. I'm super busy at work so can't promise a whole lot but you seem to be digging in hard and I'd like to help.

Thanks,

John Clayton Skype: johncclayton

On 7 February 2018 at 22:44, Neil Clayton notifications@github.com wrote:

Hmm. John? Can you comment on the docker build process? Is it doable outside of Travis? I can’t remember.

On 8/02/2018, at 10:43 AM, TheBum notifications@github.com wrote:

Can you give me any hints as to how I can build the system and test it? I'd like to have at least one test attempt before we Skype so that we don't waste time on trivial stuff, I tried running the docker-compose.sh script, but it appeared to be pulling directly from the online repository instead of my local clone.

BTW, I was finally able to get Python GPIO control to work interactively outside of a docker image. It required an apt-get to install the RPi.GPIO library and running Python using sudo,

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/ johncclayton/electric/issues/109#issuecomment-363920649, or mute the thread https://github.com/notifications/unsubscribe- auth/ABrWKuz_BfdUb4O7pkSJf4_QBgAeZ1CHks5tShjqgaJpZM4RoufG.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-363921021, or mute the thread https://github.com/notifications/unsubscribe-auth/ABVx0mcEhxpxh4XKJWP5Y47U-v10dyz_ks5tShk6gaJpZM4RoufG .

TheBum commented 6 years ago

Neil set me up with a virtual environment to aid in debugging, but I'm having an issue with the worker.

If I run it in the virtual environment, I have to sudo either the run_zmq_worker.sh script or sudo python within that script to get access to /dev/mem for GPIO. Unfortunately, when I do that, I lose access to the zmq module, getting the following output:

Traceback (most recent call last): File "electric/worker/worker.py", line 5, in import zmq ImportError: No module named zmq

If I run the worker as a docker image using "docker run --privileged -it my-test-worker", then it doesn't open up port 5001 for listening (per netstat) and the web code in the virtual environment cannot talk to it.

If I run both using "docker run" commands, then I don't even get web access, although I suspect that has something to do with not running in docker-compose.

TheBum commented 6 years ago

Got it! I just had to install the pyzmq and schematics modules.

scornflake commented 6 years ago

I think (although I didn’t have a real thing connected to the GPIO) that I managed to get that all working without sudo. I was running the worker as a non-privileged user. That’s the reason we have the udev rules and also the reason for doing the chmod /dev/gpiomem stuff I mentioned over Skype.

I guess I’m saying I don’t think you need to be sudo-ing to run the worker...

— Neil Clayton neil@cloudnine.net.nz

On 14/02/2018, at 4:19 PM, TheBum notifications@github.com wrote:

Got it! I just had to install the pyzmq and schematics modules.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-365483691, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKklDk8JqaXvS7r1JAU4zR5n9dQEzks5tUlDbgaJpZM4RoufG.

TheBum commented 6 years ago

Nope. I just tried running the worker in the virtual environment without sudo'ing and I got the /dev/mem access error. The worker docker image runs in privileged mode, so it should work in the final configuration.

I now have case fan data coming back when using the http://pi3:5000/casefan and http://pi3:5000/unified URLs. I guess the next step is to use curl to try to change the fan control parameters.

scornflake commented 6 years ago

Did you make the changes outlined here?

https://raspberrypi.stackexchange.com/questions/40105/access-gpio-pins-without-root-no-access-to-dev-mem-try-running-as-root https://raspberrypi.stackexchange.com/questions/40105/access-gpio-pins-without-root-no-access-to-dev-mem-try-running-as-root

Here’s a vid of it working for me, might be useful?

https://www.dropbox.com/s/iznc845vy6v6hhh/GPIO%20and%20permissions.mov?dl=0 https://www.dropbox.com/s/iznc845vy6v6hhh/GPIO%20and%20permissions.mov?dl=0

Some notes:

I’m accessing /dev/gpiomem (not /dev/mem).

— Neil Clayton neil@cloudnine.net.nz

On 14/02/2018, at 4:49 PM, TheBum notifications@github.com wrote:

Nope. I just tried running the worker in the virtual environment without sudo'ing and I got the /dev/mem access error. The worker docker image runs in privileged mode, so it should work in the final configuration.

I now have case fan data coming back when using the http://pi3:5000/casefan http://pi3:5000/casefan and http://pi3:5000/unified http://pi3:5000/unified URLs. I guess the next step is to use curl to try to change the fan control parameters.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-365487859, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKm-DrEfyRBHU9qdrxtJI-TixDKCsks5tUlfEgaJpZM4RoufG.

TheBum commented 6 years ago

When I attempt to add pirate to the gpio group, I get the following error:

adduser: The group `gpio' does not exist.

I think I need help with the curl command to use for PUT testing. I'm attempting to get the JSON blob from request.json as I saw in other "put" methods, but it always comes back "None". Here's the curl command I'm using:

curl -X PUT -H "Content-Type: multipart/json" -d '{ "control":"off", "threshold":35, "tolerance":4, "gpio":23 }' pi3:5000/casefan

My GitHub repository is up to date. Thanks.

scornflake commented 6 years ago

Yep. I had to add the group. I don’t think it exists by default, in a stock hypriot install. Once I did that, added the user to that group, and make it group rw, it worked ok.

I’ll try to take a look at your gitrepo later today.

— Neil Clayton neil@cloudnine.net.nz

On 14/02/2018, at 6:14 PM, TheBum notifications@github.com wrote:

When I attempt to add pirate to the gpio group, I get the following error:

adduser: The group `gpio' does not exist.

I think I need help with the curl command to use for PUT testing. I'm attempting to get the JSON blob from request.json as I saw in other "put" methods, but it always comes back "None". Here's the curl command I'm using:

curl -X PUT -H "Content-Type: multipart/json" -d '{ "control":"off", "threshold":35, "tolerance":4, "gpio":23 }' pi3:5000/casefan

My GitHub repository is up to date. Thanks.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-365498680, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKmU0Wg8QHhh9A9Vnlt08Z4X9cSEkks5tUmu2gaJpZM4RoufG.

TheBum commented 6 years ago

I was using the wrong Content-Type in the curl command: I should have been using application/json. I fixed a few bugs I found as a result of setting values via HTTP and now all I need to do is rig up my MOSFET switch and try controlling the actual fans. Almost done on the server side...

TheBum commented 6 years ago

OK, I was trying to modify my Electric Pi system to run my changes. I did a git clone from my repository, built my-test-web and my-test-worker, and changed /opt/docker-compose.yml to reference them. However, my code isn't working. On a unified request, I don't get my case fan data and the /casefan path returns a Not Found error. Here's the docker ps output:

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 18c2507459c8 my-test-web "sh -x /www/run_gu..." 29 minutes ago Up 3 minutes 0.0.0.0:5000->5000/tcp electric-web 63f47b3e4237 my-test-worker "sh -x /www/run_zm..." 29 minutes ago Up 3 minutes 5001/tcp electric-worker aee16657dc33 hypriot/rpi-dockerui "/dockerui" 3 years ago Up 3 minutes 0.0.0.0:80->9000/tcp docker-ui

I verified that the new code is in the clone. What am I doing wrong?

TheBum commented 6 years ago

OK, I ended up clearing out the old docker containers to fix it. I'm sure there's a better way, but at least it worked.

TheBum commented 6 years ago

I noticed that you removed the ability to do a partial update of the prefs (e.g. change threshold temp without touching hysteresis, gpio, or control). Was there a reason for that other than making the code a little cleaner?

scornflake commented 6 years ago

Just cleanliness.

That’s something I should test then. That we can submit a partial casefan JSON. At the moment, I doubt the model will allow it - some fields are required.

— Neil Clayton neil@cloudnine.net.nz

On 27/02/2018, at 9:57 AM, TheBum notifications@github.com wrote:

I noticed that you removed the ability to do a partial update of the prefs (e.g. change threshold temp without touching hysteresis, gpio, or control). Was there a reason for that other than making the code a little cleaner?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/johncclayton/electric/issues/109#issuecomment-368647647, or mute the thread https://github.com/notifications/unsubscribe-auth/ABrWKsU9GHe4RvPp2CMMxmPHTYihK8Yhks5tYxq7gaJpZM4RoufG.