From c5d77cf1ce97e4ba4f05cba43a43e71e1e46a7d5 Mon Sep 17 00:00:00 2001 From: kwindrem <58538395+kwindrem@users.noreply.github.com> Date: Thu, 22 Feb 2024 14:50:39 -0800 Subject: [PATCH] added alternate GPIO overlay to remove conflicts with FD can hat --- .github/workflows/latest-tag.yml | 18 + FileSets/VenusGpioOverlayForCanHats.dtbo | Bin 0 -> 637 bytes FileSets/spi1-1cs.dtbo | Bin 1523 -> 0 bytes FileSets/v2.80/relaystate.py | 2 +- FileSets/v2.81/relaystate.py | 2 +- FileSets/v2.82/relaystate.py | 2 +- FileSets/v2.83/relaystate.py | 2 +- FileSets/v2.84/relaystate.py | 2 +- FileSets/v2.85/relaystate.py | 2 +- FileSets/v2.86/relaystate.py | 2 +- FileSets/v2.87/relaystate.py | 2 +- FileSets/v2.89/relaystate.py | 2 +- FileSets/v2.90/relaystate.py | 2 +- FileSets/v2.91/relaystate.py | 2 +- FileSets/v2.92/relaystate.py | 2 +- FileSets/v2.93/relaystate.py | 2 +- FileSets/v2.94/relaystate.py | 2 +- FileSets/v3.00/relaystate.py | 2 +- FileSets/v3.00~32/relaystate.py | 2 +- FileSets/v3.01/relaystate.py | 2 +- FileSets/v3.10/relaystate.py | 2 +- FileSets/v3.11/relaystate.py | 2 +- FileSets/v3.12/relaystate.py | 2 +- FileSets/v3.13/relaystate.py | 2 +- FileSets/{v3.20~14 => v3.14}/COMPLETE | 0 FileSets/{v3.20~14 => v3.14}/LINKS_ONLY | 0 FileSets/v3.14/relaystate.py | 1 + FileSets/{v3.20~17 => v3.20}/COMPLETE | 0 FileSets/{v3.20~17 => v3.20}/LINKS_ONLY | 0 FileSets/v3.20/relaystate.py | 1 + FileSets/v3.20~14/relaystate.py | 1 - FileSets/v3.20~17/relaystate.py | 1 - FileSets/v3.20~18/relaystate.py | 1 - FileSets/v3.20~26/relaystate.py | 1 - FileSets/v3.20~29/relaystate.py | 1 - FileSets/v3.20~30/relaystate.py | 1 - FileSets/{v3.20~18 => v3.21}/COMPLETE | 0 FileSets/{v3.20~18 => v3.21}/LINKS_ONLY | 0 FileSets/v3.21/relaystate.py | 1 + FileSets/{v3.20~26 => v3.30~3}/COMPLETE | 0 FileSets/{v3.20~26 => v3.30~3}/LINKS_ONLY | 0 FileSets/v3.30~3/relaystate.py | 1 + FileSets/{v3.20~29 => v3.30~4}/COMPLETE | 0 FileSets/{v3.20~29 => v3.30~4}/LINKS_ONLY | 0 FileSets/v3.30~4/relaystate.py | 1 + FileSets/{v3.20~30 => v3.30~6}/COMPLETE | 0 FileSets/{v3.20~30 => v3.30~6}/LINKS_ONLY | 0 FileSets/v3.30~6/relaystate.py | 1 + FileSets/{v3.20~33 => v3.30~7}/COMPLETE | 0 FileSets/v3.30~7/LINKS_ONLY | 0 FileSets/v3.30~7/relaystate.py | 1 + FileSets/v3.30~8/COMPLETE | 0 FileSets/{v3.20~33 => v3.30~8}/relaystate.py | 0 .../{v3.20~33 => v3.30~8}/relaystate.py.orig | 0 HelperResources/CommonResources | 1407 +++++++++++++++++ HelperResources/DbusSettingsResources | 211 +++ HelperResources/EssentialResources | 79 + HelperResources/IncludeHelpers | 65 + HelperResources/LogHandler | 80 + HelperResources/ServiceResources | 287 ++++ HelperResources/VersionResources | 139 ++ HelperResources/forSetupScript | 14 + HelperResources/version | 1 + OverlayInstructions | 6 + VenusGpioOverlayForCanHats.dts | 27 + changes | 3 + setup | 37 +- timeStamp | 1 - version | 2 +- 69 files changed, 2392 insertions(+), 40 deletions(-) create mode 100644 .github/workflows/latest-tag.yml create mode 100644 FileSets/VenusGpioOverlayForCanHats.dtbo delete mode 100644 FileSets/spi1-1cs.dtbo rename FileSets/{v3.20~14 => v3.14}/COMPLETE (100%) rename FileSets/{v3.20~14 => v3.14}/LINKS_ONLY (100%) create mode 120000 FileSets/v3.14/relaystate.py rename FileSets/{v3.20~17 => v3.20}/COMPLETE (100%) rename FileSets/{v3.20~17 => v3.20}/LINKS_ONLY (100%) create mode 120000 FileSets/v3.20/relaystate.py delete mode 120000 FileSets/v3.20~14/relaystate.py delete mode 120000 FileSets/v3.20~17/relaystate.py delete mode 120000 FileSets/v3.20~18/relaystate.py delete mode 120000 FileSets/v3.20~26/relaystate.py delete mode 120000 FileSets/v3.20~29/relaystate.py delete mode 120000 FileSets/v3.20~30/relaystate.py rename FileSets/{v3.20~18 => v3.21}/COMPLETE (100%) rename FileSets/{v3.20~18 => v3.21}/LINKS_ONLY (100%) create mode 120000 FileSets/v3.21/relaystate.py rename FileSets/{v3.20~26 => v3.30~3}/COMPLETE (100%) rename FileSets/{v3.20~26 => v3.30~3}/LINKS_ONLY (100%) create mode 120000 FileSets/v3.30~3/relaystate.py rename FileSets/{v3.20~29 => v3.30~4}/COMPLETE (100%) rename FileSets/{v3.20~29 => v3.30~4}/LINKS_ONLY (100%) create mode 120000 FileSets/v3.30~4/relaystate.py rename FileSets/{v3.20~30 => v3.30~6}/COMPLETE (100%) rename FileSets/{v3.20~30 => v3.30~6}/LINKS_ONLY (100%) create mode 120000 FileSets/v3.30~6/relaystate.py rename FileSets/{v3.20~33 => v3.30~7}/COMPLETE (100%) create mode 100644 FileSets/v3.30~7/LINKS_ONLY create mode 120000 FileSets/v3.30~7/relaystate.py create mode 100644 FileSets/v3.30~8/COMPLETE rename FileSets/{v3.20~33 => v3.30~8}/relaystate.py (100%) rename FileSets/{v3.20~33 => v3.30~8}/relaystate.py.orig (100%) create mode 100755 HelperResources/CommonResources create mode 100755 HelperResources/DbusSettingsResources create mode 100755 HelperResources/EssentialResources create mode 100755 HelperResources/IncludeHelpers create mode 100755 HelperResources/LogHandler create mode 100755 HelperResources/ServiceResources create mode 100755 HelperResources/VersionResources create mode 100644 HelperResources/forSetupScript create mode 100644 HelperResources/version create mode 100644 VenusGpioOverlayForCanHats.dts delete mode 100644 timeStamp diff --git a/.github/workflows/latest-tag.yml b/.github/workflows/latest-tag.yml new file mode 100644 index 0000000..328c785 --- /dev/null +++ b/.github/workflows/latest-tag.yml @@ -0,0 +1,18 @@ +name: Add latest tag to new release +on: + release: + types: [published] + workflow_dispatch: + +jobs: + run: + name: Run local action + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@master + + - name: Run latest-tag + uses: EndBug/latest-tag@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/FileSets/VenusGpioOverlayForCanHats.dtbo b/FileSets/VenusGpioOverlayForCanHats.dtbo new file mode 100644 index 0000000000000000000000000000000000000000..5fb35ea6fd01230680f55a4f908e446167bfe888 GIT binary patch literal 637 zcmZWn%SyyB6ivqmiVUbAh`5-gh|-R)(OK!NUAh!X+DU66X-Xer7yhFk;nrVJ&rK8C z!N8ew?oIBq^D+MZVr=xz7`p`@gHM1xU>Bgn8S_3nx$^5-YYluyIx1sz7RBmfc6n|2 z#`4VZL*UfHs_E3`@sg6KO62u@U_6v}9oYH70efMnUqvZ-8;10N?ze#brAT-qYv-ew z2|)dMstt=QuOQ9)L-4898{kb~4A87cfU9{0O~=^_=+VG_gr@xDb3lJpt0FC{zP}0X zpZtC>e=vhT=#6q9KFQvi!iJmL2k<`+;^#FlQ&G>m4Ry5u;oF#S71uNaSWt Hi%hd$5_oro literal 0 HcmV?d00001 diff --git a/FileSets/spi1-1cs.dtbo b/FileSets/spi1-1cs.dtbo deleted file mode 100644 index 1ee5981dd8bbe5980ee9095581f82caf81653e1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1523 zcmaJ>&2AGh5O&&B1(ixbLE?bKPlbdKQL-sWRZisrcmTv<4Z_+lFW@pBp`8=Ne>>vAoe+#kmM+k8YeINQUwJmhk4E?4l&x| z&k|t8$6j_8hc!fO8~cUHZt}0demPN7Stk{znZvo)5O)sFu?NcbjCDJ_9oSj^RxY49 z+@7qTHhVBpr?&ge+%5x~d0NYy+IZgIR5$deD*m(dk-v`njb)axg>^lwEww1%QT+Xg=-Se zg8MGMdW^xSlI2WQXq2B^*?hEYUeinD^DcgCg?kJvU~nJCeD^WK^%z@Ul1DNLSE|H6 zShl*kbL;N~@!fraY2Fs%Sxmky=eWUma)X0!95KjIa)86-Q(ukpw2)OiPLycc)4X!# zg)-cl)>%}=c_xZCGMgamP);VL(z+L^B+=qf$M2Q3krh>C(#vG3v~b=)xV{R@z*5b4 tL3^p3_ok(KSF0>qAZoy;%xHUkJ>!h!xWuLf_KFALK#=it10n0V_z%ZoAesOG diff --git a/FileSets/v2.80/relaystate.py b/FileSets/v2.80/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.80/relaystate.py +++ b/FileSets/v2.80/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.81/relaystate.py b/FileSets/v2.81/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.81/relaystate.py +++ b/FileSets/v2.81/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.82/relaystate.py b/FileSets/v2.82/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.82/relaystate.py +++ b/FileSets/v2.82/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.83/relaystate.py b/FileSets/v2.83/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.83/relaystate.py +++ b/FileSets/v2.83/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.84/relaystate.py b/FileSets/v2.84/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.84/relaystate.py +++ b/FileSets/v2.84/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.85/relaystate.py b/FileSets/v2.85/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.85/relaystate.py +++ b/FileSets/v2.85/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.86/relaystate.py b/FileSets/v2.86/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.86/relaystate.py +++ b/FileSets/v2.86/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.87/relaystate.py b/FileSets/v2.87/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.87/relaystate.py +++ b/FileSets/v2.87/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.89/relaystate.py b/FileSets/v2.89/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.89/relaystate.py +++ b/FileSets/v2.89/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.90/relaystate.py b/FileSets/v2.90/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.90/relaystate.py +++ b/FileSets/v2.90/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.91/relaystate.py b/FileSets/v2.91/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.91/relaystate.py +++ b/FileSets/v2.91/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.92/relaystate.py b/FileSets/v2.92/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.92/relaystate.py +++ b/FileSets/v2.92/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.93/relaystate.py b/FileSets/v2.93/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.93/relaystate.py +++ b/FileSets/v2.93/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v2.94/relaystate.py b/FileSets/v2.94/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v2.94/relaystate.py +++ b/FileSets/v2.94/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.00/relaystate.py b/FileSets/v3.00/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.00/relaystate.py +++ b/FileSets/v3.00/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.00~32/relaystate.py b/FileSets/v3.00~32/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.00~32/relaystate.py +++ b/FileSets/v3.00~32/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.01/relaystate.py b/FileSets/v3.01/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.01/relaystate.py +++ b/FileSets/v3.01/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.10/relaystate.py b/FileSets/v3.10/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.10/relaystate.py +++ b/FileSets/v3.10/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.11/relaystate.py b/FileSets/v3.11/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.11/relaystate.py +++ b/FileSets/v3.11/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.12/relaystate.py b/FileSets/v3.12/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.12/relaystate.py +++ b/FileSets/v3.12/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.13/relaystate.py b/FileSets/v3.13/relaystate.py index 4f6ee11..667f504 120000 --- a/FileSets/v3.13/relaystate.py +++ b/FileSets/v3.13/relaystate.py @@ -1 +1 @@ -../v3.20~33/relaystate.py \ No newline at end of file +../v3.20~34/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~14/COMPLETE b/FileSets/v3.14/COMPLETE similarity index 100% rename from FileSets/v3.20~14/COMPLETE rename to FileSets/v3.14/COMPLETE diff --git a/FileSets/v3.20~14/LINKS_ONLY b/FileSets/v3.14/LINKS_ONLY similarity index 100% rename from FileSets/v3.20~14/LINKS_ONLY rename to FileSets/v3.14/LINKS_ONLY diff --git a/FileSets/v3.14/relaystate.py b/FileSets/v3.14/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.14/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~17/COMPLETE b/FileSets/v3.20/COMPLETE similarity index 100% rename from FileSets/v3.20~17/COMPLETE rename to FileSets/v3.20/COMPLETE diff --git a/FileSets/v3.20~17/LINKS_ONLY b/FileSets/v3.20/LINKS_ONLY similarity index 100% rename from FileSets/v3.20~17/LINKS_ONLY rename to FileSets/v3.20/LINKS_ONLY diff --git a/FileSets/v3.20/relaystate.py b/FileSets/v3.20/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.20/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~14/relaystate.py b/FileSets/v3.20~14/relaystate.py deleted file mode 120000 index 4f6ee11..0000000 --- a/FileSets/v3.20~14/relaystate.py +++ /dev/null @@ -1 +0,0 @@ -../v3.20~33/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~17/relaystate.py b/FileSets/v3.20~17/relaystate.py deleted file mode 120000 index 4f6ee11..0000000 --- a/FileSets/v3.20~17/relaystate.py +++ /dev/null @@ -1 +0,0 @@ -../v3.20~33/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~18/relaystate.py b/FileSets/v3.20~18/relaystate.py deleted file mode 120000 index 4f6ee11..0000000 --- a/FileSets/v3.20~18/relaystate.py +++ /dev/null @@ -1 +0,0 @@ -../v3.20~33/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~26/relaystate.py b/FileSets/v3.20~26/relaystate.py deleted file mode 120000 index 4f6ee11..0000000 --- a/FileSets/v3.20~26/relaystate.py +++ /dev/null @@ -1 +0,0 @@ -../v3.20~33/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~29/relaystate.py b/FileSets/v3.20~29/relaystate.py deleted file mode 120000 index 4f6ee11..0000000 --- a/FileSets/v3.20~29/relaystate.py +++ /dev/null @@ -1 +0,0 @@ -../v3.20~33/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~30/relaystate.py b/FileSets/v3.20~30/relaystate.py deleted file mode 120000 index 4f6ee11..0000000 --- a/FileSets/v3.20~30/relaystate.py +++ /dev/null @@ -1 +0,0 @@ -../v3.20~33/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~18/COMPLETE b/FileSets/v3.21/COMPLETE similarity index 100% rename from FileSets/v3.20~18/COMPLETE rename to FileSets/v3.21/COMPLETE diff --git a/FileSets/v3.20~18/LINKS_ONLY b/FileSets/v3.21/LINKS_ONLY similarity index 100% rename from FileSets/v3.20~18/LINKS_ONLY rename to FileSets/v3.21/LINKS_ONLY diff --git a/FileSets/v3.21/relaystate.py b/FileSets/v3.21/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.21/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~26/COMPLETE b/FileSets/v3.30~3/COMPLETE similarity index 100% rename from FileSets/v3.20~26/COMPLETE rename to FileSets/v3.30~3/COMPLETE diff --git a/FileSets/v3.20~26/LINKS_ONLY b/FileSets/v3.30~3/LINKS_ONLY similarity index 100% rename from FileSets/v3.20~26/LINKS_ONLY rename to FileSets/v3.30~3/LINKS_ONLY diff --git a/FileSets/v3.30~3/relaystate.py b/FileSets/v3.30~3/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.30~3/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~29/COMPLETE b/FileSets/v3.30~4/COMPLETE similarity index 100% rename from FileSets/v3.20~29/COMPLETE rename to FileSets/v3.30~4/COMPLETE diff --git a/FileSets/v3.20~29/LINKS_ONLY b/FileSets/v3.30~4/LINKS_ONLY similarity index 100% rename from FileSets/v3.20~29/LINKS_ONLY rename to FileSets/v3.30~4/LINKS_ONLY diff --git a/FileSets/v3.30~4/relaystate.py b/FileSets/v3.30~4/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.30~4/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~30/COMPLETE b/FileSets/v3.30~6/COMPLETE similarity index 100% rename from FileSets/v3.20~30/COMPLETE rename to FileSets/v3.30~6/COMPLETE diff --git a/FileSets/v3.20~30/LINKS_ONLY b/FileSets/v3.30~6/LINKS_ONLY similarity index 100% rename from FileSets/v3.20~30/LINKS_ONLY rename to FileSets/v3.30~6/LINKS_ONLY diff --git a/FileSets/v3.30~6/relaystate.py b/FileSets/v3.30~6/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.30~6/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.20~33/COMPLETE b/FileSets/v3.30~7/COMPLETE similarity index 100% rename from FileSets/v3.20~33/COMPLETE rename to FileSets/v3.30~7/COMPLETE diff --git a/FileSets/v3.30~7/LINKS_ONLY b/FileSets/v3.30~7/LINKS_ONLY new file mode 100644 index 0000000..e69de29 diff --git a/FileSets/v3.30~7/relaystate.py b/FileSets/v3.30~7/relaystate.py new file mode 120000 index 0000000..b74c713 --- /dev/null +++ b/FileSets/v3.30~7/relaystate.py @@ -0,0 +1 @@ +../v3.30~8/relaystate.py \ No newline at end of file diff --git a/FileSets/v3.30~8/COMPLETE b/FileSets/v3.30~8/COMPLETE new file mode 100644 index 0000000..e69de29 diff --git a/FileSets/v3.20~33/relaystate.py b/FileSets/v3.30~8/relaystate.py similarity index 100% rename from FileSets/v3.20~33/relaystate.py rename to FileSets/v3.30~8/relaystate.py diff --git a/FileSets/v3.20~33/relaystate.py.orig b/FileSets/v3.30~8/relaystate.py.orig similarity index 100% rename from FileSets/v3.20~33/relaystate.py.orig rename to FileSets/v3.30~8/relaystate.py.orig diff --git a/HelperResources/CommonResources b/HelperResources/CommonResources new file mode 100755 index 0000000..0ff74a6 --- /dev/null +++ b/HelperResources/CommonResources @@ -0,0 +1,1407 @@ +#!/bin/bash + + +# CommonResources for SetupHelper +# contains a functions and variables necessary for a setup script to interface with reinstallMods +#patch file missing for +# Refer to the SetupHelper ReadMe file for details on how to use these resources. + +# what action the script should take: +# NONE - do noting - signals script to prompt for user input on how to proceed +# INSTALL - install package components +# (decommissioned) PROMPT - prompt user for additional installation options +# UNINSTALL - remove package components +# EXIT - exit script without taking any action +# CommonResources may set the the action if initial checks +# indicate a clear direction +# otherwise, the action will be set based on user input (in the script) +# if failures occur during installation, +# scriptAction should be changed to UNINSTALL so the installation can be cleaned up +# and the setup script should test for UNINSTALL after it attempts installation +# A file set error indicates the file set for the current verion is not usable +# and installation should not occur +# checkFileSets EXITS locally + +scriptAction='NONE' +installFailed=false +installExitReason=$EXIT_SUCCESS + +# flags to control setup script behavior (in endScript) +rebootNeeded=false +runAgain=false +filesUpdated=false +restartGui=false +restartGenerator=false +restartSystemCalc=false +restartDigitalinputs=false + + +# file lists are populated by getFileLists called from_chckFileSets and autoinstall +# so these are global +fileList=() +fileListVersionIndependent=() +fileListAll=() + + +######## skip to bottom of file for remainder of code executed when script is sourced + + +# getFileLists reads the file list from files in the FileSets directory +# +# 'fileList' file must only list version-dependent files +# 'fileListVersionIndependent' file must list only version-independent files +# prior to SetupHelper v6.0, this list is ignored +# 'fileListPatched' lists all files that should be patched before installation +# +# $1 specifies where the path to the fileList files +# +# three composite file lists are returned in global arrays: +# fileList contains only version-dependent files +# fileListVersionIndependent contains only version-independent files +# fileListPatched contains only files that need to be patched +# fileListAll contains both versioned and version-independent files + +function getFileLists () +{ + local verListFile="$1/fileList" + local indListFile="$1/fileListVersionIndependent" + local patchListFile="$1/fileListPatched" + local tempListVer=() + local tempListInd=() + local tempListPatched=() + + if [ -f "$verListFile" ]; then + while read -r line || [[ -n "$line" ]]; do + read -a params <<< $line + # parse line into space-separted parameters then discard any that don't begin with / + # this strips all comments beginning with # as well as any leading or trailing spaces + for param in ${params[@]} ; do + case $param in + /*) + tempListVer+=("$param") + ;; + esac + done + done < "$verListFile" + fi + if [ -f "$indListFile" ]; then + while read -r line || [[ -n "$line" ]]; do + read -a params <<< $line + for param in ${params[@]} ; do + case $param in + /*) + tempListInd+=("$param") + ;; + esac + done + done < "$indListFile" + fi + if [ -f "$patchListFile" ]; then + while read -r line || [[ -n "$line" ]]; do + read -a params <<< $line + for param in ${params[@]} ; do + case $param in + /*) + tempListPatched+=("$param") + ;; + esac + done + done < "$patchListFile" + fi + + # remove duplicate files from each list + fileList=($(printf "%s\n" "${tempListVer[@]}" | sort -u)) + fileListVersionIndependent=($(printf "%s\n" "${tempListInd[@]}" | sort -u)) + fileListPatched=($(printf "%s\n" "${tempListPatched[@]}" | sort -u)) + tempListAll=(${fileList[@]}) + tempListAll+=(${fileListVersionIndependent[@]}) + tempListAll+=(${fileListPatched[@]}) + fileListAll=($(printf "%s\n" "${tempListAll[@]}" | sort -u)) +} + + +# yesNoPrompt provides user prompting requesting a yes/no response +# +# $1 is the prompt displayed when pausing for user input +# +# $yesResponse is set to true if the response was yes +# +# returns 0 for yes, 1 for no + +yesNoPrompt () +{ + response='' + while true; do + /bin/echo -n "$*" + read response + case $response in + [yY]*) + yesResponse=true + return 0 + break + ;; + [nN]*) + yesResponse=false + return 1 + break + ;; + *) + esac + done +} + + +# standardActionPrompt provides the standard set of options for selecting script's action +# scriptAction is set by install/uninstall +# other actions are handled locally, including quitting from the script +# +# if nonstandard prompts are necessary, duplicate this code in the setup script +# and add the additional options and do not call standardActionPrompt +# +# the reinstall option is permitted only if setup options were previously set +# if the the reinstall action is choosen, the script action is set to INSTALL +# the setup script can then test this to skip further prompts +# +# $1 indicates if there are additional prompts needed during installaiton +# if this parameter is 'MORE_PROMPTS', installaiton does NOT change scriptAction +# if this parameter does not exist, installation WILL change scriptAction to INSTALL +# this provides backaward compatibility with scripts written prior to the reinstall logic +# + +standardActionPrompt () +{ + if [ $# -gt 0 ] && [ $1 == 'MORE_PROMPTS' ]; then + updateScriptAction=false + else + updateScriptAction=true + fi + + echo + echo "Available actions:" + # don't allow install choice if incompatibilities have already been detected + if ! $installFailed ; then + echo " Install and activate (i)" + fi + if $optionsSet ; then + echo " Reinstall (r) based on options provided at last install" + fi + echo " Uninstall (u) and restores all files to stock" + echo " Quit (q) without further action" + echo " Display setup log (s) outputs the last 100 lines of the log" + if [ ! -z $packageLogFile ]; then + echo " Display Log (l) outputs the last 100 lines of the log" + fi + echo + response='' + while true; do + /bin/echo -n "Choose an action from the list above: " + read response + case $response in + [iI]*) + if ! $installFailed ; then + if $updateScriptAction ; then + scriptAction='INSTALL' + fi + break + fi + ;; + [rR]*) + if $optionsSet ; then + scriptAction='INSTALL' + break + fi + ;; + [uU]*) + scriptAction='UNINSTALL' + break + ;; + [qQ]*) + exit $EXIT_SUCCESS + ;; + [lL]*) + displayLog $packageLogFile + ;; + [sS]*) + displayLog $setupLogFile + ;; + *) + esac + done +} + + +# setInstallFailed sets flags to prevent further install steps +# and insure the package is uninstalled completely +# +# $1 indicates the reason for the failure and will evenutally be uused +# report the failure reason when exiting the script +# +# any remaining paremeters are passed to logMessage +# +# the UNINSTALL scriptAction is used so that older package setup scripts +# will restore everything it has modified (not using updateActiveFile, etc) +# +# also test $installFailed to see if this was an install failure +# or an actuall uninstall + +setInstallFailed () +{ + installFailed=true + scriptAction='UNINSTALL' + if [ ! -z "$1" ]; then + installExitReason=$1 + fi + message="${@:2}" + if [ ! -z "$message" ]; then + logMessage "$message" + fi +} + + +# backupActiveFile makes a copy of the active file in file.orig +# if the original file does not exist the NO_ORIG flag is set +# to allow restoreAcive file to remove the active file +# +# if the backup (.orig file) exists the backup is not ukpdated +# +# $1 is the full path/file name to be backed up +# +# returns 0 if backup was made, 1 if not +# + +backupActiveFile () +{ + # don't do any work if install has already failed + if $installFailed ; then + return 1 + fi + + baseName=$(basename $1) + if [ -e "$1.orig" ] || [ -e "$1.NO_ORIG" ]; then + return 1 + elif [ ! -f "$1" ]; then + touch "$1.NO_ORIG" + return 0 + else + cp "$1" "$1.orig" + rm -f "$1.NO_ORIG" + return 0 + fi +} + + +# SetupHelper maintains a set of "restart flags" +# that control service restarts and system reboot +# after the package has been installed / uninstalled +# +# some restarts/reboots are based on the directory of the modified file +# others are based on the actual file itself +# +# not all services or specific files are flagged so some work in the setup script may be needed +# +# $1 is the full path and name to the modified file + +updateRestartFlags () +{ + # flag indicating any file update occurred + filesUpdated=true + + case $1 in + /opt/victronenergy/gui*) + restartGui=true + return;; + #### TODO: add gui-v2 + /opt/victronenergy/dbus-generator-starter/*) + restartGeneratorService=true + return;; + /opt/victronenergy/dbus-systemcalc-py/*) + restartSystemCalc=true + return;; + /opt/victronenergy/dbus-digitalinputs/*) + restartDigitalinputs=true + return;; + + /u-boot/overlay./*) # Raspberry PI DT overlay + rebootNeeded=true + return;; + /etc/udev/rules.d/*) # udev rules directory + rebootNeeded=true + return;; + esac + + # reboots based on specific file + case $( basename $1 ) in + gpio_list) + rebootNeeded=true + return;; + config.txt) + rebootNeeded=true + return;; + esac +} + + +# updateActiveFile first backs up the active file +# then copies the replacement (aka source) to the active file location (aka destination) +# +# two variations: +# +# updateActiveFile activeFile +# an attempt is made to locate the source (replacement) +# in the version directory or FileSets +# +# updateActiveFile sourceFile activeFile +# a separate source (replacement) file is specified +# +# both sourceFile and activeFile must be a full path to the file +# +# if the update fails, scriptAction is changed to UNINSTALL +# +# global thisFileUpdated is set to true if file was updated, false if not +# thisFileUpdated supports the old mechanism which may be used in some setup scripts +# returns 0 if file was updated, 1 if not + + +updateActiveFile () +{ + thisFileUpdated=false + + # don't do any work if install has already failed + if $installFailed ; then + return 1 + fi + + # separate source and replacement files specified + local sourceFile="" + local activeFile="" + if [ $# == 2 ]; then + if [ -f "$1" ]; then + sourceFile="$1" + else + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: specified soure file "$1" does not exist - can't continue with install" + return 1 + fi + activeFile="$2" + # use active file for both source and destination + else + activeFile="$1" + fi + + local baseName=$(basename "$activeFile") + + # replacement files are not needed for some versions + # if so marked, leave original untouched + if [ -f "$fileSet/$baseName.USE_ORIGINAL" ]; then + return 1 + # source file not specified separately - look for it in expected places + elif [ -z "$sourceFile" ]; then + # first in patched files + if [ -f "$patchedFiles/$baseName" ]; then + sourceFile="$patchedFiles/$baseName" + # then in version-specific FileSet + elif [ -f "$fileSet/$baseName" ]; then + sourceFile="$fileSet/$baseName" + # then in version-independent file set + elif [ -f "$versionIndependentFileSet/$baseName" ]; then + sourceFile="$versionIndependentFileSet/$baseName" + # then in FileSets + elif [ -f "$pkgFileSets/$baseName" ]; then + sourceFile="$pkgFileSets/$baseName" + # nothing found - can't continue + else + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: no soure file for $baseName - can't continue with install" + return 1 + fi + fi + + local pathToFile=$(dirname "$activeFile") + if [ ! -e "$pathToFile" ]; then + # fatal if GUI v1 not present and needed for install + if [[ "$pathToFile" == "/opt/victronenergy/gui/"* ]]; then + if $guiV1required ; then + setInstallFailed $EXIT_NO_GUI_V1 "ERROR $packageName requires GUI v1 which is not on the system - can't continue" + # GUI v1 not needed - proceed without updating active file + fi + # active file is not in GUI v1 part of file system - so this is fatal + else + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: path to $activeFile does not exist - can't continue with install" + fi + return 1 + fi + + # attempt backup --if not made + # indicates installing over a previous install - so check if activeFile would be changed + # this would occur if installing over the top of an already installed package + # which SHOULD update the active file + # or a conflict with another package - OTHER PACKAGE'S MOD (active file) IS OVERWRITTEN SILENTLY !!!!!! + # or a previous install step failed (not relavant here -- already checked above) + if ! backupActiveFile "$activeFile" ; then + # check to see if active file needs to be updated + if [ -f "$activeFile" ]; then + # already updated - no change to active file + if cmp -s "$sourceFile" "$activeFile" > /dev/null ; then + return 1 + fi + fi + fi + + # all checks passed - update active file + if [ -e "$activeFile.orig" ] || [ -e "$activeFile.NO_ORIG" ]; then + # add file to installed files list (used for uninstallAll) + # do this before actually modifying things just in case there's an error + # that way the uninstall is assured + echo "$activeFile" >> "$installedFilesList" + cp "$sourceFile" "$activeFile" + + updateRestartFlags "$activeFile" + thisFileUpdated=true + return 0 + # backup missing (this should not ever happen) + else + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: no backup for $baseName - can't continue with install" + return 1 + fi +} + + +# restoreActiveFile moves the backup copy to the active location +# if the backup copy doesn't exist BUT the NO_ORIG flag is set +# the active copy is deleted to restore the system to stock +# $1 is the active name, the one to be backed up +# +# returns 0 if active file was restored, 1 if not +# also sets thisFileUpdated for backwards compatibility with existing setup scripts + +restoreActiveFile () +{ + thisFileUpdated=false + + local baseName="$(basename $1)" + if [ -e "$1.orig" ]; then + mv -f "$1.orig" "$1" + rm -f "$1.NO_ORIG" + thisFileUpdated=true + elif [ -f "$1.NO_ORIG" ]; then + rm -f "$1" + rm -f "$1.NO_ORIG" + thisFileUpdated=true + fi + + if $thisFileUpdated ; then + # remove file from installed file list + if [ -f "$installedFilesList" ]; then + grep -v "$1" "$installedFilesList" | tee "$installedFilesList" > /dev/null + fi + updateRestartFlags "$1" + return 0 + else + return 1 + fi +} + + +# checkFileSets validates the file sets used to install package modifications +# +# If a file set for the current Venus OS version exists, the replacement files in that file set +# are usable as is and no further checks are needed. +# The COMPLETE flag file indicates that the file set was validated on the computer creating +# the file sets and all replacement files (or symlinks to other file sets) exist. +# No checks are needed for a COMPLETE file set. +# If not, an attempt is made to create a file set for the current Venus OS version +# If the new active files for the new version all match another version +# the new file set is populated automatically with replacement files from the other version +# and may be used with no further action +# If not, new file set is marked INCOMPLETE and installation failure information is set +# The package can not be installed on this Venus OS version +# +# Replacement files that have no original specify an "alternate original" that is used +# for version comparisons that locate an appropriate replacement + +# dummy routine for backward compatibility +# the actual work is now done in-line when CommonResources is sourced + +checkFileSets () +{ + return +} + +_checkFileSets () +{ + # no file sets - nothing to check + if ! [ -e "$pkgFileSets" ]; then return; fi + + # no checks needed if all replacement files exist in the selected file set + if [ -f "$fileSet/COMPLETE" ]; then return; fi + + # sort versionList in reverse version order to make searches faster + # since newer versions will most likely contain the desired files to create a new file set + local rawVersionList=($(ls -d "$pkgFileSets"/v* 2> /dev/null)) + local tempList=() + local fs + local baseName + local version + local versionNumber + for fs in ${rawVersionList[@]} ; do + version=$(basename $fs) + versionStringToNumber $version + tempList+=("$version:$versionNumber") + done + local versionList=( $(echo ${tempList[@]} | tr ' ' '\n' | sort -t ':' -r -n -k 2 | uniq ) ) + + # versioned file sets exist but empty file list + if [ ! -z $versionList ] && [ -z $fileList ]; then + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: versions exist, but empty file list - can't continue" + return + # no versioned file sets - nothing to validate - allow install + elif [ -z $versionList ]; then return; fi + + # attempt to create a new file set or validate an existing one not marked as COMPLETE + + rm -f "$fileSet/INCOMPLETE" + + # attempt to create file set if it doesn't exist + if [ ! -d "$fileSet" ]; then + logMessage "creating a new file set for $venusVersion" + mkdir "$fileSet" + fi + + for file in ${fileList[@]} ; do + baseName=$(basename "$file") + + # version-independent file exists + if [ -e "$versionIndependentFileSet/$baseName" ] || [ -e "$pkgFileSets/$baseName" ]; then + # no versioned files (only version-independent found) - skip version checks + if [ -z $( find "$fileSet"/v* -name $baseName ) ]; then + continue + # continue with tests if any versioned files exist + else + logMessage "WARNING $baseName versioned file exists - version-independent file will be ignored" + fi + fi + + # skip checks if replacement file already exists + # or if there is no replacement file needed + if [ -f "$fileSet/$baseName" ] || [ -f "$fileSet/$baseName.USE_ORIGINAL" ]; then + rm -f "$fileSet/$baseName.NO_REPLACEMENT" + continue + fi + + local activeFile + if [ -f "$altOrigFileDir/$baseName.ALT_ORIG" ]; then + activeFile=$(cat "$altOrigFileDir/$baseName.ALT_ORIG") + elif [ -f "$pkgFileSets/$baseName.ALT_ORIG" ]; then + activeFile=$(cat "$pkgFileSets/$baseName.ALT_ORIG") + else + activeFile=$file + fi + # package already installed, use .orig file for comparisons + if [ -f "$activeFile.orig" ]; then + activeFile="$activeFile.orig" + fi + + # can't process if no original (aka active) file exists in the file set + if [ ! -f "$activeFile" ]; then + logMessage "ERROR $venusVersion $baseName no active file" + touch "$fileSet/$baseName.NO_ACTIVE_FILE" + touch "$fileSet/INCOMPLETE" + continue + fi + + # if an active file exists look for a match in another file set + if [ ! -z "$activeFile" ]; then + matchFound=false + for entry in ${versionList[@]}; do + otherVersion=$(echo $entry | awk -F ':' '{print $1}') + + # skip this version + if [ "$venusVersion" = "$otherVersion" ]; then + continue + fi + + otherFile="$pkgFileSets/$otherVersion/$baseName" + + # skip symbolic links and nonexistent originals + if [ ! -f "$otherFile.orig" ] || [ -L "$otherFile.orig" ] ; then + continue + fi + + # files match + if cmp -s "$activeFile" "$otherFile.orig" > /dev/null ; then + matchFound=true + break + fi + done + + if $matchFound ;then + rm -f "$fileSet/$baseName.orig" + rm -f "$fileSet/$baseName.NO_ORIG" + # if other file set contains a replacement file, link to it + if [ -f "$otherFile" ]; then + rm -f "$fileSet/$baseName" + ln -s "../$otherVersion/$baseName" "$fileSet/$baseName" + rm -f "$fileSet/$baseName.NO_REPLACEMENT" + rm -f "$fileSet/$baseName.USE_ORIGINAL" + # if other file set does not contain a replacement, this one will not either + # this IS permitted and handled in the updateActiveFile and restoreActiveFile functions + elif [ -f "$otherFile.USE_ORIGINAL" ]; then + touch "$fileSet/$baseName.USE_ORIGINAL" + rm -f "$fileSet/$baseName.NO_REPLACEMENT" + fi + # no match to a previous verison - can't create file set automatically + # but copy original file to aid manual editing + else + logMessage "ERROR $venusVersion $baseName no replacement file" + cp "$activeFile" "$fileSet/$baseName.orig" + touch "$fileSet/$baseName.NO_REPLACEMENT" + touch "$fileSet/INCOMPLETE" + fi + fi + done + + if [ -f "$fileSet/INCOMPLETE" ]; then + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: incomplete file set for $venusVersion - can't continue" + # if we get this far and fs is not marked INCOMPLETE, then the file set does not need to be checked again next pass + else + touch "$fileSet/COMPLETE" + fi +} + +# builds the installedFilesList and installedServices lists from the package's setup script +# this is needed for installs with a prior version of SetupHelper that did not +# create the installed... lists +# +# uninstall... functions then use these lists to uninstall + +buildUninstallListsfromSetupScript () +{ + # prevent this from running a second time + if [ "$uninstallListsAlreadyBuilt" == 'yes' ]; then + return + fi + uninstallListsAlreadyBuilt='yes' + local param + + scriptUninstallFilesList=() + scriptUninstallServicesList=() + while read -r line || [[ -n "$line" ]]; do + commandFound=false + read -a params <<< $line + numberOfParams=${#params} + for (( i=0; i < $numberOfParams; i++ ));do + case "${params[i]}" in + updateActiveFile) + # parameter of intrest is the second one if it exists + # otherwise, it should be the first one + param=${params[i+2]} + if [ -z "$param" ] || [[ $param == \#* ]]; then + param=$( echo ${params[i+1]} | sed s?'$qmlDir'?$qmlDir? ) + fi + if ! [ -z "$param" ] && ! [[ $param == \#* ]]; then + scriptUninstallFilesList+=("$param") + fi + ;; + installService) + # parameter of intrest is the first one if it exists + # otherwise, is the packageName + param=${params[i+1]} + if ! [ -z "$param" ] && ! [[ $param == \#* ]]; then + scriptUninstallServicesList+=("$param") + else + scriptUninstallServicesList+=($packageName) + fi + ;; + esac + done + done < "$scriptDir/setup" +} + +# install / uninstall all files / services functions +# +# the install... functions are called from endScript if the related flags are set +# but may also be called in the setup script +# if processing needs to be done after the files are installed +# +# NOTE: uninstall functions are called in endScrpit during an uninstall +# there are no flags to control this ! +# +# NOTE: only services in the package's serice directory are installed +# any services in the package's root diretory are not installed + + +installAllFiles () +{ + if [ -z "$fileListAll" ]; then + getFileLists + fi + + if [ ! -z $fileListAll ]; then + logMessage "installing files" + local file + for file in ${fileListAll[@]}; do + updateActiveFile "$file" + done + fi +} + +# uninstall files from +# installed files list if present +# and from file lists in the package +# and from updateActiveFile calls found in the setup script +# this insures complete uninstall even for packages installed +# with SetupHelper prior to v6.0 + +uninstallAllFiles () +{ + local restoreFilesList=() + # add installdeFilesList if present (might be empty but that's fine) + if [ -f "$installedFilesList" ]; then + restoreFilesList=( $( cat "$installedFilesList" ) ) + fi + # add file lists & calls to installActiveFile in setup script + restoreFilesList+=( ${fileListAll[@]} ) + buildUninstallListsfromSetupScript + restoreFilesList+=( ${scriptUninstallFilesList[@]} ) + + # remove duplicates + if (( ${#restoreFilesList[@]} > 1 )); then + restoreFilesList=( $(printf "%s\n" "${restoreFilesList[@]}" | sort -u ) ) + fi + + # uninstall the files + if [ ! -z $restoreFilesList ]; then + logMessage "uninstalling files" + local file + for file in ${restoreFilesList[@]}; do + restoreActiveFile $file + done + fi +} + + +installAllServices () +{ + local serviceList + local service + # get list of services in the package's service directory + if [ -d "$servicesDir" ]; then + servicesList=$( cd "$servicesDir"; ls -d * 2> /dev/null ) + if [ ! -z $servicesList ]; then + logMessage "installing services" + for service in $servicesList ; do + installService $service + done + fi + fi +} + + +# uninstal services found in the services directory +# and restoreServices call in the package's setup script + +uninstallAllServices () +{ + local tempList=() + local servicesList=() + local service + + if [ -f "$installedServicesList" ]; then + servicesList=( $( cat "$installedServicesList" ) ) + fi + # add list from the setup script itself + buildUninstallListsfromSetupScript + servicesList+=( ${scriptUninstallServicesList[@]} ) + + # remove duplicates + if (( ${#servicesList[@]} > 1 )); then + servicesList=( $(printf "%s\n" "${servicesList[@]}" | sort -u ) ) + fi + + # uninstall services + if [ ! -z $servicesList ]; then + logMessage "uninstalling services" + for service in $servicesList ; do + if [ -z "$service" ]; then + removeService $packageName + else + removeService $service + fi + done + fi +} + + +# restart the GUI V1 service +# begining at about v3.20~18, changes were made to accommodate the gui-v2 +# and these changes require different handling of a GUI service restart + + +restartGuiV1Service () +{ + # gui is the older service that runs GUI v1 only + if [ -e "/service/gui" ]; then + svc -t "/service/gui" + # restart GUI if NOT running v2 or can't determine if GUI v1 or v2 is selected + elif [ -e "/service/start-gui" ]; then + guiVersion="$(dbus-send --system --print-reply --dest=com.victronenergy.settings /Settings/Gui/RunningVersion com.victronenergy.BusItem.GetValue | grep variant | awk '{print $3}')" + if (( $guiVersion != 2 )); then + svc -t "/service/start-gui" + fi + fi +} + +# for backward compatibility (oler setup scripts) +restartGuiService () +{ + restartGuiV1Service +} + +restartGuiV2Service () +{ + # restart GUI if NOT running v1 or can't determine if GUI v1 or v2 is selected + if [ -e "/service/start-gui" ]; then + guiVersion="$(dbus-send --system --print-reply --dest=com.victronenergy.settings /Settings/Gui/RunningVersion com.victronenergy.BusItem.GetValue | grep variant | awk '{print $3}')" + if (( $guiVersion != 1 )); then + svc -t "/service/start-gui" + fi + fi +} + +# determine how the setup script should exit based on $scriptAction and other flags +# services may be restarted here also +# +# endScript accepts these optional parameters which determines if files and/or services are installed +# +# 'INSTALL_FILES' causes files from the file lists to be installed +# 'INSTALL_SERVICES' causes services in the services directory to be installed +# all services must be in the package's services directory +# 'ADD_DBUS_SETTINGS' will add/update dBus settings from the DbusSettingsList +# any or may be included +# do NOT include these if related processing is needed in the setup script ! +# instead, call installAllFiles and/or installAllServices in line with the other processing +# or call updateActiveFile or installService directly +# +# this function completes package installation +# and sets up conditions for reinstallation following a Venus Os firmware update +# +# may EXIT or REBOOT within the function - DOES NOT RETURN TO CALLER + + +endScript () +{ + if [ $scriptAction == 'INSTALL' ] ; then + # do installs as indicated from caller + while (( $# > 0 )); do + case "$1" in + 'INSTALL_FILES') + installAllFiles + ;; + 'INSTALL_SERVICES') + installAllServices + ;; + 'ADD_DBUS_SETTINGS') + addAllDbusSettings + ;; + esac + shift + done + + # assume that if we get this far, any command line opitons have already been set + touch "$setupOptionsDir/optionsSet" + + # clear flag preventing auto installs in PackageManager + rm -f "$setupOptionsDir/DO_NOT_AUTO_INSTALL" + + # if script needs to run again, installedVersionFile flag file is removed + # script should run again at boot time via reinstallMods + if $runAgain ; then + logMessage "script will run again at startup" + rm -f "$installedVersionFile" + # otherwise, installation is complete - update installedVersion + else + cp "$scriptDir/version" "$installedVersionFile" + fi + + # update rc.local to include call to reinstallMods + # do only for SetupHelper since other packages are now installed by PackageManager + if ! $installFailed && [ "$packageName" == "SetupHelper" ]; then + if [ ! -f "$rcLocal" ]; then + logMessage "creating $rcLocal" + cp "$scriptDir/rcS.local" "$rcLocal" + chmod +x "$rcLocal" + elif [ $(grep -c "blind install" "$rcLocal") -gt 0 ]; then + logMessage "REPLACING blind install $rcLocal with the standard one" + rm -f "$rcLocal" + cp "$scriptDir/rcS.local" "$rcLocal" + chmod +x "$rcLocal" + elif [ $(grep -c "SetupHelper" "$rcLocal") == 0 ]; then + logMessage "adding SetupHelper reinstall script to $rcLocal" + sed -e '2d' "$scriptDir/rcS.local" >> $rcLocal + fi + fi + fi + + + if [ $scriptAction == 'UNINSTALL' ] ; then + + # package was actually uninstalled (not an install failure) - set flag preventing auto installs + if ! $installFailed ; then + touch "$setupOptionsDir/DO_NOT_AUTO_INSTALL" + fi + + # ALWAYS attempt to uninstall files and services + uninstallAllFiles + uninstallAllServices + + # flag package not installed since package is being removed + rm -f "$installedVersionFile" + + # when uninstalling SetupHelper, remove EMPTY installed...Lists in all packages + # to prevent a future install with an older SetupHelper + # confusing a future future uninstall with a new SetupHelper + if [ "$packageName" == "SetupHelper" ] && [ -e "$installedFilesDir" ]; then + for file in $(ls "$installedFilesDir") ; do + if ! [ -s "$installedFilesDir/$file" ]; then + rm "$installedFilesDir/$file" + fi + done + # remove lines from rcS.local + sed -i -e "/# SetupHelper reinstall/,/fi/d" "$rcLocal" + + fi + fi + + # setup script signals nothing to do - exit without further action without errors + if [ $scriptAction == 'EXIT' ]; then + exit $EXIT_SUCCESS + elif ! [ $scriptAction == 'INSTALL' ] && ! [ $scriptAction == 'UNINSTALL' ]; then + logMessage "unexpected script action $scriptAction - did not install or uninstall" + exit $EXIT_SUCCESS + fi + + # remove temp directory used in installs of files requiring modificaion before installing + rm -rf "$patchedFiles" + + # if installation was attempted but failed, exit without checking anything else + # or signaling GUI restart or reboot + if $installFailed ; then + logMessage "installation failed - package has been uninstalled - exiting" + exit $installExitReason + elif $rebootNeeded ; then + if $userInteraction ; then + if yesNoPrompt "Reboot system now (y) or do it manually later (n): " ; then + logMessage "rebooting ..." + reboot + else + logMessage "system must be rebooted to finish installation and activate components" + exit $EXIT_REBOOT + fi + else + logMessage "completed - reboot needed" + exit $EXIT_REBOOT + fi + fi + if $restartGeneratorService ; then + logMessage "restarting generator service" + svc -t /service/dbus-generator-starter + fi + if $restartSystemCalc ; then + logMessage "restarting systemcalc service" + svc -t /service/dbus-systemcalc-py + fi + if $restartDigitalinputs ; then + logMessage "restarting digital inputs service" + svc -t /service/dbus-digitalinputs + fi + #### TODO: add gui v2 + if $restartGui ; then + if $userInteraction ; then + if yesNoPrompt "Restart the GUI now (y) or issue a do it manually later (n): " ; then + logMessage "completed - restarting GUI" + restartGuiV1Service + exit $EXIT_SUCCESS + else + echo "GUI must be restarted to activate components" + exit $EXIT_RESTART_GUI + fi + else + if $deferGuiRestart ; then + logMessage "completed - GUI restart needed" + exit $EXIT_RESTART_GUI + # GUI restart NOT deferred - do it now + else + logMessage "completed - restarting GUI" + restartGuiV1Service + exit $EXIT_SUCCESS + fi + fi + fi + logMessage "completed" + exit $EXIT_SUCCESS +} + +######## this code is executed in-line when CommonResources is sourced + +# check for reinstall parameter +# set $scriptAction to control work following the source command +# if "force" is also provided on the command line, then the installedVersionFile is not checked +# installedVersionFile contains the installed version (if any) +# it is compared to the version file in the package directory +# if installedVersionFile is missing or contents are different, the installation will proceed +# if the two versions match, there is no need to reinstall the package +# we assume a reinstall is always run without benefit of a console (runningAtBoot will be true) +# so there will be no prompts and all actions will be automatic +# +# "deferReboot" signals that endScript should not reboot the system, but return EXIT_REBOOT +# assuming the caller will evenutally reboot the system +# +# "deferGuiRestart" is similar for restarting the GUI +# +# "install" causes the package to be installed silently +# "uninstall" causes the package to be uninstalled silently +# +# command line parameters may appear in any order +# +# +# logToConsole is set to true in the LogHandler script +# It is set to false here the 'auto' parameter is passed on the command line +# which indicates this script is NOT being run from the command line + +# move old installedFlag ("...inInstalled...") +# to its new name ...installedVersionFile... +if [ ! -f "$installedVersionFile" ] && [ -f "$installedFlag" ]; then + installedVersion=$(cat "$installedFlag") + if [ -z $installedVersion ]; then + installedVersion="" + else + echo $installedVersion > "$installedVersionFile" + fi +fi +rm -f "$installedFlag" + +# cleanup from previous versions - reinstallScriptsList no loner used +rm -f "/data/reinstallScriptsList" + +# set global machine type +if [ -f /etc/venus/machine ]; then + machine=$(cat /etc/venus/machine) +else + machine="" + setInstallFailed $EXIT_INCOMPATIBLE_VERSION "can't determine Venus device type" +fi + +# initialize version strings and numbers for future checks +if [ -f "$installedVersionFile" ]; then + installedVersion=$(cat "$installedVersionFile") + versionStringToNumber $installedVersion + installedVersionNumber=$versionNumber +else + installedVersion="" + installedVersionNumber=0 +fi + +packageVersionFile="$scriptDir/version" +if [ -f "$packageVersionFile" ]; then + packageVersion=$(cat "$packageVersionFile") + + versionStringToNumber $packageVersion + packageVersionNumber=$versionNumber +else + packageVersion="" + packageVersionNumber=0 +fi + +logMessage "--- starting setup script $packageVersion" + +# collect command line options +reinstall=false +force=false +deferReboot=false +deferGuiRestart=false +userInteraction=true +while [ $# -gt 0 ]; do + case $1 in + "reinstall") + reinstall=true + ;; + "force") + force=true + ;; + "deferReboot") + deferReboot=true + ;; + "deferGuiRestart") + deferGuiRestart=true + ;; + "install") + scriptAction='INSTALL' + ;; + "uninstall") + scriptAction='UNINSTALL' + ;; + "auto") + logToConsole=false + userInteraction=false + ;; + *) + esac + shift +done + +# make sure rootfs is mounted R/W & and resized to allow space for replacement files +# arbitrary minimum size of 3 MB +rootMinimumSize=3 +availableSpace=$(df -m / | tail -1 | awk '{print $4}') + +# remount read-write +if (( $(mount | grep ' / ' | grep -c 'rw') == 0 )); then + # only remount read-write for CCGX + if [ "$machine" == "ccgx" ]; then + if [ -f /opt/victronenergy/swupdate-scripts/remount-rw.sh ]; then + logMessage "remounting root read-write" + /opt/victronenergy/swupdate-scripts/remount-rw.sh + fi + # remount and resize for other platforms + elif [ -f /opt/victronenergy/swupdate-scripts/resize2fs.sh ]; then + /opt/victronenergy/swupdate-scripts/resize2fs.sh + availableSpace=$(df -m / | tail -1 | awk '{print $4}') + logMessage "remounting read-write root and resizing - $availableSpace MB now available" + fi + # check to see if remount was successful + if (( $(mount | grep ' / ' | grep -c 'rw') == 0 )); then + logMessage "ERROR: unable to remount root read-write - can't continue" + exit $EXIT_ROOT_FULL + fi +# root already read-write, attempt to resize if space is limited (CCGX can't resize) +elif (( $availableSpace < $rootMinimumSize )); then + if [ "$machine" == "ccgx" ]; then + logMessage "can't resize root on CCGX" + else + if [ -f /opt/victronenergy/swupdate-scripts/resize2fs.sh ]; then + /opt/victronenergy/swupdate-scripts/resize2fs.sh + availableSpace=$(df -m / | tail -1 | awk '{print $4}') + logMessage "resized root - $availableSpace MB now available" + fi + fi +fi +# make sure the root partition has space for the package +if (( $availableSpace < $rootMinimumSize )); then + logMessage "no room for modified files on root ($availableSpace MB remaining) - can't continue" + exit $EXIT_ROOT_FULL +fi + + +# packages that require options to proceed unattended +# must include the optionsRequried flag file in their package directory +# if the flag is present and options haven't been previously set, +# SD/USB media will be checked for the package options directory +# and copy them into position + +opitonsRequiredFile="$scriptDir/optionsRequired" +optionsSet=false +if [ -f $opitonsRequiredFile ]; then + if [ -f "$setupOptionsDir/optionsSet" ]; then + optionsSet=true + # options not set - check media for options if doing a blind install + elif [ $scriptAction == 'INSTALL' ]; then + mediaList=($(ls /media)) + for dir in ${mediaList[@]} ; do + altSetupDir="/media/$dir/"$(basename $setupOptionsRoot)"/$packageName" + if [ -f "$altSetupDir/optionsSet" ]; then + cp -r "$altSetupDir" "$setupOptionsRoot" + if [ -f "$setupOptionsDir/optionsSet" ]; then + logMessage "options retrieved from SD/USB media" + optionsSet=true + fi + break + fi + done + fi + +# no command line options are needed - ok to reinstall even if +# setup was not run from the command line +else + optionsSet=true +fi + + +# called from reinstallMods at boot time +if $reinstall ; then + runningAtBoot=true + if $force ; then + scriptAction='INSTALL' + # not installed, do it now + elif (( installedVersionNumber == 0 )); then + scriptAction='INSTALL' + # check versions and install only if package version is newer than installed version + else + # trigger install if version numbers differ + if (( installedVersionNumber != packageVersionNumber )); then + scriptAction='INSTALL' + else + exit $EXIT_SUCCESS + fi + fi + +# not running from reinstallMods +else + runningAtBoot=false + pruneSetupLogFile +fi + +# initialze integer version number for venus version +# used below and in _checkFileSets +versionStringToNumber $venusVersion +venusVersionNumber=$versionNumber + +# create obsolete version file if it does not already exist +# accommodates previous mechanism that used shell varaible +if [ ! -z $obsoleteVersion ] && [ ! -f "$scriptDir/obsoleteVersion" ]; then + echo $obsoleteVersion > "$scriptDir/obsoleteVersion" +fi + + +# prevent installing Raspberry Pi packages on other platforms +if [ -f "$scriptDir/raspberryPiOnly" ]; then + if [[ $machine != *"raspberrypi"* ]]; then + setInstallFailed $EXIT_INCOMPATIBLE_PLATFORM "$packageName not compatible with $machine" + fi +fi + +# check to see if package is compatible with this Venus version +if [ -f "$scriptDir/firstCompatibleVersion" ]; then + firstCompatibleVersion=$(cat "$scriptDir/firstCompatibleVersion") +# no first compatible version specified - use the default +else + firstCompatibleVersion='v2.71' +fi + +versionStringToNumber $firstCompatibleVersion +firstCompatibleVersionNumber=$versionNumber +if (( $venusVersionNumber < $firstCompatibleVersionNumber )); then + setInstallFailed $EXIT_INCOMPATIBLE_VERSION "ERROR $venusVersion before first compatible $firstCompatibleVersion" +elif [ -f "$scriptDir/obsoleteVersion" ]; then + obsoleteVersion=$(cat "$scriptDir/obsoleteVersion") + versionStringToNumber $obsoleteVersion + obsoleteVersionNumber=$versionNumber + if (( $venusVersionNumber >= $obsoleteVersionNumber )); then + setInstallFailed $EXIT_INCOMPATIBLE_VERSION "ERROR $venusVersion after last compatible $obsoleteVersion" + fi +fi +if ! $installFailed ; then + if [ ! -d "$setupOptionsDir" ]; then + logMessage "creating package options directory $setupOptionsDir" + mkdir -p $setupOptionsDir + fi +fi + +# if checks above passed and uninstall was not specified on command line, +# do final checks before permitting install +if [ $scriptAction != 'UNINSTALL' ]; then + + # determine if GUI v1 is installed + # Note, it may NOT be running or selected to run!!!! + if [ ! -d "/opt/victronenergy/gui" ]; then + guiV1present=false + else + guiV1present=true + fi + + # block installs if any GUI files would be modified and GUI v1 is not present + # packages can bypass GUI v1 checks and allow installs even if package contains them + if [ -f "$scriptDir/GUI_V1_NOT_REQUIRED" ]; then + guiV1required=false + # files in the GUI v1 directory are considered mandatory + elif (( $( cat "$pkgFileSets/fileList"* 2>/dev/null | grep -c '/gui/' ) > 0 )); then + guiV1required=true + # look also in setup script + elif (( $( grep 'updateActiveFile' "$scriptDir/setup" | grep -c '$qmlDir\|/gui/') > 0 )); then + guiV1required=true + else + guiV1required=false + fi + + if ! $guiV1present && $guiV1required ; then + setInstallFailed $EXIT_NO_GUI_V1 "ERROR $packageName requires GUI v1 which is not on the system - can't install" + fi + + # attempting an install without the comand line prompting + # and needed options have not been set yet - can't continue + if [ $scriptAction == 'INSTALL' ]; then + if ! $optionsSet ; then + setInstallFailed $EXIT_OPTIONS_NOT_SET "ERROR required options have not been set - can't install" + endScript + fi + fi + getFileLists "$pkgFileSets" + + _checkFileSets + + + # create installed files (and services) directory + if [ ! -d "$installedFilesDir" ]; then + mkdir "$installedFilesDir" + fi + + # location of patch output - used as the replacement file (unique temp directory in volatile storage) + patchedFiles=$( mktemp -d ) + + # create patched files for files with VisibleItemModel for older Venus OS versions + versionStringToNumber "v3.00~14" + if (( $venusVersionNumber < $versionNumber )); then + logMessage "patching VisibleItemModel to VisualItemModel in all .qml replacements" + for file in ${fileListVersionIndependent[@]}; do + baseName=$( basename "$file" ) + if ! [[ "$baseName" == *.qml ]]; then continue; fi + sourceFile="$versionIndependentFileSet/$baseName" + if ! [ -f "$sourceFile" ]; then continue; fi + if (( $(grep -c "VisibleItemModel" "$sourceFile") == 0 )); then continue; fi + sed -e 's/VisibleItemModel/VisualItemModel/' "$sourceFile" > "$patchedFiles/$baseName" + done + fi + + # create patched files in fileListPatched + for file in ${fileListPatched[@]}; do + baseName=$( basename $file ) + patchFile="$patchSourceDir/$baseName.patch" + if ! [ -f "$file" ]; then + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: original file missing for $baseName - can't continue with install" + endScript + fi + if ! [ -f "$patchFile" ]; then + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: patch file missing for $baseName - can't continue with install" + endScript + fi + # BusyBox patch doesn't support the -o option so copy source to output first + # then patch the output + # if package already installed, patch .orig + if [ -e "$file.orig" ]; then + cp "$file.orig" "$patchedFiles/$baseName" + # if package probably not installed, patch the active file + elif [ -e "$file" ] ; then + cp "$file" "$patchedFiles/$baseName" + else + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: no source for $baseName patch - can't continue with install" + endScript + fi + if ! patch "$patchedFiles/$baseName" "$patchFile" &> /dev/null ; then + setInstallFailed $EXIT_FILE_SET_ERROR "ERROR: could not patch $baseName - can't continue with install" + endScript + fi + done +fi + +#### do standard prompting, automatic install/uninstall then exit +if [ "$standardPromptAndActions" == 'yes' ]; then + # prompt only if action hasn't been set yet (from command line) + if [ "$scriptAction" == 'NONE' ]; then + standardActionPrompt + fi + endScript 'INSTALL_FILES' 'INSTALL_SERVICES' 'ADD_DBUS_SETTINGS' +fi + +# otherwise continue with the setup script + +#### continue executing the setup script which sourced this file + + + diff --git a/HelperResources/DbusSettingsResources b/HelperResources/DbusSettingsResources new file mode 100755 index 0000000..d1cd1c4 --- /dev/null +++ b/HelperResources/DbusSettingsResources @@ -0,0 +1,211 @@ +#!/bin/bash + +# DbusSettingsResources for SetupHelper +# +# contains a functions and variables necessary to access dbus Settings parameters +# it should be sourced by scripts setting, creating and removing dbus settings +# +# dbus Settings is not operational during system boot when some setup scripts may +# need to make settings changes +# These functions check to see if the settings system is operational and defer +# the set/create/remove activity so the calling script may continue + +# dbus Settings funcitons +# These functions encapsulate an interface to dbus Settings +# NOTE: dbus Settings resources are not always active when it is necessary for +# scripts to make changes or create/remove settings +# it is up to the caller to insure dbus Settings resources are active before callling +# these functions +# a dbus exeption error will be logged if settings are not active yet + + +# updateDbusStringSetting +# updateDbusIntSetting +# updateDbusRealSetting +# updates a dbus setting parameter with a new value +# +# if the setting does not exist, it is created +# but max and min values are not set and the default is "", 0 or 0.0 depending on data type +# if these are needed use the dbus command directly +# this can also be faster if lots of settings must be created at the same time +# +# other data types may exist and would need their own function +# +# $1 is the path to the setting starting with /Settings +# $2 is the new value +# +# if the setting does not yet exist, it is created, then updated to the new value + +updateDbusStringSetting () +{ + # don't do any work if install has already failed + if $installFailed; then + return + fi + + dbus-send --system --print-reply=literal --dest=com.victronenergy.settings "$1"\ + com.victronenergy.BusItem.GetValue &> /dev/null + if (( $? != 0 )); then + logMessage "creating dbus Setting $1" + dbus -y com.victronenergy.settings / AddSettings "%[ {\"path\":\"$1\", \"default\":\"\"} ]" &> /dev/null + fi + + dbus -y com.victronenergy.settings "$1" SetValue "$2" &> /dev/null +} + + +updateDbusIntSetting () +{ + # don't do any work if install has already failed + if $installFailed; then + return + fi + + dbus-send --system --print-reply=literal --dest=com.victronenergy.settings "$1"\ + com.victronenergy.BusItem.GetValue &> /dev/null + if (( $? != 0 )); then + logMessage "creating dbus Setting $1" + dbus -y com.victronenergy.settings / AddSettings "%[ {\"path\":\"$1\", \"default\":0} ]" &> /dev/null + fi + + dbus -y com.victronenergy.settings "$1" SetValue "$2" &> /dev/null +} + + +updateDbusRealSetting () +{ + # don't do any work if install has already failed + if $installFailed; then + return + fi + + dbus-send --system --print-reply=literal --dest=com.victronenergy.settings "$1"\ + com.victronenergy.BusItem.GetValue &> /dev/null + if (( $? != 0 )); then + logMessage "creating dbus Setting $1" + dbus -y com.victronenergy.settings / AddSettings "%[ {\"path\":\"$1\", \"default\":0.0} ]" &> /dev/null + fi + + dbus -y com.victronenergy.settings "$1" SetValue "$2" &> /dev/null +} + + + +# addAllDbusSettings adds settings from DbusSettingsList in the package directory +# the format of each line is: +# {"path":"/Settings/GuiMods/ShortenTankNames", "default":1, "min":0, "max":1} +# min and max are optional + +addAllDbusSettings () +{ + local settings + + if [ -f "$scriptDir/DbusSettingsList" ]; then + logMessage "updating dbus Settings" + while read -r line || [[ -n "$line" ]]; do + settings+="$line, " + done < "$scriptDir/DbusSettingsList" + + dbus -y com.victronenergy.settings / AddSettings "%[ $settings ]" &> /dev/null + fi +} + +# same as above but removes them +# typically settings are retained when removing a package so +# the developer must make this call specifically in the setup script's UNINSTALL section +# if they wish to remove the settings + +removeAllDbusSettings () +{ + local settings + + if [ -f "$scriptDir/DbusSettingsList" ]; then + logMessage "removing dbus Settings" + while read -r line || [[ -n "$line" ]]; do + settings+=$( echo $line | awk -F[:,] '{print $2, ","}' ) + done < "$scriptDir/DbusSettingsList" + + dbus -y com.victronenergy.settings / RemoveSettings "%[ $settings ]" + fi +} + + + +# removeDbusSettings removes the setting from dbus Settings +# +# all parameters are each a quoted path to the setting to be removed +# e.g., removeDbusSettings "/Settings/foo" "/Settings/bar" +# (including all settings in one dbus call is much faster) + +removeDbusSettings () +{ + logMessage "removing dbus Settings $@" + local settings=$(echo "$@" | sed -e s_^_\"_ -e s_\$_\"_ -e s_\ _'", "'_g) + dbus -y com.victronenergy.settings / RemoveSettings "%[ $settings ]" &> /dev/null +} + + +# setSetting updates the dbus setting parameter +# the setting must already exist or the update will fail +# (the setting can not be created without knowing the data type(s)) +# +# $1 is the new value +# $2 is the setting path + +setSetting () +{ + # don't do any work if install has already failed + if $installFailed; then + return + fi + + dbus -y com.victronenergy.settings $2 SetValue $1 &> /dev/null +} + +# move a setting from setup options or from previous dbus Setting +# $1 is the setup options path +# $2 is the old dbus path (has priority over setup option) +# $3 is the new dbus path +# dbus paths start with /Settings +# if specified, the setup option file must include a value +# that value has priority over the old dbus parameter +# +# setup options can either contain a value or be a flag file +# for flag files, the file will be empty and the state of the option +# depends on the presence of the file (true) or absense of the file (false) +# +# Note: this function does NOT create or remove any old option or Setting +# use other functions or commands to do so + +moveSetting () +{ + # don't do any work if install has already failed + if $installFailed; then + return + fi + + local setupOption="$1" + local oldDbusPath=$2 + local newDbusPath=$3 + + if [ ! -z "$oldDbusPath" ]; then + oldSetting=$(dbus-send --system --print-reply=literal --dest=com.victronenergy.settings\ + $oldDbusPath com.victronenergy.BusItem.GetValue 2> /dev/null | awk '{print $3}') + elif [ ! -z $setupOption ]; then + if [ -f "$setupOption" ]; then + oldSetting=$(cat "$setupOption") + # flag file - old setting is true (1) + if [ -z $oldSetting ]; then + oldSetting=1 + fi + # file did not exist - assume a false value for a flag file + else + oldSetting=0 + fi + else + oldSetting="" + fi + if [ ! -z $oldSetting ] && [ ! -z "$newDbusPath" ]; then + dbus -y com.victronenergy.settings $newDbusPath SetValue $oldSetting &> /dev/null + fi +} diff --git a/HelperResources/EssentialResources b/HelperResources/EssentialResources new file mode 100755 index 0000000..24dd56b --- /dev/null +++ b/HelperResources/EssentialResources @@ -0,0 +1,79 @@ +#!/bin/bash + +# EssentialResources for SetupHelper +# contains a variables necessary for all setup helper scripts +# +# sourced from CommonResources, UpdateResources and reinstallMods +# and also updateFileSets + +# get the full, unambiguous path to this script (and therefore to script that sourced it) +scriptDir="$( cd "$(dirname $0)" >/dev/null 2>&1 ; /bin/pwd -P )" +packageRoot="$( dirname $scriptDir )" +packageName=$( basename "$scriptDir" ) + +shortScriptName=$(basename "$scriptDir")/$(basename "$0") +fullScriptName="$scriptDir/$(basename "$0")" + +if [ -f "/opt/victronenergy/version" ]; then + venusVersion="$(cat /opt/victronenergy/version | head -n 1)" +else + venusVersion="" +fi + +installedVersionPrefix="/etc/venus/installedVersion-" +installedVersionFile="$installedVersionPrefix"$packageName + +installedFilesDir="/etc/venus/installedModifications" +installedFilesList="$installedFilesDir/installedFiles"-$packageName +installedServicesList="$installedFilesDir/installedServices"-$packageName + + +# obsolete - use installedVersion +installedFlagPrefix="/etc/venus/inInstalled-" +installedFlag="$installedFlagPrefix"$packageName + +# set up pointers to package files +# based on the actual package for compatibility with older packages +pkgFileSets="$scriptDir/FileSets" +fileSet="$pkgFileSets/$venusVersion" +versionIndependentFileSet="$pkgFileSets/VersionIndependent" +# location of patch files +patchSourceDir="$pkgFileSets/PatchSource" +altOrigFileDir="$pkgFileSets/AlternateOriginals" + +servicesDir="$scriptDir/services" + + +# rc local file that calls reinstallMods +# rcS.local avoids conflicts with mods that blindly replace /data/rc.local +rcLocal="/data/rcS.local" + +# defined exit codes - must be consistent between all setup scripts and reinstallMods +# and PackageManager.py +EXIT_SUCCESS=0 +EXIT_REBOOT=123 +EXIT_RESTART_GUI=124 +EXIT_ERROR=255 # unknown error +EXIT_INCOMPATIBLE_VERSION=254 +EXIT_INCOMPATIBLE_PLATFORM=253 +EXIT_FILE_SET_ERROR=252 +EXIT_OPTIONS_NOT_SET=251 +EXIT_RUN_AGAIN=250 +EXIT_ROOT_FULL=249 +EXIT_DATA_FULL=248 +EXIT_NO_GUI_V1=247 +# old variables - keep for compatibility +exitReboot=$EXIT_REBOOT +exitSuccess=$EXIT_SUCCESS + +# directory that holds script's options +# options were removed from the script directory so they are preserved when the package is reinstalled +setupOptionsRoot="/data/setupOptions" +setupOptionsDir="$setupOptionsRoot"/$packageName + +# packages managed by SetupHelper +packageListFile="/data/packageList" + +qmlDir=/opt/victronenergy/gui/qml + + diff --git a/HelperResources/IncludeHelpers b/HelperResources/IncludeHelpers new file mode 100755 index 0000000..a9ca229 --- /dev/null +++ b/HelperResources/IncludeHelpers @@ -0,0 +1,65 @@ +#!/bin/sh + +# this script selects the correct location for helper Resources +# and sources them into the setup script +# +# for backward compatibility, CommonResources in the SetupHelper directory +# links to this file, not CommonResources +# CommonResources previously sourced the other files +# now sourcing all resource files is done from here +# +# the helper files location is either the package directory or in the SetupHelper directory +# if both are present, the one with the newer version number is incorporated +# into the setup script +# +# this script should be sourced in the setup script before any other activities + +# NOTE: this script uses VersionResources ONLY +# it does source any other helper files since final location has not yet been chosen + +pkgDir=$( dirname $0 ) +pkgName=$( basename $pkgDir ) +shDir=$( dirname "$pkgDir" )/SetupHelper + +# assume helper files are in package directory - change below if not +helperResourcesDir="$pkgDir/HelperResources" + +if [ -e "$helperResourcesDir/version" ]; then + # both helper file sets are present - compare them and choose the newest + if [ -e "$shDir/HelperResources" ]; then + # temporarily source the local VersionResources + source "$pkgDir/HelperResources/VersionResources" + # setup helper files are newer - switch to those helper files + compareVersions $( cat "$shDir/version" ) $( cat "$pkgDir/HelperResources/version" ) + if (( $? == 1 )); then + helperResourcesDir="$shDir/HelperResources" + fi + fi +elif [ -e "$shDir/HelperResources" ]; then + helperResourcesDir="$shDir/HelperResources" +else + echo "$pkgName: helper files not found - can't continue" | tee -a "/data/log/SetupHelper" + exit 1 +fi + +# if we get here, helper files were located - source the files +helperFileList=( EssentialResources LogHandler VersionResources \ + DbusSettingsResources ServiceResources ) +for file in ${helperFileList[@]}; do + if [ -f "$helperResourcesDir/$file" ]; then + source "$helperResourcesDir/$file" + else + echo "$pkgName: helper file $file not found - can't continue" | tee -a "/data/log/SetupHelper" + exit 1 + fi +done + +# now transfer control to CommonResoures - it may not return ! +if [ -f "$helperResourcesDir/CommonResources" ]; then + source "$helperResourcesDir/CommonResources" +else + echo "$pkgName: helper file CommonResources not found - can't continue" | tee -a "/data/log/SetupHelper" + exit 1 +fi + + diff --git a/HelperResources/LogHandler b/HelperResources/LogHandler new file mode 100755 index 0000000..6cfa585 --- /dev/null +++ b/HelperResources/LogHandler @@ -0,0 +1,80 @@ +#!/bin/bash + +# LogHandler for SetupHelper +# contains a functions and variables necessare=y to write to and output logs +# +# Refer to the SetupHelper ReadMe file for details on how to use these resources +# +# it is sourced by CommonResources and reinstall Mods +# +# there may be two logs associated with a setup script: +# the script helper log and optionally the package log +# logs are written to both places and additionally the command line if not running from reinstallMods + +setupLogFile="/var/log/SetupHelper" + +# enable logging to console +# scripts can disable logging by setting +# logToConsole to false AFTER sourcing LogHandler +logToConsole=true + +# output the last 100 lines of the log file to the console +# the full path to the log file should be passed in $1 +# converts the tai64 time stamp to human readable form +# +# $1 specifies the path to the log file +# $setupLogFile +# $packageLogFile is defined to point to the log file of the package if it exists + +displayLog () +{ + if [ ! -z "$1" ]; then + if [ -f "$1" ]; then + tail -100 "$1" | tai64nlocal + else + echo "no log File $1 found" + fi + else + echo "no log File specified" + fi +} + + +# write a message to one or more log files + +logMessage () +{ + # to console + if $logToConsole ; then + echo "$*" + fi + + # to setup helper log + if [ ! -z $setupLogFile ]; then + echo "$shortScriptName: $*" | tai64n >> $setupLogFile + fi + + # to setup helper log + if [ ! -z $packageLogFile ]; then + # no log file yet - make enclosing directory + # if directory already exists mkdir will do nothing (silently) + if [ ! -f "$packageLogFile" ]; then + mkdir -p $(dirname "$packageLogFile") + fi + echo "$shortScriptName: $*" | tai64n >> $packageLogFile + fi +} + + +# truncates the log file if it's larger than 2000 lines +# it is called from the initialization code in CommonResources +# if NOT running at boot time + +pruneSetupLogFile () +{ + if [ $(wc -l $setupLogFile | awk '{print $1}') -gt 2000 ]; then + tail -1000 $setupLogFile > $setupLogFile.tmp + mv $setupLogFile.tmp $setupLogFile + logMessage "log file truncated to last 1000 lines" + fi +} diff --git a/HelperResources/ServiceResources b/HelperResources/ServiceResources new file mode 100755 index 0000000..1512bcf --- /dev/null +++ b/HelperResources/ServiceResources @@ -0,0 +1,287 @@ +#!/bin/bash + +#!/bin/bash +# ServiceManager for SetupHelper +# contains a functions to install and remove a package's service +# +# If an active copy of the service already exists, the run and log/run files are updated +# ONLY if there are changes, then the service and/or the logger will be restarted. +# This leaves other files managed by supervise untouched. +# +# in Venus OS between v2.80~10 and v2.90~2, services are stored in /opt/victronenergy/service +# which is overlayed onto /service +# the FS overlay also maintains a "working directory": $overlayWorkDir in this script +# all services need to be added there rather than /service +# Note: service calls (eg svc) are still made on /service/... +# there is an unknown interaction between /service and the overlay source +# so code here operates on both directories +# +# in Venus OS starting with v2.90~3, /service is mounted as a tmpfs (RAM disk) +# /opt/victronenergy/service is copied to /service ONLY at boot time +# so new services need to be copied to /opt/victronenergy/service for boot processing +# AND to /service so they run immediately +# +# svc -u /service/ starts a service that is not already running +# svc -d /service/ stops a service and will not restart +# these are "temporary" and don't survive a system boot +# svc -t /service/ sends the service a TERM command +# if the service was up at the time, it restarts +# if the service was down at the time, it is NOT started +# +# the /service//down flag file controls the state of a service at boot time: +# if the file exists, the service won't start automatically at boot or when created +# if the file does not exist, the service will start at boot or immediately when it is created +# +# if the services manager (svscan) is not up, or the real service directory does not yet exist +# some steps will be skipped to avoid errors in calling daemontools functions +# +# more info here: +# https://cr.yp.to/daemontools/svc.html +# https://cr.yp.to/daemontools/supervise.html +# https://cr.yp.to/daemontools/svstat.html +# https://cr.yp.to/daemontools/svok.html + +victronServicesDir="/opt/victronenergy/service" +overlayWorkDir="/run/overlays/service" +serviceDir="$victronServicesDir" +serviceUsesFsOverlay=false +serviceMountedTmpfs=false + +versionStringToNumber "v2.90~3" +tmpfsStartVersion=$versionNumber +versionStringToNumber "v2.80~10" +overlayStartVersion=$versionNumber +versionStringToNumber $venusVersion + +# service is mounted tmpfs +if (( $versionNumber >= $tmpfsStartVersion )) ; then + serviceMountedTmpfs=true +# service uses a file system overlay +elif (( $versionNumber >= $overlayStartVersion )) ; then + serviceUsesFsOverlay=true +# service is writable in place +else + serviceDir="/service" +fi + +# check to see if services manager is running +svscanIsUp () +{ + pgrep -lx svscan &> /dev/null + if (( $? == 0 )) ; then + return 0 + else + return 1 + fi +} + +# check to see if named service is up +serviceIsUp () +{ + if ! svscanIsUp ; then + return 1 + elif [ ! -e "/service/$1" ]; then + return 1 + elif [ $(svstat "/service/$1" | awk '{print $2}') == "up" ]; then + return 0 + else + return 1 + fi +} + + +# +# removeService cleanly removes the service +# + +removeService () +{ + # no service specified + if (( $# < 1 )); then + return + fi + local serviceName="$1" + + if [ -e "$serviceDir/$serviceName" ]; then + logMessage "removing $serviceName service" + # stop the service if it is currently running + if serviceIsUp $serviceName ; then + svc -d "/service/$1" + fi + if serviceIsUp "$serviceName/log" ; then + svc -d "/service/$1/log" + fi + + # supervise processes hang around after removing the service so save info and kill them after removal + pids="" + while read -u 9 line; do + read s uid pid ppid vsz rss tty stime time cmd blah <<< "$line" + if [ $cmd == 'supervise' ]; then + pids+="$pid " + elif [ $cmd == 'multilog' ]; then + pids+="$ppid " + fi + done 9<<< $(ps -l | grep $serviceName) + + # remove the service directory + rm -rf "$serviceDir/$serviceName" + # when /service is mounted as tmpfs, the service needs to be removed from /service also + if $serviceMountedTmpfs && [ -d "/service/$serviceName" ]; then + rm -rf "/service/$serviceName" + # removing the service in the overlayed service directory doesn't remove it from /service + # it needs to be removed from the overlay work directory also + elif $serviceUsesFsOverlay && [ -d "$overlayWorkDir/$serviceName" ] ; then + rm -rf "$overlayWorkDir/$serviceName" + fi + + # now kill the supervise processes + kill $pids + fi + + # remove service from installed services list + if [ -f "$installedServicesList" ]; then + grep -v "$serviceName" "$installedServicesList" | tee "$installedServicesList" > /dev/null + fi +} + + +# installService adds the service to the /service directory or updates an existing one +# +# If the service does not yet exist, it is created +# If the service already exists, installService will +# update the service files then restart the service and the logger + + +# The service usually starts automatically within a few seconds of creation. +# installService waits 10 seconds to see if the service starts on its own +# if not, it will be started +# +# The service may contain a "down" flag file. If present, the service won't be started. +# This allows the service to be started manually later. +# If the down flag is present the service will not start at boot. +# +# +# $1 is the service name -- that is the name of the service in /service +# the package name will be used as the service name if not specified on the command line +# +# $2 is the directory in the script directory to be copied to the service in /service +# (this includes the run and control (down) files) +# the default is 'service' in the package directory +# +# for most packages with one service, the defaults are fine +# however if a package needs to install more than one service +# then the service name and directory must be specified +# installService "PackageManager" "servicePM" +# installService "SetupHelper" "serviceSH" +# servicePM/run would include a call to /data/SetupHelper/PackageManager.py +# serviceSH/run would include a call to /data/SetupHelper/SetupHelper.sh + +installService () +{ + # don't do any work if install has already failed + if $installFailed; then + return + fi + + local serviceName="" + if (( $# >= 1 )); then + serviceName=$1 + else + serviceName=$packageName + fi + + local servicePath="" + if (( $# >= 2 )); then + servicePath="$scriptDir/$2" + elif [ -e "$servicesDir/$serviceName" ]; then + servicePath="$servicesDir/$serviceName" + elif [ -e "$scriptDir/service" ]; then + servicePath="$scriptDir/service" + fi + + # no service to install + if [ ! -e "$servicePath" ]; then + setInstallFailed $EXIT_ERROR "service $service not found - can't continue" + return + fi + + if [ -L "$serviceDir/$serviceName" ]; then + logMessage "removing old $serviceName service (was symbolic link)" + removeService $serviceName + fi + + # add service to the installed services list (used for uninstallAll) + # do this before actually modifying things just in case there's an error + # that way the uninstall is assured + echo "$serviceName" >> "$installedServicesList" + + # service not yet installed, COPY service directory to the service directory(s) + if [ ! -e "/service/$serviceName" ]; then + logMessage "installing $serviceName service" + + cp -R "$servicePath" "$serviceDir/$serviceName" + if $serviceMountedTmpfs && [ -d "/service" ] ; then + cp -R "$servicePath" "/service/$serviceName" + fi + # if down flag is NOT set, check every second for service to start automatically + # then start it here if it is not running after 10 seconds + if [ -f "$serviceDir/$serviceName/down" ]; then + logMessage "$serviceName not (re)started - must be started manually (down flag set)" + elif ! svscanIsUp ; then + logMessage "services manager (svscan) not yet up - $serviceName should start automatically later" + else + local delayCount=10 + local serviceRunning=false + while (( $delayCount > 0 )); do + if serviceIsUp $serviceName ; then + serviceRunning=true + break + fi + echo "waiting for $serviceName service to start" + sleep 1 + (( delayCount-- )) + done + if $serviceRunning; then + logMessage "service $serviceName running" + else + logMessage "starting $serviceName service" + svc -u "/service/$serviceName" + if [ -e "/service/$serviceName/log" ] && ! serviceIsUp "$serviceName/log" ; then + svc -u "/service/$serviceName/log" + fi + fi + fi + + # service already installed - only copy changed files, then restart service if it is running + else + if [ -f "$servicePath/run" ]; then + cmp -s "$servicePath/run" "$serviceDir/$serviceName/run" > /dev/null + if (( $? != 0 )); then + logMessage "updating $serviceName run file" + cp "$servicePath/run" "$serviceDir/$serviceName/run" + if $serviceMountedTmpfs ; then + cp "$servicePath/run" "/service/$serviceName/run" + fi + fi + if serviceIsUp $serviceName ; then + logMessage "restarting $serviceName service" + svc -t "/service/$serviceName" + fi + fi + # log needs to be handled separtely including a restart + if [ -f "$servicePath/log/run" ]; then + cmp -s "$servicePath/log/run" "$serviceDir/$serviceName/log/run" > /dev/null + if (( $? != 0 )); then + logMessage "updating $serviceName log/run file" + cp "$servicePath/log/run" "$serviceDir/$serviceName/log/run" + if $serviceMountedTmpfs ; then + cp "$servicePath/log/run" "/service/$serviceName/log/run" + fi + fi + if serviceIsUp "$serviceName/log" ; then + logMessage "restarting $serviceName logger" + svc -t "/service/$serviceName/log" + fi + fi + fi +} diff --git a/HelperResources/VersionResources b/HelperResources/VersionResources new file mode 100755 index 0000000..c4a1439 --- /dev/null +++ b/HelperResources/VersionResources @@ -0,0 +1,139 @@ +#!/bin/sh + +# this file contains functions for comparing version numbers +# +# NOTE: this script does NOT rely on other helper files + + +# convert a version string to an integer to make comparisions easier +# the Victron format for version numbers is: vX.Y~Z-large-W +# the ~Z portion indicates a pre-release version so a version without it is "newer" than a version with it +# the -W portion has been abandoned but was like the ~Z for large builds and is IGNORED !!!! +# large builds now have the same version number as the "normal" build +# +# the version string passed to this function allows for quite a bit of flexibility +# any alpha characters are permitted prior to the first digit +# up to 3 version parts PLUS a prerelease part are permitted +# each with up to 4 digits each -- MORE THAN 4 digits is indeterminate +# that is: v0.0.0d0 up to v9999.9999.9999b9999 and then v9999.9999.9999 as the highest priority +# any non-numeric character can be used to separate main versions +# special significance is assigned to single caracter separators between the numeric strings +# b or ~ indicates a beta release +# a indicates an alpha release +# d indicates an development release +# these offset the pre-release number so that b/~ has higher numeric value than any a +# and a has higher value than d separator +# +# a blank version or one without at least one number part is considered invalid +# alpha and beta seperators require at least two number parts +# +# returns 0 if conversion succeeeded, 1 if not +# the value integer is returned in $versionNumber +# a status text string is returned in $versionStringToNumberStatus +# and will include the string passed to the function +# as well as the converted number if successful and the type of release detected +# or an error reason if not +# + + +function versionStringToNumber () +{ + local version="$*" + local numberParts + local versionParts + local numberParts + local otherParts + local other + local number=0 + local type='release' + + # split incoming string into + # an array of numbers: major, minor, prerelease, etc + # and an array of other substrings + # the other array is searched for releasy type strings and the related offest added to the version number + + read -a numberParts <<< $(echo $version | tr -cs '0-9' ' ') + numberPartsLength=${#numberParts[@]} + if (( $numberPartsLength == 0 )); then + versionNumber=0 + versionStringToNumberStatus="$version: invalid, missing major version" + return 1 + fi + if (( $numberPartsLength >= 2 )); then + read -a otherParts <<< $(echo $version | tr -s '0-9' ' ') + + for other in ${otherParts[@]}; do + case $other in + 'b' | '~') + type='beta' + (( number += 60000 )) + break ;; + 'a') + type='alpha' + (( number += 30000 )) + break ;; + 'd') + type='develop' + break ;; + esac + done + fi + + # if release all parts contribute to the main version number + # and offset is greater than all prerelease versions + if [ "$type" == "release" ] ; then + (( number += 90000 )) + # if pre-release, last part will be the pre release part + # and others part will be part the main version number + else + (( numberPartsLength-- )) + (( number += 10#${numberParts[$numberPartsLength]} )) + fi + # include core version number + (( number += 10#${numberParts[0]} * 10000000000000 )) + if (( numberPartsLength >= 2)); then + (( number += 10#${numberParts[1]} * 1000000000 )) + fi + if (( numberPartsLength >= 3)); then + (( number += 10#${numberParts[2]} * 100000 )) + fi + + versionNumber=$number + versionStringToNumberStatus="$version:$number $type" + return 0 +} + + + +# compares two version strings +# +# missing verions are treated as 0 +# +# returns 0 if they are equal +# returns 1 if the first is newer than the second +# returns -1 if the second is newer than the first + +function compareVersions () +{ + local versionNumber2 + + if [ -z $2 ]; then + versionNumber2=0 + else + versionStringToNumber $2 + versionNumber2=$versionNumber + fi + if [ -z $1 ]; then + versionNumber=0 + else + versionStringToNumber $1 + fi + + if (( versionNumber == versionNumber2 ));then + return 0 + elif (( versionNumber > versionNumber2 ));then + return 1 + else + return -1 + fi +} diff --git a/HelperResources/forSetupScript b/HelperResources/forSetupScript new file mode 100644 index 0000000..ba2ef04 --- /dev/null +++ b/HelperResources/forSetupScript @@ -0,0 +1,14 @@ +#### add the following lines to the package's setup script +#### following lines incorporate helper resources into this script +pkgDir=$( dirname $0 ) +pkgName=$( basename $pkgDir ) +pkgRoot=$( dirname $pkgDir ) +if [ -e "$pkgDir/HelperResources/IncludeHelpers" ]; then + source "$pkgDir/HelperResources/IncludeHelpers" +elif [ -e "$pkgRoot/SetupHelper/HelperResources/IncludeHelpers" ]; then + source "$pkgRoot/SetupHelper/HelperResources/IncludeHelpers" +else + echo "$pkgName: helper resources not found - can't continue" | tee -a "/data/log/SetupHelper" + exit 1 +fi +#### end of lines to include helper resources diff --git a/HelperResources/version b/HelperResources/version new file mode 100644 index 0000000..f467a21 --- /dev/null +++ b/HelperResources/version @@ -0,0 +1 @@ +v6.7 diff --git a/OverlayInstructions b/OverlayInstructions index f37b605..8a5afae 100644 --- a/OverlayInstructions +++ b/OverlayInstructions @@ -1,6 +1,7 @@ compile: dtc -@ -I dts -O dtb -o VenusGpioOverlay.dtbo VenusGpioOverlay.dts + dtc -@ -I dts -O dtb -o VenusGpioOverlayForCanHats.dtbo VenusGpioOverlayForCanHats.dts Put it in /u-boot/overlays: sudo cp VenusGpioOverlay.dtbo /u-boot/overlays/VenusGpioOverlay.dtbo @@ -8,4 +9,9 @@ Put it in /u-boot/overlays: Add a line to /u-boot/config.txt: dtoverlay=VenusGpioOverlay +The alternat overlay: VenusGpioOverlayForCanHats.dtbo is a companion for the alternate gpio_list. Install whichever is appropriate + + +You will need to compile host that has dtc installed such as Raspberry PI OS. Most desktop computers do not have dtc and you probalby can't install it there. Venus OS also does NOT have dtc installed. + Note /u-boot typically appears as /boot when the SD card is mounted on a computer diff --git a/VenusGpioOverlayForCanHats.dts b/VenusGpioOverlayForCanHats.dts new file mode 100644 index 0000000..6b2e217 --- /dev/null +++ b/VenusGpioOverlayForCanHats.dts @@ -0,0 +1,27 @@ +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2735,bcm2736,bcm2737,bcm2737A0,bcm2737B0,bcm2711"; + +// make all Venus GX digital inputs have pull-ups +// This is an alternate overlay to use with the alternate gpio_list +// the chip default is GPIO 1 - 8 have pull-ups, the rest are pull-downs + +// compile with +// dtc -@ -I dts -O dtb -o VenusGpioOverlay.dtb VenusGpioOverlay.dts + + fragment@0 { + target = <&gpio>; + __overlay__ { + pinctrl-names = "default"; + pinctrl-0 = <&my_pins>; + + my_pins: my_pins { + brcm,pins = <3 5 6 13 16 26>; /* gpio no. */ + brcm,function = <0>; /* 0:in, 1:out */ + brcm,pull = <2>; /* 2:up 1:down 0:none */ + }; + }; + }; +}; diff --git a/changes b/changes index 4a6ded2..8abda8f 100644 --- a/changes +++ b/changes @@ -1,3 +1,6 @@ +v4.4: + added alternate GPIO overlay to remove conflicts with FD can hat + v4.3: fixed: no file sets error created in v4.2 diff --git a/setup b/setup index 6cb3e37..19c1d7d 100755 --- a/setup +++ b/setup @@ -35,6 +35,7 @@ gpioListFile="/etc/venus/gpio_list" overlayFile="/u-boot/overlays/VenusGpioOverlay.dtbo" +altOverlayFile="/u-boot/overlays/VenusGpioOverlayForCanHats.dtbo" relayStateFile="/opt/victronenergy/dbus-systemcalc-py/delegates/relaystate.py" configFile="/u-boot/config.txt" @@ -92,7 +93,7 @@ if [ $scriptAction == 'NONE' ] ; then 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" + echo "CAUTION: manually check custom gpio_list and GPIO overlay for conflicts" useCustomGpioFile=true else rm "$setupOptionsDir/gpio_list" @@ -131,16 +132,29 @@ if [ $scriptAction == 'INSTALL' ] ; then # modify relaystate.py for additional relays to prevent system calc crash updateActiveFile "$relayStateFile" - # install DT overlay to for pull-ups on all digital inputs - updateActiveFile "$overlayFile" - - if [ $(grep -c "VenusGpioOverlay" "$configFile") == 0 ]; then - logMessage "activating GPIO DT overlay" - echo "#### change all digital inputs to pull ups" >> "$configFile" - echo "dtoverlay=VenusGpioOverlay" >> "$configFile" - echo "#### end change all digital inputs to pull ups" >> "$configFile" - filesUpdated=true - fi + # install / update GPIO overlay + # there are two overlays, make sure the "other" one is removed from config.txt + if [ -f "$setupOptionsDir/alternateGpio" ]; then + updateActiveFile "$altOverlayFile" + gpioOverlay="VenusGpioOverlayForCanHats" + if [ $(grep -c "VenusGpioOverlay" "$configFile") == 0 ]; then + sed -i -e '/#### change all digital inputs to pull ups/,/#### end change all digital inputs to pull ups/d' "$configFile" + fi + else + updateActiveFile "$overlayFile" + gpioOverlay="VenusGpioOverlay" + if [ $(grep -c "VenusGpioOverlayForCanHats" "$configFile") > 0 ]; then + sed -i -e '/#### change all digital inputs to pull ups/,/#### end change all digital inputs to pull ups/d' "$configFile" + fi + fi + + if [ $(grep -c "#### change all digital inputs to pull ups" "$configFile") == 0 ]; then + logMessage "activating $gpioOverlay" + echo "#### change all digital inputs to pull ups" >> "$configFile" + echo "dtoverlay=$gpioOverlay" >> "$configFile" + echo "#### end change all digital inputs to pull ups" >> "$configFile" + filesUpdated=true + fi fi # uninstalling - check scriptAction again @@ -148,6 +162,7 @@ fi if [ $scriptAction == 'UNINSTALL' ] ; then restoreActiveFile "$gpioListFile" restoreActiveFile "$overlayFile" + restoreActiveFile "$altOverlayFile" restoreActiveFile "$relayStateFile" # remove mods from configFile - do not use restore in case other mods were made manually diff --git a/timeStamp b/timeStamp deleted file mode 100644 index a96dc77..0000000 --- a/timeStamp +++ /dev/null @@ -1 +0,0 @@ -1635100489 diff --git a/version b/version index b570a0a..a7021c5 100644 --- a/version +++ b/version @@ -1 +1 @@ -v4.3 +v4.4