@justair/justair-library 7.8.0-alpha.bda2dbd → 7.8.0
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/README.md
CHANGED
|
@@ -99,7 +99,7 @@ The following parameters were added to `HEAVY_METALS` and are now included in `s
|
|
|
99
99
|
|
|
100
100
|
### New met parameters in 7.4.0
|
|
101
101
|
|
|
102
|
-
The following parameters were added to `PARAMETERS` and are now included in `parametersEnum`. Consuming services that display or filter parameters without a `type` filter (admin pickers, notification threshold UIs, reporting) will start showing them on install
|
|
102
|
+
The following parameters were added to `PARAMETERS` and are now included in `parametersEnum`. Consuming services that display or filter parameters without a `type` filter (admin pickers, notification threshold UIs, reporting) will start showing them on install.
|
|
103
103
|
|
|
104
104
|
| id | Name | Unit |
|
|
105
105
|
|---|---|---|
|
|
@@ -109,6 +109,18 @@ The following parameters were added to `PARAMETERS` and are now included in `par
|
|
|
109
109
|
|
|
110
110
|
These are **not** interchangeable with the bare `T` / `RH` / `DP` ids, which are enclosure-internal readings used only by correction equations and fog detection. Never fall back from one kind to the other. See "Ambient vs internal met parameters" in `CLAUDE.md` before wiring these up.
|
|
111
111
|
|
|
112
|
+
Processing-Engine writes these as of JA-3061 and CalculateAQIService averages them into `monitorProperties.metProperties` as of JA-3626.
|
|
113
|
+
|
|
114
|
+
### New met parameter in 7.8.0
|
|
115
|
+
|
|
116
|
+
| id | Name | Unit |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `HI` | Heat Index | `°F` |
|
|
119
|
+
|
|
120
|
+
Same install-time visibility caveat as the 7.4.0 section above.
|
|
121
|
+
|
|
122
|
+
`HI` is **derived, not measured**. Processing-Engine computes it from that reading's own `T_AMB` / `RH_AMB` pair using the NOAA formula (JA-3120); no supplier reports it. It takes no `_AMB` suffix because there is no internal counterpart — an enclosure Heat Index would describe the inside of the housing. Never compute it from the bare `T` / `RH`.
|
|
123
|
+
|
|
112
124
|
### Object shape
|
|
113
125
|
|
|
114
126
|
Each constant is an object with the following fields:
|
|
@@ -423,7 +423,7 @@ export namespace PARAMETERS {
|
|
|
423
423
|
let impacts_23: any;
|
|
424
424
|
export { impacts_23 as impacts };
|
|
425
425
|
}
|
|
426
|
-
namespace
|
|
426
|
+
namespace HI {
|
|
427
427
|
let id_24: string;
|
|
428
428
|
export { id_24 as id };
|
|
429
429
|
let label_24: string;
|
|
@@ -441,7 +441,7 @@ export namespace PARAMETERS {
|
|
|
441
441
|
let impacts_24: any;
|
|
442
442
|
export { impacts_24 as impacts };
|
|
443
443
|
}
|
|
444
|
-
namespace
|
|
444
|
+
namespace R {
|
|
445
445
|
let id_25: string;
|
|
446
446
|
export { id_25 as id };
|
|
447
447
|
let label_25: string;
|
|
@@ -459,7 +459,7 @@ export namespace PARAMETERS {
|
|
|
459
459
|
let impacts_25: any;
|
|
460
460
|
export { impacts_25 as impacts };
|
|
461
461
|
}
|
|
462
|
-
namespace
|
|
462
|
+
namespace SR {
|
|
463
463
|
let id_26: string;
|
|
464
464
|
export { id_26 as id };
|
|
465
465
|
let label_26: string;
|
|
@@ -477,7 +477,7 @@ export namespace PARAMETERS {
|
|
|
477
477
|
let impacts_26: any;
|
|
478
478
|
export { impacts_26 as impacts };
|
|
479
479
|
}
|
|
480
|
-
namespace
|
|
480
|
+
namespace P {
|
|
481
481
|
let id_27: string;
|
|
482
482
|
export { id_27 as id };
|
|
483
483
|
let label_27: string;
|
|
@@ -495,7 +495,7 @@ export namespace PARAMETERS {
|
|
|
495
495
|
let impacts_27: any;
|
|
496
496
|
export { impacts_27 as impacts };
|
|
497
497
|
}
|
|
498
|
-
namespace
|
|
498
|
+
namespace PAR {
|
|
499
499
|
let id_28: string;
|
|
500
500
|
export { id_28 as id };
|
|
501
501
|
let label_28: string;
|
|
@@ -513,7 +513,7 @@ export namespace PARAMETERS {
|
|
|
513
513
|
let impacts_28: any;
|
|
514
514
|
export { impacts_28 as impacts };
|
|
515
515
|
}
|
|
516
|
-
namespace
|
|
516
|
+
namespace ARM {
|
|
517
517
|
let id_29: string;
|
|
518
518
|
export { id_29 as id };
|
|
519
519
|
let label_29: string;
|
|
@@ -531,7 +531,7 @@ export namespace PARAMETERS {
|
|
|
531
531
|
let impacts_29: any;
|
|
532
532
|
export { impacts_29 as impacts };
|
|
533
533
|
}
|
|
534
|
-
namespace
|
|
534
|
+
namespace ARW {
|
|
535
535
|
let id_30: string;
|
|
536
536
|
export { id_30 as id };
|
|
537
537
|
let label_30: string;
|
|
@@ -549,7 +549,7 @@ export namespace PARAMETERS {
|
|
|
549
549
|
let impacts_30: any;
|
|
550
550
|
export { impacts_30 as impacts };
|
|
551
551
|
}
|
|
552
|
-
namespace
|
|
552
|
+
namespace ARD {
|
|
553
553
|
let id_31: string;
|
|
554
554
|
export { id_31 as id };
|
|
555
555
|
let label_31: string;
|
|
@@ -567,9 +567,7 @@ export namespace PARAMETERS {
|
|
|
567
567
|
let impacts_31: any;
|
|
568
568
|
export { impacts_31 as impacts };
|
|
569
569
|
}
|
|
570
|
-
|
|
571
|
-
export namespace HEAVY_METALS {
|
|
572
|
-
export namespace AS {
|
|
570
|
+
namespace ARH {
|
|
573
571
|
let id_32: string;
|
|
574
572
|
export { id_32 as id };
|
|
575
573
|
let label_32: string;
|
|
@@ -580,14 +578,16 @@ export namespace HEAVY_METALS {
|
|
|
580
578
|
export { unit_32 as unit };
|
|
581
579
|
let type_32: string;
|
|
582
580
|
export { type_32 as type };
|
|
583
|
-
let rfc_32:
|
|
581
|
+
let rfc_32: any;
|
|
584
582
|
export { rfc_32 as rfc };
|
|
585
|
-
let origin_32:
|
|
583
|
+
let origin_32: any;
|
|
586
584
|
export { origin_32 as origin };
|
|
587
|
-
let impacts_32:
|
|
585
|
+
let impacts_32: any;
|
|
588
586
|
export { impacts_32 as impacts };
|
|
589
587
|
}
|
|
590
|
-
|
|
588
|
+
}
|
|
589
|
+
export namespace HEAVY_METALS {
|
|
590
|
+
export namespace AS {
|
|
591
591
|
let id_33: string;
|
|
592
592
|
export { id_33 as id };
|
|
593
593
|
let label_33: string;
|
|
@@ -598,14 +598,14 @@ export namespace HEAVY_METALS {
|
|
|
598
598
|
export { unit_33 as unit };
|
|
599
599
|
let type_33: string;
|
|
600
600
|
export { type_33 as type };
|
|
601
|
-
let rfc_33:
|
|
601
|
+
let rfc_33: number;
|
|
602
602
|
export { rfc_33 as rfc };
|
|
603
603
|
let origin_33: string;
|
|
604
604
|
export { origin_33 as origin };
|
|
605
605
|
let impacts_33: string;
|
|
606
606
|
export { impacts_33 as impacts };
|
|
607
607
|
}
|
|
608
|
-
export namespace
|
|
608
|
+
export namespace BA {
|
|
609
609
|
let id_34: string;
|
|
610
610
|
export { id_34 as id };
|
|
611
611
|
let label_34: string;
|
|
@@ -616,14 +616,14 @@ export namespace HEAVY_METALS {
|
|
|
616
616
|
export { unit_34 as unit };
|
|
617
617
|
let type_34: string;
|
|
618
618
|
export { type_34 as type };
|
|
619
|
-
let rfc_34:
|
|
619
|
+
let rfc_34: any;
|
|
620
620
|
export { rfc_34 as rfc };
|
|
621
621
|
let origin_34: string;
|
|
622
622
|
export { origin_34 as origin };
|
|
623
623
|
let impacts_34: string;
|
|
624
624
|
export { impacts_34 as impacts };
|
|
625
625
|
}
|
|
626
|
-
export namespace
|
|
626
|
+
export namespace C6H6 {
|
|
627
627
|
let id_35: string;
|
|
628
628
|
export { id_35 as id };
|
|
629
629
|
let label_35: string;
|
|
@@ -641,7 +641,7 @@ export namespace HEAVY_METALS {
|
|
|
641
641
|
let impacts_35: string;
|
|
642
642
|
export { impacts_35 as impacts };
|
|
643
643
|
}
|
|
644
|
-
export namespace
|
|
644
|
+
export namespace BE {
|
|
645
645
|
let id_36: string;
|
|
646
646
|
export { id_36 as id };
|
|
647
647
|
let label_36: string;
|
|
@@ -659,7 +659,7 @@ export namespace HEAVY_METALS {
|
|
|
659
659
|
let impacts_36: string;
|
|
660
660
|
export { impacts_36 as impacts };
|
|
661
661
|
}
|
|
662
|
-
export namespace
|
|
662
|
+
export namespace CD {
|
|
663
663
|
let id_37: string;
|
|
664
664
|
export { id_37 as id };
|
|
665
665
|
let label_37: string;
|
|
@@ -677,7 +677,7 @@ export namespace HEAVY_METALS {
|
|
|
677
677
|
let impacts_37: string;
|
|
678
678
|
export { impacts_37 as impacts };
|
|
679
679
|
}
|
|
680
|
-
export namespace
|
|
680
|
+
export namespace CR {
|
|
681
681
|
let id_38: string;
|
|
682
682
|
export { id_38 as id };
|
|
683
683
|
let label_38: string;
|
|
@@ -688,15 +688,14 @@ export namespace HEAVY_METALS {
|
|
|
688
688
|
export { unit_38 as unit };
|
|
689
689
|
let type_38: string;
|
|
690
690
|
export { type_38 as type };
|
|
691
|
-
let rfc_38:
|
|
691
|
+
let rfc_38: number;
|
|
692
692
|
export { rfc_38 as rfc };
|
|
693
693
|
let origin_38: string;
|
|
694
694
|
export { origin_38 as origin };
|
|
695
695
|
let impacts_38: string;
|
|
696
696
|
export { impacts_38 as impacts };
|
|
697
697
|
}
|
|
698
|
-
export
|
|
699
|
-
export namespace CU {
|
|
698
|
+
export namespace CO_1 {
|
|
700
699
|
let id_39: string;
|
|
701
700
|
export { id_39 as id };
|
|
702
701
|
let label_39: string;
|
|
@@ -714,7 +713,8 @@ export namespace HEAVY_METALS {
|
|
|
714
713
|
let impacts_39: string;
|
|
715
714
|
export { impacts_39 as impacts };
|
|
716
715
|
}
|
|
717
|
-
export
|
|
716
|
+
export { CO_1 as CO };
|
|
717
|
+
export namespace CU {
|
|
718
718
|
let id_40: string;
|
|
719
719
|
export { id_40 as id };
|
|
720
720
|
let label_40: string;
|
|
@@ -732,7 +732,7 @@ export namespace HEAVY_METALS {
|
|
|
732
732
|
let impacts_40: string;
|
|
733
733
|
export { impacts_40 as impacts };
|
|
734
734
|
}
|
|
735
|
-
export namespace
|
|
735
|
+
export namespace FE {
|
|
736
736
|
let id_41: string;
|
|
737
737
|
export { id_41 as id };
|
|
738
738
|
let label_41: string;
|
|
@@ -743,14 +743,14 @@ export namespace HEAVY_METALS {
|
|
|
743
743
|
export { unit_41 as unit };
|
|
744
744
|
let type_41: string;
|
|
745
745
|
export { type_41 as type };
|
|
746
|
-
let rfc_41:
|
|
746
|
+
let rfc_41: any;
|
|
747
747
|
export { rfc_41 as rfc };
|
|
748
748
|
let origin_41: string;
|
|
749
749
|
export { origin_41 as origin };
|
|
750
750
|
let impacts_41: string;
|
|
751
751
|
export { impacts_41 as impacts };
|
|
752
752
|
}
|
|
753
|
-
export namespace
|
|
753
|
+
export namespace PB {
|
|
754
754
|
let id_42: string;
|
|
755
755
|
export { id_42 as id };
|
|
756
756
|
let label_42: string;
|
|
@@ -768,7 +768,7 @@ export namespace HEAVY_METALS {
|
|
|
768
768
|
let impacts_42: string;
|
|
769
769
|
export { impacts_42 as impacts };
|
|
770
770
|
}
|
|
771
|
-
export namespace
|
|
771
|
+
export namespace MN {
|
|
772
772
|
let id_43: string;
|
|
773
773
|
export { id_43 as id };
|
|
774
774
|
let label_43: string;
|
|
@@ -779,14 +779,14 @@ export namespace HEAVY_METALS {
|
|
|
779
779
|
export { unit_43 as unit };
|
|
780
780
|
let type_43: string;
|
|
781
781
|
export { type_43 as type };
|
|
782
|
-
let rfc_43:
|
|
782
|
+
let rfc_43: number;
|
|
783
783
|
export { rfc_43 as rfc };
|
|
784
784
|
let origin_43: string;
|
|
785
785
|
export { origin_43 as origin };
|
|
786
786
|
let impacts_43: string;
|
|
787
787
|
export { impacts_43 as impacts };
|
|
788
788
|
}
|
|
789
|
-
export namespace
|
|
789
|
+
export namespace NI {
|
|
790
790
|
let id_44: string;
|
|
791
791
|
export { id_44 as id };
|
|
792
792
|
let label_44: string;
|
|
@@ -804,7 +804,7 @@ export namespace HEAVY_METALS {
|
|
|
804
804
|
let impacts_44: string;
|
|
805
805
|
export { impacts_44 as impacts };
|
|
806
806
|
}
|
|
807
|
-
export namespace
|
|
807
|
+
export namespace SE {
|
|
808
808
|
let id_45: string;
|
|
809
809
|
export { id_45 as id };
|
|
810
810
|
let label_45: string;
|
|
@@ -822,5 +822,23 @@ export namespace HEAVY_METALS {
|
|
|
822
822
|
let impacts_45: string;
|
|
823
823
|
export { impacts_45 as impacts };
|
|
824
824
|
}
|
|
825
|
+
export namespace ZN {
|
|
826
|
+
let id_46: string;
|
|
827
|
+
export { id_46 as id };
|
|
828
|
+
let label_46: string;
|
|
829
|
+
export { label_46 as label };
|
|
830
|
+
let name_46: string;
|
|
831
|
+
export { name_46 as name };
|
|
832
|
+
let unit_46: string;
|
|
833
|
+
export { unit_46 as unit };
|
|
834
|
+
let type_46: string;
|
|
835
|
+
export { type_46 as type };
|
|
836
|
+
let rfc_46: any;
|
|
837
|
+
export { rfc_46 as rfc };
|
|
838
|
+
let origin_46: string;
|
|
839
|
+
export { origin_46 as origin };
|
|
840
|
+
let impacts_46: string;
|
|
841
|
+
export { impacts_46 as impacts };
|
|
842
|
+
}
|
|
825
843
|
}
|
|
826
844
|
//# sourceMappingURL=pollutants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/models/users.js"],"names":[],"mappings":"AA8FA,
|
|
1
|
+
{"version":3,"file":"users.d.ts","sourceRoot":"","sources":["../../src/models/users.js"],"names":[],"mappings":"AA8FA,8BAuIE;AAiCF,wBAAmD;AA5PnD,iDAA4D;AAC5D,6CAAmD;AAUnD,4DA0BC"}
|
package/package.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
// Parameters measured by air quality sensors in real time.
|
|
1
|
+
// Parameters measured by air quality sensors in real time, plus values derived from them.
|
|
2
2
|
// These correspond to the values stored in Monitors.parameters and used across the platform.
|
|
3
|
+
// Most entries are read off a sensor channel. HI and DP are always derived during normalization,
|
|
4
|
+
// and DP_AMB is derived when the supplier does not report dew point. See "Ambient vs internal met
|
|
5
|
+
// parameters" in CLAUDE.md.
|
|
3
6
|
export const PARAMETERS = {
|
|
4
7
|
CO: {
|
|
5
8
|
id: "CO",
|
|
@@ -215,6 +218,7 @@ export const PARAMETERS = {
|
|
|
215
218
|
origin: null,
|
|
216
219
|
impacts: null,
|
|
217
220
|
},
|
|
221
|
+
// ---- end of the T/RH/DP pairs. Everything below is unpaired. ----
|
|
218
222
|
WD: {
|
|
219
223
|
id: "WD",
|
|
220
224
|
label: "Wind Direction",
|
|
@@ -245,6 +249,23 @@ export const PARAMETERS = {
|
|
|
245
249
|
origin: null,
|
|
246
250
|
impacts: null,
|
|
247
251
|
},
|
|
252
|
+
// Derived, not measured. Processing-Engine computes HI from the T_AMB/RH_AMB pair on each
|
|
253
|
+
// reading (JA-3120, NOAA/Rothfusz); no supplier reports it, so nothing should ever map a raw
|
|
254
|
+
// channel onto this id. Deliberately sits BELOW the T/RH/DP block rather than next to T_AMB:
|
|
255
|
+
// a bare id under that block's header reads as "enclosure-internal", and wiring HI to the
|
|
256
|
+
// internal T/RH pair is the one mistake that must not happen. It takes no _AMB suffix because
|
|
257
|
+
// there is no internal counterpart to tell it apart from — an enclosure Heat Index would
|
|
258
|
+
// describe the inside of a plastic box.
|
|
259
|
+
HI: {
|
|
260
|
+
id: "HI",
|
|
261
|
+
label: "Heat Index",
|
|
262
|
+
name: "Heat Index (HI)",
|
|
263
|
+
unit: "°F",
|
|
264
|
+
type: "Weather",
|
|
265
|
+
rfc: null,
|
|
266
|
+
origin: null,
|
|
267
|
+
impacts: null,
|
|
268
|
+
},
|
|
248
269
|
R: {
|
|
249
270
|
id: "R",
|
|
250
271
|
label: "Rain",
|
|
@@ -83,6 +83,24 @@ describe("PARAMETERS", () => {
|
|
|
83
83
|
expect(PARAMETERS[key].unit).toBe(bare.unit);
|
|
84
84
|
expect(PARAMETERS[key].type).toBe(bare.type);
|
|
85
85
|
});
|
|
86
|
+
|
|
87
|
+
// JA-3119: Heat Index is derived from the ambient pair, so it has to share their unit and
|
|
88
|
+
// sit outside the _AMB set — a "HI_AMB" would imply an internal Heat Index exists.
|
|
89
|
+
describe("HI (Heat Index)", () => {
|
|
90
|
+
test("is declared as a Weather parameter in °F", () => {
|
|
91
|
+
expect(PARAMETERS.HI).toBeDefined();
|
|
92
|
+
expect(PARAMETERS.HI.unit).toBe("°F");
|
|
93
|
+
expect(PARAMETERS.HI.type).toBe("Weather");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("shares T_AMB's unit, since it is an apparent temperature", () => {
|
|
97
|
+
expect(PARAMETERS.HI.unit).toBe(PARAMETERS.T_AMB.unit);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("has no _AMB counterpart", () => {
|
|
101
|
+
expect(PARAMETERS.HI_AMB).toBeUndefined();
|
|
102
|
+
});
|
|
103
|
+
});
|
|
86
104
|
});
|
|
87
105
|
|
|
88
106
|
describe("HEAVY_METALS", () => {
|
package/src/models/users.js
CHANGED
|
@@ -147,16 +147,6 @@ const usersSchema = mongoose.Schema(
|
|
|
147
147
|
optInEmail: { type: Boolean, default: false },
|
|
148
148
|
isActive: { type: Boolean, default: true },
|
|
149
149
|
hasOnboarded: { type: Boolean, default: false },
|
|
150
|
-
// JA-2670: migration-cohort marker for the V2 what's-new screen. Meaning:
|
|
151
|
-
// "this account no longer needs the screen" — set true at V2 signup
|
|
152
|
-
// (client:"v2" on POST /users), or claimed once at first V2 login via
|
|
153
|
-
// findOneAndUpdate({ _id, hasSeenV2WhatsNew: { $ne: true } }, ...).
|
|
154
|
-
// $ne:true is the contract: it must match documents where the field is
|
|
155
|
-
// ABSENT (every account created before this field existed) as well as
|
|
156
|
-
// stored false — an equality filter on false would silently skip every
|
|
157
|
-
// pre-existing user. Deliberately NOT immutable (the claim flips it) and
|
|
158
|
-
// there is no backfill; absence means "hasn't seen it".
|
|
159
|
-
hasSeenV2WhatsNew: { type: Boolean, default: false },
|
|
160
150
|
isSharingLocation: { type: Boolean, default: false },
|
|
161
151
|
toolTips: Object,
|
|
162
152
|
alertPreferenceLevel: {
|