Parsing OpenHardwareMonitor JSON / null values

Tags: #<Tag:0x00007f5c950d8bf0> #<Tag:0x00007f5c950d8b28> #<Tag:0x00007f5c950d8998>
  • Platform information:
    • Hardware: Microsoft Surface 3 Pro / i5 4300U / 4GB RAM
    • OS: Windows 10
    • Java Runtime Environment: Java 8 Update 241
    • openHAB version: 2.5.0 Release Build
  • Issue of the topic:
    im trying to integrate OpenHardwareMonitor into openHAB.
    OHWM is running as server and i get a data.json at port 8092 that looks like this:
{
	"id": 0,
	"Text": "Sensor",
	"Children": [{
			"id": 1,
			"Text": "HOMESERV01",
			"Children": [{
					"id": 2,
					"Text": "Surface Pro 3",
					"Children": [],
					"Min": "",
					"Value": "",
					"Max": "",
					"ImageURL": "images_icon/mainboard.png"
				}, {
					"id": 3,
					"Text": "Intel Core i5-4300U",
					"Children": [{
							"id": 4,
							"Text": "Clocks",
							"Children": [{
									"id": 5,
									"Text": "Bus Speed",
									"Children": [],
									"Min": "100 MHz",
									"Value": "100 MHz",
									"Max": "100 MHz",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 6,
									"Text": "CPU Core #1",
									"Children": [],
									"Min": "798 MHz",
									"Value": "798 MHz",
									"Max": "2893 MHz",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 7,
									"Text": "CPU Core #2",
									"Children": [],
									"Min": "798 MHz",
									"Value": "798 MHz",
									"Max": "2893 MHz",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/clock.png"
						}, {
							"id": 8,
							"Text": "Temperatures",
							"Children": [{
									"id": 9,
									"Text": "CPU Core #1",
									"Children": [],
									"Min": "54,0 °C",
									"Value": "64,0 °C",
									"Max": "79,0 °C",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 10,
									"Text": "CPU Core #2",
									"Children": [],
									"Min": "56,0 °C",
									"Value": "67,0 °C",
									"Max": "79,0 °C",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 11,
									"Text": "CPU Package",
									"Children": [],
									"Min": "56,0 °C",
									"Value": "67,0 °C",
									"Max": "79,0 °C",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/temperature.png"
						}, {
							"id": 12,
							"Text": "Load",
							"Children": [{
									"id": 13,
									"Text": "CPU Total",
									"Children": [],
									"Min": "1,5 %",
									"Value": "41,9 %",
									"Max": "100,0 %",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 14,
									"Text": "CPU Core #1",
									"Children": [],
									"Min": "0,8 %",
									"Value": "50,0 %",
									"Max": "100,0 %",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 15,
									"Text": "CPU Core #2",
									"Children": [],
									"Min": "0,8 %",
									"Value": "33,8 %",
									"Max": "100,0 %",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/load.png"
						}, {
							"id": 16,
							"Text": "Powers",
							"Children": [{
									"id": 17,
									"Text": "CPU Package",
									"Children": [],
									"Min": "1,6 W",
									"Value": "10,7 W",
									"Max": "14,5 W",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 18,
									"Text": "CPU Cores",
									"Children": [],
									"Min": "0,1 W",
									"Value": "7,6 W",
									"Max": "10,8 W",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 19,
									"Text": "CPU Graphics",
									"Children": [],
									"Min": "0,0 W",
									"Value": "0,0 W",
									"Max": "0,6 W",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 20,
									"Text": "CPU DRAM",
									"Children": [],
									"Min": "0,2 W",
									"Value": "0,4 W",
									"Max": "0,7 W",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/power.png"
						}
					],
					"Min": "",
					"Value": "",
					"Max": "",
					"ImageURL": "images_icon/cpu.png"
				}, {
					"id": 21,
					"Text": "Generic Memory",
					"Children": [{
							"id": 22,
							"Text": "Load",
							"Children": [{
									"id": 23,
									"Text": "Memory",
									"Children": [],
									"Min": "42,4 %",
									"Value": "59,1 %",
									"Max": "69,1 %",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/load.png"
						}, {
							"id": 24,
							"Text": "Data",
							"Children": [{
									"id": 25,
									"Text": "Used Memory",
									"Children": [],
									"Min": "1,7 GB",
									"Value": "2,3 GB",
									"Max": "2,7 GB",
									"ImageURL": "images/transparent.png"
								}, {
									"id": 26,
									"Text": "Available Memory",
									"Children": [],
									"Min": "1,2 GB",
									"Value": "1,6 GB",
									"Max": "2,3 GB",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/power.png"
						}
					],
					"Min": "",
					"Value": "",
					"Max": "",
					"ImageURL": "images_icon/ram.png"
				}, {
					"id": 27,
					"Text": "Generic Hard Disk",
					"Children": [{
							"id": 28,
							"Text": "Load",
							"Children": [{
									"id": 29,
									"Text": "Used Space",
									"Children": [],
									"Min": "53,6 %",
									"Value": "53,6 %",
									"Max": "53,6 %",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/load.png"
						}
					],
					"Min": "",
					"Value": "",
					"Max": "",
					"ImageURL": "images_icon/hdd.png"
				}, {
					"id": 30,
					"Text": "SAMSUNG MZMTE128HMGR-000MV",
					"Children": [{
							"id": 31,
							"Text": "Temperatures",
							"Children": [{
									"id": 32,
									"Text": "Temperature",
									"Children": [],
									"Min": "39,0 °C",
									"Value": "39,0 °C",
									"Max": "43,0 °C",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/temperature.png"
						}, {
							"id": 33,
							"Text": "Load",
							"Children": [{
									"id": 34,
									"Text": "Used Space",
									"Children": [],
									"Min": "32,7 %",
									"Value": "32,7 %",
									"Max": "32,7 %",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/load.png"
						}, {
							"id": 35,
							"Text": "Data",
							"Children": [{
									"id": 36,
									"Text": "Total LBA Written",
									"Children": [],
									"Min": "-347,3 GB",
									"Value": "-347,0 GB",
									"Max": "-347,0 GB",
									"ImageURL": "images/transparent.png"
								}
							],
							"Min": "",
							"Value": "",
							"Max": "",
							"ImageURL": "images_icon/power.png"
						}
					],
					"Min": "",
					"Value": "",
					"Max": "",
					"ImageURL": "images_icon/hdd.png"
				}
			],
			"Min": "",
			"Value": "",
			"Max": "",
			"ImageURL": "images_icon/computer.png"
		}
	],
	"Min": "Min",
	"Value": "Value",
	"Max": "Max",
	"ImageURL": ""
}

now i wrote myself a little console program that gets me .items files with the following content:

String HOMESERV01_MAINBOARD_NAME (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[0].Text)]" }
String HOMESERV01_CPU_NAME (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Text)]" }
Number HOMESERV01_CPU_CLOCKS_BUS_SPEED "[%.0f MHz]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[0].Children[0].Value)]" }
Number HOMESERV01_CPU_CLOCKS_CPU_CORE_1 "[%.0f MHz]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[0].Children[1].Value)]" }
Number HOMESERV01_CPU_CLOCKS_CPU_CORE_2 "[%.0f MHz]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[0].Children[2].Value)]" }
Number HOMESERV01_CPU_TEMPERATURES_CPU_CORE_1 "[%.1f °C]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[1].Children[0].Value)]" }
Number HOMESERV01_CPU_TEMPERATURES_CPU_CORE_2 "[%.1f °C]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[1].Children[1].Value)]" }
Number HOMESERV01_CPU_TEMPERATURES_CPU_PACKAGE "[%.1f °C]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[1].Children[2].Value)]" }
Number HOMESERV01_CPU_LOAD_CPU_TOTAL "[%.1f %]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[2].Children[0].Value)]" }
Number HOMESERV01_CPU_LOAD_CPU_CORE_1 "[%.1f %]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[2].Children[1].Value)]" }
Number HOMESERV01_CPU_LOAD_CPU_CORE_2 "[%.1f %]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[2].Children[2].Value)]" }
Number HOMESERV01_CPU_POWERS_CPU_PACKAGE "[%.1f W]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[3].Children[0].Value)]" }
Number HOMESERV01_CPU_POWERS_CPU_CORES "[%.1f W]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[3].Children[1].Value)]" }
Number HOMESERV01_CPU_POWERS_CPU_GRAPHICS "[%.1f W]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[3].Children[2].Value)]" }
Number HOMESERV01_CPU_POWERS_CPU_DRAM "[%.1f W]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[1].Children[3].Children[3].Value)]" }
String HOMESERV01_RAM_NAME (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[2].Text)]" }
Number HOMESERV01_RAM_LOAD_MEMORY "[%.1f %]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[2].Children[0].Children[0].Value)]" }
Number HOMESERV01_RAM_DATA_USED_MEMORY "[%.1f GB]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[2].Children[1].Children[0].Value)]" }
Number HOMESERV01_RAM_DATA_AVAILABLE_MEMORY "[%.1f GB]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[2].Children[1].Children[1].Value)]" }
String HOMESERV01_HDD_NAME (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[3].Text)]" }
Number HOMESERV01_HDD_LOAD_USED_SPACE "[%.1f %]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[3].Children[0].Children[0].Value)]" }
String HOMESERV01_HDD1_NAME (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[4].Text)]" }
Number HOMESERV01_HDD1_TEMPERATURES_TEMPERATURE "[%.1f °C]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[4].Children[0].Children[0].Value)]" }
Number HOMESERV01_HDD1_LOAD_USED_SPACE "[%.1f %]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[4].Children[1].Children[0].Value)]" }
Number HOMESERV01_HDD1_DATA_TOTAL_LBA_WRITTEN "[%.1f GB]" (HOMESERV01) {http="<[serverinfo:JSONPATH($.Children[0].Children[4].Children[2].Children[0].Value)]" }

