I’ve run in some issues with the current startup process. Everything is starting at once which leads to several exceptions, errors and other problems. In my case the most annoying problem is the Homematic-Channel not found-problem.
According to my opinion, a reason is the triggering of rules during startup which leads to timing problems and other race conditions which then lead to further problems after startup.
I often read about moving or renaming the rules and copying back after startup, so the idea is not from me. But i never saw a solution which does all the stuff in the background, without manual interference, once it has been installed.
I know, this is rather a workaround than a solution and it also just works for a linux installation, but it may help some people possibly. If not, it helps me.
In the discussion some alternatives emerged. All alternatives work similar and share the same bash-script.
I hope, this helps somebody. If you have any further questions, feel free to ask.
My prefered variant
This is the most simple alternative, but just works with linux and systemd (e.g. openhabian). Thanks to @ptweety for this variant.
Simply create the file `/etc/systemd/system/openhab2.service.d/override.conf. This overrides the standard startup script where applicable.
If you are on stretch-based openhabian, you may use sudo systemctl edit openhab2.service
, otherwise you have to use sudo nano /etc/systemd/system/openhab2.service.d/override.conf
[Service]
ExecStartPre=-/bin/bash -c '/usr/bin/find ${OPENHAB_CONF} -name "*.rules" -exec /usr/bin/rename.ul .rules .rules_away {} \\;'
ExecStartPre=-/bin/bash -c '/usr/bin/find ${OPENHAB_CONF} -name "*.script" -exec /usr/bin/rename.ul .script .script_away {} \\;'
ExecStartPost=/bin/sleep 240
ExecStartPost=-/bin/bash -c '/usr/bin/find ${OPENHAB_CONF} -name "*.script_away" -exec /usr/bin/rename.ul .script_away .script {} \\;'
ExecStartPost=-/bin/bash -c '/usr/bin/find ${OPENHAB_CONF} -name "*.rules_away" -exec /usr/bin/rename.ul .rules_away .rules {} \\;'
TimeoutStartSec=360
That’s it.
Common for all other alternatives
The bash script (all my bash scripts are located in /etc/openhab2/exec-scripts, if you want a different storage make sure you change all references as well):
“/etc/openhab2/exec-scripts/moverules.sh”
#!/bin/bash
ORG=$1
NEW=$2
IGNORE=moverules.rules
for f in /etc/openhab2/rules/*.${ORG};
do
CURRENT=$(basename $f)
if [ "$CURRENT" == "$IGNORE" ]
then
echo "ignoring $IGNORE"
else
OLDFILE=$f
NEWFILE=${f%$ORG}$NEW
mv "$OLDFILE" "$NEWFILE"
fi
done
I also translated the bash script to windows batch.
“C:\openHAB2\conf\exec-scripts\moverules.cmd”
@echo off
SET ORG=%1
SET NEW=%2
SET IGNORE="moverules.rules"
cd C:\openHAB2\conf\rules
for %%f in (*.%ORG%) do (
if %%f NEQ %IGNORE% (
echo %%f %%~nf.%NEW%
)
)
Alternative 1: Two rules, no servicefile
One rule renames the rules to *.rules at startup + 240 seconds, one rule renames the rules to *.rules_away at shutdown. This variant is able to run under Windows.
Please be aware, this is untested, i do not run openHAB on windows.
Pros: no changes to service file, no need to reapply the patch after update, able to run on Windows
Cons: rules are not named rules while the service is not running, system needs one restart after a power loss or installation
Changes:
- a rules file which calls the bash script (/etc/openhab2/rules/moverules.rules)
The single new rules file (moverules.rules):
val Integer secondsDelay = 240
val String executeCmdBack = "/etc/openhab2/exec-scripts/moverules.sh rules_away rules"
val String executeCmdAway = "/etc/openhab2/exec-scripts/moverules.sh rules rules_away"
// exchange above for that on windows
//val String executeCmdBack = "C:\openHAB2\conf\exec-scripts\moverules.cmd@@rules_away@@rules"
//val String executeCmdAway = "C:\openHAB2\conf\exec-scripts\moverules.cmd@@rules@@rules_away"
var Timer renameTimer = null
rule "rename rules back in"
when
System started
then
logInfo("renameRules", "system started triggered")
if (renameTimer === null)
{
renameTimer = createTimer(now.plusSeconds(secondsDelay))
[|
logInfo("renameRules", "rename rules back in")
executeCommandLine(executeCmdBack)
]
logInfo("renameRules", "timer created")
}
else
{
logInfo("renameRules", "timer already existing")
}
end
rule "rename rules away"
when
System shuts down
then
logInfo("renameRules", "rename rules away")
executeCommandLine(executeCmdAway)
end
Alternative 2: Servicefile and one rule
Pros: rules are correctly named at all times, except for startup
Cons: The patch to the service file has to be done after each update to openHAB, just works on systemd enabled linux variants
Changes:
- a rules file which calls the bash script (/etc/openhab2/rules/moverules.rules)
- an addition to the service definition (/usr/lib/systemd/system/openhab2.service)
The single new rules file (moverules.rules):
val Integer secondsDelay = 240
var Timer renameTimer = null
rule "rename rules back in"
when
System started
then
logInfo("renameRules", "system started triggered")
if (renameTimer === null)
{
renameTimer = createTimer(now.plusSeconds(secondsDelay))
[|
logInfo("renameRules", "rename rules back in")
val String cmd = "/etc/openhab2/exec-scripts/moverules.sh rules_away rules"
executeCommandLine(cmd)
]
logInfo("renameRules", "timer created")
}
else
{
logInfo("renameRules", "timer already existing")
}
end
The addition to the service file (in openhabian this is /usr/lib/systemd/system/openhab2.service )
Just add the line:
...
ExecStartPre=/etc/openhab2/exec-scripts/moverules.sh rules rules_away
...
The complete service file
[Unit]
Description=openHAB 2 - empowering the smart home
Documentation=http://docs.openhab.org
Documentation=https://community.openhab.org
Wants=network-online.target
After=network-online.target
[Service]
Environment=OPENHAB_HOME=/usr/share/openhab2
Environment=OPENHAB_CONF=/etc/openhab2
Environment=OPENHAB_RUNTIME=/usr/share/openhab2/runtime
Environment=OPENHAB_USERDATA=/var/lib/openhab2
Environment=OPENHAB_LOGDIR=/var/log/openhab2
Environment=OPENHAB_STARTMODE=daemon
EnvironmentFile=-/etc/default/openhab2
User=openhab
Group=openhab
WorkingDirectory=/usr/share/openhab2
ExecStartPre=/etc/openhab2/exec-scripts/moverules.sh rules rules_away
ExecStart=/usr/share/openhab2/runtime/bin/karaf $OPENHAB_STARTMODE
ExecStop=/usr/share/openhab2/runtime/bin/karaf stop
SuccessExitStatus=0 143
RestartSec=5
Restart=on-failure
TimeoutStopSec=120
LimitNOFILE=102642
[Install]
WantedBy=multi-user.target
Alternative 3: Servicefile, no rules
Pros: rules are correctly named at all times, except for startup, no rules involved
Cons: The patch to the service file has to be done after each update to openHAB, just works on systemd enabled linux variants
The addition to the service file (in openhabian this is /usr/lib/systemd/system/openhab2.service )
Just add the lines:
...
ExecStartPre=/etc/openhab2/exec-scripts/moverules.sh rules rules_away
...
ExecStartPost=/bin/sleep 240
ExecStartPost=/etc/openhab2/exec-scripts/moverules.sh rules_away rules
...
The complete service file
[Unit]
Description=openHAB 2 - empowering the smart home
Documentation=http://docs.openhab.org
Documentation=https://community.openhab.org
Wants=network-online.target
After=network-online.target
[Service]
Environment=OPENHAB_HOME=/usr/share/openhab2
Environment=OPENHAB_CONF=/etc/openhab2
Environment=OPENHAB_RUNTIME=/usr/share/openhab2/runtime
Environment=OPENHAB_USERDATA=/var/lib/openhab2
Environment=OPENHAB_LOGDIR=/var/log/openhab2
Environment=OPENHAB_STARTMODE=daemon
EnvironmentFile=-/etc/default/openhab2
User=openhab
Group=openhab
WorkingDirectory=/usr/share/openhab2
ExecStartPre=/etc/openhab2/exec-scripts/moverules.sh rules rules_away
ExecStart=/usr/share/openhab2/runtime/bin/karaf $OPENHAB_STARTMODE
ExecStop=/usr/share/openhab2/runtime/bin/karaf stop
ExecStartPost=/bin/sleep 240
ExecStartPost=/etc/openhab2/exec-scripts/moverules.sh rules_away rules
SuccessExitStatus=0 143
RestartSec=5
Restart=on-failure
TimeoutStopSec=120
LimitNOFILE=102642
[Install]
WantedBy=multi-user.target