PiSupply / PiJuice

Resources for PiJuice HAT for Raspberry Pi - use your Pi Anywhere
https://uk.pi-supply.com/collections/pijuice/products/pijuice-portable-power-raspberry-pi
GNU General Public License v3.0
440 stars 104 forks source link

Help wanted on wake-up via API #216

Closed jweismann closed 5 years ago

jweismann commented 6 years ago

Hi,

I just got my hands on my first pijuice and I'm wondering how I should use the wake-up facility for my needs. My goal is to have the PI wake-up a specific times during the day (namely at the scheduled break/playtimes during the school day. The PI will then collect some information from a USB attached device and upload it to a the cloud. Then it will go to sleep again.

From the CLI interface it appears that I can only set one point of time (potentially repeated if aligned) and not different points of time, specifically I would like to wake it at:

7.30, 8.50, 9.50, 10.50, 12.00, 13.05, ...

Is this possible to do (I prefer to control this via a software API and not a menu system if possible).

More background information: The USB device will beep loudly and cannot stay usb-plugged so the schedule cannot be shifted to align it (with the RP3 I have power control over the USB hub so that would be a work-around if schedule had to be aligned but with RP0w there is no USB hub and I don't have the possibility to power control the USB port from software AFAIK). With RP3, I don't have sufficient juice to keep it running for the whole school day and with the RP0w I will need to use pijuice to turn the power on the USB port off (by shutdown) to ensure that the device can operate normally (i.e. basically behave as unplugged due to the lack of power from the USB port).

Any advice on how I could accomplish this with the pijuice wakeup feature is highly appreciated. Thank you so much in advance,

Cheers, Jacob

tvoverbeek commented 6 years ago

Assuming you have the PiJuice id-eeprom at its default 0x50, you can use os commands to set the wakeup alarm. You can set the alarm by writing to /sys/class/rtc/rtc0/wakealarm. Example: set the alarm 2 hours from now:

# Clear any existing alarm
sudo sh -c "echo 0 > /sys/classlrtc/rtc0/wakealarm"
# Set the new one 2 hours from now
sudo sh -c "echo `date '+%s' -d '+ 120 minutes'` > /sys/class/rtc/rtc0/wakealarm"

To command the actual shutdown use a small python script which shuts down the Pi and cuts the 5V power to the Pi say 30 seconds later:

#!/usr/bin/python

import os
from pijuice import PiJuice

pj=PiJuice(1, 0x14)
pj.power.SetPowerOff(30)
os.system("sudo shutdown now")

With a combination of scripts and cron jobs you can do what you want.

Note this assumes your Pi has an internet connection (which it needs to upload to the cloud), so timedatectl will sync the time with the internet and also set the RTC to the correct UTC time at boot.

jweismann commented 6 years ago

Hi,

First off, that's an excellent answer. Thank you so much. I will try to use your approach to accomplish what I'm aiming at and let you know if obstacles occur. Thanks again,

fovea1959 commented 6 years ago

I've had good luck with

sudo shutdown -P now

without having to explicitedly do apj.power.SetPowerOff(). Is the latter necessary?

tvoverbeek commented 6 years ago

@fovea1959 No, but ... Although -P means poweroff, the Raspberry Pi peripherals (USB for example) remain powered by the 5V output from the PiJuice. The red LED on the Pi remains lit. For the longest battery life you want to remove the 5V power from the Raspberry Pi after it is shutdown. This is what the SetPowerOff() does after the delay you specify as argument. You do not want to remove the power before the shutdown is finished.

jweismann commented 6 years ago

@tvoverbeek : I need SetPowerOff() for my specific purpose since the USB device that is attached should only have power when I want to retrieve data from it. Actually this raises a silly question. Before playing with the wakeup facility to extend the battery life I turned the power off the USB hub explicitly (in software) whenever I'm was done with the device and then waited until I the next round. This worked fine both with the battery alone and with power attached to the RP3. Now with the wakeup facility it appears that after the shutdown it will only wait the specified period before waking up if the battery is not charging. If it's charging it seems that it will simply boot implying that the power is re-established on the USB hub and the device starts to beep etc. This was not what I aimed at. That is, it seems to work as expected when the battery isn't charging but not when it is charging. Am I doing something wrong or is this expected behaviour ?

tvoverbeek commented 6 years ago

@jweismann In the GUI interface on the System Task tab check that 'Wakeup on charge' is not enabled.

If you cannot use the GUI check /var/lib/pijuice/pijuice_config.JSON Here is how it looks when wakeup on charge is enabled:

{
...
  "system_task": {
    "wakeup_on_charge": {
      "enabled": true,
      "trigger_level": "0"
    },
    ....
  }
....
}

To disable it remove the "enabled": true, line and change the "trigger_level" value to the empty string "". After changing the JSON file restart the pijuice service sudo systemctl restart pijuice.service (Not needed when using the GUI)

jweismann commented 6 years ago

@tvoverbeek I don't have GUI access and my local JSON file looks very simple (I haven't changed it so I guess this is default from the deb package or. It reads: {"system_task":{"enabled": true}} So that should simply be changed to:

{"system_task":{"wakeup_on_charge": { "trigger_level": ""} {"enabled": true}}

Just to confirm my understanding: wakeup_on_charge is by default (i.e. when not set by explicitly by the user) to enabled ?

Thanks

jweismann commented 6 years ago

@tvoverbeek , I guess merely something like:

{"system_task":{"wakeup_on_charge":{"trigger_level":""},"enabled":true}}

will try.

jweismann commented 6 years ago

@tvoverbeek Alas, it still turns on the RP3 as soon as I start to charge the battery.

tvoverbeek commented 6 years ago

@jweismann You seem to have wakeup-on-charge enabled. Delete the JSON file. A skeleton version will be created the next time the pijuice service starts with contents {'system_task': {'enabled': False}}. This assumes you do not use the other system task features, You can bypass the config JSON file by disabling the wakeup-on-charge yourself when you send the pj.power.SetPowerOff() command. Just before or after send the command pj.power.SetWakeUpOnCharge('DISABLED') command. This should ensure the RPi does not wake up when the battery starts charging before the scheduled wakeup time

jweismann commented 6 years ago

@tvoverbeek Thanks. That worked for me. Thank you so much for your advice and guidance. I now have things working the way I aimed at. One last thing that I would like to test is to use the pijuice on a RP0 instead of an RP3 and a new question emerges. I wonder if I should open a new issue or just continue this thread.

The "final" question goes: What is the proper way to move the juice from a rp3 to a rp0 ? If you could point me to documentation describing this or merely list the steps I should take to reduce the risk of damaging any of the parts. Thanks.

tvoverbeek commented 6 years ago

@jweismann Should work. Ofcourse you need a Pi Zero with soldered GPIO header. You either solder it yourself or you by a PiZero with headers (e.g. https://shop.pimoroni.com/products/raspberry-pi-zero-wh-with-pre-soldered-header). For net connectivity I recommend the Pi Zero W, which has built-in WiFi, other wise you need to connect a USB WiFI or USB Ethernet interface probably via a USB hub, since you have other USB sensors to connect. You might need this: https://shop.pimoroni.com/products/zero-adaptor-kit in order to connect 'normal' USB equipment and/or a HDMI monitor. Then all you need to do is moving the PiJuice to the PiZero GPIO header. You can use the same SD card as on the 3B. Otherwise you have to install the PiJuice software and your own code again. Let me know if you need more info.

jweismann commented 6 years ago

@tvoverbeek My concerns were more related what I should pay attention to when moving the PiJuice from the RP3 to the RP0. I have the RP0+w in house and with headers but the PiJuice is on the RP3. I take that I should shut down the RP3 before trying to remove the PiJuice Hat and that I shouldn't have external power on the RP3 nor the PiJuice while trying to remove the PiJuice Hat but what about the power from the battery - can I remove the battery somehow to ensure that there is no power on any parts (RP3+PiJuiceHat) while trying to split them apart ?

When I originally mounted the PiJuice Hat onto the RP3 the battery had an isolation tab so there was no power sources to be concerned about while mounting things.

Thanks

tvoverbeek commented 6 years ago

When you have shutdown the RP3 and the RP3 power led is off, the PiJuice should be in a low power mode when no power is connected to the PiJuice (slow blinking weak LED1). Best to remove the battery. There is a 'BATTERY REMOVE HERE' text on the BP7X on the side of the three PiJuice switches. Just lift the battery there and take it out.

dima72 commented 4 years ago

Hi guys,

# Clear any existing alarm
sudo sh -c "echo 0 > /sys/class/rtc/rtc0/wakealarm"
# Set the new one 2 hours from now
sudo sh -c "echo `date '+%s' -d '+ 120 minutes'` > /sys/class/rtc/rtc0/wakealarm"

/sys/class/rtc/rtc0 path does not exist on my RPI3A+ and I even can not create it with root do I need to rebuild NOOBS/Jessie core to have wakealarm functionality?

thanks in advance,

tvoverbeek commented 4 years ago

If /sys/class/rtc/rtc0 does not exist then you do not have the linux RTC driver installed. Jessie is quite old and not supported any more. Please upgrade to the current release (Buster, Debian 10)

dima72 commented 4 years ago

thank you Ton,

will I need RTC module to plug into RPI for that?

tvoverbeek commented 4 years ago

No, the PiJuice firmware has a (simulated) RTC on I2C address 0x68 (So the PiJuice has to be plugged in). If you have the PiJuice HAT and leave the EEPROM address at 0x50 (the default) then the RTC driver will be loaded at boot due to the device-tree fragment loaded from the EEPROM. The PiJuice Zero does not have an EEPROM, so you need to load the driver yourself: In /boot/config.txt add the line dtoverlay=i2c-rtc,ds1307 for a driver which supports the time but not the alarm function. For the time + alarm function use dtoverlay=i2c-rtc,ds1339.

dima72 commented 4 years ago

Ton, I have PiJuice HAT. How will I leave EEPROM address at 0x50 ? what physically should I do? sorry for dummy question

tvoverbeek commented 4 years ago

If you never changed it (using pijuice_cli or pijuice_gui) then it is at 0x50. But you probably need to be on Stretch or Buster for proper device-tree support.

zkg commented 4 years ago

For the time + alarm function use dtoverlay=i2c-rtc,ds1339.

On Raspbian 10 (buster) I had to add also wakeup-source for the alarm to work. dtoverlay=i2c-rtc,ds1339,wakeup-source

Thank you all for this thread, lots of useful information.