iobroker.utility-monitor 1.4.6 → 1.5.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.
Files changed (35) hide show
  1. package/README.md +98 -55
  2. package/admin/custom/.vite/manifest.json +90 -0
  3. package/admin/custom/@mf-types/Components.d.ts +2 -0
  4. package/admin/custom/@mf-types/compiled-types/Components/CSVImporter.d.ts +11 -0
  5. package/admin/custom/@mf-types/compiled-types/Components.d.ts +2 -0
  6. package/admin/custom/@mf-types.d.ts +3 -0
  7. package/admin/custom/@mf-types.zip +0 -0
  8. package/admin/custom/CSVImporter_v15_11.js +4415 -0
  9. package/admin/custom/assets/Components-i0AZ59nl.js +18887 -0
  10. package/admin/custom/assets/UtilityMonitor__loadShare__react__loadShare__-Da99Mak4.js +42 -0
  11. package/admin/custom/assets/UtilityMonitor__mf_v__runtimeInit__mf_v__-BmC4OGk6.js +16 -0
  12. package/admin/custom/assets/_commonjsHelpers-Dj2_voLF.js +30 -0
  13. package/admin/custom/assets/hostInit-DEXfeB0W.js +10 -0
  14. package/admin/custom/assets/index-B3WVNJTz.js +401 -0
  15. package/admin/custom/assets/index-VBwl8x_k.js +64 -0
  16. package/admin/custom/assets/preload-helper-BelkbqnE.js +61 -0
  17. package/admin/custom/assets/virtualExposes-CqCLUNLT.js +19 -0
  18. package/admin/custom/index.html +12 -0
  19. package/admin/custom/mf-manifest.json +1 -0
  20. package/admin/jsonConfig.json +90 -31
  21. package/io-package.json +39 -3
  22. package/lib/billingManager.js +235 -123
  23. package/lib/calculator.js +19 -138
  24. package/lib/consumptionManager.js +9 -252
  25. package/lib/importManager.js +300 -0
  26. package/lib/messagingHandler.js +4 -2
  27. package/lib/meter/MeterRegistry.js +110 -0
  28. package/lib/multiMeterManager.js +397 -174
  29. package/lib/stateManager.js +502 -31
  30. package/lib/utils/billingHelper.js +69 -0
  31. package/lib/utils/consumptionHelper.js +47 -0
  32. package/lib/utils/helpers.js +178 -0
  33. package/lib/utils/typeMapper.js +19 -0
  34. package/main.js +71 -8
  35. package/package.json +10 -4
