Update multiple items via REST API?

Is it possible to update multiple items with one REST call? Could I for example send a PUT request to /rest/items with

[
  {
    name: "Item1",
    state: "state1"
  },
  {
    name: "Item2",
    state: "state2"
  }
]

or is this endpoint only for uptating the items configuration?

The reason I’m asking is because I have an external script that connects to a web service for my heating system (uses OAuth2 for authentication, so can’t use rules or the http-binding).I then have a rule that calls this script (which generates a json-string) parses the output and updates the items.

I’m thinking of using the rest api to update the items directly instead, to reduce some unnecessary rules and overhead, but if this would mean I have to make a rest call for each item (about 20 calls each time the script runs), I’m not sure it would be any more efficient. Or maybe this isn’t a problem?

Any tips on how to do this more efficcient are welcome!

is it one JSON for all your 20+ (heating) items? or one JSON for each (heating) item? You could update one proxy item in openHAB with the JSON (provided it has all items in it) and then use that JSON-Transformation for updating your seperate openHAB items’ values?

It is one json for all items, which I get into the rule with executeCommandLine. If I would update one String item with the json data, I would still have to use almost the same rule to parse out the data and update all items, but with an additional item, so wouldn’t reduce the amount of rules unfortunately…

This is my current rule:

rule "Nibe uplink"
	when
		Time cron "15 * * * * ?"
	then
		val hotWaterBoost = Heatpump_Hotwater_Boost.state
		val ventilationBoost = Heatpump_Ventilation_Speed.state
		var parameters = "40004,40067,40013,40014,43416,43420,43136,40050,43066,40032,43084,43009,40047,40048,43008,40007,40129,43005,47011,47010"
		if (hotWaterBoost != 0) { parameters += ",48132" }
		if (ventilationBoost != 0) { parameters += ",47260" }
		val String output = try {
			executeCommandLine("ruby@@/etc/openhab2/scripts/ruby/nu.rb@@-p@@" + parameters + "@@-v@@rawValue", 5000)
		} catch (Exception e) {
			null
		}
		
		if (output !== null && output != "") {
 			Heatpump_Outdoor_Temp.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40004", output)) / 10)
			Heatpump_Status_MeanOutdoorTemp.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40067", output)) / 10)
			Heatpump_HotWater_Top.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40013", output)) / 10)
			Heatpump_HotWater_Bottom.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40014", output)) / 10)
			Heatpump_Compressor_Starts.postUpdate(transform("JSONPATH", "$.43416", output))
			Heatpump_Compressor_ActiveTime.postUpdate(transform("JSONPATH", "$.43420", output))
			val compressorFreq = (Double::parseDouble(transform("JSONPATH", "$.43136", output)) / 10).intValue
			Heatpump_Compressor_Frequency.postUpdate(compressorFreq)
			Heatpump_Airflow.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40050", output)) / 10)
		
			var Number defrost = Integer::parseInt(transform("JSONPATH", "$.43066", output))
			if (defrost > 0 && compressorFreq == 0) {
				Heatpump_Status_Defrost.postUpdate(ON)
			} else {
				Heatpump_Status_Defrost.postUpdate(OFF)
			}
			
			Heatpump_Status_DefrostTime.postUpdate(defrost)
			Heatpump_FF_Temp.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40032", output)) / 10)
			Heatpump_ElectricAddon.postUpdate(Double::parseDouble(transform("JSONPATH", "$.43084", output)) / 100)
			Heatpump_HeatMedium_Calc.postUpdate(Double::parseDouble(transform("JSONPATH", "$.43009", output)) / 10)
			Heatpump_HeatMedium_Flow.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40047", output)) / 10)
			Heatpump_HeatMedium_Return.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40048", output)) / 10)
			Heatpump_FloorHeating_Calc.postUpdate(Double::parseDouble(transform("JSONPATH", "$.43008", output)) / 10)
			Heatpump_FloorHeating_Flow.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40007", output)) / 10)
			Heatpump_FloorHeating_Return.postUpdate(Double::parseDouble(transform("JSONPATH", "$.40129", output)) / 10)
			Heatpump_DegreeMinutes.postUpdate(Integer::parseInt(transform("JSONPATH", "$.43005", output)) / 10)
			Heatpump_Radiators_Adjustment.postUpdate(transform("JSONPATH", "$.47011", output))
			Heatpump_FloorHeating_Adjustment.postUpdate(transform("JSONPATH", "$.47010", output))
			if (hotWaterBoost != 0) { Heatpump_Hotwater_Boost.postUpdate(transform("JSONPATH", "$.48132", output)) }
			if (ventilationBoost != 0) { Heatpump_Ventilation_Speed.postUpdate(transform("JSONPATH", "$.47260", output)) }
		} else {
			logInfo("Nibe uplink", "Empty response")
		}	
	end

I also have a few other rules that checks different aspects of the heatpump, but this is the main one.

ah, ok. I get it now.
I understand also, http-binding doesn’t support OAuth2, so you would have to set a proxy webservice in between, which then provides simple http-response, as I also think, the REST-API only supports one item update at a time…

I used multiple API-calls also, but switched to MQTT, as it is more lightweight. you can do that in two ways:

  1. using MQTT-eventbus
  2. using dedicated item-configuration

ad 1)
this is useful, if you have many items: I update 100+ items via external scripts, so I just use the eventbus-Topic to update my items

ad 2)
if it’s just those 20 items, you could configure them for listening to seperate topics and update them via your script.

in my opinion, if you have an external ressource, you have to decide where you want to plant the logic for importing the values for your items. Otherwise you’ll go crazy finding bugs or if you’d like to add another item or a new function somewhere. My present me always curses my past me for either not documenting enough or scattering logic and updates all over the place… :wink:

so, either you only import the values and do all the Magic in rules within OH2 - or you do all your Magic in your external script and just update the items (again: via REST or MQTT, …) from the outside and you’ll only have the final values within openHAB.

So - long story short: either keep your rules-magic in OH2 (as you have now) or do all your logic within your scripts and just update.

Thanks for the input, haven’t had the need for MQTT yet, but will look into it some more!