@measurequick/measurequick-report-generator 1.5.183 → 1.5.185
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/.claude/settings.local.json +13 -0
- package/base-64/mq-vitals-heatpump-heating.js +5 -7
- package/base-64/notes-summary-template.js +4 -0
- package/explore-pdf-fields.js +31 -0
- package/package.json +1 -1
- package/report-gen-scripts/full-report.js +30 -17
- package/report-gen-scripts/notes-summary-page.js +310 -0
- package/report-gen-scripts/vitals-heatpump-heating-report.js +1 -37
- package/update-hp-heating-pdf.js +153 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PDFDocument
|
|
1
|
+
import { PDFDocument } from "pdf-lib";
|
|
2
2
|
import * as base64 from "../base-64/icons.js";
|
|
3
3
|
import * as pdf from "../base-64/mq-vitals-heatpump-heating.js";
|
|
4
4
|
import * as systemInfoPage from "./system-info-page.js";
|
|
@@ -20,10 +20,6 @@ export async function getReport(payload, _test) {
|
|
|
20
20
|
const formPdfBytes = util._base64ToArrayBuffer(pdf.base64);
|
|
21
21
|
const pdfDoc = await PDFDocument.load(formPdfBytes);
|
|
22
22
|
|
|
23
|
-
// Embed font for custom text overlays
|
|
24
|
-
const helveticaBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
|
|
25
|
-
const helvetica = await pdfDoc.embedFont(StandardFonts.Helvetica);
|
|
26
|
-
|
|
27
23
|
// fetch resources
|
|
28
24
|
const iconRangeGreenBytes = util._base64ToArrayBuffer(base64.iconRangeGreen);
|
|
29
25
|
const iconRangeRedBytes = util._base64ToArrayBuffer(base64.iconRangeRed);
|
|
@@ -226,38 +222,6 @@ export async function getReport(payload, _test) {
|
|
|
226
222
|
|
|
227
223
|
form.getTextField("YourSystemScorePage2").setText(`${systemScorePercentage} ${systemScoreGrade}`);
|
|
228
224
|
|
|
229
|
-
// Get pages for label overlays
|
|
230
|
-
const pages = pdfDoc.getPages();
|
|
231
|
-
|
|
232
|
-
// Overlay custom labels for heat pump heating on page 2 (factors page)
|
|
233
|
-
// Note: These positions may need adjustment based on actual PDF layout
|
|
234
|
-
if (pages.length >= 2) {
|
|
235
|
-
const page2 = pages[1];
|
|
236
|
-
const labelFontSize = 9;
|
|
237
|
-
const labelColor = rgb(0.2, 0.2, 0.2);
|
|
238
|
-
|
|
239
|
-
// Draw white rectangles to cover original labels, then draw new labels
|
|
240
|
-
// Factor 1: Static Pressure (was Age & Efficiency)
|
|
241
|
-
page2.drawRectangle({ x: 45, y: 635, width: 150, height: 12, color: rgb(1, 1, 1) });
|
|
242
|
-
page2.drawText("Static Pressure", { x: 47, y: 637, size: labelFontSize, font: helveticaBold, color: labelColor });
|
|
243
|
-
|
|
244
|
-
// Factor 2: Air-Side Heat Delivery (was Temperature Split)
|
|
245
|
-
page2.drawRectangle({ x: 45, y: 580, width: 150, height: 12, color: rgb(1, 1, 1) });
|
|
246
|
-
page2.drawText("Air-Side Heat Delivery", { x: 47, y: 582, size: labelFontSize, font: helveticaBold, color: labelColor });
|
|
247
|
-
|
|
248
|
-
// Factor 3: Capacity Delivery (was Static Pressure)
|
|
249
|
-
page2.drawRectangle({ x: 45, y: 525, width: 150, height: 12, color: rgb(1, 1, 1) });
|
|
250
|
-
page2.drawText("Capacity Delivery", { x: 47, y: 527, size: labelFontSize, font: helveticaBold, color: labelColor });
|
|
251
|
-
|
|
252
|
-
// Factor 4: System Balance (was Approach)
|
|
253
|
-
page2.drawRectangle({ x: 45, y: 470, width: 150, height: 12, color: rgb(1, 1, 1) });
|
|
254
|
-
page2.drawText("System Balance", { x: 47, y: 472, size: labelFontSize, font: helveticaBold, color: labelColor });
|
|
255
|
-
|
|
256
|
-
// Factor 5: Efficiency (COP) (was Refrigerant Charge)
|
|
257
|
-
page2.drawRectangle({ x: 45, y: 415, width: 150, height: 12, color: rgb(1, 1, 1) });
|
|
258
|
-
page2.drawText("Efficiency (COP)", { x: 47, y: 417, size: labelFontSize, font: helveticaBold, color: labelColor });
|
|
259
|
-
}
|
|
260
|
-
|
|
261
225
|
// Print targets and range icons (using appropriate values for heat pump heating)
|
|
262
226
|
const measureLabels = ["Superheat", "Subcooling", "Condenser", "TempSplit", "Tesp", "FilterFace"];
|
|
263
227
|
for (let i = 0; i < measureLabels.length; i++) {
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { PDFDocument, rgb, StandardFonts } from "pdf-lib";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as coolingTemplate from "./base-64/mq-vitals-cooling.js";
|
|
4
|
+
|
|
5
|
+
function _base64ToArrayBuffer(base64) {
|
|
6
|
+
const binary_string = atob(base64);
|
|
7
|
+
const len = binary_string.length;
|
|
8
|
+
const bytes = new Uint8Array(len);
|
|
9
|
+
for (let i = 0; i < len; i++) {
|
|
10
|
+
bytes[i] = binary_string.charCodeAt(i);
|
|
11
|
+
}
|
|
12
|
+
return bytes;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function updateHeatPumpHeatingPdf() {
|
|
16
|
+
// Use ORIGINAL cooling template as source (from base64)
|
|
17
|
+
const outputPath = "/Users/bobby/Desktop/vitals-heat-pump-heating.pdf";
|
|
18
|
+
|
|
19
|
+
console.log("Loading original cooling template from base64...");
|
|
20
|
+
const pdfBytes = _base64ToArrayBuffer(coolingTemplate.base64);
|
|
21
|
+
const pdfDoc = await PDFDocument.load(pdfBytes);
|
|
22
|
+
|
|
23
|
+
// Embed fonts
|
|
24
|
+
const helveticaBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold);
|
|
25
|
+
const helvetica = await pdfDoc.embedFont(StandardFonts.Helvetica);
|
|
26
|
+
|
|
27
|
+
const pages = pdfDoc.getPages();
|
|
28
|
+
const page1 = pages[0];
|
|
29
|
+
const page2 = pages[1];
|
|
30
|
+
|
|
31
|
+
// Get page dimensions for reference
|
|
32
|
+
const { width, height } = page1.getSize();
|
|
33
|
+
console.log(`Page dimensions: ${width} x ${height}`);
|
|
34
|
+
|
|
35
|
+
// Colors
|
|
36
|
+
const sectionHeaderColor = rgb(0.384, 0.604, 0.196); // MeasureQuick green
|
|
37
|
+
const labelColor = rgb(0.2, 0.2, 0.2);
|
|
38
|
+
const whiteColor = rgb(1, 1, 1);
|
|
39
|
+
|
|
40
|
+
// Font sizes
|
|
41
|
+
const sectionHeaderFontSize = 18;
|
|
42
|
+
const measurementLabelFontSize = 11;
|
|
43
|
+
const factorTitleFontSize = 20;
|
|
44
|
+
const factorDescFontSize = 10;
|
|
45
|
+
|
|
46
|
+
console.log("Updating Page 1 labels...");
|
|
47
|
+
|
|
48
|
+
// ========================================
|
|
49
|
+
// PAGE 1: Heat pump heating measurement labels
|
|
50
|
+
// ========================================
|
|
51
|
+
// Based on standard letter size (612 x 792), y=0 is at bottom
|
|
52
|
+
// Need to fully cover original labels with larger white rectangles
|
|
53
|
+
|
|
54
|
+
// Section 1: "Refrigerant Charge" -> "Heat Pump Performance"
|
|
55
|
+
// Cover entire original header area
|
|
56
|
+
page1.drawRectangle({ x: 40, y: 470, width: 250, height: 35, color: whiteColor });
|
|
57
|
+
page1.drawText("Heat Pump Performance", { x: 44, y: 478, size: sectionHeaderFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
58
|
+
|
|
59
|
+
// "Superheat:" label -> "Temperature Rise:"
|
|
60
|
+
page1.drawRectangle({ x: 44, y: 443, width: 100, height: 22, color: whiteColor });
|
|
61
|
+
page1.drawText("Temperature Rise:", { x: 46, y: 449, size: measurementLabelFontSize, font: helveticaBold, color: labelColor });
|
|
62
|
+
|
|
63
|
+
// "Subcooling:" label -> "Liquid Line Temp:"
|
|
64
|
+
page1.drawRectangle({ x: 295, y: 443, width: 100, height: 22, color: whiteColor });
|
|
65
|
+
page1.drawText("Liquid Line Temp:", { x: 297, y: 449, size: measurementLabelFontSize, font: helveticaBold, color: labelColor });
|
|
66
|
+
|
|
67
|
+
// Section 2: "Heat Transfer" -> "Efficiency Metrics"
|
|
68
|
+
page1.drawRectangle({ x: 40, y: 358, width: 200, height: 35, color: whiteColor });
|
|
69
|
+
page1.drawText("Efficiency Metrics", { x: 44, y: 366, size: sectionHeaderFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
70
|
+
|
|
71
|
+
// "Condenser Approach:" -> "COP:"
|
|
72
|
+
page1.drawRectangle({ x: 44, y: 331, width: 140, height: 22, color: whiteColor });
|
|
73
|
+
page1.drawText("COP:", { x: 46, y: 337, size: measurementLabelFontSize, font: helveticaBold, color: labelColor });
|
|
74
|
+
|
|
75
|
+
// "Temperature Split:" -> "Outdoor Air Temp:"
|
|
76
|
+
page1.drawRectangle({ x: 295, y: 331, width: 130, height: 22, color: whiteColor });
|
|
77
|
+
page1.drawText("Outdoor Air Temp:", { x: 297, y: 337, size: measurementLabelFontSize, font: helveticaBold, color: labelColor });
|
|
78
|
+
|
|
79
|
+
// "Filter Face Velocity:" -> "Airflow:"
|
|
80
|
+
page1.drawRectangle({ x: 295, y: 219, width: 140, height: 22, color: whiteColor });
|
|
81
|
+
page1.drawText("Airflow:", { x: 297, y: 225, size: measurementLabelFontSize, font: helveticaBold, color: labelColor });
|
|
82
|
+
|
|
83
|
+
console.log("Updating Page 2 labels...");
|
|
84
|
+
|
|
85
|
+
// ========================================
|
|
86
|
+
// PAGE 2: Heat pump heating scoring factor labels
|
|
87
|
+
// ========================================
|
|
88
|
+
// Page 2 layout from top to bottom (y decreases as you go down)
|
|
89
|
+
// Each factor section: Title (green text) + description paragraph
|
|
90
|
+
// Using larger rectangles to fully cover original text
|
|
91
|
+
|
|
92
|
+
// Factor 1: "Age & Efficiency Losses" -> "Static Pressure / Filter"
|
|
93
|
+
page2.drawRectangle({ x: 40, y: 625, width: 350, height: 38, color: whiteColor });
|
|
94
|
+
page2.drawText("Static Pressure / Filter", { x: 44, y: 633, size: factorTitleFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
95
|
+
// Description
|
|
96
|
+
page2.drawRectangle({ x: 40, y: 570, width: 530, height: 55, color: whiteColor });
|
|
97
|
+
page2.drawText("High system static pressure reduces airflow and efficiency. Points are deducted", { x: 44, y: 605, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
98
|
+
page2.drawText("based on how much the measured static pressure exceeds the target. Dirty", { x: 44, y: 592, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
99
|
+
page2.drawText("filters and restricted ductwork are common causes of high static pressure.", { x: 44, y: 579, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
100
|
+
|
|
101
|
+
// Factor 2: "Temperature Split Losses" -> "Air-Side Heat Delivery"
|
|
102
|
+
page2.drawRectangle({ x: 40, y: 530, width: 350, height: 38, color: whiteColor });
|
|
103
|
+
page2.drawText("Air-Side Heat Delivery", { x: 44, y: 538, size: factorTitleFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
104
|
+
// Description
|
|
105
|
+
page2.drawRectangle({ x: 40, y: 475, width: 530, height: 55, color: whiteColor });
|
|
106
|
+
page2.drawText("Measures the temperature rise across the indoor coil. This indicates how", { x: 44, y: 510, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
107
|
+
page2.drawText("effectively the heat pump is delivering heat to the air. Low temperature rise", { x: 44, y: 497, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
108
|
+
page2.drawText("may indicate airflow issues, refrigerant problems, or outdoor conditions.", { x: 44, y: 484, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
109
|
+
|
|
110
|
+
// Factor 3: "Static Pressure Losses" -> "Capacity Delivery"
|
|
111
|
+
page2.drawRectangle({ x: 40, y: 435, width: 320, height: 38, color: whiteColor });
|
|
112
|
+
page2.drawText("Capacity Delivery", { x: 44, y: 443, size: factorTitleFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
113
|
+
// Description
|
|
114
|
+
page2.drawRectangle({ x: 40, y: 378, width: 530, height: 57, color: whiteColor });
|
|
115
|
+
page2.drawText("Evaluates the heat pump's actual heating output compared to expected", { x: 44, y: 415, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
116
|
+
page2.drawText("capacity for the current outdoor temperature. Heat pump capacity naturally", { x: 44, y: 402, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
117
|
+
page2.drawText("decreases as outdoor temperature drops - this factor accounts for that.", { x: 44, y: 389, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
118
|
+
|
|
119
|
+
// Factor 4: "Approach Losses" -> "System Balance"
|
|
120
|
+
page2.drawRectangle({ x: 40, y: 340, width: 280, height: 38, color: whiteColor });
|
|
121
|
+
page2.drawText("System Balance", { x: 44, y: 348, size: factorTitleFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
122
|
+
// Description
|
|
123
|
+
page2.drawRectangle({ x: 40, y: 283, width: 530, height: 57, color: whiteColor });
|
|
124
|
+
page2.drawText("Assesses the balance between refrigerant-side and air-side heat transfer", { x: 44, y: 320, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
125
|
+
page2.drawText("using liquid line temperature as an indicator. Poor system balance can", { x: 44, y: 307, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
126
|
+
page2.drawText("indicate refrigerant charge issues, airflow restrictions, or heat exchanger problems.", { x: 44, y: 294, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
127
|
+
|
|
128
|
+
// Factor 5: "Refrigerant Charge Losses" -> "Efficiency (COP)"
|
|
129
|
+
page2.drawRectangle({ x: 40, y: 245, width: 350, height: 38, color: whiteColor });
|
|
130
|
+
page2.drawText("Efficiency (COP)", { x: 44, y: 253, size: factorTitleFontSize, font: helveticaBold, color: sectionHeaderColor });
|
|
131
|
+
// Description
|
|
132
|
+
page2.drawRectangle({ x: 40, y: 188, width: 530, height: 57, color: whiteColor });
|
|
133
|
+
page2.drawText("Coefficient of Performance measures how efficiently the heat pump converts", { x: 44, y: 225, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
134
|
+
page2.drawText("electrical energy into heat. Higher COP means better efficiency. This factor", { x: 44, y: 212, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
135
|
+
page2.drawText("compares actual COP to the expected COP for current outdoor conditions.", { x: 44, y: 199, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
136
|
+
|
|
137
|
+
// Your System Score section - green background header
|
|
138
|
+
page2.drawRectangle({ x: 40, y: 148, width: 280, height: 40, color: sectionHeaderColor });
|
|
139
|
+
page2.drawText("Your System Score", { x: 52, y: 160, size: 22, font: helveticaBold, color: whiteColor });
|
|
140
|
+
// Description
|
|
141
|
+
page2.drawRectangle({ x: 40, y: 93, width: 530, height: 55, color: whiteColor });
|
|
142
|
+
page2.drawText("Heat pump heating performance is scored on a 100-point scale based on five", { x: 44, y: 130, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
143
|
+
page2.drawText("factors, each worth up to 20 points. A well-performing heat pump system in", { x: 44, y: 117, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
144
|
+
page2.drawText("heating mode should score 80-100 points under favorable outdoor conditions.", { x: 44, y: 104, size: factorDescFontSize, font: helvetica, color: labelColor });
|
|
145
|
+
|
|
146
|
+
console.log("Saving updated PDF to:", outputPath);
|
|
147
|
+
const updatedPdfBytes = await pdfDoc.save();
|
|
148
|
+
fs.writeFileSync(outputPath, updatedPdfBytes);
|
|
149
|
+
|
|
150
|
+
console.log("Done! Heat pump heating vitals PDF created at:", outputPath);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
updateHeatPumpHeatingPdf().catch(console.error);
|