@@ -0,0 +1,64 @@
1
+ import { g as getDefaultExportFromCjs } from './_commonjsHelpers-Dj2_voLF.js';
2
+
3
+ function _mergeNamespaces(n, m) {
4
+ for (var i = 0; i < m.length; i++) {
5
+ const e = m[i];
6
+ if (typeof e !== 'string' && !Array.isArray(e)) { for (const k in e) {
7
+ if (k !== 'default' && !(k in n)) {
8
+ const d = Object.getOwnPropertyDescriptor(e, k);
9
+ if (d) {
10
+ Object.defineProperty(n, k, d.get ? d : {
11
+ enumerable: true,
12
+ get: () => e[k]
13
+ });
14
+ }
15
+ }
16
+ } }
17
+ }
18
+ return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: 'Module' }));
19
+ }
20
+
21
+ var react = {exports: {}};
22
+
23
+ var react_production_min = {};
24
+
25
+ /**
26
+ * @license React
27
+ * react.production.min.js
28
+ *
29
+ * Copyright (c) Facebook, Inc. and its affiliates.
30
+ *
31
+ * This source code is licensed under the MIT license found in the
32
+ * LICENSE file in the root directory of this source tree.
33
+ */
34
+ var l=Symbol.for("react.element"),n=Symbol.for("react.portal"),p=Symbol.for("react.fragment"),q=Symbol.for("react.strict_mode"),r=Symbol.for("react.profiler"),t=Symbol.for("react.provider"),u=Symbol.for("react.context"),v=Symbol.for("react.forward_ref"),w=Symbol.for("react.suspense"),x=Symbol.for("react.memo"),y=Symbol.for("react.lazy"),z=Symbol.iterator;function A(a){if(null===a||"object"!==typeof a)return null;a=z&&a[z]||a["@@iterator"];return "function"===typeof a?a:null}
35
+ var B={isMounted:function(){return false},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},C=Object.assign,D={};function E(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B;}E.prototype.isReactComponent={};
36
+ E.prototype.setState=function(a,b){if("object"!==typeof a&&"function"!==typeof a&&null!=a)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,a,b,"setState");};E.prototype.forceUpdate=function(a){this.updater.enqueueForceUpdate(this,a,"forceUpdate");};function F(){}F.prototype=E.prototype;function G(a,b,e){this.props=a;this.context=b;this.refs=D;this.updater=e||B;}var H=G.prototype=new F;
37
+ H.constructor=G;C(H,E.prototype);H.isPureReactComponent=true;var I=Array.isArray,J=Object.prototype.hasOwnProperty,K={current:null},L={key:true,ref:true,__self:true,__source:true};
38
+ function M(a,b,e){var d,c={},k=null,h=null;if(null!=b)for(d in void 0!==b.ref&&(h=b.ref),void 0!==b.key&&(k=""+b.key),b)J.call(b,d)&&!L.hasOwnProperty(d)&&(c[d]=b[d]);var g=arguments.length-2;if(1===g)c.children=e;else if(1<g){for(var f=Array(g),m=0;m<g;m++)f[m]=arguments[m+2];c.children=f;}if(a&&a.defaultProps)for(d in g=a.defaultProps,g) void 0===c[d]&&(c[d]=g[d]);return {$$typeof:l,type:a,key:k,ref:h,props:c,_owner:K.current}}
39
+ function N(a,b){return {$$typeof:l,type:a.type,key:b,ref:a.ref,props:a.props,_owner:a._owner}}function O(a){return "object"===typeof a&&null!==a&&a.$$typeof===l}function escape(a){var b={"=":"=0",":":"=2"};return "$"+a.replace(/[=:]/g,function(a){return b[a]})}var P=/\/+/g;function Q(a,b){return "object"===typeof a&&null!==a&&null!=a.key?escape(""+a.key):b.toString(36)}
40
+ function R(a,b,e,d,c){var k=typeof a;if("undefined"===k||"boolean"===k)a=null;var h=false;if(null===a)h=true;else switch(k){case "string":case "number":h=true;break;case "object":switch(a.$$typeof){case l:case n:h=true;}}if(h)return h=a,c=c(h),a=""===d?"."+Q(h,0):d,I(c)?(e="",null!=a&&(e=a.replace(P,"$&/")+"/"),R(c,b,e,"",function(a){return a})):null!=c&&(O(c)&&(c=N(c,e+(!c.key||h&&h.key===c.key?"":(""+c.key).replace(P,"$&/")+"/")+a)),b.push(c)),1;h=0;d=""===d?".":d+":";if(I(a))for(var g=0;g<a.length;g++){k=
41
+ a[g];var f=d+Q(k,g);h+=R(k,b,e,f,c);}else if(f=A(a),"function"===typeof f)for(a=f.call(a),g=0;!(k=a.next()).done;)k=k.value,f=d+Q(k,g++),h+=R(k,b,e,f,c);else if("object"===k)throw b=String(a),Error("Objects are not valid as a React child (found: "+("[object Object]"===b?"object with keys {"+Object.keys(a).join(", ")+"}":b)+"). If you meant to render a collection of children, use an array instead.");return h}
42
+ function S(a,b,e){if(null==a)return a;var d=[],c=0;R(a,d,"","",function(a){return b.call(e,a,c++)});return d}function T(a){if(-1===a._status){var b=a._result;b=b();b.then(function(b){if(0===a._status||-1===a._status)a._status=1,a._result=b;},function(b){if(0===a._status||-1===a._status)a._status=2,a._result=b;});-1===a._status&&(a._status=0,a._result=b);}if(1===a._status)return a._result.default;throw a._result;}
43
+ var U={current:null},V={transition:null},W={ReactCurrentDispatcher:U,ReactCurrentBatchConfig:V,ReactCurrentOwner:K};function X(){throw Error("act(...) is not supported in production builds of React.");}
44
+ react_production_min.Children={map:S,forEach:function(a,b,e){S(a,function(){b.apply(this,arguments);},e);},count:function(a){var b=0;S(a,function(){b++;});return b},toArray:function(a){return S(a,function(a){return a})||[]},only:function(a){if(!O(a))throw Error("React.Children.only expected to receive a single React element child.");return a}};react_production_min.Component=E;react_production_min.Fragment=p;react_production_min.Profiler=r;react_production_min.PureComponent=G;react_production_min.StrictMode=q;react_production_min.Suspense=w;
45
+ react_production_min.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=W;react_production_min.act=X;
46
+ react_production_min.cloneElement=function(a,b,e){if(null===a||void 0===a)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+a+".");var d=C({},a.props),c=a.key,k=a.ref,h=a._owner;if(null!=b){ void 0!==b.ref&&(k=b.ref,h=K.current);void 0!==b.key&&(c=""+b.key);if(a.type&&a.type.defaultProps)var g=a.type.defaultProps;for(f in b)J.call(b,f)&&!L.hasOwnProperty(f)&&(d[f]=void 0===b[f]&&void 0!==g?g[f]:b[f]);}var f=arguments.length-2;if(1===f)d.children=e;else if(1<f){g=Array(f);
47
+ for(var m=0;m<f;m++)g[m]=arguments[m+2];d.children=g;}return {$$typeof:l,type:a.type,key:c,ref:k,props:d,_owner:h}};react_production_min.createContext=function(a){a={$$typeof:u,_currentValue:a,_currentValue2:a,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null};a.Provider={$$typeof:t,_context:a};return a.Consumer=a};react_production_min.createElement=M;react_production_min.createFactory=function(a){var b=M.bind(null,a);b.type=a;return b};react_production_min.createRef=function(){return {current:null}};
48
+ react_production_min.forwardRef=function(a){return {$$typeof:v,render:a}};react_production_min.isValidElement=O;react_production_min.lazy=function(a){return {$$typeof:y,_payload:{_status:-1,_result:a},_init:T}};react_production_min.memo=function(a,b){return {$$typeof:x,type:a,compare:void 0===b?null:b}};react_production_min.startTransition=function(a){var b=V.transition;V.transition={};try{a();}finally{V.transition=b;}};react_production_min.unstable_act=X;react_production_min.useCallback=function(a,b){return U.current.useCallback(a,b)};react_production_min.useContext=function(a){return U.current.useContext(a)};
49
+ react_production_min.useDebugValue=function(){};react_production_min.useDeferredValue=function(a){return U.current.useDeferredValue(a)};react_production_min.useEffect=function(a,b){return U.current.useEffect(a,b)};react_production_min.useId=function(){return U.current.useId()};react_production_min.useImperativeHandle=function(a,b,e){return U.current.useImperativeHandle(a,b,e)};react_production_min.useInsertionEffect=function(a,b){return U.current.useInsertionEffect(a,b)};react_production_min.useLayoutEffect=function(a,b){return U.current.useLayoutEffect(a,b)};
50
+ react_production_min.useMemo=function(a,b){return U.current.useMemo(a,b)};react_production_min.useReducer=function(a,b,e){return U.current.useReducer(a,b,e)};react_production_min.useRef=function(a){return U.current.useRef(a)};react_production_min.useState=function(a){return U.current.useState(a)};react_production_min.useSyncExternalStore=function(a,b,e){return U.current.useSyncExternalStore(a,b,e)};react_production_min.useTransition=function(){return U.current.useTransition()};react_production_min.version="18.3.1";
51
+
52
+ {
53
+ react.exports = react_production_min;
54
+ }
55
+
56
+ var reactExports = react.exports;
57
+ const index = /*@__PURE__*/getDefaultExportFromCjs(reactExports);
58
+
59
+ const index$1 = /*#__PURE__*/_mergeNamespaces({
60
+ __proto__: null,
61
+ default: index
62
+ }, [reactExports]);
63
+
64
+ export { index$1 as i };
@@ -0,0 +1,61 @@
1
+ const scriptRel = 'modulepreload';const assetsURL = function(dep) { return "/"+dep };const seen = {};const __vitePreload = function preload(baseModule, deps, importerUrl) {
2
+ let promise = Promise.resolve();
3
+ if (true && deps && deps.length > 0) {
4
+ document.getElementsByTagName("link");
5
+ const cspNonceMeta = document.querySelector(
6
+ "meta[property=csp-nonce]"
7
+ );
8
+ const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
9
+ promise = Promise.allSettled(
10
+ deps.map((dep) => {
11
+ dep = assetsURL(dep);
12
+ if (dep in seen) return;
13
+ seen[dep] = true;
14
+ const isCss = dep.endsWith(".css");
15
+ const cssSelector = isCss ? '[rel="stylesheet"]' : "";
16
+ if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) {
17
+ return;
18
+ }
19
+ const link = document.createElement("link");
20
+ link.rel = isCss ? "stylesheet" : scriptRel;
21
+ if (!isCss) {
22
+ link.as = "script";
23
+ }
24
+ link.crossOrigin = "";
25
+ link.href = dep;
26
+ if (cspNonce) {
27
+ link.setAttribute("nonce", cspNonce);
28
+ }
29
+ document.head.appendChild(link);
30
+ if (isCss) {
31
+ return new Promise((res, rej) => {
32
+ link.addEventListener("load", res);
33
+ link.addEventListener(
34
+ "error",
35
+ () => rej(new Error(`Unable to preload CSS for ${dep}`))
36
+ );
37
+ });
38
+ }
39
+ })
40
+ );
41
+ }
42
+ function handlePreloadError(err) {
43
+ const e = new Event("vite:preloadError", {
44
+ cancelable: true
45
+ });
46
+ e.payload = err;
47
+ window.dispatchEvent(e);
48
+ if (!e.defaultPrevented) {
49
+ throw err;
50
+ }
51
+ }
52
+ return promise.then((res) => {
53
+ for (const item of res || []) {
54
+ if (item.status !== "rejected") continue;
55
+ handlePreloadError(item.reason);
56
+ }
57
+ return baseModule().catch(handlePreloadError);
58
+ });
59
+ };
60
+
61
+ export { __vitePreload as _ };
@@ -0,0 +1,19 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/Components-i0AZ59nl.js","assets/UtilityMonitor__loadShare__react__loadShare__-Da99Mak4.js","assets/_commonjsHelpers-Dj2_voLF.js","assets/UtilityMonitor__mf_v__runtimeInit__mf_v__-BmC4OGk6.js"])))=>i.map(i=>d[i]);
2
+ import { _ as __vitePreload } from './preload-helper-BelkbqnE.js';
3
+
4
+ const exposesMap = {
5
+
6
+ "./Components": async () => {
7
+ const importModule = await __vitePreload(() => import('./Components-i0AZ59nl.js'),true?__vite__mapDeps([0,1,2,3]):void 0);
8
+ const exportModule = {};
9
+ Object.assign(exportModule, importModule);
10
+ Object.defineProperty(exportModule, "__esModule", {
11
+ value: true,
12
+ enumerable: false
13
+ });
14
+ return exportModule
15
+ }
16
+
17
+ };
18
+
19
+ export { exposesMap as default };
@@ -0,0 +1,12 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <script type="module" src="/assets/hostInit-DEXfeB0W.js"></script>
5
+
6
+ <meta charset="UTF-8" />
7
+ <title>ioBroker Admin Component</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ </body>
12
+ </html>
@@ -0,0 +1 @@
1
+ {"id":"UtilityMonitor","name":"UtilityMonitor","metaData":{"name":"UtilityMonitor","type":"app","buildInfo":{"buildVersion":"1.0.0","buildName":"UtilityMonitor"},"remoteEntry":{"name":"CSVImporter_v15_11.js","path":"","type":"module"},"ssrRemoteEntry":{"name":"CSVImporter_v15_11.js","path":"","type":"module"},"types":{"path":"","name":""},"globalName":"UtilityMonitor","pluginVersion":"0.2.5","publicPath":"/"},"shared":[{"id":"UtilityMonitor:react","name":"react","version":"18.3.1","requiredVersion":"^18.3.1","assets":{"js":{"async":[],"sync":["assets/index-VBwl8x_k.js"]},"css":{"async":[],"sync":[]}}},{"id":"UtilityMonitor:react-dom","name":"react-dom","version":"18.3.1","requiredVersion":"^18.3.1","assets":{"js":{"async":[],"sync":["assets/index-B3WVNJTz.js"]},"css":{"async":[],"sync":[]}}}],"remotes":[],"exposes":[{"id":"UtilityMonitor:Components","name":"Components","assets":{"js":{"async":[],"sync":["assets/Components-i0AZ59nl.js"]},"css":{"async":[],"sync":[]}},"path":"./Components"}]}
@@ -180,7 +180,7 @@
180
180
  "hidden": "!data.gasAktiv",
