Skip to content

Instantly share code, notes, and snippets.

@jsheph
Forked from wivaku/nodered_function.js
Last active April 29, 2024 01:14
Show Gist options
  • Save jsheph/a86abfceb31740409c101134c138d218 to your computer and use it in GitHub Desktop.
Save jsheph/a86abfceb31740409c101134c138d218 to your computer and use it in GitHub Desktop.
// This is a modified version of wivaku's script located at https://gist.github.com/wivaku/2d0dde069b4575a85e2d0c8f90342043
// Updated version of the very useful post: https://sixtymeters.com/automations/exporting-apple-health-data-to-home-assistant/
// preferred key names
const fieldKeyLookup = {
qty: 'value',
Avg: 'avg',
Min: 'min',
Max: 'max',
};
// Convert an ISO date string with timezone to UTC timestamp in nanoseconds.
function isoToUTCUnixNanos(dateStr) {
const date = new Date(dateStr);
if (isNaN(date.getTime())) {
console.error(`Invalid date detected: ${dateStr}`);
return null;
}
// Convert to milliseconds and then to nanoseconds for InfluxDB 1.x
const unixNanos = date.getTime() * 1e6;
console.log(`Converted Date to UTC Unix Nanoseconds: ${unixNanos} for Original Date: ${dateStr}`);
return unixNanos;
}
msg.payload = msg.payload.data.metrics.map(metric => {
return metric.data.map(measurement => {
const timestamp = isoToUTCUnixNanos(measurement.date);
if (!timestamp) {
console.error('Skipping measurement due to invalid timestamp.');
return null;
}
delete measurement.date;
var fields = {};
Object.keys(measurement).forEach(key => {
if (typeof measurement[key] !== 'object') fields[fieldKeyLookup[key] || key] = measurement[key];
});
if (fields.min && fields.max && fields.min === fields.max) {
delete fields.min;
delete fields.max;
}
return {
measurement: metric.name, // active_energy
fields: fields, // {value: 5} or {systolic:120, diastolic: 70}, etc
tags: {
unit: metric.units // e.g., kJ
},
timestamp: timestamp //2021-03-16 00:00:00 +0100
};
});
// we've created array for each metric consisting of array of measurements
// just in case, only return entries with fields
}).flat().filter(entry => entry !== null && Object.keys(entry.fields).length);
return msg;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment