Skip to content

Commit 3ada598

Browse files
authored
Install Grott proxy server (#2046)
* install grott proxy server Signed-off-by: Andrew Fiddian-Green <[email protected]>
1 parent 5aad19a commit 3ada598

File tree

8 files changed

+292
-9
lines changed

8 files changed

+292
-9
lines changed

build-image/openhabian.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ zram_reset=done # remove when zram is no longer needed to auto update
9090
hotspot=enable
9191
hotspotpw=openhabian
9292

93+
# Grott settings (only enable this if Growatt binding will be used)
94+
# grottSetupEnabled=false
95+
9396
# external SD card device to backup and mirror the internal SD card to
9497
# backupdrive=/dev/sda
9598
storageconfig=openhab-dir

docs/openhabian.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,12 +254,13 @@ Each of these are included as a part of `openhabian-config` menu option 20.
254254
- [OWServer](https://owfs.org) - 1-Wire system of Dallas/Maxim
255255
- [FIND](https://www.internalpositioning.com/) - Framework for Internal Navigation and Discovery
256256
- Mi Flora MQTT daemon
257+
- Grott Proxy server for [Growatt binding](https://www.openhab.org/addons/bindings/growatt/#grott-application-installation-and-setup)
257258

258259
## First boot configuration
259260

260261
Many settings are configurable prior to the first boot of openHABian by changing the key value pairs in the `/boot/openhabian.conf` file on the SD card once you have flashed the initial image onto it.
261262

262-
Please note that - in case you use a Windows system for writing the SD card - the `/boot/` partition will be mounted to a drive named `bootfs`. So, e.g. if this drive has the letter `D:`, `/boot/openhabian.conf` will be found as `D:\openhabian.conf`.
263+
Please note that - in case you use a Windows system for writing the SD card - the `/boot/` partition will be mounted to a drive named `bootfs`. So, e.g. if this drive has the letter `D:`, `/boot/openhabian.conf` will be found as `D:\openhabian.conf`.
263264

264265
The openHABian configuration file uses key value pairs, essentially a list of `option=value` settings in a plain text file.
265266
All supported options are already in the file but unused options and optional components are commented out by default.

functions/menu.bash

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ show_main_menu() {
110110
esac
111111

112112
elif [[ "$choice" == "20"* ]]; then
113-
choice2=$(whiptail --title "openHABian Configuration Tool — $(get_git_revision)" --menu "Optional Components" 24 118 16 --cancel-button Back --ok-button Execute \
113+
choice2=$(whiptail --title "openHABian Configuration Tool — $(get_git_revision)" --menu "Optional Components (scroll to see more)" 24 118 16 --cancel-button Back --ok-button Execute \
114114
"21 | Log Viewer" "[DEPRECATED] openHAB Log Viewer webapp (frontail)" \
115115
" | Add log to viewer" "[DEPRECATED] Add a custom log to openHAB Log Viewer (frontail)" \
116116
" | Remove log from viewer" "[DEPRECATED] Remove a custom log from openHAB Log Viewer (frontail)" \
@@ -133,6 +133,8 @@ show_main_menu() {
133133
" | Setup EVCC" "Setup EVCC from command line (German only)" \
134134
"2E | Install ESPHome dashboard" "Deploy ESPHome dashboard" \
135135
" | Remove ESPHome dashboard" "Uninstall ESPHome dashboard" \
136+
"2F | Install Grott" "Install Grott Proxy server (for Growatt binding)" \
137+
" | Remove Grott" "Uninstall Grott Proxy server (for Growatt binding)" \
136138
3>&1 1>&2 2>&3)
137139
RET=$?
138140
if [ $RET -eq 1 ] || [ $RET -eq 255 ]; then return 0; fi
@@ -160,6 +162,8 @@ show_main_menu() {
160162
*Setup\ EVCC*) setup_evcc;;
161163
2E\ *) install_esphomedashboard "install";;
162164
*Remove\ ESPHome\ dashboard*) install_esphomedashboard "remove";;
165+
2F\ *) install_grott "install";;
166+
*Remove\ Grott*) install_grott "remove";;
163167
"") return 0 ;;
164168
*) whiptail --msgbox "An unsupported option was selected (probably a programming error):\\n \"$choice2\"" 8 80 ;;
165169
esac
@@ -217,13 +221,13 @@ show_main_menu() {
217221
"42 | Remote Console" "Bind the openHAB SSH console to all external interfaces" \
218222
"43 | Clean cache" "Clean the cache for openHAB" \
219223
"44 | Nginx Proxy" "Setup reverse and forward web proxy" \
220-
"45 | OpenJDK 17" "Install + activate OpenJDK 17 as Java provider (default for OH versions 4 and older)" \
221-
" | OpenJDK 21" "Install + activate OpenJDK 21 as Java provider (DO NOT USE WILL BREAK SYSTEM)" \
222-
" | Temurin 17" "Install + activate Temurin 17 as Java provider (fallback for OH versions 4 and older)" \
223-
" | Temurin 21" "Install + activate Temurin 21 as Java provider (default)" \
224-
" | OpenJDK 11" "Install + activate OpenJDK 11 as Java provider (legacy)" \
225-
"46 | Install openhab-js" "JS Scripting: Upgrade to latest version of openHAB JavaScript library (advanced)" \
226-
" | Uninstall openhab-js" "JS Scripting: Switch back to included version of openHAB JavaScript library" \
224+
"45 | OpenJDK 17" "Setup OpenJDK 17 as Java provider (default for OH v4 and older)" \
225+
" | OpenJDK 21" "Setup OpenJDK 21 as Java provider (DO NOT USE WILL BREAK SYSTEM)" \
226+
" | Temurin 17" "Setup Temurin 17 as Java provider (fallback for OH v4 and older)" \
227+
" | Temurin 21" "Setup Temurin 21 as Java provider (default)" \
228+
" | OpenJDK 11" "Setup OpenJDK 11 as Java provider (legacy)" \
229+
"46 | Install openhab-js" "JS Scripting: Upgrade to latest version of JavaScript library (advanced)" \
230+
" | Uninstall openhab-js" "JS Scripting: Switch back to included version of JavaScript library" \
227231
"47 | Install openhab_rules_tools" "JS Scripting: Manually install openhab_rules_tools (auto-installed)" \
228232
" | Uninstall openhab_rules_tools" "JS Scripting: Uninstall openhab_rules_tools" \
229233
3>&1 1>&2 2>&3)

functions/packages.bash

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -922,3 +922,140 @@ install_esphomedashboard() {
922922
return
923923
fi
924924
}
925+
926+
## Function for (un)installing Grott proxy server on the current system
927+
## Valid arguments: "install" or "remove"
928+
##
929+
## install_grott(String install|remove)
930+
##
931+
install_grott() {
932+
echo "$(timestamp) [openHABian] Setup Grott proxy... "
933+
934+
# Skip setup if in un-attended mode and openhabian.config grottSetupEnabled is missing or not true
935+
if [[ -n "$UNATTENDED" ]] && [[ "$grottSetupEnabled" != "true" ]]; then
936+
echo "SKIPPED (setup not enabled)"
937+
return 0
938+
fi
939+
940+
# Validate install type argument
941+
if [ "$#" -lt 1 ]; then
942+
echo "FAILED (missing install type - usage: $0 <install|remove>)"
943+
return 1
944+
elif [[ "$1" != "install" && "$1" != "remove" ]]; then
945+
echo "FAILED (invalid install type $1 - usage: $0 <install|remove>)"
946+
return 1
947+
fi
948+
local installType="$1"
949+
950+
# Constants for local system
951+
local grottFolder="/home/${username:-openhabian}/grott"
952+
local iniName="grott.ini"
953+
local serviceName="grott.service"
954+
local iniFile="${grottFolder}/${iniName}"
955+
local serviceFile="/etc/systemd/system/${serviceName}"
956+
local iniTemplate="${BASEDIR:-/opt/openhabian}/includes/${iniName}"
957+
local serviceTemplate="${BASEDIR:-/opt/openhabian}/includes/${serviceName}"
958+
local runScript="grott.py"
959+
960+
# Constants for Grott GitHub files
961+
local grottSourceUrl="https://raw.githubusercontent.com/johanmeijer/grott/master"
962+
local grottSourceFiles=(
963+
"grott.py"
964+
"grottconf.py"
965+
"grottdata.py"
966+
"grottproxy.py"
967+
"grottserver.py"
968+
"grottsniffer.py"
969+
)
970+
local grottExtUrl="${grottSourceUrl}/examples/Extensions"
971+
local grottExtFile="grottext.py"
972+
973+
## Install Grott proxy
974+
if [[ $installType == "install" ]]; then
975+
echo "$(timestamp) [openHABian] Installing Grott proxy... "
976+
977+
# Get default IPv4 address
978+
local ipAddress
979+
ipAddress="$(ip route get 8.8.8.8 | awk '{print $7}' | xargs)"
980+
if ! [[ "$ipAddress" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
981+
echo "FAILED (invalid ip address ${ipAddress})"
982+
return 1
983+
fi
984+
local extUrl="http://${ipAddress}:8080/growatt"
985+
986+
# Update system and install dependencies. NOTE: paho-mqtt is a required dependency (even if disabled)
987+
if ! cond_redirect apt-get update; then echo "FAILED (apt update)"; return 1; fi
988+
if ! cond_redirect apt-get install --yes -o DPkg::Lock::Timeout="$APTTIMEOUT" python3 python3-pip python3-paho-mqtt python3-requests; then echo "FAILED (install Python or dependencies)"; return 1; fi
989+
990+
# Prepare Grott folder
991+
if ! cond_redirect mkdir -p "$grottFolder"; then echo "FAILED (create ${grottFolder})"; return 1; fi
992+
if ! cond_redirect chown -R "${username:-openhabian}" "$grottFolder"; then echo "FAILED (chown ${grottFolder})"; return 1; fi
993+
if ! cond_redirect chmod -R 755 "$grottFolder"; then echo "FAILED (chmod ${grottFolder})"; return 1; fi
994+
995+
# Download Grott Python files into Grott folder
996+
local src tgt
997+
for file in "${grottSourceFiles[@]}"; do
998+
src="${grottSourceUrl}/${file}"
999+
tgt="${grottFolder}/${file}"
1000+
curl -fsSL "${src}" -o "${tgt}" || {
1001+
echo "FAILED (download ${file})"
1002+
return 1
1003+
}
1004+
done
1005+
1006+
# Download Grott extension file into Grott folder
1007+
src="${grottExtUrl}/${grottExtFile}"
1008+
tgt="${grottFolder}/${grottExtFile}"
1009+
curl -fsSL "${src}" -o "${tgt}" || {
1010+
echo "FAILED (download ${grottExtFile})"
1011+
return 1
1012+
}
1013+
1014+
# Create grott.ini configuration in Grott folder by modifying the template
1015+
if ! sed \
1016+
-e "s|%URL|$extUrl|g" \
1017+
"$iniTemplate" > "$iniFile"; then
1018+
echo "FAILED (configure ${iniName})"
1019+
return 1
1020+
fi
1021+
1022+
# Create grott.service configuration in systemd folder by modifying the template
1023+
if ! sed \
1024+
-e "s|%USERNAME|${username:-openhabian}|g" \
1025+
-e "s|%DIRECTORY|$grottFolder|g" \
1026+
-e "s|%RUNSCRIPT|$runScript|g" \
1027+
"$serviceTemplate" > "$serviceFile"; then
1028+
echo "FAILED (configure ${serviceName})"
1029+
return 1
1030+
fi
1031+
1032+
# Enable and start Grott service
1033+
if ! cond_redirect systemctl enable --now "${serviceName}"; then echo "FAILED (enable ${serviceName})"; return 1; fi
1034+
1035+
if [[ -n "$INTERACTIVE" ]]; then
1036+
whiptail --title "Grott Proxy Installed" --msgbox "We installed Grott proxy on your system." 7 80
1037+
fi
1038+
fi
1039+
1040+
## Remove Grott proxy
1041+
if [[ $installType == "remove" ]]; then
1042+
echo "$(timestamp) [openHABian] Removing Grott Proxy... "
1043+
1044+
# Stop and disable systemd service
1045+
if ! cond_redirect systemctl disable --now "${serviceName}"; then echo "FAILED (disable ${serviceName})"; return 1; fi
1046+
cond_redirect systemctl daemon-reload
1047+
1048+
# Remove systemd service file
1049+
if ! cond_redirect rm -f "$serviceFile"; then echo "FAILED (remove ${serviceFile})"; return 1; fi
1050+
1051+
# Remove Grott folder
1052+
if ! cond_redirect rm -rf "$grottFolder"; then echo "FAILED (remove ${grottFolder})"; return 1; fi
1053+
1054+
if [[ -n "$INTERACTIVE" ]]; then
1055+
whiptail --title "Grott Proxy Removed" --msgbox "We removed Grott proxy from your system." 7 80
1056+
fi
1057+
fi
1058+
1059+
echo "OK"
1060+
return 0
1061+
}

functions/packages.bats

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ teardown_file() {
1111
unset BASEDIR
1212
systemctl kill homegear.service || true
1313
systemctl kill mosquitto.service || true
14+
systemctl kill grott.service || true
1415
}
1516

1617
@test "destructive-homegear_install" {
@@ -64,3 +65,19 @@ teardown_file() {
6465
[ "$status" -eq 0 ]
6566
echo -e "# ${COL_GREEN}$(timestamp) [openHABian] 1wire installation successful.${COL_DEF}" >&3
6667
}
68+
69+
@test "destructive-grott_install" {
70+
## Confirm Grott Proxy install completes without error
71+
echo -e "# ${COL_CYAN}$(timestamp) [openHABian] Grott Proxy installation starting...${COL_DEF}" >&3
72+
run install_grott "install" 3>&-
73+
if [ "$status" -ne 0 ]; then echo "$output" >&3; fi
74+
[ "$status" -eq 0 ]
75+
echo -e "# ${COL_GREEN}$(timestamp) [openHABian] Grott Proxy installation successful.${COL_DEF}" >&3
76+
77+
## Confirm Grott service is running
78+
echo -e "# ${COL_CYAN}$(timestamp) [openHABian] Checking if Grott Proxy service is running...${COL_DEF}" >&3
79+
run systemctl is-active --quiet grott
80+
if [ "$status" -ne 0 ]; then echo "$output" >&3; fi
81+
[ "$status" -eq 0 ]
82+
echo -e "# ${COL_GREEN}$(timestamp) [openHABian] Grott Proxy service is running.${COL_DEF}" >&3
83+
}

includes/grott.ini

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Specify grott monitor configuration
2+
# Defaults are described
3+
# Remove # and update the value to enable the setting
4+
# Last updated: 2022-11-04
5+
# Version 2.7.0
6+
7+
[Generic]
8+
# Specify verbose for extended messaging
9+
verbose = True
10+
11+
# Specify minrecl for debugging purposes only (default = 100)
12+
#minrecl = 100
13+
14+
# Specify mode (sniff or proxy)(> 2.1.0 proxy is default)
15+
mode = proxy
16+
17+
# Specify port and IP address to listen to (only proxy), default port 5279, 0.0.0.0 ==> own ip address
18+
ip = default
19+
port = 5279
20+
21+
# To blocks commands from outside (to channge inverter and shine devices settings) specify blockcmd = True,
22+
# Specify noipf = True if you still want be able to set the destination ip addres from growatt server (advice
23+
# only to use this for a short time)
24+
#blockcmd = True
25+
#noipf = True
26+
27+
# Time = auto/server parameter enable/disable date/time retrieval from data record (server), default is
28+
# auto: grott decides which time is used (data record if valid otherwise Server)
29+
# If time = server Grott server time is alwas used
30+
#time = auto
31+
32+
# Sendbuf = True / False parameter to enable / disable sending historical (buffered) data. Default is sendbuf = True.
33+
#sendbuf = True
34+
35+
# Compat is True and valoffset needs to be set if offset / growatt protocol has been changed.
36+
compat = False
37+
#valueoffset = 6
38+
39+
# Specify inverter id (not necessary in version >2.1.0 if compat = false!)
40+
#inverterid = KUM0CLU03Y
41+
# Specify the type of the inverter (default/sph/spf/max)
42+
invtype = sph
43+
44+
# Decrypt is False if growatt communication is not encrypted (older inverters), (not necessary in version
45+
# >2.1.0 if compat = false!)
46+
#decrypt = True
47+
48+
[Growatt]
49+
# Server name/IP address and port of Growatt server
50+
# specify only if the IP address of server.growatt.com is changed
51+
# The address as of Nov 2022 is 47.91.67.66
52+
53+
ip = server.growatt.com
54+
#ip = 47.91.67.66
55+
#port = 5279
56+
57+
[MQTT]
58+
# Mqtt parameters definitions
59+
# Be aware nomqtt = True means no MQTT processing will be done!!!!!!
60+
61+
nomqtt = True
62+
#ip = localhost
63+
#port = 1883
64+
#topic= energy/growatt
65+
#auth = False
66+
#user = grott
67+
#password = growatt2020
68+
69+
[PVOutput]
70+
# PVOutput parameters definitions
71+
72+
pvoutput = False
73+
#apikey = yourapikey
74+
# Data upload limit (in minutes)
75+
#pvuplimit = 5
76+
# Use this if you have one inverter
77+
#systemid = 12345
78+
79+
# Use this if you have multiple inverters
80+
#pvinverters = 2
81+
#systemid1 = 12345
82+
#inverterid1 = inverter1
83+
#systemid2 = 67890
84+
#inverterid2 = inverter2
85+
86+
#systemid99 = 99999
87+
#inverterid99 = inverter99
88+
89+
[influx]
90+
# Influxdb parameters definitions
91+
92+
#influx = False
93+
#influx2 = False
94+
#dbname = grottdb
95+
#ip = localhost
96+
#port = 8086
97+
#user = grott
98+
#password = growatt2020
99+
#token = "influx_token"
100+
#org = "grottorg"
101+
#bucket = "grottdb"
102+
103+
[extension]
104+
# grott extension parameters definitions
105+
extension = True
106+
extname = grottext
107+
extvar = {"url": "%URL"}

includes/grott.service

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[Unit]
2+
Description=Grott Proxy Service
3+
After=network.target
4+
5+
[Service]
6+
SyslogIdentifier=grott
7+
User=%USERNAME
8+
WorkingDirectory=%DIRECTORY
9+
ExecStart=-/usr/bin/python3 -u %DIRECTORY/%RUNSCRIPT
10+
Restart=on-failure
11+
12+
[Install]
13+
WantedBy=multi-user.target

openhabian-setup.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ if [[ -n "$UNATTENDED" ]]; then
121121
zram_setup
122122
exim_setup
123123
nut_setup
124+
install_grott "install"
124125
permissions_corrections
125126
setup_mirror_SD "install"
126127
install_cleanup

0 commit comments

Comments
 (0)