diff --git a/FileSets/.DS_Store b/FileSets/.DS_Store index dccf344..f05a967 100644 Binary files a/FileSets/.DS_Store and b/FileSets/.DS_Store differ diff --git a/FileSets/VenusGpioOverlay.dtb b/FileSets/VenusGpioOverlay.dtbo similarity index 100% rename from FileSets/VenusGpioOverlay.dtb rename to FileSets/VenusGpioOverlay.dtbo diff --git a/FileSets/gpio_list b/FileSets/gpio_list index 655bde5..8ddf27d 100644 --- a/FileSets/gpio_list +++ b/FileSets/gpio_list @@ -1,45 +1,51 @@ -#### modified for use by the RpiGpio package on Raspberry PI platforms ONLY +#### LEGACY assignments for Relay 1, 5 and 6 and Dig In 4 +#### WILL CONFLICT with second channel on WaveShare dual channel CANbus hats, and possiblly others +#### interrupts, chip selects and second SPI bus +#### single channel CANbus hats should be OK with these assignments +#### this includes using only the first channel of the WaveShare dual channel hats +#### note that WaveShare sells two different dual channel CANbus hats: the non FD and FD (flexible data rate) -# This is a list of gpio pins, set by the script /etc/rcS.d/S90gpio_pins.sh +### for use by the RpiGpio package on Raspberry PI platforms ONLY + +# This is a list of GPIO pins, set by the script /etc/rcS.d/S90gpio_pins.sh # They are documented at: https://github.com/victronenergy/venus/wiki/bbb-gpio # Format: # # The part is used to create an symlink in /dev/gpio. # relays are active HIGH -# Relay 1 Pin 40 / GPIO 21 +# Relay 1 GPIO 21 / header pin 40 21 out relay_1 -# Relay 2 Pin 11 / GPIO 17 +# Relay 2 GPIO 17 / header pin 11 17 out relay_2 -# Relay 3 Pin 13 / GPIO 27 +# Relay 3 GPIO 27 / header pin 13 27 out relay_3 -# Relay 4 Pin 15 / GPIO 22 +# Relay 4 GPIO 22 / header pin 15 22 out relay_4 -# Relay 5 Pin 16 / GPIO 23 +# Relay 5 GPIO 23 / header pin 16 23 out relay_5 -# Relay 6 Pin 18 / GPIO 24 +# Relay 6 GPIO 24 / header pin 18 24 out relay_6 # these have pull UPs -# Digital input 1 Pin 29 / GPIO 05 +# Digital input 1 GPIO 5 / header pin 29 5 in digital_input_1 -# Digital input 2 Pin 31 / GPIO 06 +# Digital input 2 PIO 6 / header pin 31 6 in digital_input_2 - # in stock code these have pull DOWNs #### modified to pull UPs by the GPIO overlay that is installed as part of this package -# Digital input 3 Pin 33 / GPIO 13 +# Digital input 3 GPIO 13 / header pin 33 13 in digital_input_3 -# Digital input 4 Pin 35 / GPIO 19 +# Digital input 4 GPIO 19 / header pin 35 19 in digital_input_4 -# Digital input 5 Pin 37 / GPIO 26 +# Digital input 5 GPIO 26 / header pin 37 26 in digital_input_5 #### Gracefull shutdown input #### Note this input is NOT added to the available I/O used by Venus OS !!!! -# Pin 36 / GPIO 16 +# GPIO 16 / header pin 36 16 in digital_input_6 diff --git a/FileSets/gpio_listForCanHats b/FileSets/gpio_listForCanHats new file mode 100644 index 0000000..2d53483 --- /dev/null +++ b/FileSets/gpio_listForCanHats @@ -0,0 +1,59 @@ +#### ALTERNATE assignments for Relay 1, 5 and 6 and Dig In 4 +#### avoids conflict with second CANbus hat interface +#### supports Waveshare dual CAN and dual CAN FD +#### should work with CAN FD mode A or mode B +#### but not more than 1 CAN FD hat board +#### NO i2c bus is possible since relay 1 and dig in 4 use these pins !!!! +#### must use spi1-1cs.dtbo overlay, NOT spi1-3cs.dtbo because of conflicts +#### digital input 3 conflicts with spi0-1 interrupt on CAN FD hat +#### Shutdown monitor shutdown GPIO spi1-2 chip select on CAN FD hat +#### relay 2 conflicts wih spi1-1 chip select on CAN FD hat +#### relay 4 conflicts wih spi1-2 interrupt on CAN FD hat +# +#### other conflicts must be resolved manually by carefully selecting hat boards +#### and creating a custom gpio_list file + +#### for use by the RpiGpio package on Raspberry PI platforms ONLY + +# This is a list of GPIO pins, set by the script /etc/rcS.d/S90gpio_pins.sh +# They are documented at: https://github.com/victronenergy/venus/wiki/bbb-gpio +# Format: +# +# The part is used to create an symlink in /dev/gpio. + +# relays are active HIGH +# Relay 1 GPIO 2 / header pin 3 ALTERNATE assignment +2 out relay_1 +# Relay 2 GPIO 17 / header pin 11 +17 out relay_2 + +# Relay 3 GPIO 27 / header pin 13 +27 out relay_3 +# Relay 4 GPIO 22 / header pin 15 +22 out relay_4 +# Relay 5 GPIO 12 / header pin 32 ALTERNATE assignment +12 out relay_5 +# Relay 6 GPIO 4 / header pin 7 ALTERNATE assignment +4 out relay_6 + +# these have pull UPs +# Digital input 1 GPIO 5 / header pin 29 +5 in digital_input_1 +# Digital input 2 GPIO 6 / header pin 31 +6 in digital_input_2 + +# in stock code these have pull DOWNs +#### modified to pull UPs by the GPIO overlay that is installed as part of this package + +# Digital input 3 GPIO 13 / header pin 33 +13 in digital_input_3 +# Digital input 4 GPIO 3 / header pin 5 ALTERNATE assignment +3 in digital_input_4 +# Digital input 5 GPIO 26 / header pin 37 +26 in digital_input_5 + +#### Gracefull shutdown input +#### Note this input is NOT added to the available I/O used by Venus OS !!!! +# GPIO 16 / header pin 36 +16 in digital_input_6 + diff --git a/FileSets/spi1-1cs.dtbo b/FileSets/spi1-1cs.dtbo new file mode 100644 index 0000000..1ee5981 Binary files /dev/null and b/FileSets/spi1-1cs.dtbo differ diff --git a/FileSets/v2.42/.DS_Store b/FileSets/v2.42/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/FileSets/v2.42/.DS_Store and /dev/null differ diff --git a/FileSets/v2.42/relaystate.py b/FileSets/v2.42/relaystate.py deleted file mode 100644 index 019f260..0000000 --- a/FileSets/v2.42/relaystate.py +++ /dev/null @@ -1,107 +0,0 @@ -import gobject -import logging -import os -import traceback -from glob import glob - -# Victron packages -from ve_utils import exit_on_error - -from delegates.base import SystemCalcDelegate - -class RelayState(SystemCalcDelegate): - RELAY_GLOB = '/dev/gpio/relay_*' - - def __init__(self): - SystemCalcDelegate.__init__(self) - self._relays = {} - - def get_input(self): - return [ - ('com.victronenergy.settings', [ - '/Settings/Relay/Function'])] # Managed by the gui - - def get_settings(self): - return [ - ('/Relay/0/State', '/Settings/Relay/0/InitialState', 0, 0, 1), - ('/Relay/1/State', '/Settings/Relay/1/InitialState', 0, 0, 1), - ('/Relay/2/State', '/Settings/Relay/2/InitialState', 0, 0, 1), - ('/Relay/3/State', '/Settings/Relay/3/InitialState', 0, 0, 1), - ('/Relay/4/State', '/Settings/Relay/4/InitialState', 0, 0, 1), - ('/Relay/5/State', '/Settings/Relay/5/InitialState', 0, 0, 1), - ('/Relay/6/State', '/Settings/Relay/6/InitialState', 0, 0, 1) - ] - - @property - def relay_function(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/Relay/Function') - - def set_sources(self, dbusmonitor, settings, dbusservice): - SystemCalcDelegate.set_sources(self, dbusmonitor, settings, dbusservice) - relays = sorted(glob(self.RELAY_GLOB)) - - if len(relays) == 0: - logging.info('No relays found') - return - - self._relays.update({'/Relay/{}/State'.format(i): os.path.join(r, 'value') \ - for i, r in enumerate(relays) }) - - gobject.idle_add(exit_on_error, self._init_relay_state) - for dbus_path in self._relays.iterkeys(): - self._dbusservice.add_path(dbus_path, value=None, writeable=True, - onchangecallback=self._on_relay_state_changed) - - logging.info('Relays found: {}'.format(', '.join(self._relays.values()))) - - def _init_relay_state(self): - if self.relay_function is None: - return True # Try again on the next idle event - - for dbus_path, path in self._relays.iteritems(): - if self.relay_function != 2 and dbus_path == '/Relay/0/State': - continue # Skip primary relay if function is not manual - state = self._settings[dbus_path] - self._dbusservice[dbus_path] = state - self.__on_relay_state_changed(dbus_path, state) - - # Sync state back to dbus - self._update_relay_state() - - # Watch changes and update dbus. Do we still need this? - gobject.timeout_add(5000, exit_on_error, self._update_relay_state) - return False - - def _update_relay_state(self): - # @todo EV Do we still need this? Maybe only at startup? - for dbus_path, file_path in self._relays.items(): - try: - with open(file_path, 'rt') as r: - state = int(r.read().strip()) - self._dbusservice[dbus_path] = state - except (IOError, ValueError): - traceback.print_exc() - return True - - def __on_relay_state_changed(self, dbus_path, state): - try: - path = self._relays[dbus_path] - with open(path, 'wt') as w: - w.write(str(state)) - except IOError: - traceback.print_exc() - return False - return True - - def _on_relay_state_changed(self, dbus_path, value): - try: - state = int(bool(value)) - except ValueError: - traceback.print_exc() - return False - try: - return self.__on_relay_state_changed(dbus_path, state) - finally: - # Remember the state to restore after a restart - self._settings[dbus_path] = state diff --git a/FileSets/v2.42/relaystate.py.orig b/FileSets/v2.42/relaystate.py.orig deleted file mode 100644 index 9d5eaaf..0000000 --- a/FileSets/v2.42/relaystate.py.orig +++ /dev/null @@ -1,102 +0,0 @@ -import gobject -import logging -import os -import traceback -from glob import glob - -# Victron packages -from ve_utils import exit_on_error - -from delegates.base import SystemCalcDelegate - -class RelayState(SystemCalcDelegate): - RELAY_GLOB = '/dev/gpio/relay_*' - - def __init__(self): - SystemCalcDelegate.__init__(self) - self._relays = {} - - def get_input(self): - return [ - ('com.victronenergy.settings', [ - '/Settings/Relay/Function'])] # Managed by the gui - - def get_settings(self): - return [ - ('/Relay/0/State', '/Settings/Relay/0/InitialState', 0, 0, 1), - ('/Relay/1/State', '/Settings/Relay/1/InitialState', 0, 0, 1) - ] - - @property - def relay_function(self): - return self._dbusmonitor.get_value('com.victronenergy.settings', - '/Settings/Relay/Function') - - def set_sources(self, dbusmonitor, settings, dbusservice): - SystemCalcDelegate.set_sources(self, dbusmonitor, settings, dbusservice) - relays = sorted(glob(self.RELAY_GLOB)) - - if len(relays) == 0: - logging.info('No relays found') - return - - self._relays.update({'/Relay/{}/State'.format(i): os.path.join(r, 'value') \ - for i, r in enumerate(relays) }) - - gobject.idle_add(exit_on_error, self._init_relay_state) - for dbus_path in self._relays.iterkeys(): - self._dbusservice.add_path(dbus_path, value=None, writeable=True, - onchangecallback=self._on_relay_state_changed) - - logging.info('Relays found: {}'.format(', '.join(self._relays.values()))) - - def _init_relay_state(self): - if self.relay_function is None: - return True # Try again on the next idle event - - for dbus_path, path in self._relays.iteritems(): - if self.relay_function != 2 and dbus_path == '/Relay/0/State': - continue # Skip primary relay if function is not manual - state = self._settings[dbus_path] - self._dbusservice[dbus_path] = state - self.__on_relay_state_changed(dbus_path, state) - - # Sync state back to dbus - self._update_relay_state() - - # Watch changes and update dbus. Do we still need this? - gobject.timeout_add(5000, exit_on_error, self._update_relay_state) - return False - - def _update_relay_state(self): - # @todo EV Do we still need this? Maybe only at startup? - for dbus_path, file_path in self._relays.items(): - try: - with open(file_path, 'rt') as r: - state = int(r.read().strip()) - self._dbusservice[dbus_path] = state - except (IOError, ValueError): - traceback.print_exc() - return True - - def __on_relay_state_changed(self, dbus_path, state): - try: - path = self._relays[dbus_path] - with open(path, 'wt') as w: - w.write(str(state)) - except IOError: - traceback.print_exc() - return False - return True - - def _on_relay_state_changed(self, dbus_path, value): - try: - state = int(bool(value)) - except ValueError: - traceback.print_exc() - return False - try: - return self.__on_relay_state_changed(dbus_path, state) - finally: - # Remember the state to restore after a restart - self._settings[dbus_path] = state diff --git a/OverlayInstructions b/OverlayInstructions index 1f24c7a..f37b605 100644 --- a/OverlayInstructions +++ b/OverlayInstructions @@ -1,15 +1,11 @@ compile: - dtc -@ -I dts -O dtb -o VenusGpioOverlay.dtb VenusGpioOverlay.dts ------------ or ??? ----------- dtc -@ -I dts -O dtb -o VenusGpioOverlay.dtbo VenusGpioOverlay.dts -Put it in /boot/overlays: - sudo cp VenusGpioOverlay.dtb /boot/overlays/VenusGpioOverlay.dtb ------------ or ??? ----------- - sudo cp VenusGpioOverlay.dtbo /boot/overlays/VenusGpioOverlay.dtbo +Put it in /u-boot/overlays: + sudo cp VenusGpioOverlay.dtbo /u-boot/overlays/VenusGpioOverlay.dtbo -Add a line to /boot/config.txt: +Add a line to /u-boot/config.txt: dtoverlay=VenusGpioOverlay -Note /boot might be /u-boot \ No newline at end of file +Note /u-boot typically appears as /boot when the SD card is mounted on a computer diff --git a/ReadMe b/ReadMe index c41f780..5c1a00a 100644 --- a/ReadMe +++ b/ReadMe @@ -1,28 +1,57 @@ This package adds additional digital inputs and relay outputs +for Venus OS running on Raspberry PI platforms. +It is not suitable for other GX devices such as CCGX or Cerbo GX. -The stock RPI Venus distribution includes two relays and two digital inputs +The stock RPI Venus distribution there are NO relays or digital inputs defined. This script adds: - the additional GPIO pins (5 total) to /etc/venus/gpio_list + 5 digital inputs makes additional digital inputs available makes all digital inputs behave the same: pull up so they are active low - activates GPIO $16 (header pin 36) as a shutdown pin + 6 relay outputs + activates GPIO 16 (header pin 36) as a shutdown pin This requires ShutdownMonitor v2.0 or later The Raspberry PI default is for the first 8 GPIO pins to have pull UPs and the remaining have pull DOWNs. This makes some digital input pins behave differently This script installs a DT overlay that switches to pull UPs for all digital input pins -This package adds 4 more relays. -Only the first relay can be assigned to a function: alarm, genertor start/stop or pump. -Others are only provided manual on/off control from the menu. +Only the relay 1 can be assigned to a function: alarm, genertor start/stop or pump. +In addition, relay 2 can be assigned to temperature alarm +The remaining 4 relays are only provided manual on/off control from the menu. -The remaining 5 relays are manual on/off only. +Note that the Raspberry PI has no relays or isolated/filtered digital inputs on board. + +Relay outputs are 0 volts when inactive and 3.3 volts when active. +Current sink and source is limited. Check Raspberry PI specifications for details. +You must attach the GPIO pins to external relays. +Relays should active on a high (3.3 volt) input. +Relays that activate on a low signal are NOT COMPATIBLE since +the relays would still close during Raspberry PI boot regardless of the logic provided by Venus OS. + +Digital inputs expect 0 volts for an inactive input and 3.3 volts for an active input. +You must provide isolation for the digital inputs to avoid damage to the CPU chip!!! + +Venus OS does not provide native support for i2c relay boards and this package does not add any. This script should be run manually initally. It will then called from reinstallMods to reinstall functionality after a Venus update + +GPIO conflicts: + +GPIO assignments for relays 5 and 6 may cause conflicts with hat board interrupts. +This conflict may cause the system to not boot properly or be extremely sluggish. +This script allows for two assignments for relays 5 and 6. +gpio_list is the legacy one: GPIO 23 and 24, respectively +gpio_listForCanHats provides compatibility with at least the two Waveshare CANbus dual channel hats + GPIOs 12 and 20 are used for relays 5 and 6, respectively + +An option to select the legady or compatible set is offered during manual setup. +However, this optoin is considered optional and installation with the legacy set +is allowed even if the setup script is not run manually first. + Custom GPIO list: If /data/setupOptions/RpiGpioSetup/gpio_list exists it is used in place diff --git a/changes b/changes index 02fcaa6..456d0b6 100644 --- a/changes +++ b/changes @@ -1,3 +1,11 @@ + +v4.0: + add option to move relay 5 & 6 do different GPIOs to avoid conflict with CAN hats + renamed overlay .dtbo to support v2.90 + +v3.8: + dropped support for Venus OS v2.4x and 2.5x + v3.7: added v2.80 - no functional changes diff --git a/setup b/setup index b2abd44..b8ad0ef 100755 --- a/setup +++ b/setup @@ -19,10 +19,22 @@ # run manually initally, then called from reinstallMods # to uninstall/deactivate, call this script with "uninstall" as first parameter +# original assignments for relays 5 and 6 create conflicts with interrypt pins +# on hat boards such as the Waveshare dual CANbus hats (regular and FD versions) +# An option in this setup script allows selection of different GPIO assignments +# for relays 5 and 6 to avoid these conflicts +# +# Because this conflict will be rare, the option is considered optional. +# That is, an automatic install WILL be permitted even if a manual install has not +# been perfomred. +# +# VeCanSetup will alert the user of conflicts and prevent installing the second +# CANbus interface until this script is rerun to move the relay assignments. + # Note, this script DOES require a system reboot. gpioListFile="/etc/venus/gpio_list" -overlayFile="/u-boot/overlays/VenusGpioOverlay.dtb" +overlayFile="/u-boot/overlays/VenusGpioOverlay.dtbo" relayStateFile="/opt/victronenergy/dbus-systemcalc-py/delegates/relaystate.py" configFile="/u-boot/config.txt" @@ -64,19 +76,55 @@ if [ $scriptAction == 'NONE' ] ; then # display innitial message echo echo "This package makes the following modifications:" - echo " Activates all 5 predefined digital inputs" + echo " Activates 6 relay outputs" + echo " Activates 5 digital inputs" echo " Changes all digital inputs to have pull-ups in stead of a mix of pull up/down" - standardActionPrompt + standardActionPrompt 'MORE_PROMPTS' + + if [ $scriptAction == 'NONE' ]; then + echo + echo "Legacy assignment for relays 5 and 6 may conflict with interrupts for some CANbus interface hat boards" + echo "Conflicts WILL render the Raspberry PI at least partially unresponsive" + echo "To avoid conflicts, an alternate set of GPIO assignments is available" + + useCustomGpioFile=false + if [ -f "$setupOptionsDir/gpio_list" ]; then + yesNoPrompt "A custom gpio_list file exists - use it (y/n)?: " + if $yesResponse ; then + echo "CAUTION: manually check custom gpio_list for conflicts" + useCustomGpioFile=true + else + rm "$setupOptionsDir/gpio_list" + fi + fi + if ! $useCustomGpioFile ; then + echo + yesNoPrompt "Do you wish to install the alternate set of GPIO assignments (y/n)?: " + if $yesResponse ; then + touch "$setupOptionsDir/alternateGpio" + else + rm -f "$setupOptionsDir/alternateGpio" + fi + fi + + scriptAction='INSTALL' + fi fi - #### installing if [ $scriptAction == 'INSTALL' ] ; then - # use a custom gpio list if present + # use custom GPIO list if present if [ -f "$setupOptionsDir/gpio_list" ]; then + logMessage "installing CUSTOM gpio_list" updateActiveFile "$setupOptionsDir/gpio_list" "$gpioListFile" + # use a alternate gpio list if option is set + elif [ -f "$setupOptionsDir/alternateGpio" ]; then + logMessage "installing ALTERNATE gpio_list" + updateActiveFile "$setupOptionsDir/gpio_listForCanHats" "$gpioListFile" + # use a legacy gpio list otherwise else + logMessage "installing LEGACY gpio_list" updateActiveFile "$gpioListFile" fi @@ -84,7 +132,7 @@ if [ $scriptAction == 'INSTALL' ] ; then updateActiveFile "$relayStateFile" # install DT overlay to for pull-ups on all digital inputs - updateActiveFile $pkgFileSets/VenusGpioOverlay.dtb "$overlayFile" + updateActiveFile "$overlayFile" if [ $(grep -c "VenusGpioOverlay" "$configFile") == 0 ]; then logMessage "activating GPIO DT overlay" diff --git a/version b/version index 5a2f3db..1961bcc 100644 --- a/version +++ b/version @@ -1 +1 @@ -v3.7 +v4.0