181
181
  "label": "Grundgebühr (€/Monat)",
182
182
  "placeholder": "z.B. 15.30",
183
- "default": 0,
183
+ "default": "0",
184
184
  "xs": 12,
185
185
  "sm": 12,
186
186
  "md": 6,
@@ -192,7 +192,7 @@
192
192
  "hidden": "!data.gasAktiv",
193
193
  "label": "Jahresgebühr (z.B. Zählermiete) (€/Jahr)",
194
194
  "placeholder": "z.B. 20.00",
195
- "default": 0,
195
+ "default": "0",
196
196
  "xs": 12,
197
197
  "sm": 12,
198
198
  "md": 6,
@@ -323,7 +323,7 @@
323
323
  "label": "Monatlicher Abschlag (€)",
324
324
  "placeholder": "z.B. 85.00",
325
325
  "hidden": "!data.gasAktiv",
326
- "default": 0,
326
+ "default": "0",
327
327
  "sm": 12,
328
328
  "md": 6,
329
329
  "xs": 12,
@@ -385,7 +385,7 @@
385
385
  "filter": false,
386
386
  "sort": false,
387
387
  "width": "10%",
388
- "default": 0
388
+ "default": "0"
389
389
  },
390
390
  {
391
391
  "type": "text",
@@ -394,7 +394,7 @@
394
394
  "filter": false,
395
395
  "sort": false,
396
396
  "width": "8%",
397
- "default": 0
397
+ "default": "0"
398
398
  },
