Resources Numerical accuracy Calculation policy

Sensor readings: values, times and limits

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.

assets-bim-sensors.js BimCraft 0.8.1 64-bit 3 calculations Reviewed

Tests tools/bimcraft-test/ops-sensors.mjs

Reading text as a number

64-bit

A cell of a sensor file as a value.

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.

Every policy that takes this approach