bt-sensors-plugin-sk 1.2.0-beta.0.1.2.b → 1.2.0-beta.0.1.4
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/.vscode/launch.json +7 -0
- package/BTSensor.js +2 -1
- package/README.md +9 -0
- package/package.json +1 -1
- package/public/159.js +1 -1
- package/public/239.js +5 -11
- package/public/540.js +1 -1
- package/public/778.js +1 -1
- package/public/main.js +1 -1
- package/public/remoteEntry.js +1 -1
- package/sensor_classes/BTHome/AbstractBTHomeSensor.js +159 -20
- package/sensor_classes/ShellySBHT003C.js +7 -66
- package/sensor_classes/ShellySBMO003Z.js +73 -0
- package/testqueue.js +64 -0
- package/bt-sensors-plugin-sk.json.bak +0 -121
package/public/540.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see 540.js.LICENSE.txt */
|
|
2
|
-
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[540],{
|
|
2
|
+
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[540],{5287:(e,r,t)=>{var n=t(5228),o="function"==typeof Symbol&&Symbol.for,u=o?Symbol.for("react.element"):60103,f=o?Symbol.for("react.portal"):60106,l=o?Symbol.for("react.fragment"):60107,c=o?Symbol.for("react.strict_mode"):60108,i=o?Symbol.for("react.profiler"):60114,a=o?Symbol.for("react.provider"):60109,s=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,y=o?Symbol.for("react.suspense"):60113,d=o?Symbol.for("react.memo"):60115,h=o?Symbol.for("react.lazy"):60116,v="function"==typeof Symbol&&Symbol.iterator;function m(e){for(var r="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t<arguments.length;t++)r+="&args[]="+encodeURIComponent(arguments[t]);return"Minified React error #"+e+"; visit "+r+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var b={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_={};function S(e,r,t){this.props=e,this.context=r,this.refs=_,this.updater=t||b}function k(){}function g(e,r,t){this.props=e,this.context=r,this.refs=_,this.updater=t||b}S.prototype.isReactComponent={},S.prototype.setState=function(e,r){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(m(85));this.updater.enqueueSetState(this,e,r,"setState")},S.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},k.prototype=S.prototype;var w=g.prototype=new k;w.constructor=g,n(w,S.prototype),w.isPureReactComponent=!0;var $={current:null},C=Object.prototype.hasOwnProperty,E={key:!0,ref:!0,__self:!0,__source:!0};function R(e,r,t){var n,o={},f=null,l=null;if(null!=r)for(n in void 0!==r.ref&&(l=r.ref),void 0!==r.key&&(f=""+r.key),r)C.call(r,n)&&!E.hasOwnProperty(n)&&(o[n]=r[n]);var c=arguments.length-2;if(1===c)o.children=t;else if(1<c){for(var i=Array(c),a=0;a<c;a++)i[a]=arguments[a+2];o.children=i}if(e&&e.defaultProps)for(n in c=e.defaultProps)void 0===o[n]&&(o[n]=c[n]);return{$$typeof:u,type:e,key:f,ref:l,props:o,_owner:$.current}}function x(e){return"object"==typeof e&&null!==e&&e.$$typeof===u}var P=/\/+/g,j=[];function O(e,r,t,n){if(j.length){var o=j.pop();return o.result=e,o.keyPrefix=r,o.func=t,o.context=n,o.count=0,o}return{result:e,keyPrefix:r,func:t,context:n,count:0}}function A(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>j.length&&j.push(e)}function I(e,r,t,n){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var l=!1;if(null===e)l=!0;else switch(o){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case u:case f:l=!0}}if(l)return t(n,e,""===r?"."+q(e,0):r),1;if(l=0,r=""===r?".":r+":",Array.isArray(e))for(var c=0;c<e.length;c++){var i=r+q(o=e[c],c);l+=I(o,i,t,n)}else if("function"==typeof(i=null===e||"object"!=typeof e?null:"function"==typeof(i=v&&e[v]||e["@@iterator"])?i:null))for(e=i.call(e),c=0;!(o=e.next()).done;)l+=I(o=o.value,i=r+q(o,c++),t,n);else if("object"===o)throw t=""+e,Error(m(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t,""));return l}function U(e,r,t){return null==e?0:I(e,"",r,t)}function q(e,r){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var r={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,(function(e){return r[e]}))}(e.key):r.toString(36)}function F(e,r){e.func.call(e.context,r,e.count++)}function L(e,r,t){var n=e.result,o=e.keyPrefix;e=e.func.call(e.context,r,e.count++),Array.isArray(e)?M(e,n,t,(function(e){return e})):null!=e&&(x(e)&&(e=function(e,r){return{$$typeof:u,type:e.type,key:r,ref:e.ref,props:e.props,_owner:e._owner}}(e,o+(!e.key||r&&r.key===e.key?"":(""+e.key).replace(P,"$&/")+"/")+t)),n.push(e))}function M(e,r,t,n,o){var u="";null!=t&&(u=(""+t).replace(P,"$&/")+"/"),U(e,L,r=O(r,u,n,o)),A(r)}var D={current:null};function V(){var e=D.current;if(null===e)throw Error(m(321));return e}var B={ReactCurrentDispatcher:D,ReactCurrentBatchConfig:{suspense:null},ReactCurrentOwner:$,IsSomeRendererActing:{current:!1},assign:n};r.Children={map:function(e,r,t){if(null==e)return e;var n=[];return M(e,n,null,r,t),n},forEach:function(e,r,t){if(null==e)return e;U(e,F,r=O(null,null,r,t)),A(r)},count:function(e){return U(e,(function(){return null}),null)},toArray:function(e){var r=[];return M(e,r,null,(function(e){return e})),r},only:function(e){if(!x(e))throw Error(m(143));return e}},r.Component=S,r.Fragment=l,r.Profiler=i,r.PureComponent=g,r.StrictMode=c,r.Suspense=y,r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=B,r.cloneElement=function(e,r,t){if(null==e)throw Error(m(267,e));var o=n({},e.props),f=e.key,l=e.ref,c=e._owner;if(null!=r){if(void 0!==r.ref&&(l=r.ref,c=$.current),void 0!==r.key&&(f=""+r.key),e.type&&e.type.defaultProps)var i=e.type.defaultProps;for(a in r)C.call(r,a)&&!E.hasOwnProperty(a)&&(o[a]=void 0===r[a]&&void 0!==i?i[a]:r[a])}var a=arguments.length-2;if(1===a)o.children=t;else if(1<a){i=Array(a);for(var s=0;s<a;s++)i[s]=arguments[s+2];o.children=i}return{$$typeof:u,type:e.type,key:f,ref:l,props:o,_owner:c}},r.createContext=function(e,r){return void 0===r&&(r=null),(e={$$typeof:s,_calculateChangedBits:r,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:a,_context:e},e.Consumer=e},r.createElement=R,r.createFactory=function(e){var r=R.bind(null,e);return r.type=e,r},r.createRef=function(){return{current:null}},r.forwardRef=function(e){return{$$typeof:p,render:e}},r.isValidElement=x,r.lazy=function(e){return{$$typeof:h,_ctor:e,_status:-1,_result:null}},r.memo=function(e,r){return{$$typeof:d,type:e,compare:void 0===r?null:r}},r.useCallback=function(e,r){return V().useCallback(e,r)},r.useContext=function(e,r){return V().useContext(e,r)},r.useDebugValue=function(){},r.useEffect=function(e,r){return V().useEffect(e,r)},r.useImperativeHandle=function(e,r,t){return V().useImperativeHandle(e,r,t)},r.useLayoutEffect=function(e,r){return V().useLayoutEffect(e,r)},r.useMemo=function(e,r){return V().useMemo(e,r)},r.useReducer=function(e,r,t){return V().useReducer(e,r,t)},r.useRef=function(e){return V().useRef(e)},r.useState=function(e){return V().useState(e)},r.version="16.14.0"},6540:(e,r,t)=>{e.exports=t(5287)}}]);
|
package/public/778.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! For license information please see 778.js.LICENSE.txt */
|
|
2
|
-
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[540,778],{
|
|
2
|
+
"use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[540,778],{5228:e=>{var r=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var r={},t=0;t<10;t++)r["_"+String.fromCharCode(t)]=t;if("0123456789"!==Object.getOwnPropertyNames(r).map((function(e){return r[e]})).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach((function(e){n[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var u,c,f=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l<arguments.length;l++){for(var i in u=Object(arguments[l]))t.call(u,i)&&(f[i]=u[i]);if(r){c=r(u);for(var a=0;a<c.length;a++)n.call(u,c[a])&&(f[c[a]]=u[c[a]])}}return f}},5287:(e,r,t)=>{var n=t(5228),o="function"==typeof Symbol&&Symbol.for,u=o?Symbol.for("react.element"):60103,c=o?Symbol.for("react.portal"):60106,f=o?Symbol.for("react.fragment"):60107,l=o?Symbol.for("react.strict_mode"):60108,i=o?Symbol.for("react.profiler"):60114,a=o?Symbol.for("react.provider"):60109,s=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,y=o?Symbol.for("react.suspense"):60113,d=o?Symbol.for("react.memo"):60115,h=o?Symbol.for("react.lazy"):60116,b="function"==typeof Symbol&&Symbol.iterator;function v(e){for(var r="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t<arguments.length;t++)r+="&args[]="+encodeURIComponent(arguments[t]);return"Minified React error #"+e+"; visit "+r+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_={};function g(e,r,t){this.props=e,this.context=r,this.refs=_,this.updater=t||m}function S(){}function k(e,r,t){this.props=e,this.context=r,this.refs=_,this.updater=t||m}g.prototype.isReactComponent={},g.prototype.setState=function(e,r){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(v(85));this.updater.enqueueSetState(this,e,r,"setState")},g.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},S.prototype=g.prototype;var w=k.prototype=new S;w.constructor=k,n(w,g.prototype),w.isPureReactComponent=!0;var j={current:null},O=Object.prototype.hasOwnProperty,C={key:!0,ref:!0,__self:!0,__source:!0};function $(e,r,t){var n,o={},c=null,f=null;if(null!=r)for(n in void 0!==r.ref&&(f=r.ref),void 0!==r.key&&(c=""+r.key),r)O.call(r,n)&&!C.hasOwnProperty(n)&&(o[n]=r[n]);var l=arguments.length-2;if(1===l)o.children=t;else if(1<l){for(var i=Array(l),a=0;a<l;a++)i[a]=arguments[a+2];o.children=i}if(e&&e.defaultProps)for(n in l=e.defaultProps)void 0===o[n]&&(o[n]=l[n]);return{$$typeof:u,type:e,key:c,ref:f,props:o,_owner:j.current}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===u}var P=/\/+/g,x=[];function R(e,r,t,n){if(x.length){var o=x.pop();return o.result=e,o.keyPrefix=r,o.func=t,o.context=n,o.count=0,o}return{result:e,keyPrefix:r,func:t,context:n,count:0}}function A(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>x.length&&x.push(e)}function I(e,r,t,n){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var f=!1;if(null===e)f=!0;else switch(o){case"string":case"number":f=!0;break;case"object":switch(e.$$typeof){case u:case c:f=!0}}if(f)return t(n,e,""===r?"."+U(e,0):r),1;if(f=0,r=""===r?".":r+":",Array.isArray(e))for(var l=0;l<e.length;l++){var i=r+U(o=e[l],l);f+=I(o,i,t,n)}else if("function"==typeof(i=null===e||"object"!=typeof e?null:"function"==typeof(i=b&&e[b]||e["@@iterator"])?i:null))for(e=i.call(e),l=0;!(o=e.next()).done;)f+=I(o=o.value,i=r+U(o,l++),t,n);else if("object"===o)throw t=""+e,Error(v(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t,""));return f}function q(e,r,t){return null==e?0:I(e,"",r,t)}function U(e,r){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var r={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,(function(e){return r[e]}))}(e.key):r.toString(36)}function F(e,r){e.func.call(e.context,r,e.count++)}function L(e,r,t){var n=e.result,o=e.keyPrefix;e=e.func.call(e.context,r,e.count++),Array.isArray(e)?M(e,n,t,(function(e){return e})):null!=e&&(E(e)&&(e=function(e,r){return{$$typeof:u,type:e.type,key:r,ref:e.ref,props:e.props,_owner:e._owner}}(e,o+(!e.key||r&&r.key===e.key?"":(""+e.key).replace(P,"$&/")+"/")+t)),n.push(e))}function M(e,r,t,n,o){var u="";null!=t&&(u=(""+t).replace(P,"$&/")+"/"),q(e,L,r=R(r,u,n,o)),A(r)}var N={current:null};function D(){var e=N.current;if(null===e)throw Error(v(321));return e}var T={ReactCurrentDispatcher:N,ReactCurrentBatchConfig:{suspense:null},ReactCurrentOwner:j,IsSomeRendererActing:{current:!1},assign:n};r.Children={map:function(e,r,t){if(null==e)return e;var n=[];return M(e,n,null,r,t),n},forEach:function(e,r,t){if(null==e)return e;q(e,F,r=R(null,null,r,t)),A(r)},count:function(e){return q(e,(function(){return null}),null)},toArray:function(e){var r=[];return M(e,r,null,(function(e){return e})),r},only:function(e){if(!E(e))throw Error(v(143));return e}},r.Component=g,r.Fragment=f,r.Profiler=i,r.PureComponent=k,r.StrictMode=l,r.Suspense=y,r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=T,r.cloneElement=function(e,r,t){if(null==e)throw Error(v(267,e));var o=n({},e.props),c=e.key,f=e.ref,l=e._owner;if(null!=r){if(void 0!==r.ref&&(f=r.ref,l=j.current),void 0!==r.key&&(c=""+r.key),e.type&&e.type.defaultProps)var i=e.type.defaultProps;for(a in r)O.call(r,a)&&!C.hasOwnProperty(a)&&(o[a]=void 0===r[a]&&void 0!==i?i[a]:r[a])}var a=arguments.length-2;if(1===a)o.children=t;else if(1<a){i=Array(a);for(var s=0;s<a;s++)i[s]=arguments[s+2];o.children=i}return{$$typeof:u,type:e.type,key:c,ref:f,props:o,_owner:l}},r.createContext=function(e,r){return void 0===r&&(r=null),(e={$$typeof:s,_calculateChangedBits:r,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:a,_context:e},e.Consumer=e},r.createElement=$,r.createFactory=function(e){var r=$.bind(null,e);return r.type=e,r},r.createRef=function(){return{current:null}},r.forwardRef=function(e){return{$$typeof:p,render:e}},r.isValidElement=E,r.lazy=function(e){return{$$typeof:h,_ctor:e,_status:-1,_result:null}},r.memo=function(e,r){return{$$typeof:d,type:e,compare:void 0===r?null:r}},r.useCallback=function(e,r){return D().useCallback(e,r)},r.useContext=function(e,r){return D().useContext(e,r)},r.useDebugValue=function(){},r.useEffect=function(e,r){return D().useEffect(e,r)},r.useImperativeHandle=function(e,r,t){return D().useImperativeHandle(e,r,t)},r.useLayoutEffect=function(e,r){return D().useLayoutEffect(e,r)},r.useMemo=function(e,r){return D().useMemo(e,r)},r.useReducer=function(e,r,t){return D().useReducer(e,r,t)},r.useRef=function(e){return D().useRef(e)},r.useState=function(e){return D().useState(e)},r.version="16.14.0"},6540:(e,r,t)=>{e.exports=t(5287)}}]);
|
package/public/main.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e,r,t={
|
|
1
|
+
(()=>{var e,r,t={9445:()=>{}},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var a=n[e]={exports:{}};return t[e](a,a.exports,o),a.exports}o.m=t,o.c=n,o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce(((r,t)=>(o.f[t](e,r),r)),[])),o.u=e=>e+".js",o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="bt-sensors-plugin-sk:",o.l=(t,n,a,i)=>{if(e[t])e[t].push(n);else{var s,l;if(void 0!==a)for(var u=document.getElementsByTagName("script"),c=0;c<u.length;c++){var p=u[c];if(p.getAttribute("src")==t||p.getAttribute("data-webpack")==r+a){s=p;break}}s||(l=!0,(s=document.createElement("script")).charset="utf-8",s.timeout=120,o.nc&&s.setAttribute("nonce",o.nc),s.setAttribute("data-webpack",r+a),s.src=t),e[t]=[n];var d=(r,n)=>{s.onerror=s.onload=null,clearTimeout(f);var o=e[t];if(delete e[t],s.parentNode&&s.parentNode.removeChild(s),o&&o.forEach((e=>e(n))),r)return r(n)},f=setTimeout(d.bind(null,void 0,{type:"timeout",target:s}),12e4);s.onerror=d.bind(null,s.onerror),s.onload=d.bind(null,s.onload),l&&document.head.appendChild(s)}},(()=>{o.S={};var e={},r={};o.I=(t,n)=>{n||(n=[]);var a=r[t];if(a||(a=r[t]={}),!(n.indexOf(a)>=0)){if(n.push(a),e[t])return e[t];o.o(o.S,t)||(o.S[t]={});var i=o.S[t],s="bt-sensors-plugin-sk",l=[];return"default"===t&&((e,r,t,n)=>{var a=i[e]=i[e]||{},l=a[r];(!l||!l.loaded&&(1!=!l.eager?n:s>l.from))&&(a[r]={get:()=>o.e(778).then((()=>()=>o(6540))),from:s,eager:!1})})("react","16.14.0"),e[t]=l.length?Promise.all(l).then((()=>e[t]=1)):1}}})(),(()=>{var e;o.g.importScripts&&(e=o.g.location+"");var r=o.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),o.p=e})(),(()=>{var e={792:0};o.f.j=(r,t)=>{var n=o.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else{var a=new Promise(((t,o)=>n=e[r]=[t,o]));t.push(n[2]=a);var i=o.p+o.u(r),s=new Error;o.l(i,(t=>{if(o.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var a=t&&("load"===t.type?"missing":t.type),i=t&&t.target&&t.target.src;s.message="Loading chunk "+r+" failed.\n("+a+": "+i+")",s.name="ChunkLoadError",s.type=a,s.request=i,n[1](s)}}),"chunk-"+r,r)}};var r=(r,t)=>{var n,a,[i,s,l]=t,u=0;if(i.some((r=>0!==e[r]))){for(n in s)o.o(s,n)&&(o.m[n]=s[n]);l&&l(o)}for(r&&r(t);u<i.length;u++)a=i[u],o.o(e,a)&&e[a]&&e[a][0](),e[a]=0},t=self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),o(9445)})();
|
package/public/remoteEntry.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var bt_sensors_plugin_sk;(()=>{"use strict";var e,r,t,n,a,o,i,u,s,l,f,d,c,p,h,v,g,b,m,y,w,k={
|
|
1
|
+
var bt_sensors_plugin_sk;(()=>{"use strict";var e,r,t,n,a,o,i,u,s,l,f,d,c,p,h,v,g,b,m,y,w,k={3237:(e,r,t)=>{var n={"./PluginConfigurationPanel":()=>Promise.all([t.e(239),t.e(159)]).then((()=>()=>t(2995)))},a=(e,r)=>(t.R=r,r=t.o(n,e)?n[e]():Promise.resolve().then((()=>{throw new Error('Module "'+e+'" does not exist in container.')})),t.R=void 0,r),o=(e,r)=>{if(t.S){var n="default",a=t.S[n];if(a&&a!==e)throw new Error("Container initialization failed as it has already been initialized with a different share scope");return t.S[n]=e,t.I(n,r)}};t.d(r,{get:()=>a,init:()=>o})}},S={};function _(e){var r=S[e];if(void 0!==r)return r.exports;var t=S[e]={id:e,loaded:!1,exports:{}};return k[e](t,t.exports,_),t.loaded=!0,t.exports}_.m=k,_.c=S,_.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return _.d(r,{a:r}),r},_.d=(e,r)=>{for(var t in r)_.o(r,t)&&!_.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},_.f={},_.e=e=>Promise.all(Object.keys(_.f).reduce(((r,t)=>(_.f[t](e,r),r)),[])),_.u=e=>e+".js",_.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),_.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),e={},r="bt-sensors-plugin-sk:",_.l=(t,n,a,o)=>{if(e[t])e[t].push(n);else{var i,u;if(void 0!==a)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var f=s[l];if(f.getAttribute("src")==t||f.getAttribute("data-webpack")==r+a){i=f;break}}i||(u=!0,(i=document.createElement("script")).charset="utf-8",i.timeout=120,_.nc&&i.setAttribute("nonce",_.nc),i.setAttribute("data-webpack",r+a),i.src=t),e[t]=[n];var d=(r,n)=>{i.onerror=i.onload=null,clearTimeout(c);var a=e[t];if(delete e[t],i.parentNode&&i.parentNode.removeChild(i),a&&a.forEach((e=>e(n))),r)return r(n)},c=setTimeout(d.bind(null,void 0,{type:"timeout",target:i}),12e4);i.onerror=d.bind(null,i.onerror),i.onload=d.bind(null,i.onload),u&&document.head.appendChild(i)}},_.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},_.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{_.S={};var e={},r={};_.I=(t,n)=>{n||(n=[]);var a=r[t];if(a||(a=r[t]={}),!(n.indexOf(a)>=0)){if(n.push(a),e[t])return e[t];_.o(_.S,t)||(_.S[t]={});var o=_.S[t],i="bt-sensors-plugin-sk",u=[];return"default"===t&&((e,r,t,n)=>{var a=o[e]=o[e]||{},u=a[r];(!u||!u.loaded&&(1!=!u.eager?n:i>u.from))&&(a[r]={get:()=>_.e(778).then((()=>()=>_(6540))),from:i,eager:!1})})("react","16.14.0"),e[t]=u.length?Promise.all(u).then((()=>e[t]=1)):1}}})(),(()=>{var e;_.g.importScripts&&(e=_.g.location+"");var r=_.g.document;if(!e&&r&&(r.currentScript&&"SCRIPT"===r.currentScript.tagName.toUpperCase()&&(e=r.currentScript.src),!e)){var t=r.getElementsByTagName("script");if(t.length)for(var n=t.length-1;n>-1&&(!e||!/^http(s?):/.test(e));)e=t[n--].src}if(!e)throw new Error("Automatic publicPath is not supported in this browser");e=e.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),_.p=e})(),t=e=>{var r=e=>e.split(".").map((e=>+e==e?+e:e)),t=/^([^-+]+)?(?:-([^+]+))?(?:\+(.+))?$/.exec(e),n=t[1]?r(t[1]):[];return t[2]&&(n.length++,n.push.apply(n,r(t[2]))),t[3]&&(n.push([]),n.push.apply(n,r(t[3]))),n},n=(e,r)=>{e=t(e),r=t(r);for(var n=0;;){if(n>=e.length)return n<r.length&&"u"!=(typeof r[n])[0];var a=e[n],o=(typeof a)[0];if(n>=r.length)return"u"==o;var i=r[n],u=(typeof i)[0];if(o!=u)return"o"==o&&"n"==u||"s"==u||"u"==o;if("o"!=o&&"u"!=o&&a!=i)return a<i;n++}},a=e=>{var r=e[0],t="";if(1===e.length)return"*";if(r+.5){t+=0==r?">=":-1==r?"<":1==r?"^":2==r?"~":r>0?"=":"!=";for(var n=1,o=1;o<e.length;o++)n--,t+="u"==(typeof(u=e[o]))[0]?"-":(n>0?".":"")+(n=2,u);return t}var i=[];for(o=1;o<e.length;o++){var u=e[o];i.push(0===u?"not("+s()+")":1===u?"("+s()+" || "+s()+")":2===u?i.pop()+" "+i.pop():a(u))}return s();function s(){return i.pop().replace(/^\((.+)\)$/,"$1")}},o=(e,r)=>{if(0 in e){r=t(r);var n=e[0],a=n<0;a&&(n=-n-1);for(var i=0,u=1,s=!0;;u++,i++){var l,f,d=u<e.length?(typeof e[u])[0]:"";if(i>=r.length||"o"==(f=(typeof(l=r[i]))[0]))return!s||("u"==d?u>n&&!a:""==d!=a);if("u"==f){if(!s||"u"!=d)return!1}else if(s)if(d==f)if(u<=n){if(l!=e[u])return!1}else{if(a?l>e[u]:l<e[u])return!1;l!=e[u]&&(s=!1)}else if("s"!=d&&"n"!=d){if(a||u<=n)return!1;s=!1,u--}else{if(u<=n||f<d!=a)return!1;s=!1}else"s"!=d&&"n"!=d&&(s=!1,u--)}}var c=[],p=c.pop.bind(c);for(i=1;i<e.length;i++){var h=e[i];c.push(1==h?p()|p():2==h?p()&p():h?o(h,r):!p())}return!!p()},i=(e,r)=>e&&_.o(e,r),u=e=>(e.loaded=1,e.get()),s=e=>Object.keys(e).reduce(((r,t)=>(e[t].eager&&(r[t]=e[t]),r)),{}),l=(e,r,t)=>{var a=t?s(e[r]):e[r];return(r=Object.keys(a).reduce(((e,r)=>!e||n(e,r)?r:e),0))&&a[r]},f=(e,r,t,a)=>{var i=a?s(e[r]):e[r];return(r=Object.keys(i).reduce(((e,r)=>!o(t,r)||e&&!n(e,r)?e:r),0))&&i[r]},d=(e,r,t,n,o)=>{var i=e[t];return"No satisfying version ("+a(n)+")"+(o?" for eager consumption":"")+" of shared module "+t+" found in shared scope "+r+".\nAvailable versions: "+Object.keys(i).map((e=>e+" from "+i[e].from)).join(", ")},c=e=>{throw new Error(e)},h=(e,r,t)=>t?t():((e,r)=>c("Shared module "+r+" doesn't exist in shared scope "+e))(e,r),v=(p=e=>function(r,t,n,a,o){var i=_.I(r);return i&&i.then&&!n?i.then(e.bind(e,r,_.S[r],t,!1,a,o)):e(r,_.S[r],t,n,a,o)})(((e,r,t,n,a)=>i(r,t)?u(l(r,t,n)):h(e,t,a))),g=p(((e,r,t,n,a,o)=>{if(!i(r,t))return h(e,t,o);var s=f(r,t,a,n);return s?u(s):o?o():void c(d(r,e,t,a,n))})),b={},m={1490:()=>g("default","react",!1,[,[1,17,0,0],[1,16,8,0],1],(()=>_.e(540).then((()=>()=>_(6540))))),2085:()=>g("default","react",!1,[1,16,14,0],(()=>_.e(540).then((()=>()=>_(6540))))),2417:()=>g("default","react",!1,[0,16,8,0],(()=>_.e(540).then((()=>()=>_(6540))))),4115:()=>g("default","react",!1,[,[1,19,0,0,,"rc",1],[1,18,0,0],[1,17,0,0,,"rc",1],[1,16,8,0],1,1,1],(()=>_.e(540).then((()=>()=>_(6540))))),4147:()=>g("default","react",!1,[1,16,13,1],(()=>_.e(540).then((()=>()=>_(6540))))),4167:()=>v("default","react",!1,(()=>_.e(540).then((()=>()=>_(6540))))),4564:()=>g("default","react",!1,[0,16,14,0],(()=>_.e(540).then((()=>()=>_(6540))))),6932:()=>g("default","react",!1,[0,15,0,0],(()=>_.e(540).then((()=>()=>_(6540))))),7227:()=>g("default","react",!1,[0,16,6,0],(()=>_.e(540).then((()=>()=>_(6540))))),7920:()=>g("default","react",!1,[,[0,17],[1,16,14,0],1],(()=>_.e(540).then((()=>()=>_(6540))))),8271:()=>g("default","react",!1,[0,0,14,0],(()=>_.e(540).then((()=>()=>_(6540)))))},y={159:[1490,2085,2417,4115,4147,4167,4564,6932,7227,7920,8271]},w={},_.f.consumes=(e,r)=>{_.o(y,e)&&y[e].forEach((e=>{if(_.o(b,e))return r.push(b[e]);if(!w[e]){var t=r=>{b[e]=0,_.m[e]=t=>{delete _.c[e],t.exports=r()}};w[e]=!0;var n=r=>{delete b[e],_.m[e]=t=>{throw delete _.c[e],r}};try{var a=m[e]();a.then?r.push(b[e]=a.then(t).catch(n)):t(a)}catch(e){n(e)}}}))},(()=>{var e={592:0};_.f.j=(r,t)=>{var n=_.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else{var a=new Promise(((t,a)=>n=e[r]=[t,a]));t.push(n[2]=a);var o=_.p+_.u(r),i=new Error;_.l(o,(t=>{if(_.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var a=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;i.message="Loading chunk "+r+" failed.\n("+a+": "+o+")",i.name="ChunkLoadError",i.type=a,i.request=o,n[1](i)}}),"chunk-"+r,r)}};var r=(r,t)=>{var n,a,[o,i,u]=t,s=0;if(o.some((r=>0!==e[r]))){for(n in i)_.o(i,n)&&(_.m[n]=i[n]);u&&u(_)}for(r&&r(t);s<o.length;s++)a=o[s],_.o(e,a)&&e[a]&&e[a][0](),e[a]=0},t=self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var j=_(3237);bt_sensors_plugin_sk=j})();
|
|
@@ -1,7 +1,18 @@
|
|
|
1
1
|
const BTSensor = require("../../BTSensor");
|
|
2
2
|
const BTHomeServiceData = require("./BTHomeServiceData");
|
|
3
3
|
const KaitaiStream = require("kaitai-struct/KaitaiStream");
|
|
4
|
+
/**
|
|
5
|
+
* @typedef ButtonPressEvent {string}
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Shelly Blu devices support single press and hold press options.
|
|
9
|
+
* @type {Readonly<{PRESS: string, HOLD_PRESS: string}>}
|
|
10
|
+
*/
|
|
4
11
|
|
|
12
|
+
const ButtonPressEvent = Object.freeze({
|
|
13
|
+
PRESS: "press",
|
|
14
|
+
HOLD_PRESS: "hold_press",
|
|
15
|
+
});
|
|
5
16
|
/**
|
|
6
17
|
* Base class for sensors publishing BTHome data.
|
|
7
18
|
*
|
|
@@ -11,6 +22,8 @@ const KaitaiStream = require("kaitai-struct/KaitaiStream");
|
|
|
11
22
|
* @see https://bthome.io/
|
|
12
23
|
*/
|
|
13
24
|
class AbstractBTHomeSensor extends BTSensor {
|
|
25
|
+
|
|
26
|
+
|
|
14
27
|
/**
|
|
15
28
|
* Offset from Celsius to Kelvin, used to convert between these units.
|
|
16
29
|
* 273.15 degrees Kelvin correspond to 0 degrees Celsius.
|
|
@@ -25,16 +38,31 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
25
38
|
*/
|
|
26
39
|
static BTHOME_SERVICE_ID = "0000fcd2-0000-1000-8000-00805f9b34fb";
|
|
27
40
|
|
|
41
|
+
|
|
42
|
+
|
|
28
43
|
/**
|
|
29
|
-
* Returns
|
|
44
|
+
* Returns the `AbstractBTHomeSensor` sensor class if the specified device has been identified as Shelly BLU H&T.
|
|
30
45
|
*
|
|
31
|
-
* @param
|
|
32
|
-
* @
|
|
33
|
-
* @return {any|null} Returns the measurement data for the given object ID, or `null`, if the BTHomeData does not
|
|
34
|
-
* contain the measurement.
|
|
46
|
+
* @param device The Bluetooth device to be identified.
|
|
47
|
+
* @returns {Promise<AbstractBTHomeSensor|null>} Returns the sensor class if the device has been identified, or null.
|
|
35
48
|
*/
|
|
36
|
-
static
|
|
37
|
-
|
|
49
|
+
static async identify(device) {
|
|
50
|
+
if (
|
|
51
|
+
(await this.hasBtHomeServiceData(device)) &&
|
|
52
|
+
((await this.hasName(
|
|
53
|
+
device,
|
|
54
|
+
this.SHORTENED_LOCAL_NAME,
|
|
55
|
+
)) || (await this.hasNameAndAddress(
|
|
56
|
+
device,
|
|
57
|
+
this.SHORTENED_LOCAL_NAME,
|
|
58
|
+
)) || (await this.hasName(
|
|
59
|
+
device,
|
|
60
|
+
this.LOCAL_NAME,
|
|
61
|
+
)))
|
|
62
|
+
) {
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
38
66
|
}
|
|
39
67
|
|
|
40
68
|
/**
|
|
@@ -56,12 +84,12 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
56
84
|
* if not.
|
|
57
85
|
*/
|
|
58
86
|
static async hasBtHomeServiceData(device) {
|
|
59
|
-
const serviceData = await
|
|
87
|
+
const serviceData = await this.getDeviceProp(
|
|
60
88
|
device,
|
|
61
89
|
"ServiceData",
|
|
62
90
|
);
|
|
63
91
|
if (serviceData) {
|
|
64
|
-
if (
|
|
92
|
+
if (this.BTHOME_SERVICE_ID in serviceData) {
|
|
65
93
|
return true;
|
|
66
94
|
}
|
|
67
95
|
}
|
|
@@ -88,7 +116,8 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
88
116
|
* if not.
|
|
89
117
|
*/
|
|
90
118
|
static async hasName(device, name) {
|
|
91
|
-
const deviceName = await
|
|
119
|
+
const deviceName = await this.getDeviceProp(device, "Name");
|
|
120
|
+
|
|
92
121
|
if (deviceName) {
|
|
93
122
|
if (deviceName === name) {
|
|
94
123
|
return true;
|
|
@@ -97,14 +126,53 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
97
126
|
return false;
|
|
98
127
|
}
|
|
99
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Returns whether the specified device has a given name plus the last two bytes of its address.
|
|
131
|
+
*
|
|
132
|
+
* This method can be included in the {@link BTSensor#identify} method of inheriting sensor classes.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* static async identify(device) {
|
|
136
|
+
* if (await this.hasNameAndAddress(device)) {
|
|
137
|
+
* // Additional checks, if required
|
|
138
|
+
* return YourSensorClass;
|
|
139
|
+
* }
|
|
140
|
+
* return null;
|
|
141
|
+
* }
|
|
142
|
+
* @see BTSensor#identify
|
|
143
|
+
* @param device The Bluetooth device to check the name.
|
|
144
|
+
* @param name {string} The name to be checked for.
|
|
145
|
+
* @returns {Promise<boolean>} Returns `true`, if the device exposes BTHome service data, or `false`,
|
|
146
|
+
* if not.
|
|
147
|
+
*/
|
|
148
|
+
static async hasNameAndAddress(device, name) {
|
|
149
|
+
let deviceName = await this.getDeviceProp(device, "Name");
|
|
150
|
+
const address = (await this.getDeviceProp(device, "Address")).split(":")
|
|
151
|
+
if (deviceName) {
|
|
152
|
+
if (`${name}-${address[4]}${address[5]}`.localeCompare(deviceName, undefined, { sensitivity: 'base' } )==0)
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Returns measurement data for the given object ID from the given BTHomeData.
|
|
159
|
+
*
|
|
160
|
+
* @param btHomeData {BTHomeServiceData.BthomeServiceData}
|
|
161
|
+
* @param objectId {number}
|
|
162
|
+
* @return {any|null} Returns the measurement data for the given object ID, or `null`, if the BTHomeData does not
|
|
163
|
+
* contain the measurement.
|
|
164
|
+
*/
|
|
165
|
+
getSensorDataByObjectId(btHomeData, objectId) {
|
|
166
|
+
return btHomeData.measurement.find((m) => m.objectId === objectId)?.data;
|
|
167
|
+
}
|
|
100
168
|
/**
|
|
101
169
|
* Extracts battery level from the given BTHome data.
|
|
102
170
|
*
|
|
103
171
|
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
104
172
|
* @returns {number|null} The device's battery level as ratio (0‒1).
|
|
105
173
|
*/
|
|
106
|
-
|
|
107
|
-
const batteryLevel =
|
|
174
|
+
parseBatteryLevel(btHomeData) {
|
|
175
|
+
const batteryLevel = this.getSensorDataByObjectId(
|
|
108
176
|
btHomeData,
|
|
109
177
|
BTHomeServiceData.BthomeObjectId.SENSOR_BATTERY,
|
|
110
178
|
)?.battery;
|
|
@@ -120,14 +188,14 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
120
188
|
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
121
189
|
* @returns {number|null} The temperature in Kelvin.
|
|
122
190
|
*/
|
|
123
|
-
|
|
124
|
-
const tempCelsius =
|
|
191
|
+
parseTemperature(btHomeData) {
|
|
192
|
+
const tempCelsius = this.getSensorDataByObjectId(
|
|
125
193
|
btHomeData,
|
|
126
194
|
BTHomeServiceData.BthomeObjectId.SENSOR_TEMPERATURE_0_1,
|
|
127
195
|
)?.temperature;
|
|
128
196
|
if (tempCelsius) {
|
|
129
197
|
return Number.parseFloat(
|
|
130
|
-
(
|
|
198
|
+
(this.constructor.KELVIN_OFFSET + tempCelsius).toFixed(2),
|
|
131
199
|
);
|
|
132
200
|
}
|
|
133
201
|
return null;
|
|
@@ -139,8 +207,8 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
139
207
|
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
140
208
|
* @returns {number|null} The relative humidity as ratio (0‒1).
|
|
141
209
|
*/
|
|
142
|
-
|
|
143
|
-
const humidity =
|
|
210
|
+
parseHumidity(btHomeData) {
|
|
211
|
+
const humidity = this.getSensorDataByObjectId(
|
|
144
212
|
btHomeData,
|
|
145
213
|
BTHomeServiceData.BthomeObjectId.SENSOR_HUMIDITY,
|
|
146
214
|
)?.humidity;
|
|
@@ -150,14 +218,54 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
150
218
|
return null;
|
|
151
219
|
}
|
|
152
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Extracts luminance from the given BTHome data.
|
|
223
|
+
*
|
|
224
|
+
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
225
|
+
* @returns {number|null} The luminance as float.
|
|
226
|
+
*/
|
|
227
|
+
parseIlluminance(btHomeData) {
|
|
228
|
+
const illuminance = this.getSensorDataByObjectId(
|
|
229
|
+
btHomeData,
|
|
230
|
+
BTHomeServiceData.BthomeObjectId.SENSOR_ILLUMINANCE_0_01,
|
|
231
|
+
)?.illuminance;
|
|
232
|
+
return illuminance;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Extracts motion detection from the given BTHome data.
|
|
236
|
+
*
|
|
237
|
+
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
238
|
+
* @returns {Boolean|null} The device's button press state.
|
|
239
|
+
*/
|
|
240
|
+
parseMotion(btHomeData) {
|
|
241
|
+
const motion = this.getSensorDataByObjectId(
|
|
242
|
+
btHomeData,
|
|
243
|
+
BTHomeServiceData.BthomeObjectId.BINARY_MOTION
|
|
244
|
+
)?.motion;
|
|
245
|
+
return motion.intValue==1
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Extracts packet ID from the given BTHome data.
|
|
250
|
+
*
|
|
251
|
+
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
252
|
+
* @returns {Number|null} The packet ID.
|
|
253
|
+
*/
|
|
254
|
+
parsePacketID(btHomeData) {
|
|
255
|
+
return this.getSensorDataByObjectId(
|
|
256
|
+
btHomeData,
|
|
257
|
+
BTHomeServiceData.BthomeObjectId.MISC_PACKET_ID,
|
|
258
|
+
).packetId
|
|
259
|
+
}
|
|
260
|
+
|
|
153
261
|
/**
|
|
154
262
|
* Extracts button press event from the given BTHome data.
|
|
155
263
|
*
|
|
156
264
|
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
157
265
|
* @returns {BTHomeServiceData.ButtonEventType|null} The device's button press state.
|
|
158
266
|
*/
|
|
159
|
-
|
|
160
|
-
const buttonEvent =
|
|
267
|
+
parseButton(btHomeData) {
|
|
268
|
+
const buttonEvent = this.getSensorDataByObjectId(
|
|
161
269
|
btHomeData,
|
|
162
270
|
BTHomeServiceData.BthomeObjectId.EVENT_BUTTON,
|
|
163
271
|
)?.event;
|
|
@@ -165,8 +273,38 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
165
273
|
return buttonEvent;
|
|
166
274
|
}
|
|
167
275
|
return null;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Parses the relevant button press events for the Shelly BLU H&T from the specified BTHome data. This device only
|
|
280
|
+
* uses a subset of all available BTHome button press events.
|
|
281
|
+
*
|
|
282
|
+
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
283
|
+
* @returns {ButtonPressEvent|null} The device's button state.
|
|
284
|
+
* @see https://shelly-api-docs.shelly.cloud/docs-ble/Devices/ht/#button-press-events
|
|
285
|
+
* @see https://bthome.io/format/
|
|
286
|
+
*/
|
|
287
|
+
parseShellyButton(btHomeData) {
|
|
288
|
+
const buttonEvent = this.parseButton(btHomeData);
|
|
289
|
+
if (buttonEvent) {
|
|
290
|
+
if (buttonEvent === BTHomeServiceData.ButtonEventType.PRESS) {
|
|
291
|
+
return ButtonPressEvent.PRESS;
|
|
292
|
+
/*
|
|
293
|
+
* Prior to firmware version 1.0.20, the hold press event is indicated by 0xFE, which does
|
|
294
|
+
* not conform with the BTHome standard.
|
|
295
|
+
*/
|
|
296
|
+
}
|
|
297
|
+
if (
|
|
298
|
+
buttonEvent === BTHomeServiceData.ButtonEventType.HOLD_PRESS ||
|
|
299
|
+
buttonEvent === 0xfe
|
|
300
|
+
) {
|
|
301
|
+
return ButtonPressEvent.HOLD_PRESS;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return null;
|
|
168
305
|
}
|
|
169
306
|
|
|
307
|
+
|
|
170
308
|
propertiesChanged(props) {
|
|
171
309
|
super.propertiesChanged(props);
|
|
172
310
|
|
|
@@ -176,7 +314,7 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
176
314
|
}
|
|
177
315
|
|
|
178
316
|
// Retrieve BTHome data
|
|
179
|
-
const buffer = this.getServiceData(
|
|
317
|
+
const buffer = this.getServiceData(this.constructor.BTHOME_SERVICE_ID);
|
|
180
318
|
if (!buffer) {
|
|
181
319
|
this.debug(
|
|
182
320
|
`ServiceData does not contain BTHome service, which is unexpected for ${this.getDisplayName()}`,
|
|
@@ -189,6 +327,7 @@ class AbstractBTHomeSensor extends BTSensor {
|
|
|
189
327
|
const btHomeData = new BTHomeServiceData(new KaitaiStream(buffer));
|
|
190
328
|
this.emitValuesFrom(btHomeData);
|
|
191
329
|
} catch (e) {
|
|
330
|
+
this.debug(e)
|
|
192
331
|
throw new Error(
|
|
193
332
|
`Unable to parse BTHome data for ${this.getDisplayName()}`,
|
|
194
333
|
);
|
|
@@ -7,74 +7,15 @@ const AbstractBTHomeSensor = require("./BTHome/AbstractBTHomeSensor");
|
|
|
7
7
|
* This sensor is publishing data utilising the BTHome format and inherits from {@link AbstractBTHomeSensor}.
|
|
8
8
|
*/
|
|
9
9
|
class ShellySBHT003C extends AbstractBTHomeSensor {
|
|
10
|
-
static Domain =
|
|
10
|
+
static Domain = this.SensorDomains.environmental
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* The shortened local name as advertised by the Shelly BLU H&T.
|
|
14
14
|
* @type {string}
|
|
15
15
|
*/
|
|
16
16
|
static SHORTENED_LOCAL_NAME = "SBHT-003C";
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* @typedef ButtonPressEvent {string}
|
|
20
|
-
*/
|
|
21
|
-
/**
|
|
22
|
-
* The Shelly BLU H&T only supports single press and hold press options.
|
|
23
|
-
* @type {Readonly<{PRESS: string, HOLD_PRESS: string}>}
|
|
24
|
-
*/
|
|
25
|
-
static ButtonPressEvent = Object.freeze({
|
|
26
|
-
PRESS: "press",
|
|
27
|
-
HOLD_PRESS: "hold_press",
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Returns the `ShellySBHT003C` sensor class if the specified device has been identified as Shelly BLU H&T.
|
|
32
|
-
*
|
|
33
|
-
* @param device The Bluetooth device to be identified.
|
|
34
|
-
* @returns {Promise<ShellySBHT003C|null>} Returns the sensor class if the device has been identified, or null.
|
|
35
|
-
*/
|
|
36
|
-
static async identify(device) {
|
|
37
|
-
if (
|
|
38
|
-
(await ShellySBHT003C.hasBtHomeServiceData(device)) &&
|
|
39
|
-
(await ShellySBHT003C.hasName(
|
|
40
|
-
device,
|
|
41
|
-
ShellySBHT003C.SHORTENED_LOCAL_NAME,
|
|
42
|
-
))
|
|
43
|
-
) {
|
|
44
|
-
return ShellySBHT003C;
|
|
45
|
-
}
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Parses the relevant button press events for the Shelly BLU H&T from the specified BTHome data. This device only
|
|
51
|
-
* uses a subset of all available BTHome button press events.
|
|
52
|
-
*
|
|
53
|
-
* @param btHomeData {BTHomeServiceData.BthomeServiceData} The BTHome data provided by the device.
|
|
54
|
-
* @returns {ShellySBHT003C.ButtonPressEvent|null} The device's button state.
|
|
55
|
-
* @see https://shelly-api-docs.shelly.cloud/docs-ble/Devices/ht/#button-press-events
|
|
56
|
-
* @see https://bthome.io/format/
|
|
57
|
-
*/
|
|
58
|
-
static parseShellySBHT003CButton(btHomeData) {
|
|
59
|
-
const buttonEvent = ShellySBHT003C.parseButton(btHomeData);
|
|
60
|
-
if (buttonEvent) {
|
|
61
|
-
if (buttonEvent === BTHomeServiceData.ButtonEventType.PRESS) {
|
|
62
|
-
return ShellySBHT003C.ButtonPressEvent.PRESS;
|
|
63
|
-
/*
|
|
64
|
-
* Prior to firmware version 1.0.20, the hold press event is indicated by 0xFE, which does
|
|
65
|
-
* not conform with the BTHome standard.
|
|
66
|
-
*/
|
|
67
|
-
}
|
|
68
|
-
if (
|
|
69
|
-
buttonEvent === BTHomeServiceData.ButtonEventType.HOLD_PRESS ||
|
|
70
|
-
buttonEvent === 0xfe
|
|
71
|
-
) {
|
|
72
|
-
return ShellySBHT003C.ButtonPressEvent.HOLD_PRESS;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
|
|
17
|
+
static LOCAL_NAME = "TBD"
|
|
18
|
+
|
|
78
19
|
initSchema() {
|
|
79
20
|
super.initSchema()
|
|
80
21
|
this.addDefaultParam("zone")
|
|
@@ -82,24 +23,24 @@ class ShellySBHT003C extends AbstractBTHomeSensor {
|
|
|
82
23
|
this.addDefaultPath(
|
|
83
24
|
"battery",
|
|
84
25
|
"sensors.batteryStrength")
|
|
85
|
-
.read=
|
|
26
|
+
.read=this.parseBatteryLevel.bind(this)
|
|
86
27
|
|
|
87
28
|
this.addDefaultPath(
|
|
88
29
|
"temp",
|
|
89
30
|
"environment.temperature"
|
|
90
31
|
)
|
|
91
|
-
.read=
|
|
32
|
+
.read=this.parseTemperature.bind(this)
|
|
92
33
|
|
|
93
34
|
this.addDefaultPath(
|
|
94
35
|
"humidity",
|
|
95
36
|
"environment.humidity")
|
|
96
|
-
.read=
|
|
37
|
+
.read=this.parseHumidity.bind(this),
|
|
97
38
|
|
|
98
39
|
this.addMetadatum(
|
|
99
40
|
"button",
|
|
100
41
|
"enum",
|
|
101
42
|
"button",
|
|
102
|
-
|
|
43
|
+
this.parseShellyButton.bind(this),
|
|
103
44
|
)
|
|
104
45
|
.default="sensors.{macAndName}.button"
|
|
105
46
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const BTHomeServiceData = require("./BTHome/BTHomeServiceData");
|
|
2
|
+
const AbstractBTHomeSensor = require("./BTHome/AbstractBTHomeSensor");
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Sensor class representing the Shelly BLU Motion.
|
|
6
|
+
*
|
|
7
|
+
* This sensor is publishing data utilising the BTHome format and inherits from {@link AbstractBTHomeSensor}.
|
|
8
|
+
*/
|
|
9
|
+
class ShellySBMO003Z extends AbstractBTHomeSensor {
|
|
10
|
+
static Domain = this.SensorDomains.environmental
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The shortened local name as advertised by the Shelly BLU Motion.
|
|
14
|
+
* @type {string}
|
|
15
|
+
*/
|
|
16
|
+
static SHORTENED_LOCAL_NAME = "SBMO-003Z";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The local name as advertised by the Shelly BLU Motion after pairing .
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
22
|
+
static LOCAL_NAME="Shelly BLU Motion";
|
|
23
|
+
|
|
24
|
+
initSchema() {
|
|
25
|
+
super.initSchema()
|
|
26
|
+
this.addDefaultParam("zone")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
this.addMetadatum(
|
|
30
|
+
"motion",
|
|
31
|
+
"boolean",
|
|
32
|
+
"motion detected",
|
|
33
|
+
this.parseMotion.bind(this)
|
|
34
|
+
)
|
|
35
|
+
.default="environment.{zone}.motion"
|
|
36
|
+
|
|
37
|
+
this.addMetadatum(
|
|
38
|
+
"illuminance",
|
|
39
|
+
"Lux",
|
|
40
|
+
"illuminance in zone",
|
|
41
|
+
this.parseIlluminance.bind(this)
|
|
42
|
+
)
|
|
43
|
+
.default="environment.{zone}.illuminance"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
this.addDefaultPath(
|
|
47
|
+
"battery",
|
|
48
|
+
"sensors.batteryStrength")
|
|
49
|
+
.read=this.parseBatteryLevel.bind(this)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
this.addMetadatum(
|
|
53
|
+
"button",
|
|
54
|
+
"enum",
|
|
55
|
+
"button",
|
|
56
|
+
this.parseShellyButton.bind(this),
|
|
57
|
+
)
|
|
58
|
+
.default="sensors.{macAndName}.button"
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
this.addMetadatum(
|
|
62
|
+
"packetID",
|
|
63
|
+
null,
|
|
64
|
+
"packetID from sensor",
|
|
65
|
+
this.parsePacketID.bind(this)
|
|
66
|
+
)
|
|
67
|
+
.default="sensors.{macAndName}.packetID"
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
module.exports = ShellySBMO003Z;
|