399
399
  {
400
400
  "type": "text",
@@ -403,7 +403,7 @@
403
403
  "filter": false,
404
404
  "sort": false,
405
405
  "width": "12%",
406
- "default": 0
406
+ "default": "0"
407
407
  },
408
408
  {
409
409
  "type": "text",
@@ -421,7 +421,7 @@
421
421
  "filter": false,
422
422
  "sort": false,
423
423
  "width": "10%",
424
- "default": 0
424
+ "default": "0"
425
425
  },
426
426
  {
427
427
  "type": "text",
@@ -430,7 +430,7 @@
430
430
  "filter": false,
431
431
  "sort": false,
432
432
  "width": "10%",
433
- "default": 0
433
+ "default": "0"
434
434
  },
435
435
  {
436
436
  "type": "text",
@@ -439,7 +439,7 @@
439
439
  "filter": false,
440
440
  "sort": false,
441
441
  "width": "10%",
442
- "default": 0
442
+ "default": "0"
443
443
  }
444
444
  ]
445
445
  }
@@ -585,7 +585,7 @@
585
585
  "hidden": "!data.wasserAktiv",
586
586
  "label": "Grundgebühr (€/Monat)",
587
587
  "placeholder": "z.B. 5.00",
588
- "default": 0,
588
+ "default": "0",
589
589
  "xs": 12,
