Checking and Upgrading OH2 from a Sitemap

I wanted to bring together 3 solutions posted into 1 single topic on how I have included into a sitemap the ability to both check for an OH2 update, and then if an update exists to unhide and press a button (err. switch) to upgrade your OH2 installation.

This was done on a Ubuntu 16 Server system, so the process could be slightly different for Habian and others.

The main 3 steps that need to be done is to.

  1. Add a ‘Sudoers’ file to give your openhab user Sudo access without needing to prompt for any passwords
  2. Create 2 Shell scripts.
  3. Create the OH2 Rules, Items, and SiteMap Info.

As a point of reference, these are the 3 main topics that helped me in getting things done. A BIG thanks to these guys in sharing all their hard work.

edit soduers hxxps://community.openhab.org/t/exec-binding-with-sudo/6482/7
Create Scripts hxxps://community.openhab.org/t/stop-start-oh2-from-sitemap-with-rule-script/37104/9
Create Rules hxxps://community.openhab.org/t/checking-for-openhab-updates-simple-rule/36313

Step 1. Create your openhabcontrol Sudoer’s file and provide Sudo access to the scripts you will need. You MUST do this with viSudo to create the file to avoid messing up your system.

sudo visudo -f /etc/sudoers.d/openhabcontrol

And then add this line to the file

openhab ALL = (ALL) NOPASSWD: ALL

Note 1. IMPORTANT. The file will actually be saved as a ‘tmp’ file. Do NOT change this or you may get locked out of sudo. So the file will save as
’/etc/sudoers.d/openhabcontrol.tmp’

Note 2. Using PASSWD: ALL is a higher risk allowing the user openhab full sudo access without a password. But for some reason, I cannot get restricting access to just 2 scripts to work:

Should work, but doesn’t?
openhab ALL = (ALL) NOPASSWD: /etc/openhab2/scripts/oh-screen.sh, /etc/openhab2/scripts/oh-upgrade.sh

Step 2. Create your 2 scripts. The first one is used to launch the second script inside Screen which will then update OH2 via Stop, update, updgrade, and any other commands you think necessary. ie, I prefer to delete my logs prior to a restart to make it easier to review and find things.

2.1 Create the /etc/openhab2/scripts/oh-screen.sh script

sudo nano /etc/openhab2/scripts/oh-screen.sh

And add this code

#!/bin/bash
sudo -u openhab screen -dmS OHScreen /etc/openhab2/scripts/oh-upgrade.sh

2.2 And the actual upgrade script. /etc/openhab2/scripts/oh-upgrade.sh
Note, the use of Sudo in each line may not be necessary here, but I left it since it works as is. Can probably also combine the apt-get lines as well.

#!/bin/bash
sudo systemctl stop openhab2.service
sleep 30s
sudo apt-get -qq update
sleep 30s
sudo apt-get -qq -y install --only-upgrade openhab2
sleep 90s
sudo rm /var/log/openhab2/openhab.*
sudo rm /var/log/openhab2/events.*
sudo systemctl start openhab2.service
#sudo reboot -h now

Step 3. Create your rules. I decided to go with the ‘Rules’ approach vs the Http binding approach, primarily so that I could check for an OH2 update at any time.

I have 2 rules here. The first rule is based off the earlier rules mentioned above, where I only modified to post the actual Build Number as a Number Item vs a String Item to the sitemap. The first rule will also set a dummy switch to On to unhide (make visible) the Upgrade button in the sitemap. And the second rule runs the actual update script.

The hardest part for me was getting the right syntax combination working in the ExecuteCommand line. The below works passing the info to your openhab user to run the script with sudo permssions. But perhaps their is an easier way.

rule "Check for openHAB distro updates"
when
    System started or
    Time cron "0 0 0 * * ?" or
    Item OH_CheckForUpdates received command ON
then
    OH_Status.postUpdate("Checking...")

    var String cloudbeesUrl =
        "https://openhab.ci.cloudbees.com/job/openHAB-Distribution/api/json?tree=lastSuccessfulBuild[number]"
    var String currentBuild =
        executeCommandLine("/etc/openhab2/scripts/check-oh-build.sh", 2000)

    // logInfo("update", "currentBuild: " + currentBuild)

    var response = sendHttpGetRequest(cloudbeesUrl)
    var lastBuildNumber = transform("JSONPATH", "$.lastSuccessfulBuild.number", response)
    // logInfo("update", "lastBuild: " + lastBuildNumber)

    OH_CurrentBuild.postUpdate(Integer.parseInt(currentBuild))
    OH_LatestBuild.postUpdate(Integer.parseInt(lastBuildNumber))    
    
    if (Integer.parseInt(currentBuild) < Integer.parseInt(lastBuildNumber)) {
        OH_Status.postUpdate("Update available: #" + lastBuildNumber)
        //Make Upgrade Switch Visible on Sitemap
        OH_Upgradeable.postUpdate(ON)
        // Do something with that information
    } else {
        OH_Status.postUpdate("No updates")
        OH_Upgradeable.postUpdate(OFF)
    }

    OH_CheckForUpdates.postUpdate(OFF)
end

rule "Upgrade Openhab"
when
    Item OH_Upgrade received command ON
then
    //Run Upgrade Script in Screen
    executeCommandLine("sudo su -c '/etc/openhab2/scripts/oh-screen.sh' -s /bin/bash openhab", 5000)
    //Reset to Off
    OH_Upgrade.postUpdate(OFF)
