Update: February 4, 2023
The issues with myopenhab connections appear to have been solved. Hooray!
Over the past year or so, users have found that their openHAB server are unexpectedly disconnecting from myopenHAB and then immediately reconnecting. However, myopenHAB continues to think that the OH server is offline, so you can’t access it remotely.
While our developers continue working on the problem, I’ve cobbled together a solution for automatically restarting the cloud connector when this happens. It’s based on these posts:
- Display Myopenhab cloud connection status - Checking the log for disconnects/reconnects
- Myopenhab not reachable - Sending POST commands to myopenHAB
- Myopenhab not reachable - Restarting a binding
Constructive feedback and suggestions are welcome and appreciated.
Note that there are other solutions in the community that use different methods. Feel free to mention them in this post so that we can collect them all in one spot.
1. Install bindings and transformations
Start by installing these add-ons, if you don’t already have them:
2. Turn on Implicit User Role
Check that the Implicit User Role is ON
in your API Security settings (it most likely is).
3. Make an unbound item to store the testing message
Create a string item that has no channel attached to it. Mine is called myopenHAB_Connection
.
When the connnection test starts, the string will be updated to Testing
. We’ll then send a command through myopenHAB to change the string to Online
. If the command succeeds, it’s not necessary to restart the cloud connector.
If you want, you can add this item to a page or sitemap as an indicator of the cloud status.
4. Make a thing and item to send a POST command to myopenHAB
-
In MainUI, manually add a thing using the Exec Binding. You can edit the ID and label to be whatever you want them to be (mine is called
Post_Test_Command
). -
Enter the following statement in the
Command
field, substituting in your myopenHAB username and password:curl -u username:password -H "Content-Type: text/plain" -X POST -d "Online" https://myopenhab.org/rest/items/myopenHAB_Connection
This curl command changes the string in the
myopenHAB_Connection
item to beOnline
. -
Click the “Create thing” button to save your work.
-
Create a switch item that’s connected to the
Running
channel of your exec thing (I’ve called my itemPost_Test_Command
). When this item is turnedON
, it will execute the shell command and then reset itself toOFF
.
5. Make a thing and item to restart the cloud connector
-
In MainUI, add another thing using the Exec Binding. You can edit the ID and label to be whatever you want them to be.
-
Enter the following statement in the
Command
field:openhab-cli console -p habopen bundle:restart org.openhab.io.openhabcloud
This shell command will log into the console and restart the openhabcloud bundle.
NOTE:
habopen
is the default password for the console (which is different from the password you use to log into your server via SSH. Most users leave it as `habopen’, but if you’ve changed it then you’ll need to change it here as well. -
Click the “Create thing” button to save your work.
-
Create a switch item that’s connected to the
Running
channel of your exec thing (I’ve called my itemRestart_Cloud_Connector
).
6. Add the exec commands to the exec.whitelist
Before you can execute a shell command, it has to be added to the exec.whitelist
file, which you’ll find in the openhab-conf/misc
folder on your OH server.
-
Open
exec.whitelist
in a text editor and insert the commands we used in our exec things:curl -u username:password -H "Content-Type: text/plain" -X POST -d "Online" https://myopenhab.org/rest/items/myopenHAB_Connection
openhab-cli console -p habopen bundle:restart org.openhab.io.openhabcloud
Don’t forget to update your username, password, and item name (if you changed it from
myopenHAB_Connection
). The commands in your exec things must be identical to the whitelist. -
Save and close
exec.whitelist
.
7. Test your exec items
At this point, your items should work. You can add them to a page or sitemap and toggle them on to see the results in your log.
8. Make a thing to monitor the log
-
In MainUI, manually add a thing using the Log Reader Binding. For the ID and label, I’ve used:
- ID:
openhabcloud
- Label:
LogReader: openHAB Cloud
- ID:
-
In the
Custom Patterns
field, enter the following string:Connected to the openHAB Cloud service
The thing will monitor the log and update whenever it sees this exact string of text.
NOTE: We installed the REGEX Transformation earlier so that it can be used by this item (using the default settings). You don’t need to do anything else with REGEX.
-
Click the “Create thing” button to save your work.
The log reader thing has an an advanced channel called
New Custom Event
. It can be used to trigger a rule without needing an item (though you can also make a switch if you prefer).So, let’s make that rule.
9. Restart the binding whenever a disconnect is detected
Apologies for the fact that I’m still using Rules DSL. In a nutshell, this rule does the following:
- Triggers whenever openHAB reconnects to myopenHAB.
- Updates the
myopenHAB_Connection
string item toTesting
- Sends a command through the cloud to change
myopenHAB_Connection
string item toOnline
- Checks if
myopenHAB_Connection
changed toOnline
- Restarts the binding if the
Online
command was not received
And that’s all. The hard part is really getting the things/items set up, but only if you’ve never used the exec or log reader bindings before.
Some things to note:
- The rule will trigger every time it sees the “Connected to…” message in the log. So, it will loop continuously until it successfully reconnects. For this reason, I’ve set a five-minute waiting period in case there are multiple disconnects/reconnects in a brief span of time.
- The rule will not run unless it sees the “Connected to…” message. So, if there’s an actual myopenHAB outage, we won’t keep pinging it with this rule and potentially making things worse.
As I said earlier, constructive feedback and suggestions are welcome and appreciated.
var Timer Cloud_Test_Timer = null
rule "Restart cloud connector following an unsuccessful reconnection"
when
Channel "logreader:reader:openhabcloud:newCustomEvent" triggered
then
//Cancel any running timers. This is in case you have multiple disconnections/reconnections in a short time frame.
Cloud_Test_Timer?.cancel
//Set the testing status message
myopenHAB_Connection.postUpdate("Testing")
//Post a command to reset myopenHAB_Connection through the cloud
Post_Test_Command.sendCommand(ON)
//Wait 300 seconds, then restart the cloud connector if myopenHAB_Connection has not been updated to "Online" by the REST command
Cloud_Test_Timer = createTimer(now.plusSeconds(300),
[|
if (myopenHAB_Connection.state == "Testing")
{
logInfo("openHAB Cloud", "Restarting cloud connector due to unsuccessful reconnection")
sendNotification("russ@scatterthought.com", "openHAB Cloud connector restarted")
Restart_Cloud_Connector.sendCommand(ON)
}
else
{
logInfo("openHAB Cloud", "Successful reconnection to myopenHAB")
}
])
end
Bonus rule with counter
Just for fun, this version has a counter that increments every time there’s a successful reconnection and resets when the cloud connector is restarted. The counter requires another unbound item (similar to myopenHAB_Connection
), which I’ve called myopenHAB_Connection_Success
.
var Timer Cloud_Test_Timer = null
var Counter = null
rule "Restart cloud connector following an unsuccessful reconnection"
when
Channel "logreader:reader:openhabcloud:newCustomEvent" triggered
then
//Cancel any running timers. This is in case you have multiple disconnections/reconnections in a short time frame.
Cloud_Test_Timer?.cancel
//Set the testing status message
myopenHAB_Connection.postUpdate("Testing")
//Post a command to reset myopenHAB_Connection through the cloud
Post_Test_Command.sendCommand(ON)
//Wait 300 seconds, then restart the cloud connector if myopenHAB_Connection has not been updated to "Online" by the REST command
Cloud_Test_Timer = createTimer(now.plusSeconds(300),
[|
if (myopenHAB_Connection.state == "Testing")
{
logInfo("openHAB Cloud", "Restarting cloud connector due to unsuccessful reconnection")
sendNotification("russ@scatterthought.com", "Cloud connector restarted after " + myopenHAB_Connection_Success.state.toString + " successful reconnections")
Restart_Cloud_Connector.sendCommand(ON)
myopenHAB_Connection_Success.postUpdate(0)
}
else
{
//Initialize the counter so that the rule won't fail due to a NULL value
if (myopenHAB_Connection_Success.state == "NULL") { myopenHAB_Connection_Success.postUpdate(0) }
//Increment the counter after a successful reconnection
var Counter = ((myopenHAB_Connection_Success.state as Number) + 1)
myopenHAB_Connection_Success.postUpdate(Counter.toString)
// logInfo("openHAB Cloud", "Successful reconnections to myopenHAB: " + Counter.toString)
}
])
end