590
590
  "sm": 12,
591
591
  "md": 6,
@@ -597,7 +597,7 @@
597
597
  "hidden": "!data.wasserAktiv",
598
598
  "label": "Jahresgebühr (z.B. Zählermiete) (€/Jahr)",
599
599
  "placeholder": "z.B. 20.00",
600
- "default": 0,
600
+ "default": "0",
601
601
  "xs": 12,
602
602
  "sm": 12,
603
603
  "md": 6,
@@ -630,7 +630,7 @@
630
630
  "label": "Monatlicher Abschlag (€)",
631
631
  "placeholder": "z.B. 25.00",
632
632
  "hidden": "!data.wasserAktiv",
633
- "default": 0,
633
+ "default": "0",
634
634
  "sm": 12,
635
635
  "md": 6,
636
636
  "xs": 12,
@@ -692,7 +692,7 @@
692
692
  "filter": false,
693
693
  "sort": false,
694
694
  "width": "10%",
695
- "default": 0
695
+ "default": "0"
696
696
  },
697
697
  {
698
698
  "type": "text",
@@ -701,7 +701,7 @@
701
701
  "filter": false,
702
702
  "sort": false,
703
703
  "width": "8%",
704
- "default": 0
704
+ "default": "0"
705
705
  },
706
706
  {
707
707
  "type": "text",
@@ -710,7 +710,7 @@
710
710
  "filter": false,
711
711
  "sort": false,
712
712
  "width": "12%",
713
- "default": 0
713
+ "default": "0"
714
714
  },
715
715
  {
716
716
  "type": "text",
@@ -728,7 +728,7 @@
728
728
  "filter": false,
729
729
  "sort": false,
730
730
  "width": "10%",
731
- "default": 0
731
+ "default": "0"
732
732
  },
733
733
  {
734
734
  "type": "text",
@@ -737,7 +737,7 @@
737
737
  "filter": false,
738
738
  "sort": false,
739
739
  "width": "10%",
740
- "default": 0
740
+ "default": "0"
741
741
  },
742
742
  {
743
743
  "type": "text",
@@ -746,7 +746,7 @@
746
746
  "filter": false,
747
747
  "sort": false,
748
748
  "width": "10%",
749
- "default": 0
749
+ "default": "0"
750
750
  }
751
751
  ]
752
752
  }
@@ -890,7 +890,7 @@
890
890
  "type": "text",
891
891
  "hidden": "!data.stromAktiv",
892
892
  "label": "Grundgebühr (€/Monat)",
893
- "default": 0,
893
+ "default": "0",
894
894
  "xs": 12,
895
895
  "sm": 12,
896
896
  "md": 6,
@@ -901,7 +901,7 @@
901
901
  "type": "text",
902
902
  "hidden": "!data.stromAktiv",
903
903
  "label": "Jahresgebühr (z.B. Zählermiete) (€/Jahr)",
904
- "default": 0,
904
+ "default": "0",
905
905
  "xs": 12,
906
906
  "sm": 12,
907
907
  "md": 6,
@@ -1032,7 +1032,7 @@
1032
1032
  "hidden": "!data.stromAktiv",
1033
1033
  "sm": 12,
1034
1034
  "md": 6,
1035
- "default": 0,
1035
+ "default": "0",
1036
1036
  "xs": 12,
1037
1037
  "lg": 4,
1038
1038
  "xl": 3
@@ -1092,7 +1092,7 @@
1092
1092
  "filter": false,
1093
1093
  "sort": false,
1094
1094
  "width": "10%",
1095
- "default": 0
1095
+ "default": "0"
1096
1096
  },
1097
1097
  {
1098
1098
  "type": "text",
@@ -1101,7 +1101,7 @@
1101
1101
  "filter": false,
1102
1102
  "sort": false,
1103
1103
  "width": "8%",
1104
- "default": 0
1104
+ "default": "0"
1105
1105
  },
1106
1106
  {
1107
1107
  "type": "text",
@@ -1110,7 +1110,7 @@
1110
1110
  "filter": false,
1111
1111
  "sort": false,
1112
1112
  "width": "12%",
1113
- "default": 0
1113
+ "default": "0"
1114
1114
  },
1115
1115
  {
1116
1116
  "type": "text",
@@ -1128,7 +1128,7 @@
1128
1128
  "filter": false,
1129
1129
  "sort": false,
1130
1130
  "width": "10%",
1131
- "default": 0
1131
+ "default": "0"
1132
1132
  },
1133
1133
  {
1134
1134
  "type": "text",
@@ -1137,7 +1137,7 @@
1137
1137
  "filter": false,
1138
1138
  "sort": false,
1139
1139
  "width": "10%",
1140
- "default": 0
1140
+ "default": "0"
1141
1141
  },
