Reads sensor values and times from a CSV file or a live feed and flags a reading as high or low against the asset's limits.
How the precision is kept
A value is converted from text by Number() after a strict pattern check, so it is the nearest 64-bit number to what the file says. With a decimal comma, spaces and thousands points are removed and the comma becomes a point. A reading is flagged only when it is strictly above the high limit or strictly below the low limit; there is no tolerance.
Calculations under this policy
3 calculations in 1 source file. The code is read from the released app when this page loads. It is the calculation people run, not a copy kept for this page.
Text that is not a plain decimal or exponent form gives NaN. In decimal-comma mode a point followed by exactly three digits is taken as a thousands separator and removed, then the first comma becomes the decimal point.
assets-bim-sensors.js
lines 67 to 72
BimCraft 0.8.1
export function numOf(s, decimalComma = false) {
let v = String(s ?? '').trim();
if (!v) return NaN;
if (decimalComma) v = v.replace(/\s/g, '').replace(/\.(?=\d{3}(\D|$))/g, '').replace(',', '.');
return /^[+-]?(\d+(\.\d*)?|\.\d+)([eE][+-]?\d+)?$/.test(v) ? Number(v) : NaN;
}
Time text as milliseconds
64-bit
The time of a reading, from Unix time or a written date and time.
Unix seconds × 1000; with a zone: UTC ms − sign × (hh × 60 + mm) × 60000
A number below 1e11 is multiplied by 1000 as seconds. The fraction of a second is cut to its first three digits, not rounded. The zone offset is subtracted as whole milliseconds.
assets-bim-sensors.js
lines 50 to 66
BimCraft 0.8.1
/** A time cell → ms since 1970 (UTC), or NaN. A time with no zone is read in the browser's own zone, as people write them. */
export function timeOf(s) {
const v = String(s ?? '').trim();
if (!v) return NaN;
if (/^\d{9,13}(\.\d+)?$/.test(v)) { const x = Number(v); return x < 1e11 ? x * 1000 : x; } // Unix seconds or milliseconds
const m = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.(\d+))?)?)?\s*(Z|[+-]\d{2}:?\d{2})?$/.exec(v);
if (!m) return NaN;
const [, Y, Mo, D, h = '0', mi = '0', se = '0', frac = '0', z] = m;
const ms = Number(('0.' + frac).slice(0, 5)) * 1000;
const parts = [+Y, +Mo - 1, +D, +h, +mi, +se, ms];
const d = new Date(Date.UTC(...parts));
if (d.getUTCFullYear() !== +Y || d.getUTCMonth() !== +Mo - 1 || d.getUTCDate() !== +D || +h > 23 || +mi > 59 || +se > 59) return NaN;
if (!z) return new Date(...parts).getTime();
if (z === 'Z') return d.getTime();
const zm = /^([+-])(\d{2}):?(\d{2})$/.exec(z);
return d.getTime() - (zm[1] === '-' ? -1 : 1) * (+zm[2] * 60 + +zm[3]) * 60000;
}
High or low against the limits
64-bit
Whether a reading is above the asset's high limit or below its low limit.
high if v > high; low if v < low
Two strict comparisons of 64-bit numbers, the high limit first. A reading equal to a limit is not flagged.
assets-bim-sensors.js
lines 147 to 152
BimCraft 0.8.1
export function flagOf(v, { low = null, high = null } = {}) {
if (!fin(v)) return '';
if (fin(high) && v > high) return 'high';
if (fin(low) && v < low) return 'low';
return '';
}
In detail
Method
Pattern-checked decimal text to a number; date and time text to milliseconds since 1970; strict comparison with the low and high limits.
Number types
64-bit numbers; times are milliseconds.
Limits
A number of 9 to 13 digits in a time cell is read as Unix time: below 1e11 as seconds, otherwise as milliseconds. A fraction of a second is cut to three decimals. A time with no zone is read in the browser's own zone.
Approach: 64-bit, direct
Every value is a 64-bit number from input to result. Formulas are closed form or a direct solve, and every comparison uses a stated tolerance.