@measurequick/measurequick-report-generator 1.5.199 → 1.5.201

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@measurequick/measurequick-report-generator",
3
- "version": "1.5.199",
3
+ "version": "1.5.201",
4
4
  "description": "Generates PDF documents for various measureQuick applications.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -223,55 +223,123 @@ export async function getReport(payload, _test) {
223
223
 
224
224
  form.getTextField("YourSystemScorePage2").setText(`${systemScorePercentage} ${systemScoreGrade}`);
225
225
 
226
- // Print targets and range icons (using appropriate values for heat pump heating)
227
- // Only show range icons for measurements that exist
228
- // Map field names to textFields values and check if they exist
229
- const measureChecks = [
230
- { label: "Superheat", value: textFields.tempRise }, // Temperature Rise
231
- { label: "Subcooling", value: textFields.approach, ref: "temperature_difference_condenser" }, // Approach
232
- { label: "Condenser", value: textFields.cop }, // COP/Efficiency
233
- { label: "TempSplit", value: textFields.oat }, // Outdoor Air Temp
234
- { label: "Tesp", value: textFields.tesp }, // Total External Static Pressure
235
- { label: "FilterFace", value: textFields.airflow } // Airflow
236
- ];
237
-
238
- for (let i = 0; i < measureChecks.length; i++) {
239
- const { label, value, ref } = measureChecks[i];
240
- // Only show range indicator if value exists (is not "--")
241
- if (value && value !== "--") {
242
- let icon = iconRangeGreen;
243
- let iconPlacement = "Mid";
244
-
245
- // Check if we have target zone data for this measurement
246
- if (ref && t.targets && t.targets[ref] !== undefined) {
247
- const target = parseFloat(t.targets[ref]);
248
- const idealLow = t.targets[`${ref}_ideal_low`] ? parseFloat(t.targets[`${ref}_ideal_low`]) : 0;
249
- const idealHigh = t.targets[`${ref}_ideal_high`] ? parseFloat(t.targets[`${ref}_ideal_high`]) : 0;
250
- const actual = parseFloat(value);
251
- const low = target - idealLow;
252
- const high = target + idealHigh;
253
-
254
- if (actual < low) {
255
- icon = iconRangeRed;
256
- iconPlacement = "Low";
257
- } else if (actual > high) {
258
- icon = iconRangeRed;
259
- iconPlacement = "High";
226
+ // Print targets and range icons for heat pump heating
227
+ // Heat pump heating target zones - some are in data, some in targets
228
+ const measureLabels = ["Superheat", "Subcooling", "Condenser", "TempSplit", "Tesp", "FilterFace"];
229
+
230
+ for (let i = 0; i < measureLabels.length; i++) {
231
+ const label = measureLabels[i];
232
+ let targetZone = "";
233
+ let icon = iconRangeGreen;
234
+ let iconPlacement = "Mid";
235
+ let value = "";
236
+ let mid, low, high;
237
+
238
+ if (label === "Superheat") {
239
+ // Temperature Rise - uses temperature_split targets for HP heating
240
+ value = textFields.tempRise;
241
+ if (t.targets && t.targets.temperature_split !== undefined) {
242
+ mid = parseFloat(t.targets.temperature_split);
243
+ const idealLow = t.targets.temperature_split_ideal_low !== undefined ? parseFloat(t.targets.temperature_split_ideal_low) : 5;
244
+ const idealHigh = t.targets.temperature_split_ideal_high !== undefined ? parseFloat(t.targets.temperature_split_ideal_high) : 5;
245
+ low = mid - idealLow;
246
+ high = mid + idealHigh;
247
+ if (!isNaN(low) && !isNaN(high)) {
248
+ targetZone = `(${low.toFixed(1)} - ${high.toFixed(1)})`;
249
+ }
250
+ }
251
+ } else if (label === "Subcooling") {
252
+ // Approach - LLT minus entering dry bulb
253
+ value = textFields.approach;
254
+ // Check for approach targets in targets object
255
+ if (t.targets && t.targets.approach !== undefined) {
256
+ mid = parseFloat(t.targets.approach);
257
+ const idealLow = t.targets.approach_ideal_low !== undefined ? parseFloat(t.targets.approach_ideal_low) : 3;
258
+ const idealHigh = t.targets.approach_ideal_high !== undefined ? parseFloat(t.targets.approach_ideal_high) : 3;
259
+ low = mid - idealLow;
260
+ high = mid + idealHigh;
261
+ if (!isNaN(low) && !isNaN(high)) {
262
+ targetZone = `(${low.toFixed(1)} - ${high.toFixed(1)})`;
263
+ }
264
+ }
265
+ } else if (label === "Condenser") {
266
+ // COP - target is in data.hp_heating_cop_target
267
+ value = textFields.cop;
268
+ if (t.data && t.data.hp_heating_cop_target !== undefined) {
269
+ mid = parseFloat(t.data.hp_heating_cop_target);
270
+ // COP ideal range is typically ±0.3
271
+ low = mid - 0.3;
272
+ high = mid + 0.3;
273
+ if (!isNaN(low) && !isNaN(high)) {
274
+ targetZone = `(${low.toFixed(2)} - ${high.toFixed(2)})`;
275
+ }
276
+ }
277
+ } else if (label === "TempSplit") {
278
+ // Outdoor Air Temp - no target zone, just informational
279
+ value = textFields.oat;
280
+ } else if (label === "Tesp") {
281
+ // Total External Static Pressure
282
+ value = textFields.tesp;
283
+ if (t.targets && t.targets.pressure_static_total_external !== undefined) {
284
+ mid = parseFloat(t.targets.pressure_static_total_external);
285
+ high = mid * 1.4;
286
+ if (!isNaN(high)) {
287
+ targetZone = `(< ${high.toFixed(2)})`;
288
+ }
289
+ }
290
+ } else if (label === "FilterFace") {
291
+ // Airflow - use airflow target if available
292
+ value = textFields.airflow;
293
+ // Check for airflow target (airflow_estimated or airflow)
294
+ const airflowTarget = t.targets && (t.targets.airflow_estimated || t.targets.airflow);
295
+ if (airflowTarget !== undefined) {
296
+ mid = parseFloat(airflowTarget);
297
+ // Airflow ideal range is typically ±10%
298
+ low = mid * 0.9;
299
+ high = mid * 1.1;
300
+ if (!isNaN(low) && !isNaN(high)) {
301
+ targetZone = `(${low.toFixed(0)} - ${high.toFixed(0)})`;
260
302
  }
261
303
  }
304
+ }
262
305
 
263
- try {
264
- form.getButton(`Image${label}${iconPlacement}_af_image`).setImage(icon);
265
- } catch (e) {
266
- // Field may not exist
306
+ // Determine range indicator position if we have target values
307
+ if (value && value !== "--" && mid !== undefined) {
308
+ const actual = parseFloat(value);
309
+ if (!isNaN(actual)) {
310
+ if (label === "Tesp") {
311
+ // TESP: only check if above threshold
312
+ if (actual > high) {
313
+ icon = iconRangeRed;
314
+ iconPlacement = "High";
315
+ }
316
+ } else if (low !== undefined && high !== undefined) {
317
+ if (actual < low) {
318
+ icon = iconRangeRed;
319
+ iconPlacement = "Low";
320
+ } else if (actual > high) {
321
+ icon = iconRangeRed;
322
+ iconPlacement = "High";
323
+ }
324
+ }
267
325
  }
268
326
  }
269
- // Clear target zone text for heat pump heating (different targets apply)
327
+
328
+ // Set target zone text
270
329
  try {
271
- form.getTextField(`${label}Target`).setText("");
330
+ form.getTextField(`${label}Target`).setText(targetZone);
272
331
  } catch (e) {
273
332
  // Field may not exist
274
333
  }
334
+
335
+ // Set range indicator icon if value exists
336
+ if (value && value !== "--") {
337
+ try {
338
+ form.getButton(`Image${label}${iconPlacement}_af_image`).setImage(icon);
339
+ } catch (e) {
340
+ // Field may not exist
341
+ }
342
+ }
275
343
  }
276
344
 
277
345
  // Skip pass/fail subsystem review for heat pump heating