where each line would be a seperate .items file i just copied them together for this thread.

the http config looks like this:

# timeout in milliseconds for the http requests (optional, defaults to 5000)
#timeout=5000

# the interval in milliseconds when to find new refresh candidates
# (optional, defaults to 1000)
#granularity=

# whether to substitute the current time or state value into the URL
# (optional, defaults to true)
#format=

# configuration of the first cache item
#<id1>.url=
#<id1>.updateInterval=

# configuration of the second cache item  
#<id2>.url=
#<id2>.updateInterval=

serverinfo.url=http://192.168.92.53:8092/data.json
serverinfo.updateInterval=1000

riginfo.url=http://192.168.92.29:8092/data.json
riginfo.updateInterval=1000

doing this, the items do show up in paperUI but only string items show in HABmin and HABpanel does allow binding items to dummy widgets but they all just display null.

im sure im missing something here. this is my first time setting up openhab after all and im really not fully in the know about inner workings of it yet.

can someone maybe already tell some stupid mistake i made or step i overlooked?
i know the values are all represented as string in the json and i do need to figure out some way to read and correctly parse them into number but even then values that actually are string show up as null so i have no clue what im doing wrong

Have you looked in your openhab.log and events.log ?

not a single entry in the events.log about it
openhab.log does contain the same error a bunch of times:

