myio-js-library 0.1.26 → 0.1.28

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/dist/index.cjs CHANGED
@@ -7889,10 +7889,16 @@ function formatDateTime(date, locale) {
7889
7889
  minute: "2-digit"
7890
7890
  });
7891
7891
  }
7892
- async function fetchTelemetryData(token, deviceId, startDate, endDate) {
7892
+ async function fetchTelemetryData(token, deviceId, startDate, endDate, queryParams) {
7893
7893
  const startTs = new Date(startDate).getTime();
7894
7894
  const endTs = new Date(endDate).getTime();
7895
- const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=consumption&startTs=${startTs}&endTs=${endTs}&limit=50000&intervalType=MILLISECONDS&interval=54000000&agg=SUM&orderBy=ASC`;
7895
+ const keys = queryParams?.keys || "consumption";
7896
+ const limit = queryParams?.limit || 5e4;
7897
+ const intervalType = queryParams?.intervalType || "MILLISECONDS";
7898
+ const interval = queryParams?.interval || 54e6;
7899
+ const agg = queryParams?.agg || "SUM";
7900
+ const orderBy = queryParams?.orderBy || "ASC";
7901
+ const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=${keys}&startTs=${startTs}&endTs=${endTs}&limit=${limit}&intervalType=${intervalType}&interval=${interval}&agg=${agg}&orderBy=${orderBy}`;
7896
7902
  const response = await fetch(url, {
7897
7903
  headers: {
7898
7904
  "X-Authorization": `Bearer ${token}`,
@@ -7903,50 +7909,72 @@ async function fetchTelemetryData(token, deviceId, startDate, endDate) {
7903
7909
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
7904
7910
  }
7905
7911
  const data = await response.json();
7906
- return data.consumption || [];
7907
- }
7908
- function processChartData(rawData, locale) {
7909
- if (!rawData || rawData.length === 0) {
7910
- return { points: [], peak: null, isEmpty: true };
7911
- }
7912
- const sortedData = rawData.sort((a, b) => a.ts - b.ts);
7913
- const points = [];
7914
- let previousValue = 0;
7915
- let previousTs = 0;
7916
- for (let i = 0; i < sortedData.length; i++) {
7917
- const current = sortedData[i];
7918
- const currentValue = parseFloat(current.value);
7919
- const currentTs = current.ts;
7920
- if (i > 0) {
7921
- const deltaWh = currentValue - previousValue;
7922
- const deltaHours = (currentTs - previousTs) / (1e3 * 60 * 60);
7923
- if (deltaWh > 0 && deltaHours > 0) {
7924
- const demandKw = deltaWh / 1e3 / deltaHours;
7925
- points.push({
7926
- x: currentTs,
7927
- y: demandKw
7928
- });
7912
+ return data;
7913
+ }
7914
+ function processMultiSeriesChartData(rawData, keys, correctionFactor, locale) {
7915
+ const seriesKeys = keys.split(",").map((k) => k.trim());
7916
+ const seriesData = [];
7917
+ let globalPeak = null;
7918
+ let isEmpty = true;
7919
+ const colors = ["#4A148C", "#2196F3", "#4CAF50", "#FF9800", "#F44336", "#9C27B0", "#795548", "#607D8B"];
7920
+ seriesKeys.forEach((key, index) => {
7921
+ const rawSeries = rawData[key] || [];
7922
+ if (rawSeries.length === 0) {
7923
+ seriesData.push({ key, label: key, points: [], peak: null, color: colors[index % colors.length] });
7924
+ return;
7925
+ }
7926
+ isEmpty = false;
7927
+ const sortedData = rawSeries.sort((a, b) => a.ts - b.ts);
7928
+ const points = [];
7929
+ let previousValue = 0;
7930
+ let previousTs = 0;
7931
+ for (let i = 0; i < sortedData.length; i++) {
7932
+ const current = sortedData[i];
7933
+ const currentValue = parseFloat(current.value);
7934
+ const currentTs = current.ts;
7935
+ if (i > 0) {
7936
+ const deltaWh = currentValue - previousValue;
7937
+ const deltaHours = (currentTs - previousTs) / (1e3 * 60 * 60);
7938
+ if (deltaWh > 0 && deltaHours > 0) {
7939
+ const demandKw = deltaWh / 1e3 / deltaHours * correctionFactor;
7940
+ points.push({
7941
+ x: currentTs,
7942
+ y: demandKw
7943
+ });
7944
+ }
7929
7945
  }
7946
+ previousValue = currentValue;
7947
+ previousTs = currentTs;
7930
7948
  }
7931
- previousValue = currentValue;
7932
- previousTs = currentTs;
7933
- }
7934
- let peak = null;
7935
- if (points.length > 0) {
7936
- const maxPoint = points.reduce(
7937
- (max, point) => point.y > max.y ? point : max
7938
- );
7939
- peak = {
7940
- value: maxPoint.y,
7941
- timestamp: maxPoint.x,
7942
- formattedValue: maxPoint.y.toFixed(2),
7943
- formattedTime: formatDateTime(new Date(maxPoint.x), locale)
7944
- };
7945
- }
7949
+ let seriesPeak = null;
7950
+ if (points.length > 0) {
7951
+ const maxPoint = points.reduce(
7952
+ (max, point) => point.y > max.y ? point : max
7953
+ );
7954
+ seriesPeak = {
7955
+ value: maxPoint.y,
7956
+ timestamp: maxPoint.x,
7957
+ formattedValue: maxPoint.y.toFixed(2),
7958
+ formattedTime: formatDateTime(new Date(maxPoint.x), locale),
7959
+ key
7960
+ };
7961
+ if (!globalPeak || seriesPeak.value > globalPeak.value) {
7962
+ globalPeak = seriesPeak;
7963
+ }
7964
+ }
7965
+ seriesData.push({
7966
+ key,
7967
+ label: key,
7968
+ // Use key as label for now, can be customized later
7969
+ points,
7970
+ peak: seriesPeak,
7971
+ color: colors[index % colors.length]
7972
+ });
7973
+ });
7946
7974
  return {
7947
- points,
7948
- peak,
7949
- isEmpty: points.length === 0
7975
+ series: seriesData,
7976
+ globalPeak,
7977
+ isEmpty
7950
7978
  };
7951
7979
  }
7952
7980
  function createFocusTrap(container) {
@@ -8135,15 +8163,21 @@ async function openDemandModal(params) {
8135
8163
  errorText.textContent = "O Limite de busca \xE9 de 30 dias de intervalo.";
8136
8164
  return;
8137
8165
  }
8138
- const rawData = params.fetcher ? await params.fetcher({ token: params.token, deviceId: params.deviceId, startDate: params.startDate, endDate: params.endDate }) : await fetchTelemetryData(params.token, params.deviceId, params.startDate, params.endDate);
8139
- chartData = processChartData(rawData, locale);
8166
+ const rawData = params.fetcher ? await params.fetcher({ token: params.token, deviceId: params.deviceId, startDate: params.startDate, endDate: params.endDate, telemetryQuery: params.telemetryQuery }) : await fetchTelemetryData(params.token, params.deviceId, params.startDate, params.endDate, params.telemetryQuery);
8167
+ chartData = processMultiSeriesChartData(
8168
+ rawData,
8169
+ params.telemetryQuery?.keys || "consumption",
8170
+ params.correctionFactor || 1,
8171
+ locale
8172
+ );
8140
8173
  if (chartData.isEmpty) {
8141
8174
  errorEl.style.display = "flex";
8142
8175
  errorText.textContent = strings.noData;
8143
8176
  return;
8144
8177
  }
8145
- if (chartData.peak) {
8146
- const date = new Date(chartData.peak.timestamp);
8178
+ if (chartData.globalPeak) {
8179
+ const peak = chartData.globalPeak;
8180
+ const date = new Date(peak.timestamp);
8147
8181
  const dateStr = date.toLocaleDateString(locale, {
8148
8182
  day: "2-digit",
8149
8183
  month: "2-digit",
@@ -8153,7 +8187,7 @@ async function openDemandModal(params) {
8153
8187
  hour: "2-digit",
8154
8188
  minute: "2-digit"
8155
8189
  });
8156
- peakEl.textContent = `${strings.maximum}: ${chartData.peak.formattedValue} kW ${strings.at} ${dateStr} ${strings.atTime} ${timeStr}${strings.timeUnit}`;
8190
+ peakEl.textContent = `${strings.maximum}: ${peak.formattedValue} kW ${peak.key ? `(${peak.key}) ` : ""}${strings.at} ${dateStr} ${strings.atTime} ${timeStr}${strings.timeUnit}`;
8157
8191
  peakEl.style.display = "block";
8158
8192
  }
8159
8193
  const Chart = window.Chart;
@@ -8161,22 +8195,27 @@ async function openDemandModal(params) {
8161
8195
  chart = new Chart(chartCanvas, {
8162
8196
  type: "line",
8163
8197
  data: {
8164
- datasets: [{
8165
- label: strings.demand,
8166
- data: chartData.points,
8167
- borderColor: styles.primaryColor,
8168
- backgroundColor: styles.primaryColor + "20",
8169
- fill: true,
8198
+ datasets: chartData.series.map((series) => ({
8199
+ label: series.label,
8200
+ data: series.points,
8201
+ borderColor: series.color,
8202
+ backgroundColor: series.color + "20",
8203
+ fill: false,
8204
+ // No fill for multi-series
8170
8205
  tension: 0.4,
8171
8206
  pointRadius: 2,
8172
8207
  pointHoverRadius: 6
8173
- }]
8208
+ }))
8174
8209
  },
8175
8210
  options: {
8176
8211
  responsive: true,
8177
8212
  maintainAspectRatio: false,
8178
8213
  plugins: {
8179
- legend: { display: false },
8214
+ legend: {
8215
+ display: chartData.series.length > 1,
8216
+ // Show legend only if multiple series
8217
+ position: "top"
8218
+ },
8180
8219
  zoom: {
8181
8220
  zoom: {
8182
8221
  wheel: { enabled: true },
@@ -8214,7 +8253,8 @@ async function openDemandModal(params) {
8214
8253
  y: {
8215
8254
  title: {
8216
8255
  display: true,
8217
- text: strings.demand
8256
+ text: params.yAxisLabel || strings.demand
8257
+ // Use configurable Y-axis label
8218
8258
  },
8219
8259
  beginAtZero: true
8220
8260
  }
package/dist/index.d.cts CHANGED
@@ -862,13 +862,25 @@ interface DemandModalParams {
862
862
  pdf?: DemandModalPdfConfig;
863
863
  styles?: Partial<DemandModalStyles>;
864
864
  fetcher?: TelemetryFetcher;
865
+ telemetryQuery?: TelemetryQueryParams;
866
+ yAxisLabel?: string;
867
+ correctionFactor?: number;
868
+ }
869
+ interface TelemetryQueryParams {
870
+ keys?: string;
871
+ limit?: number;
872
+ intervalType?: string;
873
+ interval?: number;
874
+ agg?: string;
875
+ orderBy?: string;
865
876
  }
866
877
  type TelemetryFetcher = (params: {
867
878
  token: string;
868
879
  deviceId: string;
869
880
  startDate: string;
870
881
  endDate: string;
871
- }) => Promise<any[]>;
882
+ telemetryQuery?: TelemetryQueryParams;
883
+ }) => Promise<any>;
872
884
  interface DemandModalPdfConfig {
873
885
  enabled?: boolean;
874
886
  fileName?: string;
package/dist/index.js CHANGED
@@ -7823,10 +7823,16 @@ function formatDateTime(date, locale) {
7823
7823
  minute: "2-digit"
7824
7824
  });
7825
7825
  }
7826
- async function fetchTelemetryData(token, deviceId, startDate, endDate) {
7826
+ async function fetchTelemetryData(token, deviceId, startDate, endDate, queryParams) {
7827
7827
  const startTs = new Date(startDate).getTime();
7828
7828
  const endTs = new Date(endDate).getTime();
7829
- const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=consumption&startTs=${startTs}&endTs=${endTs}&limit=50000&intervalType=MILLISECONDS&interval=54000000&agg=SUM&orderBy=ASC`;
7829
+ const keys = queryParams?.keys || "consumption";
7830
+ const limit = queryParams?.limit || 5e4;
7831
+ const intervalType = queryParams?.intervalType || "MILLISECONDS";
7832
+ const interval = queryParams?.interval || 54e6;
7833
+ const agg = queryParams?.agg || "SUM";
7834
+ const orderBy = queryParams?.orderBy || "ASC";
7835
+ const url = `/api/plugins/telemetry/DEVICE/${deviceId}/values/timeseries?keys=${keys}&startTs=${startTs}&endTs=${endTs}&limit=${limit}&intervalType=${intervalType}&interval=${interval}&agg=${agg}&orderBy=${orderBy}`;
7830
7836
  const response = await fetch(url, {
7831
7837
  headers: {
7832
7838
  "X-Authorization": `Bearer ${token}`,
@@ -7837,50 +7843,72 @@ async function fetchTelemetryData(token, deviceId, startDate, endDate) {
7837
7843
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
7838
7844
  }
7839
7845
  const data = await response.json();
7840
- return data.consumption || [];
7841
- }
7842
- function processChartData(rawData, locale) {
7843
- if (!rawData || rawData.length === 0) {
7844
- return { points: [], peak: null, isEmpty: true };
7845
- }
7846
- const sortedData = rawData.sort((a, b) => a.ts - b.ts);
7847
- const points = [];
7848
- let previousValue = 0;
7849
- let previousTs = 0;
7850
- for (let i = 0; i < sortedData.length; i++) {
7851
- const current = sortedData[i];
7852
- const currentValue = parseFloat(current.value);
7853
- const currentTs = current.ts;
7854
- if (i > 0) {
7855
- const deltaWh = currentValue - previousValue;
7856
- const deltaHours = (currentTs - previousTs) / (1e3 * 60 * 60);
7857
- if (deltaWh > 0 && deltaHours > 0) {
7858
- const demandKw = deltaWh / 1e3 / deltaHours;
7859
- points.push({
7860
- x: currentTs,
7861
- y: demandKw
7862
- });
7846
+ return data;
7847
+ }
7848
+ function processMultiSeriesChartData(rawData, keys, correctionFactor, locale) {
7849
+ const seriesKeys = keys.split(",").map((k) => k.trim());
7850
+ const seriesData = [];
7851
+ let globalPeak = null;
7852
+ let isEmpty = true;
7853
+ const colors = ["#4A148C", "#2196F3", "#4CAF50", "#FF9800", "#F44336", "#9C27B0", "#795548", "#607D8B"];
7854
+ seriesKeys.forEach((key, index) => {
7855
+ const rawSeries = rawData[key] || [];
7856
+ if (rawSeries.length === 0) {
7857
+ seriesData.push({ key, label: key, points: [], peak: null, color: colors[index % colors.length] });
7858
+ return;
7859
+ }
7860
+ isEmpty = false;
7861
+ const sortedData = rawSeries.sort((a, b) => a.ts - b.ts);
7862
+ const points = [];
7863
+ let previousValue = 0;
7864
+ let previousTs = 0;
7865
+ for (let i = 0; i < sortedData.length; i++) {
7866
+ const current = sortedData[i];
7867
+ const currentValue = parseFloat(current.value);
7868
+ const currentTs = current.ts;
7869
+ if (i > 0) {
7870
+ const deltaWh = currentValue - previousValue;
7871
+ const deltaHours = (currentTs - previousTs) / (1e3 * 60 * 60);
7872
+ if (deltaWh > 0 && deltaHours > 0) {
7873
+ const demandKw = deltaWh / 1e3 / deltaHours * correctionFactor;
7874
+ points.push({
7875
+ x: currentTs,
7876
+ y: demandKw
7877
+ });
7878
+ }
7863
7879
  }
7880
+ previousValue = currentValue;
7881
+ previousTs = currentTs;
7864
7882
  }
7865
- previousValue = currentValue;
7866
- previousTs = currentTs;
7867
- }
7868
- let peak = null;
7869
- if (points.length > 0) {
7870
- const maxPoint = points.reduce(
7871
- (max, point) => point.y > max.y ? point : max
7872
- );
7873
- peak = {
7874
- value: maxPoint.y,
7875
- timestamp: maxPoint.x,
7876
- formattedValue: maxPoint.y.toFixed(2),
7877
- formattedTime: formatDateTime(new Date(maxPoint.x), locale)
7878
- };
7879
- }
7883
+ let seriesPeak = null;
7884
+ if (points.length > 0) {
7885
+ const maxPoint = points.reduce(
7886
+ (max, point) => point.y > max.y ? point : max
7887
+ );
7888
+ seriesPeak = {
7889
+ value: maxPoint.y,
7890
+ timestamp: maxPoint.x,
7891
+ formattedValue: maxPoint.y.toFixed(2),
7892
+ formattedTime: formatDateTime(new Date(maxPoint.x), locale),
7893
+ key
7894
+ };
7895
+ if (!globalPeak || seriesPeak.value > globalPeak.value) {
7896
+ globalPeak = seriesPeak;
7897
+ }
7898
+ }
7899
+ seriesData.push({
7900
+ key,
7901
+ label: key,
7902
+ // Use key as label for now, can be customized later
7903
+ points,
7904
+ peak: seriesPeak,
7905
+ color: colors[index % colors.length]
7906
+ });
7907
+ });
7880
7908
  return {
7881
- points,
7882
- peak,
7883
- isEmpty: points.length === 0
7909
+ series: seriesData,
7910
+ globalPeak,
7911
+ isEmpty
7884
7912
  };
7885
7913
  }
7886
7914
  function createFocusTrap(container) {
@@ -8069,15 +8097,21 @@ async function openDemandModal(params) {
8069
8097
  errorText.textContent = "O Limite de busca \xE9 de 30 dias de intervalo.";
8070
8098
  return;
8071
8099
  }
8072
- const rawData = params.fetcher ? await params.fetcher({ token: params.token, deviceId: params.deviceId, startDate: params.startDate, endDate: params.endDate }) : await fetchTelemetryData(params.token, params.deviceId, params.startDate, params.endDate);
8073
- chartData = processChartData(rawData, locale);
8100
+ const rawData = params.fetcher ? await params.fetcher({ token: params.token, deviceId: params.deviceId, startDate: params.startDate, endDate: params.endDate, telemetryQuery: params.telemetryQuery }) : await fetchTelemetryData(params.token, params.deviceId, params.startDate, params.endDate, params.telemetryQuery);
8101
+ chartData = processMultiSeriesChartData(
8102
+ rawData,
8103
+ params.telemetryQuery?.keys || "consumption",
8104
+ params.correctionFactor || 1,
8105
+ locale
8106
+ );
8074
8107
  if (chartData.isEmpty) {
8075
8108
  errorEl.style.display = "flex";
8076
8109
  errorText.textContent = strings.noData;
8077
8110
  return;
8078
8111
  }
8079
- if (chartData.peak) {
8080
- const date = new Date(chartData.peak.timestamp);
8112
+ if (chartData.globalPeak) {
8113
+ const peak = chartData.globalPeak;
8114
+ const date = new Date(peak.timestamp);
8081
8115
  const dateStr = date.toLocaleDateString(locale, {
8082
8116
  day: "2-digit",
8083
8117
  month: "2-digit",
@@ -8087,7 +8121,7 @@ async function openDemandModal(params) {
8087
8121
  hour: "2-digit",
8088
8122
  minute: "2-digit"
8089
8123
  });
8090
- peakEl.textContent = `${strings.maximum}: ${chartData.peak.formattedValue} kW ${strings.at} ${dateStr} ${strings.atTime} ${timeStr}${strings.timeUnit}`;
8124
+ peakEl.textContent = `${strings.maximum}: ${peak.formattedValue} kW ${peak.key ? `(${peak.key}) ` : ""}${strings.at} ${dateStr} ${strings.atTime} ${timeStr}${strings.timeUnit}`;
8091
8125
  peakEl.style.display = "block";
8092
8126
  }
8093
8127
  const Chart = window.Chart;
@@ -8095,22 +8129,27 @@ async function openDemandModal(params) {
8095
8129
  chart = new Chart(chartCanvas, {
8096
8130
  type: "line",
8097
8131
  data: {
8098
- datasets: [{
8099
- label: strings.demand,
8100
- data: chartData.points,
8101
- borderColor: styles.primaryColor,
8102
- backgroundColor: styles.primaryColor + "20",
8103
- fill: true,
8132
+ datasets: chartData.series.map((series) => ({
8133
+ label: series.label,
8134
+ data: series.points,
8135
+ borderColor: series.color,
8136
+ backgroundColor: series.color + "20",
8137
+ fill: false,
8138
+ // No fill for multi-series
8104
8139
  tension: 0.4,
8105
8140
  pointRadius: 2,
8106
8141
  pointHoverRadius: 6
8107
- }]
8142
+ }))
8108
8143
  },
8109
8144
  options: {
8110
8145
  responsive: true,
8111
8146
  maintainAspectRatio: false,
8112
8147
  plugins: {
8113
- legend: { display: false },
8148
+ legend: {
8149
+ display: chartData.series.length > 1,
8150
+ // Show legend only if multiple series
8151
+ position: "top"
8152
+ },
8114
8153
  zoom: {
8115
8154
  zoom: {
8116
8155
  wheel: { enabled: true },
@@ -8148,7 +8187,8 @@ async function openDemandModal(params) {
8148
8187
  y: {
8149
8188
  title: {
8150
8189
  display: true,
8151
- text: strings.demand
8190
+ text: params.yAxisLabel || strings.demand
8191
+ // Use configurable Y-axis label
8152
8192
  },
8153
8193
  beginAtZero: true
8154
8194
  }