@etainabl/nodejs-sdk 1.1.26 → 1.1.27

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.
@@ -1,6 +1,6 @@
1
1
  import moment from 'moment';
2
2
  export const dayNightConsumption = (data) => data.reduce((acc, item) => {
3
- const hour = moment(item.date).hour(); // End Time of HH consumption period
3
+ const hour = moment.utc(item.date).hour(); // End Time of HH consumption period
4
4
  if (hour >= 0 && hour < 7) {
5
5
  acc.nightConsumption += item.consumption;
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"consumption.js","sourceRoot":"","sources":["../src/consumption.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAa5B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAwB,EAAE,IAAqB,EAAuB,EAAE;IACnJ,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,oCAAoC;IAE3E,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE;QACzB,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC,WAAW,CAAC;KAC1C;SAAM;QACL,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,CAAC;KACxC;IAED,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC;IAEpC,OAAO,GAAG,CAAC;AACb,CAAC,EAAE;IACD,cAAc,EAAE,CAAC;IACjB,gBAAgB,EAAE,CAAC;IACnB,WAAW,EAAE,CAAC;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAqB,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AAEvI,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE5F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,SAAiB,EAAE,SAAiC,EAAE,OAA+B,EAAE,EAAE;IACzI,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAE9E,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/E,CAAC,CAAC"}
1
+ {"version":3,"file":"consumption.js","sourceRoot":"","sources":["../src/consumption.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAa5B,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAwB,EAAE,IAAqB,EAAuB,EAAE;IACnJ,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,oCAAoC;IAE/E,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE;QACzB,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC,WAAW,CAAC;KAC1C;SAAM;QACL,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,WAAW,CAAC;KACxC;IAED,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAC;IAEpC,OAAO,GAAG,CAAC;AACb,CAAC,EAAE;IACD,cAAc,EAAE,CAAC;IACjB,gBAAgB,EAAE,CAAC;IACnB,WAAW,EAAE,CAAC;CACf,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAqB,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;AAEvI,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,IAAuB,EAAE,EAAE,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE5F,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,WAAmB,EAAE,SAAiB,EAAE,SAAiC,EAAE,OAA+B,EAAE,EAAE;IACzI,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAE9E,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/E,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,4 +4,5 @@ import db from './db.js';
4
4
  import slack from './slack.js';
5
5
  import * as units from './units.js';
6
6
  import * as consumption from './consumption.js';
7
- export { api, logger, consumption, db, slack, units };
7
+ import * as monitoring from './monitoring.js';
8
+ export { api, logger, consumption, monitoring, db, slack, units };
package/dist/index.js CHANGED
@@ -4,5 +4,6 @@ import db from './db.js';
4
4
  import slack from './slack.js';
5
5
  import * as units from './units.js';
6
6
  import * as consumption from './consumption.js';
7
- export { api, logger, consumption, db, slack, units };
7
+ import * as monitoring from './monitoring.js';
8
+ export { api, logger, consumption, monitoring, db, slack, units };
8
9
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAEhD,OAAO,EACL,GAAG,EACH,MAAM,EACN,WAAW,EACX,EAAE,EACF,KAAK,EACL,KAAK,EACN,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,WAAW,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EACL,GAAG,EACH,MAAM,EACN,WAAW,EACX,UAAU,EACV,EAAE,EACF,KAAK,EACL,KAAK,EACN,CAAA"}
@@ -0,0 +1 @@
1
+ export declare const sendHeartbeat: () => Promise<boolean>;
@@ -0,0 +1,16 @@
1
+ import axios from 'axios';
2
+ import logger from './logger.js';
3
+ const log = logger('monitoring');
4
+ export const sendHeartbeat = async () => {
5
+ if (!process.env.HEARTBEAT_URL)
6
+ return false;
7
+ try {
8
+ await axios.post(process.env.HEARTBEAT_URL);
9
+ return true;
10
+ }
11
+ catch (e) {
12
+ log.warn(`Failed to send heartbeat: ${e.message || e}`);
13
+ return false;
14
+ }
15
+ };
16
+ //# sourceMappingURL=monitoring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitoring.js","sourceRoot":"","sources":["../src/monitoring.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;AAEjC,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,IAAI,EAAE;IACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI;QACA,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAE5C,OAAO,IAAI,CAAC;KACf;IAAC,OAAO,CAAM,EAAE;QACb,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC;KAChB;AACL,CAAC,CAAA"}
package/dist/units.d.ts CHANGED
@@ -5,9 +5,9 @@ interface Item {
5
5
  value: number;
6
6
  [key: string]: any;
7
7
  }
8
- export type AccountType = 'electricity' | 'gas' | 'water' | 'waste' | 'solar' | 'heating' | 'flow' | 'cooling' | 'temperature' | 'other';
9
- export type ETNUnit = 'kwh' | 'kg' | 'm3' | 'lbs' | 'tonnes' | 'wh' | 'mwh' | 'ft3' | 'hcf' | 'm3/h' | 'qty' | 'l' | 'C';
10
- export type BaseUnit = 'kwh' | 'm3' | 'C' | 'kg' | 'm3/h';
8
+ export declare type AccountType = 'electricity' | 'gas' | 'water' | 'waste' | 'solar' | 'heating' | 'flow' | 'cooling' | 'temperature' | 'other';
9
+ export declare type ETNUnit = 'kwh' | 'kg' | 'm3' | 'lbs' | 'tonnes' | 'wh' | 'mwh' | 'ft3' | 'hcf' | 'm3/h' | 'qty' | 'l' | 'C';
10
+ export declare type BaseUnit = 'kwh' | 'm3' | 'C' | 'kg' | 'm3/h';
11
11
  export declare const accountTypeMap: {
12
12
  [key: string]: BaseUnit;
13
13
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etainabl/nodejs-sdk",
3
- "version": "1.1.26",
3
+ "version": "1.1.27",
4
4
  "main": "dist/index.js",
5
5
  "author": "Jonathan Lambert <jonathan@etainabl.com>",
6
6
  "type": "module",
@@ -12,7 +12,7 @@ interface DayNightConsumption {
12
12
  }
13
13
 
14
14
  export const dayNightConsumption = (data: ConsumptionData[]) => data.reduce((acc: DayNightConsumption, item: ConsumptionData): DayNightConsumption => {
15
- const hour = moment(item.date).hour(); // End Time of HH consumption period
15
+ const hour = moment.utc(item.date).hour(); // End Time of HH consumption period
16
16
 
17
17
  if (hour >= 0 && hour < 7) {
18
18
  acc.nightConsumption += item.consumption;
package/src/index.ts CHANGED
@@ -4,11 +4,13 @@ import db from './db.js';
4
4
  import slack from './slack.js';
5
5
  import * as units from './units.js';
6
6
  import * as consumption from './consumption.js';
7
+ import * as monitoring from './monitoring.js';
7
8
 
8
9
  export {
9
10
  api,
10
11
  logger,
11
12
  consumption,
13
+ monitoring,
12
14
  db,
13
15
  slack,
14
16
  units
@@ -0,0 +1,17 @@
1
+ import axios from 'axios';
2
+
3
+ import logger from './logger.js';
4
+
5
+ const log = logger('monitoring');
6
+
7
+ export const sendHeartbeat = async () => {
8
+ if (!process.env.HEARTBEAT_URL) return false;
9
+ try {
10
+ await axios.post(process.env.HEARTBEAT_URL);
11
+
12
+ return true;
13
+ } catch (e: any) {
14
+ log.warn(`Failed to send heartbeat: ${e.message || e}`);
15
+ return false;
16
+ }
17
+ }
@@ -1 +0,0 @@
1
- export declare function interpolate(meterReadings: any[], targetDate: any, method?: string): any;
@@ -1,73 +0,0 @@
1
- import moment from 'moment';
2
- export function interpolate(meterReadings, targetDate, method = 'linear') {
3
- if (method === 'cubic') {
4
- return cubicInterpolation(meterReadings, targetDate);
5
- }
6
- if (method === 'linear') {
7
- return linearInterpolation(meterReadings, targetDate);
8
- }
9
- throw new Error(`Interpolation method ${method} not supported`);
10
- }
11
- function linearInterpolation(meterReadings, targetDate) {
12
- // Ensure the meter readings are sorted by date
13
- meterReadings.sort((a, b) => moment(a.submittedAt).unix() - moment(b.submittedAt).unix());
14
- const targetTimestamp = moment(targetDate).startOf('minute').unix();
15
- // Find the two nearest meter readings for the target date
16
- let lowerIndex = -1;
17
- let upperIndex = -1;
18
- for (let i = 0; i < meterReadings.length; i++) {
19
- const reading = meterReadings[i];
20
- if (moment(reading.submittedAt).startOf('minute').unix() <= targetTimestamp) {
21
- lowerIndex = i;
22
- }
23
- else {
24
- upperIndex = i;
25
- break;
26
- }
27
- }
28
- // If no readings are available for interpolation, return null
29
- if (lowerIndex === -1 || upperIndex === -1) {
30
- return null;
31
- }
32
- const lowerReading = meterReadings[lowerIndex];
33
- const upperReading = meterReadings[upperIndex];
34
- // Linear interpolation formula
35
- const consumption = lowerReading.value
36
- + ((targetTimestamp - moment(lowerReading.submittedAt).startOf('minute').unix())
37
- / (moment(upperReading.submittedAt).startOf('minute').unix() - moment(lowerReading.submittedAt).startOf('minute').unix()))
38
- * (upperReading.value - lowerReading.value);
39
- return consumption;
40
- }
41
- ;
42
- function cubicInterpolateCalc(x0, y0, x1, y1, x2, y2, x3, y3, x) {
43
- const t = (x - x1) / (x2 - x1);
44
- const t2 = t * t;
45
- const t3 = t2 * t;
46
- const a0 = y3 - y2 - y0 + y1;
47
- const a1 = y0 - y1 - a0;
48
- const a2 = y2 - y0;
49
- const a3 = y1;
50
- return a0 * t3 + a1 * t2 + a2 * t + a3;
51
- }
52
- function cubicInterpolation(meterReadings, targetDate) {
53
- // Ensure the meter readings are sorted by date
54
- meterReadings.sort((a, b) => moment(a.submittedAt).unix() - moment(b.submittedAt).unix());
55
- const targetTimestamp = new Date(targetDate).getTime();
56
- // Find the four nearest meter readings for the target date
57
- let startIndex = -1;
58
- for (let i = 0; i < meterReadings.length; i++) {
59
- const reading = meterReadings[i];
60
- if (moment(reading.submittedAt).startOf('minute').unix() > targetTimestamp) {
61
- startIndex = i - 2;
62
- break;
63
- }
64
- }
65
- // If no readings are available for interpolation, return null
66
- if (startIndex < 0 || startIndex + 3 >= meterReadings.length) {
67
- return null;
68
- }
69
- const readings = meterReadings.slice(startIndex, startIndex + 4);
70
- const interpolatedConsumption = cubicInterpolateCalc(moment(readings[0].submittedAt).startOf('minute').unix(), readings[0].value, moment(readings[1].submittedAt).startOf('minute').unix(), readings[1].value, moment(readings[2].submittedAt).startOf('minute').unix(), readings[2].value, moment(readings[3].submittedAt).startOf('minute').unix(), readings[3].value, targetTimestamp);
71
- return interpolatedConsumption;
72
- }
73
- //# sourceMappingURL=readingsInterpolate.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"readingsInterpolate.js","sourceRoot":"","sources":["../src/lib/readingsInterpolate.ts"],"names":[],"mappings":"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"}
@@ -1,100 +0,0 @@
1
- import moment from 'moment';
2
-
3
- export function interpolate(meterReadings: any[], targetDate: any, method: string = 'linear') {
4
- if (method === 'cubic') {
5
- return cubicInterpolation(meterReadings, targetDate);
6
- }
7
-
8
- if (method === 'linear') {
9
- return linearInterpolation(meterReadings, targetDate);
10
- }
11
-
12
- throw new Error(`Interpolation method ${method} not supported`);
13
- }
14
-
15
- function linearInterpolation(meterReadings: any[], targetDate: any) {
16
- // Ensure the meter readings are sorted by date
17
- meterReadings.sort((a, b) => moment(a.submittedAt).unix() - moment(b.submittedAt).unix());
18
-
19
- const targetTimestamp = moment(targetDate).startOf('minute').unix();
20
-
21
- // Find the two nearest meter readings for the target date
22
- let lowerIndex = -1;
23
- let upperIndex = -1;
24
- for (let i = 0; i < meterReadings.length; i++) {
25
- const reading = meterReadings[i];
26
- if (moment(reading.submittedAt).startOf('minute').unix() <= targetTimestamp) {
27
- lowerIndex = i;
28
- } else {
29
- upperIndex = i;
30
- break;
31
- }
32
- }
33
-
34
- // If no readings are available for interpolation, return null
35
- if (lowerIndex === -1 || upperIndex === -1) {
36
- return null;
37
- }
38
-
39
- const lowerReading = meterReadings[lowerIndex];
40
- const upperReading = meterReadings[upperIndex];
41
-
42
- // Linear interpolation formula
43
- const consumption = lowerReading.value
44
- + ((targetTimestamp - moment(lowerReading.submittedAt).startOf('minute').unix())
45
- / (moment(upperReading.submittedAt).startOf('minute').unix() - moment(lowerReading.submittedAt).startOf('minute').unix()))
46
- * (upperReading.value - lowerReading.value);
47
-
48
- return consumption;
49
- };
50
-
51
- function cubicInterpolateCalc(x0: number, y0: number, x1: number, y1: number, x2: number, y2: number, x3: number, y3: number, x: number) {
52
- const t = (x - x1) / (x2 - x1);
53
- const t2 = t * t;
54
- const t3 = t2 * t;
55
-
56
- const a0 = y3 - y2 - y0 + y1;
57
- const a1 = y0 - y1 - a0;
58
- const a2 = y2 - y0;
59
- const a3 = y1;
60
-
61
- return a0 * t3 + a1 * t2 + a2 * t + a3;
62
- }
63
-
64
- function cubicInterpolation(meterReadings: any[], targetDate: any) {
65
- // Ensure the meter readings are sorted by date
66
- meterReadings.sort((a, b) => moment(a.submittedAt).unix() - moment(b.submittedAt).unix());
67
-
68
- const targetTimestamp = new Date(targetDate).getTime();
69
-
70
- // Find the four nearest meter readings for the target date
71
- let startIndex = -1;
72
- for (let i = 0; i < meterReadings.length; i++) {
73
- const reading = meterReadings[i];
74
- if (moment(reading.submittedAt).startOf('minute').unix() > targetTimestamp) {
75
- startIndex = i - 2;
76
- break;
77
- }
78
- }
79
-
80
- // If no readings are available for interpolation, return null
81
- if (startIndex < 0 || startIndex + 3 >= meterReadings.length) {
82
- return null;
83
- }
84
-
85
- const readings = meterReadings.slice(startIndex, startIndex + 4);
86
-
87
- const interpolatedConsumption = cubicInterpolateCalc(
88
- moment(readings[0].submittedAt).startOf('minute').unix(),
89
- readings[0].value,
90
- moment(readings[1].submittedAt).startOf('minute').unix(),
91
- readings[1].value,
92
- moment(readings[2].submittedAt).startOf('minute').unix(),
93
- readings[2].value,
94
- moment(readings[3].submittedAt).startOf('minute').unix(),
95
- readings[3].value,
96
- targetTimestamp
97
- );
98
-
99
- return interpolatedConsumption;
100
- }