2020-02-20 13:10:23.544 [ERROR] [org.apache.felix.configadmin        ] - [org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler, id=520, bundle=291/mvn:org.openhab.binding/org.openhab.binding.http/[1.14.0,1.15)]: Unexpected problem updating configuration org.openhab.http
java.lang.NumberFormatException: For input string: "1000.0"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[?:1.8.0_241]
	at java.lang.Integer.parseInt(Integer.java:580) ~[?:1.8.0_241]
	at java.lang.Integer.valueOf(Integer.java:766) ~[?:1.8.0_241]
	at org.openhab.binding.http.internal.HttpBinding.updated(HttpBinding.java:535) ~[?:?]
	at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updated(ManagedServiceTracker.java:189) ~[bundleFile:?]
	at org.apache.felix.cm.impl.helper.ManagedServiceTracker.updateService(ManagedServiceTracker.java:152) [bundleFile:?]
	at org.apache.felix.cm.impl.helper.ManagedServiceTracker.provideConfiguration(ManagedServiceTracker.java:85) [bundleFile:?]
	at org.apache.felix.cm.impl.ConfigurationManager$UpdateConfiguration.run(ConfigurationManager.java:1405) [bundleFile:?]
	at org.apache.felix.cm.impl.UpdateThread.run0(UpdateThread.java:138) [bundleFile:?]
	at org.apache.felix.cm.impl.UpdateThread.run(UpdateThread.java:105) [bundleFile:?]
	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_241]

