Convert string of values to key/value object

Hi,
I am reading the SMART values from a Harddrive and getting the following payload back:

{
  "health":"PASSED",
  "type":"text",
  "wearout":90,
  "text":"\n
     SMART/Health Information (NVMe Log 0x02)
	 \n
	 Critical Warning:                   0x00
	 \n
	 Temperature:                        42 Celsius
	 \n
	 Available Spare:                    100%
	 \n
	 Available Spare Threshold:          100%
	 \n
	 Percentage Used:                    10%
	 \n
	 Data Units Read:                    43,125,108 [22.0 TB]
	 \n
	 Data Units Written:                 16,184,137 [8.28 TB]
	 \n
	 Host Read Commands:                 636,777,953
	 \n
	 Host Write Commands:                803,393,168
	 \n
	 Controller Busy Time:               4,597
	 \n
	 Power Cycles:                       89
	 \n
	 Power On Hours:                     15,157
	 \n
	 Unsafe Shutdowns:                   37
	 \n
	 Media and Data Integrity Errors:    0
	 \n
	 Error Information Log Entries:      0
	 \n
	 Warning  Comp. Temperature Time:    0
	 \n
	 Critical Comp. Temperature Time:    0
	 \n
	 Temperature Sensor 2:               42 Celsius
	 \n
	 \n"
}

Now, I want to work with the "text" and either create a new JSON output from it, like:

{
  "SMART/Health Information (NVMe Log 0x02)":
  {
    "Critical Warning":0x00,
    "Temperature":"42 Celsius", //maybe this can be modified to 42 (without 'celsius')
    "Available Spare":"100%", //maybe this can be modified to 100 without percentage
    "Available Spare Threshold":"100%", //maybe this can be modified to 100 without percentage
    "Percentage Used":"10%", //maybe this can be modified to 100 without percentage
    "Data Units Read":"43,125,108 [22.0 TB]",
    "Data Units Written":"16,184,137 [8.28 TB]",
    "Host Read Commands":"636,777,953",
    "Host Write Commands":"803,393,168",
    "Controller Busy Time":"4,597",
    "Power Cycles":89,
    "Power On Hours":"15,157",
    "Unsafe Shutdowns":37,
    "Media and Data Integrity Errors":0,
    "Error Information Log Entries":0,
    "Warning  Comp. Temperature Time":0,
    "Critical Comp. Temperature Time":0,
    "Temperature Sensor 2":"42 Celsius" //maybe this can be modified to 42 (without 'celsius')
  }
}

Thanks and with best regards,
Christoph

There are a few examples of this around the forum.

For example, you could easily adapt this: Help converting string to key/value object - #2 by Steve-Mcl

E.g...

const lines = msg.payload.split("\n");
let result = {};

for (let i = 0; i < lines.length ; i++) {
    const line = lines[i].trim();
    if(!line) continue;
    let parts = line.split(":");
    if(parts.length != 2) continue;
    let key = parts[0].trim();
    let val = parts[1].trim();
    if(isNumeric(val)) val = Number(val)
    result[key] = val;
}

msg.payload = result;
return msg;

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

:point_up: Untested - may need tweaking

thanks, I will test it with this and reply a feedback

This should remove % and Celsius from the result

const lines = msg.payload.text.split(/\n/).filter(e =>  e.trim() !== "");
let obj = lines[0].trim();
let output = {[obj]:{}};
for (i = 1; i < lines.length; i++){
      let parts = lines[i].split(":");
      let key = parts[0].trim();
      let bit = parts[1].split(/%|Celsius/)[0].trim()
      if (!isNaN(bit)){
          bit = Number(bit)
      }
      output[obj][key] = bit;
}
msg.payload = output;
return msg;
1 Like