1142
1142
  {
1143
1143
  "type": "text",
@@ -1146,7 +1146,7 @@
1146
1146
  "filter": false,
1147
1147
  "sort": false,
1148
1148
  "width": "10%",
1149
- "default": 0
1149
+ "default": "0"
1150
1150
  }
1151
1151
  ]
1152
1152
  }
@@ -1290,7 +1290,7 @@
1290
1290
  "type": "text",
1291
1291
  "hidden": "!data.pvAktiv",
1292
1292
  "label": "Grundgebühr (Messstellenbetrieb) (€/Monat)",
1293
- "default": 0,
1293
+ "default": "0",
1294
1294
  "xs": 12,
1295
1295
  "sm": 12,
1296
1296
  "md": 6,
@@ -1301,7 +1301,7 @@
1301
1301
  "type": "text",
1302
1302
  "hidden": "!data.pvAktiv",
1303
1303
  "label": "Jahresgebühr (€/Jahr)",
1304
- "default": 0,
1304
+ "default": "0",
1305
1305
  "xs": 12,
1306
1306
  "sm": 12,
1307
1307
  "md": 6,
@@ -1437,7 +1437,7 @@
1437
1437
  "type": "text",
1438
1438
  "label": "Tag des Monats (1-28)",
1439
1439
  "hidden": "!data.notificationEnabled || !data.notificationMonthlyEnabled",
1440
- "default": 1,
1440
+ "default": "1",
1441
1441
  "sm": 12,
1442
1442
  "xs": 12,
1443
1443
  "md": 4,
@@ -1563,6 +1563,38 @@
1563
1563
  }
1564
1564
  }
1565
1565
  },
1566
+ "tabImport": {
1567
+ "type": "panel",
1568
+ "label": "📥 Import",
1569
+ "items": {
1570
+ "_importHeader": {
1571
+ "type": "header",
1572
+ "text": "CSV Daten-Import",
1573
+ "size": 3
1574
+ },
1575
+ "_importInfo": {
1576
+ "type": "staticText",
1577
+ "text": "Hier kannst du historische Zählerstände importieren. Diese Funktion hilft dir, den Adapter schnell mit alten Daten zu füttern.\n\n⚠️ **Wichtig:** Wähle zuerst den Typ und den Zähler aus, für den die Daten bestimmt sind.",
1578
+ "xs": 12,
1579
+ "sm": 12,
1580
+ "md": 12,
1581
+ "lg": 12,
1582
+ "xl": 12
1583
+ },
1584
+ "importCustom": {
1585
+ "type": "custom",
1586
+ "name": "UtilityMonitor/Components/CSVImporter",
1587
+ "url": "custom/CSVImporter_v15_11.js",
1588
+ "bundlerType": "module",
1589
+ "newLine": true,
1590
+ "xs": 12,
1591
+ "sm": 12,
1592
+ "md": 12,
1593
+ "lg": 12,
1594
+ "xl": 12
1595
+ }
1596
+ }
1597
+ },
1566
1598
  "tabInfo": {
1567
1599
  "type": "panel",
1568
1600
  "label": "ℹ️ Info & Hilfe",
@@ -1574,7 +1606,7 @@
1574
1606
  },
1575
1607
  "_infoVersion": {
1576
1608
  "type": "staticText",
1577
- "text": "**Version:** 1.4.6\n\n**Autor:** fischi87\n\n⚠️ **Breaking Change in v1.4.6:** State-Pfade haben sich geändert! Siehe unten.",
1609
+ "text": "**Version:** 1.5.0\n\n**Autor:** fischi87",
1578
1610
  "sm": 12,
1579
1611
  "xs": 12,
1580
1612
  "md": 12,
@@ -1660,6 +1692,33 @@
1660
1692
  },
1661
1693
  "_divider4": {
1662
1694
  "type": "divider"
1695
+ },
1696
+ "_advancedHeader": {
1697
+ "type": "header",
1698
+ "text": "⚙️ Erweiterte Einstellungen",
1699
+ "size": 4
1700
+ },
1701
+ "_advancedInfo": {
1702
+ "type": "staticText",
1703
+ "text": "Technische Einstellungen für fortgeschrittene Benutzer.",
1704
+ "sm": 12,
1705
+ "xs": 12,
1706
+ "md": 12,
1707
+ "lg": 12,
1708
+ "xl": 12
1709
+ },
1710
+ "sensorSpikeThreshold": {
1711
+ "type": "number",
1712
+ "label": "Sensor-Spike-Schwellwert (kWh/m³)",
1713
+ "help": "Delta-Werte über diesem Schwellwert werden als Spikes ignoriert und nicht zum Verbrauch addiert. Standard: 500",
1714
+ "default": 500,
1715
+ "min": 10,
1716
+ "max": 10000,
1717
+ "sm": 12,
1718
+ "md": 6,
1719
+ "xs": 12,
1720
+ "lg": 4,
1721
+ "xl": 3
1663
1722
  }
