From b6b2e1a5d1cd645207de4da729533ea7d3bd21b3 Mon Sep 17 00:00:00 2001 From: zbeacon Date: Tue, 19 Nov 2019 15:53:36 +0200 Subject: [PATCH] Added building map of device to BLEConnector and processing of the READ characteristics. --- python3-thingsboard-gateway.deb | Bin 31388 -> 0 bytes thingsboard-gateway-2.0.0-1.noarch.rpm | Bin 17169 -> 0 bytes thingsboard-gateway-2.0.1.tar.gz | Bin 27075 -> 0 bytes thingsboard_gateway/config/ble.json | 28 ++ .../connectors/ble/ble_connector.py | 286 ++++++++++-------- thingsboard_gateway/connectors/connector.py | 4 + .../gateway/tb_gateway_service.py | 3 + 7 files changed, 187 insertions(+), 134 deletions(-) delete mode 100644 python3-thingsboard-gateway.deb delete mode 100644 thingsboard-gateway-2.0.0-1.noarch.rpm delete mode 100644 thingsboard-gateway-2.0.1.tar.gz create mode 100644 thingsboard_gateway/config/ble.json diff --git a/python3-thingsboard-gateway.deb b/python3-thingsboard-gateway.deb deleted file mode 100644 index 9b416006b83418f706ad3febf20a8df2837fcb0a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31388 zcmaglQ;;r76eZ}gZJVcT+xpA4ZQHhOpR(;!wr$(i-0q(4hl!Zz6+7}R^ZARlBZ+wp zos2E`VN6VoEDi1Gj4bU8oji$%h?v+om|0o4IJp>!i2j@Z^1n_dMn-m4RwAPR=KqZW z3^P3=jIq6)i<7+#y^Em}y@%KT{XR1*^Z$B~$N=V>!%IU82ng(CrCA)TzZoT<0GJpU z1L%KdiTlB8PyQF0Ru>2pwj0kEIJF;Nn%@(BaEhW>8v!h48B1u_lcD-T%aG+}P6?eS z)hIf)KaEmXW>WXef7aDItG6f-5J++6UO?#>KH7vYM`sg<@yeS5Eza3zi|P>Sg7hO5 zYiQcM_wY62I6O{YDPoYM0h`)=S^%D-nj7~v@X zTU#8eYPkWjd@lG-b!;r)hhA%zN`d)!I%QWne~&}v6Q?t-By)T;{c3WFG5|6BP=>z_ zU4tIXkcR#gRrlKu(AKoqkY80Jv zL;II>C9qz3mKfyKXM#K9CUAE3<#!vRk|4BGUfSM7LQ8St1dwfk;2eE8?kkzaAxE z&XK}Z+jWmT?NN~zEe5JNT6r(y@dm-g@EYP=?G?_hu7v9z9Q=tbs%)jsSN(p^J%hI9 z1a&+DOP)F$k@Lp3?u;qiwaj_k@6-YldXlBmyqxwzbyt3>xXF3H1F;rHrmm0aG7Ggm zlpSxqfIXe{2B}9u(kHMX$5lY;GNM%`6w1_{jTQ4(UPDaxi(_c)S|$CFZ#WRQWH;~j zUSm}~q>2#8UbbrnhB##~G?i<s_75^18q?`*0aDgdSlMS;M$OJnA$od z_CMOdEeO=(vCvl*-k6lxR5xA3zOCcO;*?++Ya+}|Xo;86;KeP(xE!oQkz#0WkD%Lb!>%&cp z5o{KZ44uwllbow-1@115yM}au87#rJ`OXvz4m-`-6lD=OQ4_+Cdg^gqy89kD%3=g8 zH?77S&udIKsDvNpTXGg9F9E`VRwO4Dte;xG#TvwM0jGr_7~>Eh)UseNJe`-b>vEH1 zfTgZj-p$af6OmIgGR2Cx7~?KZ=W$r6>!No-g0@8(%BV6o<UHB7g~fR9+tAlNi1fyuhgd;(pj;$kOr z$NSjFdhA!c0|L^pn^sEzlGArhkCir)fk2+Me`d87>T2#~00|MiLtmv?Bf(z z@+nbhOj+9zTPNf!Ys2yWT?rJrHw7!HrO+901hIUIfsjO5uP<~Flvsq&Jfx%E-sNFS zq~TqUhPf;f_r%3q26lW1;;)33MI?ZYW`fe2GPs|-nFWt`L?ZiAMa*Vm)b*%~Z4Y5e ztZn!ihk08ay_Ejijk7dCQo>efTpNW3R+Kzy#u2dsEc-AH(z9f@3ot>1@dBT33q|!o zq`VU z)pK}rYGLbP_W@qTU@r!A&M=o|M1jZ~`*xd1D^tEu91$%U?gjP%Px~i4Jb0@SM^^b) zKY;#*JIhvkThClgeJh1GtR*Bu@PN{c4GCK=Z)ToI@@G9n(X2b3X=PUcDGUokM3UF#M z;r=&%j^i6>ds#GzT*Gz-cM6g$wWE;cW$Ar>#re;y`pu3)d}&!^`9}j8WM;c6jDO@; zrVPp8Z*;S`>KJqt0RyS)s(IYSh)0E@1s#esiFLI8A;(-PM; zkLWtjaQ5$!=wFso_wUgfOo57sEAE1C@rX}U+#Yn%Ftb2Y(TVCDPr!6<{U+u-SMVP( zt-&$s{6`Z`3}V8&O?;6nx^>+FyiZLHlvts1Xj(%-FGIjF#D?-!deV-_FtLKrqn{>B z9WeYRVL@VO?#R}tgCI^e%33DI9jt6!XD1 zPYqb#9Ge_h;X}c{<0%qrF5=?k(3?DEL;~=!xCkoTR?uaOJRE>%H;vfPK|eT1N~8An zSFb(zQ^kDLSx^TzI$bqJ$bEuX21Ot9Ncp#tN<4oL$!Ql*##%UW_tLmF1US4js`JQ3 z8wrr?5X1Ir(T@h+US3k(!~!KhHZMUX_W(e>9eNo*Bg)9|{>wN` zvKf)%{D$4pWm0`bd<*UkE!{Qh6K!hUVaC?Bc;wjRSY|CX`Kbeu&u@H!QRN;frq5WM zqy$f{JVp4Oz3*loU}?g;W|gI8F6_>c&hBNV&^n-naEO^cUTEQg+t%9+c27$}_aW7z z2<56zGum=?i1q~nfPlNgajGjnZSieICo2QoK>g+a9h=x=<>hs{@zEZl~qzu#JpZM>!Dr7UMOepnTkpNNc zy}CN5ShX&)VBl)Whct-XX>r zX;ypUm!tME()zo*aHO6}^sz|6OUFH+1Y2OMxt5JOAmF+G;VB@P6~~i?f99Vc|3g(^ znp!4?E{6XHYyU~^|K>erP7V(C|0%xzuh+`=fCK6g{x{elZugfD(|;WZ|9`x;_OpM% z2d0^PQLQ692lH!T*yaGePMJST2=C=={982WQTy{O&Cx#7+MMlt#?AR1Ac3k3k;ssQR>2dj>r8^X& zIdA?$vyIwC54$)C!=SP;TC32jpu>6yca`(;~Eprn9A$ZQ^@}X zml-pErB0s-GD>D*L4cuv`)|VD4c10@RPbR*WmGM_j#2VUSUj(il+4jqr^_I_y3?KS zXo2Uu3`F0~DqT|)hY(cM6$?KYf^eaUR^!=Xicy=ZG!23n9c+p)HoHg=hN5;Y3RIm&aYuVgCR+MZ543#b9b~WlpJY*e_CD z8aEb1bhU?o5ZOP&5hdC3D{k`h&Kir&gY6P%vk7YI_6YuUTmJ!_O>ZPFz{2u0%q^(|g&f z^Z&joe_}S<8~g*@>%US)^QUs5UaF;m`?~GHGi}9`b4qGx20@dstYXI}sxJNI{-jeQ z${T+$kynzd-$U?!JM=-{%LjAA3o4hy|5^q)2~EQq%e$`Vm`*UKVF6>#hEJWv!&c)k zYZx@CZ5RlqQcpG)fSu|1gCeo^xgVSAe1NBt<~d($*EscYlSWio zvE!>{u4e5jfTJG)RL()(j2?>cO+3;;;L{Q=sW_n|3X~lW_4~MDGb>q*lHv5v!&WtS zF+R;26hE>?1Wr-|fS?u*@IVS2ry!fGkd5PnevjuN&#KVi)bq)0Cc$G>{oALrlh6L< zhE3E2TND!cMM%LKbrcc&=>Kzs(w7el!REx*ky#!@zLK? zsWGingiUpz0TH#s#w-&`R|&)jR|e+I1E3MEHoFe-`2tmnyox*Mu&yyhH>W2VtQ6T` z>JE5kC2Y;d*6W?n4yXszdIatd@s!rvdyBL@*1K85d8g8}Vq0jVF^FQnSF}mmTD{Cf zMO!a1wcxv57tr;`>IA2kf0AvCbD;pAfoxCub;}*C&x{f@X2cReZ_c5a#Ka7&4kq9_LH=Hl?=z;WDT>5;JnGhI4 zUEH=jlP+9#Y;-#klC)X{xRw~ zt5lLV$t&v-4JMY!hSG;Z#11n{sqGIuai^t=y55db{W|f3Ab&`D_s=-ea)Jl&biaG& zs{`q=(T6K53uQXXqFK)IS+W-sdfewkLYD!!#{Ko2UY3t)z^+u%3>QA;MZuW-4_80% zU%u)IrWO2?{qbws_xV$nKr+REV#nA9|Br1eu~d=qlq)G1%$9u{Z;Q@)oZ)fc_f9KN*MXMz99J-eFP%yOWzBDWtTwKVx zQxa-}nH#5zm&x`>E5)N_{FFbwO!w`R&TJ3UwI-k=jlIopHD<}@!sps^amE?=ioL#X z+O0U~RH8UyajykiT3SUm>&0PfC9C#;@yAn%PwzUOa(!GW95c$_Bjk+})NjS7$2*M1 zLpFZoXSHfE2zL+0Wq}Jk4i&-D-Iv7_P%DbcG;fgLW|U1<-Aznxezu~=9O6ym*bmIO zxf>6BwvFLdOE$lw7IgP2M!AFkC#v?L8gDF|kMixYNSBHpNsFNgBRf*?V5lWBiY?cp`7Z*# zAw?aWXy2&VM05W-c#rsyX9~Pn{Z^vnp`PjpLl7C>A07(~@D9BfC{G1BiJE)a7byA1 z^(sQi8B&Z4QoL0E7;2Kx0)4-Tr5tN$U05&q*OQL&T!mk*!Ai{($ZLeDHI@tghaS31 zOFbi0vU5ZTAv$lrds8^>6JD>B@4SmBdyq7QLs#Z)$#aiD_pRLC)}!gQ15b`dpsT%& zl~P2>z;2w0LbijWz3p;Oi7Ft(Bcd3Rk>C}X+}$;%F!zo!pEw*;+>&>kLW9*SeDj;G zRykTW#URp1|9h}=;^ATh<}-2&8|R|I>wSo{%w!w#!4_hf_HE;&jf9uC7#pH@+4Tjs zgN)HZ87~q($lg^YXeLZJ>_d*k?KdT_oH3Wt@NVB6=)QsS|XCKPW`?KJ0{g)Q{sns2ua9l6;o9*}H zM~a|P*5)|!9PhcFwbU&JwY+UjV9JW+$FNV@h9hoKIylu-3-=i3U$^9wbJ-SOC9RRFD zxEi9vByj_U8(}IR4Fi{56HnwOa5$7fswj_GgWav#tknL#uJO;b%0cc8s3XPahAX0j z8)DQlx)ntCZFMTFidKy>Gj{5?r)4A-Chm?xzlGGe-r3>O0FL@G@nQLMxZVl7DNdap zzXOkNzgV1hbcIjf$3Q(C8|(L=bx?`TGu>|uv^Cfkb!CBINA_kxNR1)>q&>z1u8aerfyO_^larem1|f*!6$wW!bFya{B6 zq!~iJB^TV(ML$#P*p!YySD;W$b0x(pjB;kgeQUyKgFFuw59E=8ZH1qYn>ak2bsDS3 z8bk9E4hwT2iq~#D_}cmWzXY3H>g}QJkPgAH@>* z?gbm8Bkr`Zm|$y>c6E(mA`9nf*uPjTNPAdkN~OE(14fn-noJ7L?(Ul^?$ai^7Ur+k z>?jBZj#f2{OUBIp1Ea2^$RnDZRa>vA8l zH(RZh*ooVje0)i4X`2N5c0F3yb$x~ z;0MBJIV{n1NM?PGLM-L&%qyo0Gh&>bD{! zTT=M2m13vwt{-WRc{?I+xN0D-6QxzD`Y-!V|@CNJ&gBqRW~%QA;M+Urq*nt+n+h5NUcn}lQ$?- zFZNPUzF4+O_hO*ix6mb3G`SXh5>#7>)pcnPrb;$H!qjH0?C0xePY8!B1)q3Rd-u1E z1Az&gK%|+Pvxi%fSxcWBb0Bv5P`#;P%!{?$%Ki_&^$}d+_sC=DL_YpU5T60rR@FzI z`zY?-N$A!B0fiH;?xWpy0F<|HK*A` z%a*L}V-$;HmeUoOrb{TMG`EqIxr~ICJ9j#XDxv%gj=-IQw}fQS_Mh2rHKKs3)G-Q~ zrlj#gU@cV|CXZIUN|Oa(dXvC%dJ+^TAK~oEH@mBJg~49ln-gaep6^Gl zI4g&D-w_aqVIawIevWG6hMhS%;>b*{gyYzDMHDwP?nEmiEBo|qMX`)bNPY@vHJd?S zyhE&{(yj)Wc{W;YXPy}M&WCqBodLN`7!*!V^Q|r^@mz>vGs1~*#j)|)FnyZ`w&hJa zo#{PswSvaIjI{w(>QR-xXL~WfffXs;A?eW)g!^oxC`Y&IJ_#R44a zg!^~vN8Wn#OKmnTo!tP#rBf-@wI3dHCEZ!6YafpcnjnghEg@<*3O#9t72rG*J~t#A zZL-!ml_roddkvm!}-x15WWUiBCLSkp`VkSAe=~%5CMFr{E!0 z^A5w8%LqJIM?)oh8KR#8c28#as7eDxtnt+u532B^HcMFcPrh^pc;h+&)i(H_%X*Dd zlu4I)u1jMOosbuWGrC#BBR)X+6|)t^{02ln-#Hv8qnMxon2}~TN6KaN7B}*N|2>Bm zB%P*(r_7bt-M=@Tv@Qim{tmGa6JeWd#3RAT(Iw;a*;Gd4DOyi8D7C|iS4}zs zcw`d$LPeb_`lYE08|D-ReeSnuA&Ef{dRq$gs~CEFKl1`4)BDY^0YKS8;h@pkP*EB8 z`7G+eOo+tYFW|TI$tvIalca9G_#w#UE=CMctuf{x`UtrF`Nw;r@gHB0Ll-pY9FEQV zy(DC~W`QK^xRiOmRSW+T^p0QMF9|V`-A|pQQm{MJR~jRE;I)o!xL}ChI@7OItmkDj z=eyfmL`14iRE&Q3BrQ}2d&;gpY(b^TAqKIy8stmrjHd7 zAX9O@`jsBVC6VaGN+QLI!Y(9gJw|3)(BGrQs-8;$fCA@!!`$XMSKm;5(ozG}oiz+GLc7fo23YESBWV&M^Vmp1)RV>F2MPE^U8wpBWU2TBCz$_@ z!e0|slKzbtQlC|&7JI9sKy2uibe!vrbDVNePU)2*PnF{!tPuGl|fzmQi7 z@yJI-8Q#gbMKJ)FC>K8lGqGFUq8PoF@5B!=bCBLvU}`a<8)BLqUQ5P7e5lEyBx`;- ziW~3kN{#t!*FcJLI2WljQHU5Jd@&X{D)zokF_{lFLehk5vMLQYb;3dcgBQABag!#m z;n~?uzeP(i{h%-Qlx;3mWOOx<(9MKdI@(nUr-L41gNV4lyPrc0A{Z1wXsCDRvCg7^ z>hy2Xt?T5_WC>YM_IsHn{=)$bwH|#I#F?ZO0+HV6Q!^IL)nW$Vu0Imx$7WqN4nx3s zL9EnZ`+_407alT9FG-hrDX|YVe^9D8?4#!g%;BZPNnqj!Z(aPg2F!*8$E5PI$(atL z_Z+_rC*&-_F67-$r4>pMzNXR+TVF}~?UTK98u$FdHn94~Q(I>P<2P_sjPy(^x0ek4 zHFAk`V!B=QOC>le($G{3*e@C?n ziAx4F3cSsw2Ofb3HD)p9{@dg;r$$O>kG%Oomwtshn`!N#msXwHMCHX#3hRaXZ`WQV z-XUHP18v3nDE;|pVK`1-7S>sw1##6v=uJxg(>(t2AN zitrz6ofN3J?OrBuGv6!Z^i538i?Q15S**U)C*|!F+^NU?9xpe|BMl;NsW__t7Cr&vMGVJ~;$5=cEbGnL2FYt4- zVe}?=A|#?SE-h86y7t8YiupxzbM$w=mZ+f;g>%T^F>P~o-s(ZJ*KL%0KT#G&c8Z4u zo9etCrGrXSuc`f>X<~$LB9WyrKe#9HS~|4(5_W`$&-4kp(|&$?@&M}n!hND3HmsY% zx$H$7r&jeSGLKWHBbI7>ncuglD4W<~9$tJ=3U&N7Z)my`q5>!cCdMhfOFsb9PZN5{ ztNs!pbOfA<#?9(X6@>gxsDTcFkkk)yqKst+6uwis^0UE?6EExM1w##DYrHy=u@DOI zl;H+)(A>Scy^b2jPOb!jxqv)`IusM39nEh-xmJJAE@T9Le@*WmNQS>EaSmzT0|rQ#A7pu z;-A;>6=swGA}t2isd>Usi#iU)GBcj%S0_^EX`uD^w!2rQl=yXfKW zr^=IRjYeTSzFr{!)`Ph!nZj9!8>M=JgYL$;P5xx=^|uBX(nj-p3Yj6#r$nv&FO(ZDxddc|`MO0!hO_hEeN z+~F@SX7EpymQ?L-3y9M9HO0oUy_BEMpHOK3w<*%<8Kyohb$V!f?uez6KBq=BArYs} z>X>BuuHkjvKr1tZLZ=xF%FD;w0LW!vOn#`L3vHr&m&cFM0^gg-7BJn_sLd3H$-wO! zNlb?mM>^#oHtTA%Z9*!nNtrCr_Nnj>yml)Fv^6mX0>q!V7<-g{T01hLE@p5(VFQGkrFyOL83|5ThFPRpp2GgNc|yca76S>J?Vl0nHkVn(S=1=S)}v zAvCqa&q~-sgSd7EJ!Tvx=dtdY2)x{CyyisDax~!;p{)Bas&MFq> zprz8V6+5jH0t6r74=oiYEZjUKC8}MM6m^t^F@~71M#2Q#Lo}GI&Ck;a>YiTYv;n70 zG91f#!QW}Y6_2>sd<2GfY1}y8;0LmDQ5((Rv4;MEtrZnr!_Im^v6E*EvXQlIM#hW| zMt`11dA2+(&CC65bUOok3zwHdL#XvA&{`F~gsntkLa*{qBOOHhs z6P`a^x0<8%u@S3n=q^4i8k$KZ1mI&JyjN74RU?~lIPz^R&bNvFMD`t0iP^-~arBmv zq@sZCoGw$3(5&zvgVn|euciH02Q(V98&WUG?};bd%&Caoyrs96PV!eMqnx%fGpj3` zovkoYIsz=AN{>r6yfj%_&6w47d6YgX2+xw*L9w&&w+!y>R&A1U!`Y#4Cl`P~G!4ql zj{4F&?phGqG&m^1!`TM)x75`4iR?*D3RUq+vY71S=geIS6OCM3sbOCo3xT(VhEfJz zkGbm*Sf*;NX<)ozp_OsMp$z_gQmpO{{URh_E(f)jR5_7t#|q@V53M&DlFwqqVD^0m|Rl z1SDLky_!dGquJE(#rtg@d( z#~BE8@JdNG*4VQ^jBPZmYjBeq)vckRc!0QW%C}F+F;21WJqWb9xUWfFp)_Cc31F#^ zM_0_%p|$2`;WPe87esqWaxSEe7ZI_hhU?yb6X*uhUvs5*9S*!&1+t*am#gT(XdKf0 z!!c3xjL<&CSV;K2D2<{3e~6fle@_z8_Q}TnNxmCLN$k&vy{YkO@z8??j83It7iDbi%#R6 zubk_XeU1pr6i;~QngQ%}L%T#Y^q<|gNRdxk*IAsB7?lY57yoDjvMa_zPpF!?sFz?D zbB0=M0Q9B+jj4@F?|}jWQLuW+gK(8LAWfs45@tzK(~C9F(O$k@FjL4R;&$iBR2k08 zuKq7VuO?Z$!}J&5L_%))8VOxulQl4$b}qfhI{ zQC);3&exd%zxwisXBT=$^CH)|06wV)=xtm7v6kS^;?nfWaJZQoV(*DvTmk{?S z8zZu>P}psF%SMm5bHO0-wcsf1X%QVZqUXGE+?urZf?fENe8#6fC`>)QWEOH^m0qw{ zqedz#j?_f?@g-*4<_fhj13Z^|8UV|)GM}mkN(1gJB9igixePVo@ytqev;sG%?30-) z*Ug7lMF93Nzm$JggI+n_Synv-LIp<~P6d(%U*Jz^Fk-}uyw`J)!Y>^neZ5@|2Uvy7 z8f_I|>J46NCrS3PrEA-OXg zx3(h#lK%x%f}1_(6y$5FUMZ)vU_gt@yE9CH%w3HH5Mh3UzoSM1*WhQ&Xi$v};5h&F zc)$|s3ajs1p_J%i^Qv(vKXDIo$Y{|*I9;|082bm~$Y`K4)8H@sVgEg6>eDG^R`zAl zcaY;=a@$&?fs){tE`lvqiVh{TOHN;70ayNw++o~?Qjri=2fLrA(6TW_2QzeJkG5IEYUq=q4Hmko>u0Pll{N$+qdI zb-0`25A!&rB6w@8kFmxfs23z&(5eyBL#o&rqX)D4iC<(s_CJUl=dZ=bdLVEn6C57V zHwUjpAEiU3yC~Sq$O&jdgCdc=d`Itn5E`2>J&y_s*3AT|HC~%5Zd_qu0Ah@uc2F^E z?cMEf1U{is?$>kgp|mTm|Am_3k6Uy|g7I{-m!pFf(vd66-xXn^nz4OG_>%5-6djm@ z*ga%@H??AWwem(fH1Jr&$rkP4=dMi^y)&Bi+vh37i&p*S+xsU3C>j@BF#iPiGjwB9lfu}rhxrah+%Vikw!@^@UTehcynrpjy~P<6`Wl#Z_1nvhFQ;N=APa&XZRbFQaJ^GXd3KT2hT2g>!seQ~fR?afL!PW! zw6`wtcEu_1TVkLc%kRRGAWYBtK9HQ))v;v#ypB;8x@fGLaG6$bhh~%Bw6_diPj@A< z7RH0GoM+4-_zdCiWl^M0i0EG_W>d)a zmq#zk=`W(EuQH;$3I;7@F%6pA#|!pa8D93-{$p;#q&Yen@>2MFu=@=#`b=&fi=u0! zeh4q$9900h#U!iT-0Mkg4q(yqy+H08_b2j^pyotF0#wmtLA3}tN174FK;VJ`_>(SV2Ip?EPak_B@SVCV`)QCq0 zD_wuT3P^37^5;WcdEmDIO6r4-ki0B1KMz|IId&H&#*1KGDhniRZM$~LjYP+@6!K0x zJ!zJaMlB>@;-4qT7(WZ;?l3BQp25oZh%+&% zn_i_e7q%C3SJ+smh&^s~SzD~gv`h2QfBS;oA;_tXUo;TuQY3csR zhU5r-s{db!Cq3u`okCRJec4hH7``@lGE(%a{4Q2b=S6bM>Hd=wVV;WIRd%S2C#%U0zC;)%R*j%Ri#lhi8plZF{aT2uJW|vrp!d;lX%8dKtKn&V~u~L#PG6r>`C!!rND=Z*$ z`V0xH)#t8-$fqq9WPuJ&laYE*e-scgj&RxDL(HE?g*!vz&NWCE1mwI)`fMUAH&sfN zVB_?jh+#{ylO19QNdAudgsbdSq8T8u9(E9{w)%c;n``IR?zD(NW;92aeR770>|Ct> zldJ5d(Q>-qf!oi>QJ)j!-9lOq?a*s$fP`r)GF$5hf)-U5GJ!UCI|pX5mR}N|BJT^9XX$$*RkbX}UyyjOD)(VrI;B&J4j!j4W5MKP zMJusH^`uWcRxjoawvEDocAY5ndSs~YH(h(>G%{`zxIm7q5HiIhl>Yq!cSv4bh~shl z01c)#WTF5PDoL&z)MR7E;^#mKpGP{FB3o+tSir%U@>E%)X9;dZfH4=O$!5D_lP(wq za>4`t`)yS$U*tdTM*FBb5&es-3({9Q;5*^MrQ8l>Ew*_kqTmV~Xt>LYp6!#pleyST z_%%4;%S-krdB&xW34AN^EC4^!ed`_?C=z^iKDM$dlO<#goE->0z~H-7N{CDaT#c@_ zUcNBd(V7dRJrlCA6q?y6O}ZPpEDgnipXQF@80VCV8mwba`g+ZW>J1cHhbyL5|7e(-*7Q`0|!FYp2aA=>q8H(!^m2FlZz|VG7R>bK2 zV~>U6N81;|YLH*?^AGoc;4_dZGJbR_kmhkHVK2C$qw+_a)pnK-Tw;a5tu%eN)tvy0 z94_{oES`;FEC$df5z;Qu@)zltj@^il{?PjRdThUsZ6X1G;AQ-I_y)U@%{b~W_WEcG zCPS&%JA%nw$g7%hWRAT+vEI8CJF`s-kC?mj0hpsokgLD#R||Dp>sIR_I<4psLi#U( z?`I3xN4ts9s8!~h^|t=iS*>$#SX&|-ZUvPXlZrFQvO-GHbYKAzawrRhD({D#wOXYL zlT%K7?!-4*UOjV>=%;r>b9S@O5%kt6N z{5SwyM>$g;;g_6VP1K<@d+LsJ`;`dG+f$cfIcd6%Bue0%K;Df4b^8kI+X;JDD z_j9pkNMUad5i@v2)A%%&w%^cCV>iEhX*yQ8;qrOG=JnpMoo*|lGk0y>)S|VP-km_R zDv5!^Xc+)$Wte=MtD2W4G@Asx^7nmYN|^F2-pw=k$ga%t8QT~xxw7Sgc-k;Q6jrnGX8#FFldam4xpX=tbH{e8syR-TG}w@DE z<7VcPTqvD-wxqv=)wKb>@TaT0Kd;#^IoQk=BO6-fv}zPCT|UVTO{7qdX?0+=qj z#-~uMM2xQyRWjp-x`7PM4xTL_fdyX`vB2n`0$h7^hlDir0+LIH*|OX?th0yA0V|BN zkeE;n5U0tL=)x~|0O6_NXx$SEk)`W3-$D>9Iu_#WI>>cGvP>TZVHuslk?FC{Uscgczo$kw%W4i`A+AAt5w*&3 zIxry}Q&E17@YP!9`!Mz6Fv}OM^*Y!he!T>77M|p}nhyRd$+ESUDxupqL6Od(bcq3N z6GYIX(eJCd8Dt&ie;UDmTpWJ0w)>E5SVR_}#w1fAlA`2LnzYKUUEmG5S#JWj7cw6* ztEh2n>}>IJ6zDYEaK}n5nFVFDkKeY9X4)z*z2-8da(-t2+kPY+lW;fNZo83t)K--H=1e-A_;`>59tCR(gp@U@e61t% zNhISjx3U2Nb^tva9%A!w7LNP|e==4iR&R(>r!L=K9ra;8i-vR>Pf;8vs-V);(aKtr z76nhOoE8A7QU{>U^r1TYXXL~?AOdslJ#%DiWmxZ zV~Bd4YnR{9WgA`}g$ir=0CB~s8)2|EEgR0fE}lPZV21I_-TmpTxkllS$te&)19pa@ z`ILL-gOpQ(&|^AfOyl}*bXp?EdtEUT);yupX?B@vcq)aG_zEcA7dyuK9+a*1yPnO? zc-Q3fHwk)WmIEXGprCoy%3r;`>R@z^3e|Jrr}J~q7HS6dV$}nqI}jJBU3?29`af?n$Fa&4|{J^JF=6#yH>NuFkK`FJSTT->?(=X`J@uo1L!+&0JEHBVA1 z8U>qDJl&>DdSFCF36}lVITQV=zY+Om*NCpU0nQUxgxZ?~eh{aI+w`}re`XlK6w*k; zXYEOrSnw>A6^apTkB@*HqP$$?aQhXQ_=b*g# zJybx!4|xb6IH(`IhrqIe_Ks{(a}Zyqg6m*1y?i12t2L#aTD1$?=%(DcMKL~&wJ9bl z+W(1Zj-K)E&nDZZSt=ayqz%ZWz`ENv`wn*Sl4KLnNqcFE+j|9H**jK+BS-i6Ai^k? z`wBa7pMPIBhhALJRX(hk-x)Q$HzZq-`B7yu$S*YsVo8CsbwL{(8zf3R}{yfLtKq+Yo|J=qM z+4f90N`(@D`h>~Dd13y=-P@x7CX6(FKkberjmXN~zEzseM6m8~qTl+#l7qni_v(5} z%}~fJsktX{fOKu9FtO-%!=2*n|Ksk^*?tVFcYGc$%->JtaM z>EWki3~Yx9Dg6$?<5)=nd0^xSNHS(XFLR1RhMM*4437fU#b=m}JkpDSQmgl$MhK@# zgxNpA)L)xYRcuSbHcWiNS&nN3J-#aZiTHEp%*)&t^sFQf@<$t5o1Gy0Z$*wVI?CX9 z7_LyPx{#!kR%fFt`MCB%gn;PcZ^m=Mq45}qX&EW5`V21C6k1zxx^HW5BoTW6*mP-{ zmm;0%!R~BV9lLw~^Xgn7c~Yr9NzCa%!%F6}weI5#6Ic8sQKFMd8?hRTT0^%k+Ww=i z#9!APW%%$4K9n#z0i@5jKEW6T*qFZU@@{e%1E);-EwLs%NL#`J%1u40sm^re3@+*6WgCj zpMrx>T?q)P)UKTzYECse&8s!!%@Mv{n@6-rlN+3p_41f1GOHW(+MEGxe!l~A5yW(- zYfe?R<8{bIqk6oIFnhwUEi`K61{Z9>*nA7<(FOw=u+=VC1)XVR{&dmqY<=QNQ##t? zOBC#Wrkh5~JON>nX6Oi&2VyD~{DTZ2jI;A2CNf}FA>Byq!N1sG|E-T{G5?m^T?Ct+ zvzEMBrvvw?{OUv`NeV_H;?$wmIQh&p9eN28J2Ykl$FK(}*m0gC|CqD86YAG|xOVNA z@1xqEMk1e5m1a2pZkc>TCkj)N)>#abev6jP8|ntG#iN{U4z5J^YH33l>70;?RR%G2 z$~6`PD$&(`$MRH`hx8{ex*QRznQ)D2>eFo}%WF*7pPbN-R7{ zFO~Hhd=Ahlz_6yhNcL49Y=U z&k69xRAFBquFp!IS$YpbstCG;FG#0ZnkP+1SlFVv(<&EYB1B+|7^Ws=d|sQ?UQZcA z(Iw4)W9UVVURz>r_$PTi2iyq`#{=kAj1D`$!G68fx5G2 zQ?$;GinP(yU$6;LWO1h=CRLTEGlL4IG&3Cr=6?>rQDa1)`63^a2;#*SaC5%J9(mmH zCeAr>T~j^4n5LCfchp2u1V1`vLGY5~j`};j0Rl@<_b2{0|Bz0uMGVyJmE_W4JKctn zJW>MX8WL@pJP?#SdvvMUDij6zD`qE>0wJJ?FjX;_bkM+1{ZeKc_27h<1O{vFNoIJM z{m80cg5`Z?;-qwk=&?W06(^O4!02xf!i^y&=UBy+566=M`;jh2I}wBjsyJ!)MJ7ti z{GC7@$WVzOYb6B|4q_|387k=NzjRZvHFvMWXD{-cC-MTbOiXm;-c4^%Tcw;c;Mktb zCFJc9D8rPUFEcPR3bs)6U9B*O4V>&i2zUm-f~`Bh<3bZ68dWIW$n10Bms>)tyi^P8Bp+4Ql;>Q(P) zY<09@1$Y8HAn+UD7cZcqvbE*oy)qt6r~$QNt_J$8R;^mHy;F?Zg*NK+C2hC) zUGWjsW>csf$|{myISi@@0uOS*l9x4TrK!5Qzx0!efXd@ZlECB9WSx_>$(t=I0d+OD zojDS4vL3>tz2uD#fU5Qq_sM7dOe(D`Thv99Z7PTl!_-?vu zFd29ph@GFrb0tZ1vxMM1W%;hYn>4kyyfx|+xD957YmAL8Gpy~2s=5)j zL4h`RrOQAqC(-DT$E2s=j0+Hp}c-jLw(cc}dE&m~2X zlk0Q7el4FhStU`jZ(h^BKCv2*M>1G53(X9gN{eARnV+X9#@JakVp?~#PV?MuTqctK z^EBJ=P(1!^)+3aMZPc@=hUUOY-|F&I&I_N^3tcTrIl4X3v2k0a@X#8VAd4Tul{=yy z@m3YRi;36{*=&!rH!{8GiL%S!Bs^-wbuifE>y$Ifw8Y$pC~@0P(4jb3bHwG8TR)D9 z@9$t8vqx$*A$*#zexuuDJoRy#Gj_2kl)yNjzbs!Ty44`PSY6m7;PAVZw$+X@v{#Zw zBONWW76Zt3z~W9zr$(ioTN)k25q3q*RYpU*3eL;)82WOl8^u-kk15kFQMvYac%1u} z39dYnS~6ej;DguBXaasVo#!O{+XRDMckP5ImZ(4jna9j=P@uK#QzytmE<(IJXfL@7 zW~bBlb@(K_!iUAtSgXg2l;y@XH?j;uR`>$@O7Lh1)w=R8`fjN;cf)*5;5k^flM3 zxg}vGZG<;ptt^~dwc(Y+Eet$j=SO<9>ZD`PIWSwVRYBxy4i46~r^$^n$ON+jSgy_Y zV5SzwnETE%t@r$en*j1%qV~#_oVRt<_+-UN^T!l}8SP@!F6tmko;(C?G7P96NlIe-w?x1evj%sTJGi?P06?Z+LNJw%~npMy_4KuXzv>dLqwWhzJNdz zOww13dJkeeXM`Ds!fV9{HGm<)xgyw)%bw-)v>~-TX2L-;WeGgmH$r_!zw<*cNbK_i zabxPYk)jKbNnJ@f-8Fnn$X7Axk-vvc@+3;R(PW?W@)L}-^m10nfAu|rSn)VaPPN!~ zR#gv@=P!DD08ykZ)wip>k9$9C#JPwwo|y6b^?m10NiTB(nGA6P@uEM)e1* z{~YG3DNdJ8MFtT^9PieIkM}a#6VhP&RF1 z(_+Uo4~H+-k1q~}WmN^aWJgYl5KL71>GDh_^#9)Q;p+V59=hRSLXKdT65=3K2^G%K zksC>5O;MW987C%AJbG!y4kQ&(sSHT@FpPgNZ+2{7Wb9k?Y2v)TFzW_x!UVHTL(X4m zN{Ms7ytUwkrdshcD8~N|(Nr0^Ki)?s;=E^uf0t%ZdSsai0LSPa-r zyuLi{S>liEB1{~iNGqK()hX4a%=`CQbEpnKLnw&ESn(97Zot3 zs+|P;TT87jR`}UqU@QyAg>{)0JZ^}Z5Ewr@hKymU{=A>0nIw6j0f+C2L&KL@Rs7zI zWMjYmu&~F)4B2c0e3DeZjf;?U;7*{kD5V?XJTV@}-2r|R>MegqAKJGSaR}B4raENN zr?E?%Q?m`3`3N(_5k34)@q6N>Cl8(Mg(hZ*Vkj6S(&hPLEy{2K|9+wO9QC-Gp$Z^9 z@0hHcmpX|1tL5|tQY{Dvc@BeYEhHEidgP5?g0lz4`46+pwo`V4Oxn)K!c2G>1^xut z)_8JHgv^;XuqC;ZA&v-W&&{|m^OfusEvGK-mhC2*7cuP<`ku8W91^PngOboMjMfwe zu7IsKhXRcD$C~m2%v{DAUvtgTL`owF`I+lmmr$KjN%JCvcLXq-3502t!6FP-T>N?# zd9)1-^OZd#gK{0QR}gOew;C*!07wF>nFo@tupH72;3XQ#_+HB%gi`<#ScmXItFSiA zi7fgg0OG{*g7U(5xt@&M^b9^Y=F{OyKBBr=5@V!Lst{Gn6d8mP&&bL_|4wD~uE;(x zPNXqEwR$b?s?;>Pho3~@>pN+^8p7xC~inzA$r`a2Qz1u{OO(eSlm zm(7Fye9hZJ&9%CYm3Dwax`YgTs8**H)oAQ0t}s{D`cAWAA^>%Fs$@h)FhAfk=hOE> z1lN8saE&|0H%gQl%UQ;5wN=<9{h($P=YFHa8jD0FmAJ&U-T)xNpNo~n!97SiLDsPl z73*4nrQ$p(j4sQxHwChE9?5d{l{mfVy^R;M@|^6u0up?d7oat8E1-Uu#b(zKxku*r zLO`;rkrnIrQg~=yQfCmuH8xwE}u)Bb#g1W`%-j5eKD&ypHP}v~dPDr6Z z>QKLG6Zz{CctwlcmW|!%8O7Rp<=37_aLPaU}Aq_EA37kvYDlQQWZQ0UTFZ zghVeaO8shg=j2R1ARJ_K+6fK4mhMfz=G+z3fCb-l$m$F4JDRCpt4IN&JU;@pl;yJ9 zhfc}!Z$Ni)U!Ilnzd)cyp)y?Q_pJk-Pq`gn*6oGGs%eoGjUIAU2nQ`zVy{ z!woylU1G~(aSg>QMGV&Otgtv@L|k6B(!{BQnY-Q zORMYY4?U68@^A~kNK6QO0?mkrUtk>x%H$|;x^4bGRSi#!1s9Ygvor(8K?uY4`ViQo z0)*Vs+vagKNSxU`3vW1@E&zQJ0X_Fam?As50KU&;$SH2eUlzN2l>OlPZxp2K#fi&h zK_EqD;ACf7XAM-jPawHH#$00yazZsAcMM{6{_E^7NU^<44ZpSan~^@36rFAXsf&F! zi6TBGp=pO6Mr1}fs3MAv)L6^sORG-r9a$5Vym;P$=0lQk-7ThOC~%0HwA$UME&U~ zhg?>%p}}#!XOt>S7W@Aa0c8P^?P+GIQd0~rvJ;b((%j$o*tNm3+j~Rki>Ln-CL#iW&aHZPJwLk`{d4%y6c0bi_gU~CTm6%0_A7LA2 z@Ow!eZn9pTQn=ZFrvJ7aE!(yemd;N^WivpdO zg%U15F%}nQ#z7a0mvyBo#5bBcBeH&nydupuZC-Fv=VHVUqLUY4A&x%!f+4<4UXbf# zTb=X)5vyXDDLHkq_~fpk8y6~80ch2D*-;SrP@;vkV5OL}y~k)liQMi5^-wNI8LD*z zUXs!U<-Dv&-{V1XOhK=BUu$3yGm1vrW>=58r+;OD9P~3ah^Q$WZkG{55M4{1Y5SjQ z!}Fw&9*-KTw(s&}B;yDwq&eMXOVziZ#l#Ha1Uky4#1^cUEe?<1CgQIYpP`bb!CO~85&NWuKR5zA9}kj5LJwF0*#!O=OY+-4-jOr!E_vpjp40L2c{ zImQwtIb9uV#r;XH9dSn-VMP{WbsbW`@~Wcbe3yl^UP@j7j<`%#j{KjYQSogWb9hRn z^}7J~CQGD6R2n5YA`_MIgiQ9-Zx7v@ig8I75VSSFExspwr?Xnleod73K~SL6Ac8mQ zdZdne(rT&p%DsW1@3W~6QHJ^@-zmdWD`B8X;F8DFVZ=bXAvSxNSGJ!p7#e6=CM@Ld z=a3*h(h$tCmp+pc^qW9J`w{%;lapev^2^iQu4)6g!*8*aFvBw1j1ghd0cw>Bw!p@t zk*}3C0GE-sT;1fL|KQ{6jlAyX6;Z{z`w|MMKdFkJJP#N+C;-G($^3484r1H<9>4$tU{Y;LsXg7j1(q|i+6P+6m{UQl zcYiau?}(@RDeJR4SeM0BmT2VO;z+$8I>0$2NOal4OulkmVjTClM=$ESMgBN%W+H4x zP%A)yuC5j3393sAL)ip8dm`Rf8As*F3I5fDQ0X^AduzRtoc8qj zvebQ`3sACI_hCVAwpmQJigNh`kZUg@Y)pz_7gWcp{b?Z+P}*a{Ll`3Q@hD`kwU{~wL3rxgki_V z;C#)ui@#-G876hu_s6ow(@v%fDl0iKU|+8gF9rvOy*LY(?_HD2GA>@}K*^-iZde=9 z7$j?tO{$)lhe>+q2r7Fr!1;j&5LVru(6Ry}|Hn*<#02y*OGmFTJ`>Ttot+JD?#I1K z>-qGR6_zIxSDQzAHv+{+k_zB1@d*F03mjKh1yzokPCU2}6Xpm_l^Q$YZk_rDLZ zpgv=c;aJlkIzG|cH1Vd8|0&>Nc4cc4ozK}`bF|kY8WScgJ}=;q5f~dLn%vn6A*xw* zcW7J#G$f0<$8}gOX=GEFqfwB9`hGnC5Vw?3eb^U~m&^_O#4(i(lltvzyP8!xF$gQ} z3yT~CWCh`TkZh9Mf=hqcX`-wUUA5FDMfSn`{8AUH^x%PUU;Vph zO>gqfO86zIj2mj^S=fw9Uq;Q+TTD`d+N0Fpmge9!dSfZgP^yvi1?Dd-Sr<0|d#?yQFGMi|;OZPP;Yj`I%?;G{EnITyUF{#?&++2`__^z}CJGwysNm7n0` zF&dd}g|?q24$`WEU|9Jc1T1B6GPYoh^2)kRAK%Zh{Xe_KGK&%TnI|CG4-($`?wZ3v zc98X|1VeMvDDK9(V8|@6v)4ZeTi2@pPm07T7mKe|UF2&_97C&12|GLXtU*hBFGVu4 zu8aUSMx30GykxIx4Gd|I@d>(%2*wXk6)&JtxHU+GuUFV~Rg2#W@2S_)>(DTRBoc&j z6@}^gn{=@ffow=;vxB=yhy~ergssD!^=aFcA7a`zTRoD)(}a9HQH6E`k#x2|v$7(^ zL3%J4$O~4gjS0)tVHRb@Ya1sg9Z_L11WF$3E28PenF3T_nIwTXB0NGmsypT&>9&%U zYdUKM8>J5#EA4=I+?IfVNvW3sbP=A}=5`O?-WZvYr9?)7F$>Umrv$cS>awY z@0~yDmUCLCY<$P+sL%?K8ZT&Z2ULP+)SR!skt~Q2nkhL5g#a$?+9Pzk$ufJ)Dzrdq zt~IyY|72ZA^8Lkt6*5``>uz@0s6s})r;{z`E5x=+fHB6N~4u}VXv2$i2C*jKhUGL~9>Ukf3?SKsTRG%cE3IhoIqE-W@gOrrE*R7lCP zD);V$#Ojar_Cu0#t)~N$y3<-s_KAL~`KWI(1AP5Kaj2>hN!l&e6Xut-YKghC4r6L5 zAR**>QXi1u3sbyPa`U-gQEQ?l-RB1B+i$qg2Sn=4ivCZ(-q2Fjn<&Q@7@YM)ofGh2TEZiD1R$TC;h85PZ1$>X4pWM74N4;ev&n)s>KS>& zm@h2I_a80$J-<1N5&+*F%)J=Grl1wSl5L5mjX6(zKP*c|ZYJ6a;UD{4K^AL_Fmoiuz*j!!b`>qC&G zD>$1c_4Afq-hKm+l<#a~vpBxrh5vJ23j;xhms(@B>v$k~q<1dO0pp7-VJ~Cd5VYdi z^{PSZnmgZfF|%30r7AFm(p&{1y^S#dZ0~rj<4-98qs(%HiXnoN+LeLTuB81%h_C2V zL2}SD%W8{P`o;b*oUSkyl`d%GHWXX_n?&2 z)5Crxn>ughUcogBKJF~`U2XfDzaS|L3>0&)Z*Tm+=(+@Zy+%SOO)Z)iSdsLs8TUa) zS#fJX^u@8*&VoCdLlx#^d=zJgrA8MQ_r@z69f)3uL(n#eNR$P9r~fYq9>V$xgSiY%3~uQql0gHot%#ss8ty zP-kk7`4HvCiHnChId!5OnSZ{s!Y;)9E@-aN5fx(T08T%Ju)5Npd;yp${PsWvwT|T! z$+9HgqfmO%_V9k%5P4N>;vT+WjUR3eD)wOY=paU+nY0DQ1;#nCAU!Wxnbzer(w+uG z9@@RaEM^!Es$c!m+{VYK9-5`HEutvOQ;L_a5*WX~HKdlc6HGa2Oy2a~+fj;QQh3>E zHh(h|(t0D2!^VSQV@evxcOyZ48tm;D`D_EWxK&-jdh}-WpO3Tz-74&WBS=wlz7%w@ zl0{7xA-8_hr=cP*n-YOI3mKko8V;}!3yRG9inGu;2LB7k^5Q^)TETiQaf`e_!L9$i z)iyUGJ>I4CGi*qA(e3bHfUXVilj04g;J|_t?lk?X$Kw+lTO|CZyv^^n2@nrs-uOh) z$&AVsw^06WZ?iAWHrYssh@Va!J?odztQOL?>CT^-4%=Eii5V32Dcx8>A*e}_wuFU9 z8ieTD8P76oHVi5PtYe}GU7iH0w}X2Im;Q|vONO#W-d4`A**yRnFoasD6=n8vKx4Eq zntg;8(vIzMI!6jZRH4uI&AyR~PD)G0Kal^Uj_$DvjR7hJ*|&Umq63LV)+CZ+Y1oB>0+Vr0fmXuuw%vQSEnNu^K} z(*D^@heIH2qw3jV10rfSq$tb~A6i>| zWEsO^UOx@53~UEE@fE=93+m_D!ovc!H6mNTA(T~DoWx+nS=e<0lR#~C(Tnjrb=d^H z;#c_C=>u%p%^KT&Nw4Uo7c=nB^>OUF7#Bij`BG3_3mh=HcN`4#l%NS3a(lwL9PQ50 z^%?6m=2XVmy#5UdSdSg&ic`oD#pgls#&4HDvmUKXLvF=YV{yfrSS%Xd>u@IDimkc` zebh-~d|$ql5A8=Ykf_5(IC>dge-J+vGxZJ(b*$#7=RLO0ffYQoN}UF4sSXAL%aVeemf&@oUY#MdqLs)m|^jg7f&Sw8;-mnEjl6xM9NecajxL2#pOp9M7(QxdwB z5ykNh8y@u;Qe0<`PtP!(5bxeNd2XMqL!9eF^?eg-#L3%Nsgerl(*EB41HM=omaBe) z8O&1lq@j21Fd!`O^z=_+;StwK!BPH>L&FK5YAv?5j@nN1ZO%_Uy58fa(Srfe2;6Vn zf{}_gP7CYl>N&0O#^%%5E=jnWC9t1{l?6`1I&GXOp3L7$9Sm#84F;1XiRvp^gdbcmSk8y#Om}dGu1GLmwxP*MY!p+wb#wk1;Wt0? zJ8YKZG-)pNvd~)==C+5^d+$@W5<}OWNkrW0bjbQ6^i!>8rm0|Vt`;_`Z3HPv||I`zo${? z^0%#p1l4%>Rne#EUjrDVPK90OUjHUCTd(Bv-^VpNED6T51AROx?S>s;p$P&CV8q9_ zF2G~Ah?^zAF46c6NRy%(=gP74xPD9bB(_6eRBC$ArJ~Jk--f5}<{vL#mdHF>dlMSM zRqpT*s<(nS&s1pblo%3Sc1(ykBg|2Piy_vjsB6~vr>`W8bv=cwIbu`e*G>U0DY@0@ zQ1NOU!YYjwnOI^i+BFIS=SQxC1x(lLH=;rt=tW1U{qu~g-U>9UD=@J~;DZg6C6Yv5 z;Cc-q7d+bv%>sgko_rH5pppk^;Wr(>u9;E>dcYn9ZN?EI17A6IZ^P(Hpll#1J@#29 zhq4M0mp*Q9aq3@H=dQ}1c_H~!@u@jR6dr`f0G>n-je}rNH~HH$$v52!a{c~vC>i&I zpC(u+`#cQJJ7{eG`?lb~a0}^rlGx3}6o4e<(NSriNkAHu0{j2MpCWV8b;6)Z3A~wn z?2bA}sY>cG)TNiN{eVHyOd%;=pxZnzEFzg}^xbqeQ_$EVDxKFkwQ;tfo;@c&A3pF!0`n^E z8L}tpt0W5yCl|_Dbz_hjKX;zAATo-P`^-D?OT~wj!?9s{JEzGYX<%8l) zX(g|3%NB|AS32Q&eNkRzggKV}_-1rlT#CE*!v-TBzjg5-6YXv4pu8{%y|_qP;-6CF@%GSf<<4g z57a_>oL=&ufKx-rpNBUQ>*!}_xbaUPh;*}Xf?a=$Tmtxslu+nUcYi%&va%QELMO2J zg6nt&PBGO(x#oeQ&Iez?+?B)Yu*_%{I^IHF8>Yoi?4UQ;rn-P7bgb0}>65zc2C|r#+r0&DfxoZ=GxwZ9tYgn0iJe?D{YFUfz9d)(3Rf%zPUc^ zVq6G7?ru|L?6p?|E-16`TEc0H}(V~f25 zHd*BnsqZ!~wWnCbu%f>u$BiN7C9(~%Z8>y23boBNT7{J>T;1LOe}b>d=&PgT}GA3Yv?4d+3lMdaOr?* zy-vm*8crSDg6UW%)Gh@~MS^DQm^ij7mS$sP5b9rxsv~+pO^eWX#{eFc0KVQHcQh0j z{Y61eD5=}1;aU5$?m$td;4^{(S^CAc=_`sig5by-|CrX{p`NfAN_2}p97}rEX&!wZ zQv&nVHej(mvG2|>&QIQ_Z8*O5{lXOo2VWS4e?+86<29ij1QWoILpIVG_gLxq5^wdp zgJS|bI^qJ@iesGJNc+U$stFeMhs^9Ck#%RTKAnj%B~Xw5v3n&8%A%Tpvo4A&Tp7wn zCkHicoWN7ucv3%WKVy#nb|F4^JDW+T*Ft-;aJT78lIA423C+ldoP`WE3z&cd%RH4G05rlpyihqqGZn>M z5Evn+jgnO_=HlV2BsYEp<@nrr<>k;(05gg*3##4c%vmVL84I5E{F_e?a{?IrSdQ#q zp}S^9X7T^rr{?+)Y~ah0X#jkl0c7lcT{Scqe01YiaFcBUh={xz^s<(tNgDE}4%534 zfuFt>gGlO91Va}v^==Kr6mCHYARU9tqykAOadz_PJ!+0N=)h+3`BaD>ohV@*!7*^QBC04&Yu}1_0!tx-iZWo zs_5j{fjj;_e$aR@Yxm5h)|9T`AtGPS4Nw#Q8cCD_(gdtTp8=+vL?K#*CG!B;E)lKLb&qXv#_av-?pu`7vc(d$pSc#aVbiDl{T(`Kv}NyxY`vr>Nw zl|vAis*rX5b-NIw70T8HB?>h!u(HTa;yZ97Ivg&qH?MX$SddTKF&=os6*l2a)?Jo` z#WHSdYBS(wo@kNgT}YzZZCy0%v?hz7GfP9x$}jeJ-$pJ(IkHD+OA86?mcW?D#}`=uf8&H1Ti*89avHdp7>0<8T3^mDg6^fu zkA!)bCt(HY$bt~TX8+8X2EG}SIeGF8W1s04c&6qeDriVD+6qa(RMl6dEW^$>m?83h zWU9*gDs$H07s+?wRSV`Lu%!td;~F!VcW%>7odJ)9ME>U zw3yNDG+)62i9b@jV|TZ@NT)n%!b+9WMz~z>q(vS z`acGPP9M0#M8QQ}*sp6hp$n@0&E<6KTxn!G(db%jP?b!sl+bMa5eDsXnhU!+vsul~ zkvIbH#!;>$G0L~b6ZI1D#0#*^Qy}hB8DE%LsrH~nfZwXg-n%O)y_jvqD2pLQok z34-XL-YH76U;oG6c&^gzQq^Z7@>%CF^w(omg#l%yYSSw;1G(D-8l?e^bu?z>Ju^_l zk11gdVA|{SoSTr&3F4%kb!ogVU!@s+ty(Xon&^TP3gk{_9W9XhhIa46(?jP<2#SAK zRZBFQ)x@9z*H(goL!O{Rm>)=^ObEID%d?OX0NejPIcWRx96km=x7j49yZ@Pl_Nl6LZ={8!Fj; zBdp*q{+c5c7D32SRhkAasNN_(^56N6hvg$&159eCOTwWpsm(nF_7ol{OqS#}bv>^Gs?`x$?ej34g(~eT) z;qd}YoYBG)mM$bm%$x6soYz8V>)908#Q2^Pddycd`(5ob6)WqE z5=G;e(9bT9`B2#e?L8=MM^3Bw@vz$H;vbuCtv}R($&})~S*p0ih>-yA;%GLGnReW{ zhg`e`svEzkC$KCfLWW8zVGI#apE|8zqs~`~F}xv3#F~ow3jgJL-(=+$y?~zqTpnj9 ziMQq>RfKMl$w$^^s&z>jbB-#<0daZmfo}p~n=l>pix$%O$Gp@Qrwhe8IX@@J>R!5g zZ+Nvi`!hs}P`{KpK{Lgk+=b+4_%|0KwCUu&+^<;fJRWmVrOrWc{Q1b2@wa&_Gr-&k zD8@wxfLNK~Ohb9vg0#UsBRTP67#mlem!Zy$K6N5aV75>@^SOeyALx8|GPZH(B26#( zMcxd?#yGC$gmK4`SXQT5d&mcXSbPEQ`TrYmUm6cy@Yu`ViVGZyVJfoV(eBTRSE`)1 zA)zij)^dzjea1p8-EPb`Ot_vzzk8P(J}mBML+g-Vhge5f#F&xtmce&c9G0gq$mPGmkDlGH6us+3Ls%vAjo#ehLO;Y(vh?N0zpQg;0;KZ}rTV0+W1< z+P~?G4VvWe=o@g9#_?Q&njxO$Y#E$LT!CILD#R9}bV!$$qlDJTQiVK9&)1BF=~yGr zh#HG~LwABeBN|ltkyXV-dP7>T)@j3V)hYkkK!pZJrK4MVw2GgQ$8ZsJV2Uz7f z#ct)ZxWQJEp%9g9O(l&4sx+&yl723ooP7W2M-rGPBcp`$Ewf1S=x2ytbO)o`^b~o# zRs<}l{A!xAkkw)^J_uKn9UUpWANnT=fP;-;mtiFLVQ=bwd+RskTaP&+ki}>YYTuE! zymR$07HdqZNEmfxsE0BJF22W(W#CnDnouy>Qj*)YLimPPt>PP>o6BkCVlz9(XUYh8 z83Q9(C}W)63cX`P{3{{Rt5K?xVBmia2*oYxV>gq^NmKesOGhJt;(ngq?vk=ABEt^e zB|P%E4L2F4-$9unMr8UYRT$K!)0HA78?*Cfo5q53N`wvZB<8Tr|VKCWQ*A4#I(-5vX5K=Wo3sLBi+5latQ*XV7ag zh1?%D?AXS){9 z{ZGV&o~;D&uBN-~GNEcsgvw#ymX5%(j#z{*^$iau%im4J->!`5A(uylZ(^1EYbe>{ z5x|cN9w>QzRw5dN1%jQat7Mwy+NcHxk)zggUPmD!D!u=U<~#Tuq-bsl3@@)6&7>T> zqb3shhDKP0#UFwmz(TzyC34eq92Na}o%nPM7NC<^f--t#S!#puUTw9Y{u2TwV}4lytLX??b$h5?h(aR?>45PB8?shL z=UbO98}GRj?$DRZZ9ULZzIJtBd;Qo@NunxFs_`Wh6f)9xM)$c0yC@NmhVlY9FY4V? zU36{Fomex^W$M<(q`iA79vjYpFTZ>D-(dLmd-_3Isic?q9LXF5!@~Yqbxv}g-334 z5MIZJ`k%S&FKg0^P@^BDUBxHP!x!HP^}CL3Fa2voA%E zY)^zUj4Vz&Tgo_Y*jvAMcV1XVF~F3$CDSO$SA-VNQ}=Y%^C311@VDgKT{h|AU$rcE zy+`HtoLr8%4z|*?1Yv%q-(8pVl(l(%p5(&X{aMdW(1VoIaBm0eV#wyWI#5-|vi(-x z*ju~IBZcTVv*9t%@T32pInprz=r`O3n0dBJK=aQ{L_9(SV8(3Lu-&lQwO^FWUO%MxfVTF za9h`cCM`lS_|=4hB!G&e>-0? zGFk?QCle^SV{Tw)r;R*mHGGkgj3%E<4<7dO{Btt?T;kCXW6rlMEw<%BI-9B(D8z+x zA{CQ@K+peAX+XmZtF_u0aD{6|!v6U<0dbGOck1Of&@GF}pifY4A^HzQIvJp-ja-cS zJ;N9*1ofVQM8O%I3^v7hRRUXQ`mtUTKn>}DViKKZ1AsMBN#PrSp5X;g@|;Ey=WCJj zzw~4H{%SH(d4L}#Dr3XRYdXGIVroF;^SkA0<>q>Gr+gafW|lqxgKaF@#yv*pr#gwt z26V;gqk*yu-5%&Ar97ziaje71wb&5$cF3Q@QV=Gb+d3Zqyq7bb>!#pAxKSVxOne#4 zXDJ`AJK#TyRcq?xFv5>jHRzndG#hdRm`WXj9o(5eLXuGw?9f>ORDk2=Ujb4`Hm4PC zdn_?tATqVdR=3<0eeD_BSXdqn)yGt$h{@*u^@jmenAwDV9*~r&5Qeapa4w?w(ObHM z)CkIW%3F^ivtJ>$fu3Ref|kc+oHs`Q*e8#z>|iEO8HpVdYDu1;eo=Zr`2>gr4htkb z5m%?v?0tTkm-QHCtv?=bW}Y}*_ys^~+t=t=;CfXgbq5Pb#&nR$S5+VhidpkhSU1FP z>|ZmuC=kckLCdH#?a6|$C65`iS6bo3l%X95L?gOxV9pU9toU@VGIm!@VshHGfW$fL z$ih%CyE;ebe|f;uOJBQIvK)5fs8kI4yr zpJ3HFv@6r;9*DC4Jdf$KRkHFGssqM?EbLYSd zPS~`N1K|LuPxq~47Qw2X3fOz=^fvoB1e+<0cZ)0TzV!>olp-d@T z%wAy@PY+}3g3kbGTLGoRi{2a=?C4ZX$ph*F_f&Ezj9{n4WVadR){x)`m(&(JMoUeb z)bOAdZ!5J-M@@Jo>i|Peyow$>)w+o zm)uE#0d@$*S9jUrU0a*#llhy9xe*`~^>qjyBo^?e=Z-o4A0wnYOX6gvXjA=OL8uwoTb<{ zO77Z*fUw6p`if7jYevl)4M@{?_Z+d_Dxe{lEqe0mt(dfBE%x6 z=iLf-U*3U|82#6UnyGp$MAS9zYPwF5t@3b&6NZbDnQB0Y1qjZDW~>7Fq+}VQpN0+- zi_-}Xx#^z#NQ{!SohHVSK|t5O>mwzA{HO=#mJ`k9@2a!S9^GCj=aN0u8ObtXoME^y zdsI3XTj9)!bt1#=$<;=13@ci2uvmWY1`41TY4%TN#Yw*)(wvfAQX$=l!rkM1Tl|9u zJ^Y;?v1JvV`U#Z1;72fuNHjjXorQm3K1Nl znKkvJR1}M`V1M$;Sqh4DDJdvsK7@h=8;$kS%U=a%Wgd!5W(gwj?;RH=B3Vmkdk0Wm z*_4W;2!S|K*Ouh7VGeXA$-UgLn|)3W+xa~*aJO+uIs;X9uE2FDqAWI3Bs8{B+gSUr-b=Y)7PcS61JYi1DiYAn~|NW&Z*&TASRqymA#&XFX?G}M^Ct#5WOOgCLw%bqahv>ck2^P!WTJ zwtYAXqs)Cmg~%Ae$Fa0H0uVDS0pOM-_LTAUBaYWRc>{D}0E|uFAW#~fFD{;*xIiQ)PRp+yKe|o|$ic{%& z7pmfNWl1R&$@d(_<$kW)?eY8FKYpLz*Sp7gzs~cV*Lj`Sd7X3S?fpFOT7PS+ zmd1cfO66pgfqe!;$i*ITvC`Z|EU&prb$XtCWFB!UI2MB zkYGL;NJY@`1R%$P1TUZ~r356zGyAc06Of}p;!1D}kf1$A01{{~{SHW2zY!$RUb-Df zSic2SW0?d3g+V4G2%APFvWVc0BNACC4W*zYHUYsCSY#4`fumq33>q0nM_B|Mi9jGz zXbd{Ik??d1N@p{eR5G4KrQ^wXG6TgE2skE@#zJUp8UtlA*?5#fV1f=Y7<^DdkobVf ziM3Qpd-c^Xtep86%+j>Js*&4B1V$n-5`mEjj6`500wWO^iNHt%Mj|j0fsqJ|L|`NW z|Jx(b$BFdz_U-|J0GtK}GlVyphr#G-fFg5{0I#7d3nbKGfdupLg1iUhNg!`BN`l`= z@FWR-E5X_l40)7sAn8hQs{~s~a2t@2S9u}9kY|DR>m>L+kgy*13;XW?64pbz5O?-t zsfiN&1xV1Jl(htZlhnIQaE}D(a}qi#zu95=vYPDwCS0BLL_ zkh4J+`Ua>j8IlCUu|vE=g5`h&`Z6zog!1%6laBaLz%!ax#$0Agd{!uGcmSDKXVEr-)o-e_xCD=xS*%E9EBA{{QkCNNA5G!Ejwej7l(Erx3$&K>d#r%#~ocE@3?!7wBIb&MO?BzXaz< zZ~%~?e;wEl;5A1F0}1w@P707W84P0SgdV77mH={g;+bj8Z0p^C6_K$#=LB0MZ# zfbtAQe19Pm#ftb`e=!-{>@Bio(RRx_`3=asF@gRGyvuD1->Xx zY`loW5F$bjD#G}P#R8Fuv9ULB%b#Jy27F#fab<=$jh8_i!`%Z}&3%7W-2#{l7s>F&B&S5C#_=E^tO*Kfw(% z7=gi7U|kEvKWc;-s>>G)rz!_GEDQb9_83^?{eAwit$(Nm_x|53=^q4ra8y5PJA5en zexIfK9>{%JjEp;Y)Xl|UCTN2{jhevURyX_0;e8aRKR=w5Oa5~mME}0sh-8aai`Izb z!G919O#`UE?B{g*J^#1w;Q1%zdGUsmXWlK2XT}r0=c(7L}s#C2!VhhlUU&NmBBzLcorU|vk)>1!L!J8Hk$}M zVpFLsHj%_4u)%374$mSo$SfKS$AHJOWQ0PavM_8C4tU8XFe!8*38hk)6gHiWM`#4# z1CEZvk=ZyFlfhsR7*vFY1INHjGD@SfC=><`oa+*37y=7rP+2qr0c9XKHj7FJ)^S7{ zo`z?l1aN@NB#~%17M)H5zB33UGLcBdvB*S}g(rhUW(FIBqkuzU8k0@{nhX*UG$sxY z4v?u-5|KqAqhvCXg@EH@A`LW0ad?Cb`o>cUBmy{&W|FBGlnCNYA`$2`HWSapljsPW z!6q?jbUKC2paVTBf|Bqki9(_?z#y3jiB6`|@eC@BOaQ0XWDJJPMp;Z050r2OCW{VY z%SPx-Fl+(|A>x5)HUo#?5gd+2WH50!9G(WI0Z#)OD20NOhQmb{Bfh9; z=0F`RvF3QABJp6EGkCe=Al!w3_yQEuI#={hbwOM{(q~At5D7q?g(#a7I1>bL=tTq{ zV3NQGm?R@g--no_KQR0(lVpS^84--|e~qjp(!p3fnF{`tCzElIweI67;q?61B)Fj9 zB7_SJaIlbH?fbS9@Tz@h7m%}uJU!%aAs-LV8Xyl37bRS@fES0{F-8?6$hX6HUC6UT zZXNRGe`gm9>Y!bHkf7bEAVIqZAPv}sa|P`J?)axK$nrsD+5h;m7S74QSmAhwCRh#= z^mV{rC}Aw11e|nVf_WGhs5=fM7#o-$h!2d>&;-k2g5w*A9h7jKP{J6(1oM4k9_BY< zfLp-~Q-|rNxG-Ekpt)ckjLqN|5o=;H13qHGGJ-q%-!e`acy5aKw*LE#jt?cZuVz4eT;3N+mXYz$X7!2ww z5C>tLgTy}IFjT}8as=Wz*g;h+8i+Fe#qclzb4*dac%f3^H-pb;R8Hzsc;E{zS${Fx zkcOcVQ3l{5*(8Kbq~jQS^TKXaeWP-mOs%*TNSZ|FkWG)40Vh=3(`bHPz#!M@7o$s+yE#cTVr5 zovSTv=>GI-!Q8n#&-eVRR_TSWDYfM4>ex>Ew;RY1vs*UzzwN zp(tyW#q#d>157uytM?j@Zc6BkYs{6;D53L1yq9|13lh|rRz7{cNVjEQJ@fJ$YQRKF z>@Oj6cmKZZi1F3dyLESJZ@$JEm7J()W543vb60N+UERv#k6ovgp}Q-a^dw+CHF?!} zvs%XYR$Z=aGs`zUg}$=>)Asl5$IBlzzR|1+%eT05;z7OWQ|q*#%-Ibxk89iNitc&3 zwJ6~ZPrk1H>4N^nYdX14{S5O%#;kW$KD(}U_Th8+8(nIn_xY>%m@-pO|AtAq!yMroo)R?nLGWX6M|ft!}q9zCWr=iM%Sr_0lq zePDi>-r_P|x8CukJ5i^!^5qx>*#PGCl~2dBZWP4mJVq9CalDE>)L()$=~=fw+t{hj z8#|ry>bj;?^|Z(I`a@Rl=T@(L?67ry_>8!V%Gj~aO^$9^YaJhQ60d1L%bj4RSt)xf z-&r)aUF@tDEpuYhl-k$`$Bn8lI)#Een+jqr$|7cNjmPPshrMhq71m`oAF^0?kfc#% znb~}PivA4i&$u)4@yYi)BW-_)J3To%LX)z>F$+^xp!V#0Rd6fs+Qsr_g`OwJyE2W} zZoPbCF-SMRufFHum%vz>a563E{CjFrt$Srauv+7Z>iF!2ne^P}P9?$qu8Q;ebF;M6wg*38)J*-Dyh_j2 zp`5FJTAGlpnezcZVP3-WG)w+UslXWzFA&u}-~Qa}a;E3xXHxs!0zU=|d9mTbN$R)K z*>3fL>PvR{Mx?Bo(X%ZcM@gA;h<&->c3n}_ezP3shW+iY?;X^ed9h)dO+KZac6i@> zuN&c4yW7wD2dM9MIFUL>&W&)E?m9!K{map=+{Xo%xhq{JsYzofh35YkAFKSF~z=>euuKPoKYAFedsCvZiC@ ztu?VY!mUz@N^^Okf$-Q^r{`^-cv2tg%eu!kzq%J*_Jw2rCjVJW+}Pj0h&^|nvF_T@ z#&|BnvXftw;_{q=l-xRigf(ACoccs)H#^oqdFHRg;$5am@!G*BZgF`>7e1c8{(8H5 z`;2iJB#ZCV3#AXPbxn+_y;a6(im?-zKVM`zc?RFWB|Ysf+1~Zqg?!t({G5aG#f_VL zmJ@c03KoWXDf%{aE!C|OCFm~5U6B9y6)p=awXNOZ;-Qv#>v}q^H+R~b$_JO8joRi! z7vS`!l}RUcmh4g8IkrV9D@G%3LH;?bNmZ_diwc|Wl=s+H?Vpc3OIhb+E`GtYd~(rx zf4I*>Mxq{p#V)4#>*3u`Bg<@W$3>)>#XUNXbz0qZ*5!NfF~RJ0=Tbhbz0IAIokk_T z%<>5akfpwapy@~3@c}+bYPxTU&_SdRE`jz5g#NB!9PCavs z4lAThIn3(Jg_uKB(wPbS4^NmKK-b^yQb<{5?Upd1=f;t*51Gj(`~`Vh9a9~}=Q)X7 z+0`39`)veA!R5;zCD~pY^=fX`@x(iFHACKU;lZ-hvf3&UAS^PR}jde=p

0tA@2-uCNO`%&XVM_Z%%c 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%0A1kC z$-fVLi*F8PymB7!zc-BPgHHk*O$%b(Y`_NMFpiL4kL8zE z1yf%$BOYeZRnKG^XjJg|{C8VrAp0?w%aW<>?1|C9N8)BcKd9cUt+_XpupU~-HTVMH zmKR3)frLb_b{o-g&=I4wBE#tJ@!w4qXUp_0NSqPAxSevb9tHF{ZBIn1@`M9{_^Hr( ztUWj8Vu|xv^V3TnsU}^j9(fi~di5?@0vuNZrXU225Yv;X$$W#}wHp|eOe{cQq%T9i*cqe0aJFx! zAO=3y3t&SRz*fO=T(p1Lwj2XEY3(~s%b`NFT)2f5t>Vf5A**D?Bxw+XIL}Kp>W#l! z_jDa3cSl!AP-4_}${galQHwFnY#QRqXFwKjhb$dEhq@+kz}YzE*l~0O)mOoH=QwX{ zS1>Q3b5;kP3-R_&p3gFrTI;t^R@SMq^I91|nELHAcvFbTaiUSEe3Qk}5%nKKi{FMfp#`ZC-AhBhbv9wc_Q~D= self.__rescan_time != 0: self.__scan_ble() - for device_addr in self.__devices_found: - device = self.__devices_found[device_addr] - log.debug('%s\t\t%s', device.addr, device.rssi) - scanned_data = device.getScanData() - try: - log.debug(scanned_data[-1][-1]) - except Exception as e: - log.exception(e) + # for device_addr in self.__devices_found: + # device = self.__devices_found[device_addr] + # # log.debug('%s\t\t%s', device.addr, device.rssi) + # scanned_data = device.getScanData() + # try: + # log.debug(scanned_data[-1][-1]) + # except Exception as e: + # log.exception(e) self.__get_services_and_chars() time.sleep(.1) if self.__stopped: @@ -71,6 +65,12 @@ class BLEConnector(Connector, Thread): def close(self): self.__stopped = True + for device in self.__devices_around: + try: + self.__devices_around[device]['peripheral'].disconnect() + except Exception as e: + log.exception(e) + raise e def get_name(self): return self.name @@ -81,6 +81,9 @@ class BLEConnector(Connector, Thread): def server_side_rpc_handler(self, content): pass + def is_connected(self): + return self._connected + def open(self): self.__stopped = False self.start() @@ -89,50 +92,74 @@ class BLEConnector(Connector, Thread): for interested_device in self.__devices_around: if device.addr.upper() == interested_device: self.__devices_around[interested_device]['scanned_device'] = device + log.debug('Device with address: %s - found.', device.addr.upper()) else: - if device.addr not in self.__devices_found: - self.__devices_found[device.addr] = device - log.debug('Device with address: %s - found.', device.addr.upper()) + log.debug('Unknown device with address: %s - found.', device.addr.upper()) def __get_services_and_chars(self): for device in self.__devices_around: try: - if self.__devices_around.get(device) is not None and self.__devices_around[device].get('scanned_device') is not None: - log.debug('Trying connect to device with address: %s', + if self.__devices_around.get(device) is not None and self.__devices_around[device].get( + 'scanned_device') is not None: + log.debug('Connecting to device with address: %s', self.__devices_around[device]['scanned_device'].addr.upper()) + new_device = False if self.__devices_around[device].get('peripheral') is None: peripheral = Peripheral(self.__devices_around[device]['scanned_device']) self.__devices_around[device]['peripheral'] = peripheral + new_device = True else: peripheral = self.__devices_around[device]['peripheral'] peripheral.connect(self.__devices_around[device]['scanned_device']) services = peripheral.getServices() for service in services: if self.__devices_around[device].get('services') is None: + log.debug('Building device %s map, it may take a time, please wait...', device) self.__devices_around[device]['services'] = {} service_uuid = str(service.uuid).upper() if self.__devices_around[device]['services'].get(service_uuid) is None: + self.__devices_around[device]['services'][service_uuid] = {} for characteristic in service.getCharacteristics(): - log.debug('\n\nCharacteristic %s found in device %s,\n mode: %s,\n Characteristic name: %s,\n Characteristic UUID: %s,\n Characteristic handle: %s\n', - characteristic, - device, - characteristic.propertiesToString(), - characteristic.uuid.getCommonName(), - characteristic.uuid, - characteristic.handle) - log.debug('service uuid: %s', service_uuid) - service_available = self.__devices_around[device]['services'].get(service_uuid) - if service_available is None: - self.__devices_around[device]['services'][service_uuid] = {"service_object": service, - "characteristic": [characteristic], - } - else: - service_available['characteristic'].append(characteristic) - self.__service_processing() + descriptors = [] + try: + self.__check_and_reconnect(device) + try: + descriptors = characteristic.getDescriptors() + except BTLEDisconnectError: + self.__check_and_reconnect(device) + descriptors = characteristic.getDescriptors() + except BTLEGattError: + log.debug('Device %s - services, characteristics and descriptors found.', device) + except Exception as e: + log.exception(e) + characteristic_uuid = str(characteristic.uuid).upper() + self.__devices_around[device]['services'][service_uuid][characteristic_uuid] = { + 'characteristic': characteristic, + 'descriptors': {}} + for descriptor in descriptors: + self.__devices_around[device]['services'][service_uuid][characteristic_uuid][ + 'descriptors'] = {str(descriptor.uuid).upper(): descriptor} + except BTLEDisconnectError: + self.__check_and_reconnect(device) + if new_device: + self.__new_device_processing(device) + self.__service_processing(device) except BTLEDisconnectError: log.debug('Cannot connect to device.') continue + except Exception as e: + log.exception(e) + self.__previous_scan_time = time.time() + + def __new_device_processing(self, device): + if self.__config.get('readStandardInformation', False): + log.debug(pformat(self.__devices_around[device])) + # TODO READ STANDARD INFORMATION + + def __check_and_reconnect(self, device): + while self.__devices_around[device]['peripheral']._helper is None: + self.__devices_around[device]['peripheral'].connect(self.__devices_around[device]['scanned_device']) def __notify_handler(self, device, notify_handle, delegate=None): class NotifyDelegate(DefaultDelegate): @@ -144,11 +171,11 @@ class BLEConnector(Connector, Thread): def handleNotification(self, handle, data): self.incoming_data = data + self.data = data + log.debug('Notification received handle, data:') log.debug(handle) - fromByte = 0 - toByte = -1 - # self.data = {"temperature": data.decode('UTF-8')[2:6], "humidity": data.decode('UTF-8')[9:13]} - self.data = {"temperature": data.decode('UTF-8')} + log.debug(data) + if delegate is None: delegate = NotifyDelegate() device['peripheral'].withDelegate(delegate) @@ -157,60 +184,98 @@ class BLEConnector(Connector, Thread): log.debug("Data received: %s", delegate.data) return delegate - def __service_processing(self): - for device in self.__devices_around: - for service_uuid in self.__devices_around[device]['interest_services']: - if self.__devices_around[device]['peripheral']._helper is None: - self.__devices_around[device]['peripheral'].connect(self.__devices_around[device]['scanned_device']) - service_processing_conf = self.__devices_around[device]['interest_services'][service_uuid] - log.debug('Service with UUID: %s processing for %s key %s', - service_uuid, - service_processing_conf['type'], - service_processing_conf['section_config']['key']) - for characteristic in self.__devices_around[device]['services'][service_uuid]['characteristic']: - if self.__devices_around[device]['peripheral']._helper is None: - self.__devices_around[device]['peripheral'].connect(self.__devices_around[device]['scanned_device']) + def __service_processing(self, device): + for uuid in self.__devices_around[device]['interest_uuid']: + for service in self.__devices_around[device]['services']: + if uuid in self.__devices_around[device]['services'][service]: + characteristic = self.__devices_around[device]['services'][service][uuid]['characteristic'] - log.debug(characteristic) - log.debug(characteristic.propertiesToString()) - if 'READ' not in characteristic.propertiesToString() and 'NOTIFY' in characteristic.propertiesToString(): - self.__notify_delegators[str(characteristic.uuid).upper()] = self.__notify_handler( - self.__devices_around[device], - characteristic.handle+1, - self.__notify_delegators.get(str(characteristic.uuid).upper())) - else: - try: - data = characteristic.read() - log.debug(data) - # data = {"temperature": data.decode('UTF-8')[2:6], "humidity": data.decode('UTF-8')[9:13]} - data = data.decode('UTF-8') - log.debug('data: %s', data) - except: - pass + log.debug('Characteristic with name: "%s" and uuid: %s - processing.', characteristic.uuid.getCommonName(), uuid) + self.__check_and_reconnect(device) + characteristic_processing_conf = self.__devices_around[device]['interest_uuid'][uuid]['section_config'] + if 'READ' in characteristic.propertiesToString(): + self.__check_and_reconnect(device) + data = characteristic.read() + log.debug(data) + # for desc in self.__devices_around[device]['peripheral'].getDescriptors(): + # try: + # if self.__devices_around[device]['peripheral']._helper is None: + # self.__devices_around[device]['peripheral'].connect(self.__devices_around[device]['scanned_device']) + # if desc.uuid.getCommonName() == 'Service Changed': + # + # log.debug(desc) + # # log.debug(desc.read()) + # log.debug(desc.uuid) + # log.debug(desc.handle) + # self.__notify_delegators[str(desc.uuid).upper()] = self.__notify_handler(self.__devices_around[device], + # int.from_bytes(bytes.fromhex(str(desc.handle)), "big"), + # self.__notify_delegators.get(str(desc.uuid).upper())) + # except Exception as e: + # log.error(e) + # for characteristic in self.__devices_around[device]['services'][service_uuid]['characteristic']: + # self.__check_and_reconnect(device) + # log.debug(characteristic) + # log.debug(characteristic.propertiesToString()) + # characteristic_properties = characteristic.propertiesToString() + # if 'NOTIFY' in characteristic.propertiesToString() or 'READ' in characteristic.propertiesToString(): + # descriptors = characteristic.getDescriptors() + # for descriptor in descriptors: + # try: + # if 'READ' in characteristic_properties: + # log.debug(descriptor.handle) + # if descriptor.handle != 17 and descriptor.handle != 26 and descriptor.handle != 43 and descriptor.handle != 47: + # self.__check_and_reconnect(device) + # log.debug(descriptor.read()) + # elif 'NOTIFY' in characteristic_properties: + # log.debug(characteristic.handle) + # if descriptor.handle != 17 and descriptor.handle != 26 and descriptor.handle != 43: + # if self.__devices_around[device]['peripheral']._helper is None: + # self.__devices_around[device]['peripheral'].connect( + # self.__devices_around[device]['scanned_device']) + # self.__notify_delegators[str(descriptor.uuid).upper()] = self.__notify_handler( + # self.__devices_around[device], + # descriptor.handle + 1, + # self.__notify_delegators.get(str(descriptor.uuid).upper())) + # self.__notify_delegators[descriptor.handler] = {'function': self.__notify_handler, + # 'args': ( + # self.__devices_around[device], + # descriptor.handle + 1, + # self.__notify_delegators.get( + # str(descriptor.uuid).upper())) + # } + # except Exception as e: + # log.exception(e) def __scan_ble(self): log.debug("Scanning for devices...") try: - devices = self.__scanner.scan(15) - log.debug(devices) - except BTLEDisconnectError: - pass + self.__scanner.scan(self.__config.get('scanTimeSeconds', 5), passive=self.__config.get('passiveScanMode', False)) + except BTLEManagementError as e: + log.error('BLE working only with root user.') + log.error('Or you can try this command:\nsudo setcap ' + '\'cap_net_raw,cap_net_admin+eip\' %s' + '\n====== Attention! ====== ' + '\nCommand above - provided access to ble devices to any user.' + '\n========================', str(bluepy_path[0] + '/bluepy-helper')) + self._connected = False + raise e except Exception as e: log.exception(e) + time.sleep(10) def __fill_interest_devices(self): for interest_device in self.__config.get('devices'): keys_in_config = ['attributes', 'telemetry'] if interest_device.get('MACAddress') is not None: - interest_services = {} + interest_uuid = {} for key_type in keys_in_config: for type_section in interest_device.get(key_type): - if type_section.get("serviceId") is not None: - interest_services[type_section["serviceId"].upper()] = {'section_config': type_section, - 'type': key_type} + if type_section.get("characteristicUUID") is not None: + interest_uuid[type_section["characteristicUUID"].upper()] = {'section_config': type_section, + 'type': key_type} if self.__devices_around.get(interest_device['MACAddress'].upper()) is None: self.__devices_around[interest_device['MACAddress'].upper()] = {} - self.__devices_around[interest_device['MACAddress'].upper()]['interest_services'] = interest_services + self.__devices_around[interest_device['MACAddress'].upper()]['interest_uuid'] = interest_uuid else: log.error("Device address not found, please check your settings.") @@ -223,50 +288,3 @@ class ScanDelegate(DefaultDelegate): def handleDiscovery(self, dev, is_new_device, is_new_data): if is_new_device: self.__connector.device_add(dev) - - def handleNotification(self, handle, data): - log.debug('Received notification for handle: %s', handle) - log.debug(data) - - -if __name__ == '__main__': - test_config = { - "name": "BLE Connector", - "rescanIntervalSeconds": 10, - "devices": [ - { - "name": "Temperature and humidity sensor", - "notify": True, - "MACAddress": "EC:C8:BB:6E:05:67", - "checkIntervalMillis": 10000, - "telemetry": [ - { - "key": "temperature", - "serviceId": "00001800-0000-1000-8000-00805F9B34FB", - "fromNotify": True, - "fromByte": 0, - "toByte": -1, - } - ], - "attributes": [ - { - "key": "batteryLevel", - "handle": 0x15, - } - ] - } - ] - } - - connector = BLEConnector(None, test_config) - try: - connector.open() - log.debug('Started') - except Exception as e: - log.exception(e) - log.error(e) - connector.close() - while True: - time.sleep(.1) - # connector.close() - # break diff --git a/thingsboard_gateway/connectors/connector.py b/thingsboard_gateway/connectors/connector.py index 6af3ad6a..9ad7ae76 100644 --- a/thingsboard_gateway/connectors/connector.py +++ b/thingsboard_gateway/connectors/connector.py @@ -32,6 +32,10 @@ class Connector(ABC): def get_name(self): pass + @abstractmethod + def is_connected(self): + pass + @abstractmethod def on_attributes_update(self, content): pass diff --git a/thingsboard_gateway/gateway/tb_gateway_service.py b/thingsboard_gateway/gateway/tb_gateway_service.py index 57ed0e13..0423dc81 100644 --- a/thingsboard_gateway/gateway/tb_gateway_service.py +++ b/thingsboard_gateway/gateway/tb_gateway_service.py @@ -25,6 +25,7 @@ from thingsboard_gateway.tb_utility.tb_utility import TBUtility from thingsboard_gateway.connectors.mqtt.mqtt_connector import MqttConnector from thingsboard_gateway.connectors.opcua.opcua_connector import OpcUaConnector from thingsboard_gateway.connectors.modbus.modbus_connector import ModbusConnector +from thingsboard_gateway.connectors.ble.ble_connector import BLEConnector from thingsboard_gateway.storage.memory_event_storage import MemoryEventStorage from thingsboard_gateway.storage.file_event_storage import FileEventStorage @@ -57,6 +58,7 @@ class TBGatewayService: "mqtt": MqttConnector, "modbus": ModbusConnector, "opcua": OpcUaConnector, + "ble": BLEConnector, } self.__event_storage_types = { "memory": MemoryEventStorage, @@ -135,6 +137,7 @@ class TBGatewayService: connector.open() except Exception as e: log.exception(e) + connector.close() def __send_statistic(self): self.tb_client.client.gw_send_telemetry()