end

and then for Items file, I have"

/* Check OH Build */
Switch OH_CheckForUpdates "OH: Check for updates"
String OH_Status          "OH: Status [%s]"
Number OH_CurrentBuild    "Current Build [%d]"
Number OH_LatestBuild     "Latest Build [%d]"
Switch OH_Upgrade         "Upgrade Now?"
Switch OH_Upgradeable

and the sitemap

Frame {
		Text label="openHAB Update" {
    	Switch item=OH_CheckForUpdates  mappings=[ON="Check now!"]
		Text item=OH_Status
		Text item=OH_CurrentBuild
		Text item=OH_LatestBuild
		Switch item=OH_Upgrade mappings=[ON="Run Upgrade"] visibility=[OH_Upgradeable == ON]
		}
  	}
2 Likes

It would be safer to only give openhab sudo with no password on just that command(s) it needs. With this configuration you have effectively made the openhab user root. In this case only give systemctl and apt-get permissions
.

You certainly don’t need the 30 second sleep between the apt-get commands.

Thanks for posting! Great tutorial!

3 Likes

I can´t get it to work.

Do i have to remove the # from the last line in sudoers-file?

#includedir /etc/sudoers.d/

remove # --- yes or no?

I made a separat openhabcontrol-file inside sudoers.d-directory.

Don’t remove the #, this is part of the command

1 Like

Thanks, now it works.

I can check current Version and last Version already.

Which way is better to ckeck for new versions and why?

With cronjob inside rule or with http-binding and “when item changes”-rule?

Or is there no big difference and i can use the version i like?

What would be, if you have to answer some questions on OH update?

Sometimes there are new configuration files and you will be asked what should be done with them? Overwrite / Keep the old and so on…

How will this be handled with the script from the first post?

-qq -y

means always answer YES and quiet install? So i will not get any information, if there has something changed on my config?

Is there a way to show the date and time of the last update i made on my openhab server?

I can see, the file /var/lib/openhab2/etc/version.properties mas made on that time. Can i read out the data and show on my sitemap?

Got it working:

check-oh-date.sh:

#!/bin/bash
stat -c %z /var/lib/openhab2/etc/version.properties | cut -f3  | cut -c1-19

oh_update.rule


val currentBuild = new Integer(executeCommandLine("/etc/openhab2/scripts/check-oh-build.sh", 2000))
val currentDate = executeCommandLine("/etc/openhab2/scripts/check-oh-date.sh", 2000)


rule "openhab current build at startup"
when
    System started
then
    OH_CurrentBuild.postUpdate(currentBuild)
	OH_CurrentDate.postUpdate(currentDate)
end
...

oh_update.items:

...
String OH_CurrentDate      "OH: CurrentDate [%s]"
...

Only thing i haven´t figured out, is how i can format the string output to a better readable format.

Now i get:

currentDate: 2017-12-21 09:11:43

How can i format this in this way: 21.12.2017, 09:11:43

???

Hi, This might help with the format specifiers: string format examples. Good luck.

The other way it is working: simpledateformat —> string:

    var SimpleDateFormat df = new SimpleDateFormat( "dd.MM., HH:mm" )
    var String timestamp = df.format( new Date() )
    time-item.postUpdate(timestamp)

But how can i do the other way? string —> simpledateformat

This is my current string-value: 2018-01-03 12:50:00

take a look at this posting:

Thank you, that helped a little bit.

Now i have a variable DateTime.

How can i get an datetime-item out of this?

Here is my current rule:

import java.util.Date
import java.text.SimpleDateFormat

val currentDate = executeCommandLine("/etc/openhab2/scripts/check-oh-date.sh", 2000)

rule "openhab current build at startup"
when
    System started
then
    OH_CurrentDate.postUpdate(currentDate)
    var currentDate_split = currentDate.toString().split(" ")
    var DateTime dtcurrentDate = parse(currentDate_split.get(0) + "T" + currentDate_split.get(1))
    logInfo("OH Update - current date split", "datetime ---> " + dtcurrentDate)
    OH_dt_CurrentBuild.postUpdate(dtcurrentDate)
end

Log:

2018-01-04 09:35:31.320 [INFO ] [cript.OH Update - current date split] - datetime ---> 2018-01-03T11:36:40.000+01:00
2018-01-04 09:36:24.568 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Error during the execution of startup rule 'openhab current build at startup': Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.postUpdate(org.eclipse.smarthome.core.items.Item,java.lang.Number) on instance: null

items:

String   OH_CurrentDate      "OH: letztes Update durchgeführt [%s]"
DateTime OH_dt_CurrentBuild  "OH: letztes Update [%1$td.%1$tm., %1$tH:%1$tM]"

I think the error is because of:

variable DateTime != item DateTime

But how can i convert a datetime-var to a datetime-item?

I think i got the answer by myself.

This seems to work:

rule:

    OH_dt_CurrentBuild.postUpdate(dtcurrentDate.toString)
    logInfo("OH Update - current date split", "datetime ---> " + OH_dt_CurrentBuild)

Logfile:

2018-01-04 11:15:45.550 [INFO ] [cript.OH Update - current date split] - datetime ---> OH_dt_CurrentBuild (Type=DateTimeItem, State=2018-01-03T11:36:40.000+0100, Label=OH: letztes Update, Category=null)
1 Like