1664
1723
  }
1665
1724
  }
package/io-package.json CHANGED
@@ -1,11 +1,46 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "utility-monitor",
4
- "version": "1.4.6",
4
+ "version": "1.5.0",
5
5
  "news": {
6
+ "1.5.0": {
7
+ "en": "New: CSV Import feature with drag and drop support. New: Weekly tracking points. Fix: Resets now performed at 23:59. Refactoring: Modular backend architecture.",
8
+ "de": "Neu: CSV-Import mit Drag-and-Drop. Neu: Wöchentliche Datenpunkte. Fix: Resets werden jetzt um 23:59 Uhr ausgeführt. Refactoring: Modulare Backend-Architektur.",
9
+ "ru": "Новое: функция импорта CSV с поддержкой перетаскивания. Новое: точки еженедельного отслеживания. Исправление: сброс теперь выполняется в 23:59. Рефакторинг: модульная архитектура бэкенда.",
10
+ "pt": "Novo: recurso de importação de CSV com suporte para arrastar e soltar. Novo: pontos de rastreamento semanais. Correção: as reinicializações agora são realizadas às 23:59. Refatoração: arquitetura de back-end modular.",
11
+ "nl": "Nieuw: CSV-importfunctie met drag-and-drop-ondersteuning. Nieuw: Wekelijkse trackingpunten. Fix: Resets worden nu uitgevoerd om 23:59 uur. Refactoring: Modulaire backend-architectuur.",
12
+ "fr": "Nouveau : fonctionnalité d'importation CSV avec prise en charge du glisser-déposer. Nouveau : points de suivi hebdomadaires. Correction : les réinitialisations sont désormais effectuées à 23:59. Refactorisation : architecture backend modulaire.",
13
+ "it": "Nuovo: funzione di importazione CSV con supporto drag-and-drop. Nuovo: punti di tracciamento settimanali. Correzione: i ripristini vengono ora eseguiti alle 23:59. Refactoring: architettura backend modulare.",
14
+ "es": "Nuevo: función de importación de CSV con soporte para arrastrar y soltar. Nuevo: puntos de seguimiento semanali. Corrección: los reinicios ahora se realizan a las 23:59. Re-factorización: arquitectura de backend modular.",
15
+ "pl": "Nowość: funkcja importu CSV z obsługą przeciągnij i upuść. Nowość: tygodniowe punkty śledzenia. Naprawa: resety wykonywane teraz o 23:59. Refaktoryzacja: modułowa architektura backendu.",
16
+ "uk": "Нове: функція імпорту CSV з підтримкою перетягування. Нове: щотижневі точки відстеження. Виправлення: скидання тепер виконується о 23:59. Рефакторинг: модульна архітектура бекенда.",
17
+ "zh-cn": "新增:支持拖放的 CSV 导入功能。新增:每周跟踪点。修复:现在在 23:59 执行重置。重构:模块化后端架构。"
18
+ },
19
+ "1.4.7": {
20
+ "en": "Fix: Removed redundant initialization code causing state object warnings. Fix: Race conditions in multi-meter initialization. New: Support for German umlauts (ä,ö,ü,ß) in meter names.",
21
+ "de": "Fix: Redundanten Initialisierungscode entfernt, der State-Object-Warnungen verursachte. Fix: Race Conditions bei Multi-Meter-Initialisierung. Neu: Unterstützung für deutsche Umlaute (ä,ö,ü,ß) in Zählernamen.",
22
+ "ru": "Исправление: удален избыточный код инициализации, вызывавший предупреждения об объектах состояния. Исправление: состояния гонки при инициализации нескольких счетчиков. Новое: поддержка немецких умляутов (ä, ö, ü, ß) в названиях счетчиков.",
23
+ "pt": "Correção: código de inicialização redundante removido que causava avisos de objetos de estado. Correção: Condições de corrida na inicialização do multi-medidor. Novo: Suporte para tremas alemães (ä, ö, ü, ß) em nomes de medidores.",
24
+ "nl": "Fix: Overbodige initialisatiecode verwijderd die waarschuwingen voor staatsobjecten veroorzaakte. Fix: Race-omstandigheden bij initialisatie van meerdere meters. Nieuw: Ondersteuning voor Duitse umlauten (ä, ö, ü, ß) in meternamen.",
25
+ "fr": "Correction : suppression du code d'initialisation redondant provoquant des avertissements d'objet d'état. Correction : conditions de concurrence lors de l'initialisation de plusieurs compteurs. Nouveau : prise en charge des trémas allemands (ä, ö, ü, ß) dans les noms des compteurs.",
26
+ "it": "Correzione: rimosso il codice di inizializzazione ridondante che causava avvisi sugli oggetti di stato. Correzione: race condition nell'inizializzazione di più contatori. Nuovo: supporto per le dieresi tedesche (ä, ö, ü, ß) nei nomi dei contatori.",
27
+ "es": "Solución: se eliminó el código de inicialización redundante que causaba advertencias de objetos de estado. Solución: condiciones de carrera en la inicialización de múltiples medidores. Nuevo: soporte para diéresis alemanas (ä, ö, ü, ß) en nombres de medidores.",
28
+ "pl": "Naprawa: usunięto nadmiarowy kod inicjalizacji powodujący ostrzeżenia o obiektach stanu. Naprawa: wyścigi podczas inicjalizacji wielu liczników. Nowość: obsługa niemieckich umlautów (ä, ö, ü, ß) w nazwach liczników.",
29
+ "uk": "Виправлення: видалено надлишковий код ініціалізації, що викликав попередження про об'єкти стану. Виправлення: стан гонки при ініціалізації декількох лічильників. Нове: підтримка німецьких умляутів (ä, ö, ü, ß) у назвах лічильників.",
30
+ "zh-cn": "修复:删除了导致状态对象警告的冗余初始化代码。修复:多表初始化中的竞态条件。新增:支持仪表名称中的德语变音符号 (ä, ö, ü, ß)。"
31
+ },
6
32
  "1.4.6": {
7
33
  "en": "Breaking Change: Main meter now requires a name (default: 'main'). State paths changed from 'gas.*' to 'gas.METER_NAME.*'. All meters now use consistent naming structure.",
8
- "de": "Breaking Change: Hauptzähler benötigt jetzt einen Namen (Standard: 'main'). State-Pfade geändert von 'gas.*' zu 'gas.METER_NAME.*'. Alle Zähler nutzen jetzt konsistente Namensstruktur."
34
+ "de": "Breaking Change: Hauptzähler benötigt jetzt einen Namen (Standard: 'main'). State-Pfade geändert von 'gas.*' zu 'gas.METER_NAME.*'. Alle Zähler nutzen jetzt konsistente Namensstruktur.",
35
+ "ru": "Критическое изменение: для главного счетчика теперь требуется имя (по умолчанию — «main»). Пути состояний изменены с 'gas.*' на 'gas.METER_NAME.*'. Все счетчики теперь используют согласованную структуру именования.",
36
+ "pt": "Mudança estrutural: o medidor principal agora requer um nome (padrão: 'main'). Os caminhos de estado mudaram de 'gas.*' para 'gas.METER_NAME.*'. Todos os medidores agora usam uma estrutura de nomenclatura consistente.",
37
+ "nl": "Breaking Change: Hoofdmeter vereist nu een naam (standaard: 'main'). Staatspaden gewijzigd van 'gas.*' naar 'gas.METER_NAME.*'. Alle meters gebruiken nu een consistente naamstructuur.",
38
+ "fr": "Changement radical : le compteur principal nécessite désormais un nom (par défaut : 'main'). Les chemins d'état sont passés de 'gas.*' à 'gas.METER_NAME.*'. Tous los compteurs utilisent désormais une structure de dénomination cohérente.",
39
+ "it": "Cambiamento radicale: il contatore principale ora richiede un nome (predefinito: 'main'). I percorsi di stato sono cambiati da 'gas.*' a 'gas.METER_NAME.*'. Tutti i contatori ora utilizzano una struttura di denominazione coerente.",
40
+ "es": "Cambio importante: el medidor principal ahora requiere un nombre (predeterminado: 'main'). Las rutas de estado cambiaron de 'gas.*' na 'gas.METER_NAME.*'. Todos los medidores ahora utilizan una estructura de nombres consistente.",
41
+ "pl": "Przełomowa zmiana: licznik główny wymaga teraz nazwy (domyślnie „main”). Ścieżki stanów zmieniły się z „gas.*” na „gas.METER_NAME.*”. Wszystkie liczniki używają teraz spójnej struktury nazewnictwa.",
42
+ "uk": "Критична зміна: для головного лічильника тепер потрібна назва (за замовчуванням — «main»). Шляхи статусів змінено з 'gas.*' на 'gas.METER_NAME.*'. Тепер усі лічильники використовують єдину структуру назв.",
43
+ "zh-cn": "重大更改:主表现在需要一个名称(默认值:'main')。状态路径从 'gas.*' 更改为 'gas.METER_NAME.*'。所有计量表现在都使用一致的命名结构。"
9
44
  },
10
45
  "1.4.5": {
11
46
  "en": "Fix: Critical multi-meter cost calculation bugs (main meter sync, basicCharge/paidTotal accumulation, annualFee as fixed yearly value). Fix: Balance formula corrected. Fix: Removed duplicate initialization causing sync issues.",
@@ -142,7 +177,8 @@
142
177
  "notificationPVMeters": [],
143
178
  "notificationBillingEnabled": true,
144
179
  "notificationBillingDays": 7,
145
- "notificationChangeDays": 60
180
+ "notificationChangeDays": 60,
181
+ "sensorSpikeThreshold": 500
146
182
  },
147
183
  "objects": [],
148
184
  "instanceObjects": []