but i cant really tell what to do about it from just reading it

Perhaps you already figured this out, but it’s trying to parse the string “1000.0” as an Integer, which fails.

Unfortunately, looking through the json sample from above, I don’t see any attributes that have a value of “1000.0”.

This would appear to indicate the problem is in the http config, not in the parsed value.
Guessing the answer is to clear the cached config and restart a few times…

Good catch. I should’ve scrolled a little farther to the right…

but i posted the config i dont see anything wron with it and also i have tried clearing the cache via console even uninstalled the http binding and deleted the actual http.config not just the .cfg
but as soon as i go to reinstall it and and reconfigure i get the same message.

also what do you mean by restart “a few times” what effect would that have?

alright so i got the issues figured out by following the openhab.log and manually correcting the mentionend files.

now i actually do finally get the values of string items shown in habpanel but number items still return null.

im assuming i need to do some sort of transformation but im not sure what and how. ill do some reading but im also happy for any input you guys might have

What was wrong with your config, then? It was not obvious.
There is bit of confusion about .cfg/.config with version 1.x bindings. Make your settings in xxx.cfg - the other xxx.config is created by system.
In case of trouble, stop OH, delete xxx.config, restart (it gets recreated)

well initially i had just put my caching items in brackets into the cfg.
so
.url
instead of
serverinfo.url

and changing the cfg didnt translate to the generated file so i had to chase after them manually and correct them. now it run with no entrys in openhab.log

but again my number items still show up as null

1 Like

In the first instance, I’d make another test String type Item with the same http link as one of your Numbers.
Just to make sure your JSONPATH works and yields what you expect.

Looking through your JSON source though, there do not appear to be any numeric values.
"Min": "53,6 %",
for an example is a string, with non-numeric characters.

EDIT - So, how to deal with that?

HTTP is a version 1.x binding, it does not support the use of channel profiles to transform between binding and Item. That’s out.

HTTP is a version 1.x binding, it does not support the chaining of multiple transforms, if you use JSONPATH you cannot use another transform or script as well. JSONPATH cannot convert the strings.

However you could use a JS javascript transform with this binding. This could include both JSON analysis and conversion of string to strictly numeric.
This would allow linking to Number type Items.
You’d need a unique script for each Item (because of the unique JSON path), it’s rather clumsy.

HTTP is a version 1.x binding, it does not really understand the Units of Measurement framework in openHAB. This is worth a try but I do not expect success - link a field like “53,6 %” to a Number:Dimensionless type Item (which understands %). I don’t know if the comma decimal will give trouble here.

If all else fails, rules.
With the use of Groups and “associated Item” naming convention, you should be able to construct a single rule that triggers on raw-string-Item changing, analyses the string into a number with units, and updates a paired number-with-units Item.

yes. i just switched them all to string (was easier than changing a single one) and the values are displayed correctly.

but you are right the jon only contains strings and i need to figure a way to parse them so i can display them properly in charts and dials or whatever

looking at it a simple .split(’ ').get(0) should do the trick i think but i dont know where to put that. do i need a transformation or something?

Previous post updated with possible courses of action.

It would be really really helpful if statements like that were accompanied by what is actually displayed. You get units, right? We cannot see what you see.

sorry, youre right heres a screenshot of a roughly thrown together habpanel where all items are strings

1 Like

Off-topic - Interesting it struggles with the degrees symbol, code mismatch somewhere.

yeah i was wondering about that as well. looks like ome encoding mismatch but not sure where to look for that yet and would be irrelevant i think if i only really want the number anyway

just found out the openhardwaremonitor is not only open source but unlike crystaldiskinfo its written in c# so maybe its easier for me to just compile my own OHWM version and change the incoming json to mkae the values actual number values

Why discard information? I offered different suggestions.

yes and i am grateful but this wa seems…easier? also i dont need that information i can already map format based on “CLOCKS” ,“TEMPERATURES” and so on.