From 09cffe0279ff9dcc40c795f243e9626bea767aeb Mon Sep 17 00:00:00 2001 From: Scott Petersen Date: Wed, 26 Jun 2013 16:05:23 -0700 Subject: [PATCH] sphinx docs --- docs/_build/doctrees/environment.pickle | Bin 63006 -> 82379 bytes docs/_build/doctrees/index.doctree | Bin 5484 -> 5486 bytes docs/_build/doctrees/modules.doctree | Bin 2798 -> 2798 bytes docs/_build/doctrees/pyad2usb.doctree | Bin 149781 -> 229463 bytes docs/_build/doctrees/pyad2usb.event.doctree | Bin 15916 -> 15921 bytes docs/_build/html/_modules/index.html | 2 + .../html/_modules/pyad2usb/messages.html | 289 +++++ .../html/_modules/pyad2usb/zonetracking.html | 368 ++++++ docs/_build/html/_sources/pyad2usb.txt | 32 +- docs/_build/html/genindex.html | 138 ++- docs/_build/html/index.html | 4 +- docs/_build/html/modules.html | 4 +- docs/_build/html/objects.inv | Bin 1022 -> 1225 bytes docs/_build/html/py-modindex.html | 20 +- docs/_build/html/pyad2usb.event.html | 14 +- docs/_build/html/pyad2usb.html | 1009 ++++++++++++----- docs/_build/html/searchindex.js | 2 +- docs/conf.py | 2 + docs/pyad2usb.rst | 32 +- pyad2usb/__init__.py | 4 - pyad2usb/ad2usb.py | 73 ++ pyad2usb/devices.py | 120 ++ pyad2usb/messages.py | 26 + pyad2usb/util.py | 7 + pyad2usb/zonetracking.py | 52 + 25 files changed, 1865 insertions(+), 333 deletions(-) create mode 100644 docs/_build/html/_modules/pyad2usb/messages.html create mode 100644 docs/_build/html/_modules/pyad2usb/zonetracking.html diff --git a/docs/_build/doctrees/environment.pickle b/docs/_build/doctrees/environment.pickle index b2d6160c75ca159e72ce1f34ce2dbc9913f7b0f1..e34f4ac2898482b2593158ab89fbde7772a0f148 100644 GIT binary patch delta 22624 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 diff --git a/docs/_build/doctrees/index.doctree b/docs/_build/doctrees/index.doctree index 60cc750d838f082cbb37d816a2de4d030ef4c82c..98e13cf2b97ef9ce082eeec25678ac6d175cf4a1 100644 GIT binary patch delta 62 zcmaE(^-gO;HIt|&0|SG8aY<=fntpm_iGE^=QE73~=6_Xa@;$Jxo7*j*V(lT>W z<1_P$Q;SM6^Yh|U^AeMCQd0`oc7$>lC6>ea>%195c~eSr3*w7YOG+~H(u)h%`;{hz ziWXPqCgtbEr{(9Dt#j6z}HR!YvuH8JZdL fwS`+JZ{|`L*%n*4J(R5|H4UV0M{VKG(j+|qpyy4- delta 203 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�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

MDg~PCC zCfWEJK{(82p*-(FWBkA!1tadxLF=dZLHO`SU%dv?izKbeE* zf%W~#oS;EV&IJ&;x$(^UlX+qh<^IGsg_{>-^_g~(;$p+6OSVPv5|ivVCtxA?6=sn&c+JV#tiBn?KAKNUM`k9Tg1 zi@4gJC4i58Nm4gUA`b>F1%Nev2{41G-wcZ9iA#%QnSdl~g`X#O6GgQZ%L4D`iOWgm z@+MQCOu|mYb)oL1(mHFjh9Th!gz;yGp#Ql>@LbZ5=v;^Q;B@ZQ_cN>SJ2cf z-T@)+zzSZfq1A(k_upq*kcix1vDkV->?m3Oy_8+Ff=VfA2%)`)VlFonStxuB09&Q; z^o6G)D|~*R!7yVPE|w7i3)RHy8LdK&Opq{cA10EOiPB^7_=7qJvS2Numc}m?ix6~S zzJP6D_8(>2@pt4#Q7hix6w4~wSLtFE(O_25euU`{>h?zx)iW9(atGk)tB2C9daCvq z94MZH0-m^jf^V`Bun>Q+NDnC^T?J9rHugT_m)N$JW;bw%E|zYw{S1J}orxz*uQ*4aidC2ieP=yO!p=5f^4+TYF*SR)B;Q%j z5k%BXU=ZyrU-e&KlJqw#CW4Isu^wVD4Cw#Bvj?} z^k$*QHLU=j!lThAJT>)4=`YGT=`CO{nUmg%?8x0F*?bTC1W^Nq#nZHxgJ`XBI}t4*A)r3Wy5TZCpLI_EL42{#LCcTI!vr&l0AS zKL7poUTMbs^**8(tv`RgA2ewC2LK}XAfDOz>qD^!&0qOZF*C7dQQX5IsW*3h1o&h@ z>`^3eOfj=iH^GtmthBT!e!lp)2n+o=iQAqam%X-R%acf>G*1CwZC%XP^3DX zBa&wWlB@-OuK1iNsx5e)ct2TuK|)_Np&IzvcIKFWsZ=1YphG@K>C1#RO0&%F-@u@7 zuK+~uRXn{PqFNiDHevMUye7)mjk4k!=NrQ2%a@w-Ch)O2$p-{||95Wz19RR6z+PmD zvAU+(GIQP)<$FfigmVt3u%q$W%ULt;3sY^%e}IQ6Sw{B(a$&|e0BlE=2s4A~%FOsk zlph;qofGkC(kG&-HtAE~VN#uA^*;jz%=;VwMpd%@=?;Sgt=M%Z^%PC{0df;06x&|`Th{gZS^juY;(Y))2NKx1Ef$Ve@Xw`0UVmqes>nY#VPOV84{}ir z^8!R}K0JM|qXz4B*%|!&qFf-Mgysd6sMfp?@cxGi3yXb`kbTh#c50&GixKaCsL+4} zPUa9xT<|57D5|F_@-Ioq9=#O)zyhtvW8S5eDDqMbd6yyHFCcV70{gGUQao9IIpr5c zQ7c6)PiSM_zcyWW8p1$^}%4$Eqgs`Hq^bpHR0SooSO9(3qxk`dW8?DMj z{UrpvJ>6;`3zrbmaI?-5f-m9fVD?K0Yv6Be#imv)Ay6#)=vqn_>xc%kj@BkjPat0h zNmS3e0Fmp7r>`DLx9X`{LRe2c>jyk>{RB%08vqOO8;Z178R=5+Xxyyp8!SG6ykWng z?L#t$gKcD@dP~&CCQ9G+y21?)YQ_~dZ2MlniR5l-a&5S8rbMwSeXs8Wyn6lS;_Vyq zZc)KYHEf10iTAyJDE-YmG}D{ zjAci$>=dw2QQYqt=0tAi1c@HE3lsJGJ(tdQ1=&RRdtb!e!0h||?)W=$dr&L-J;k!$ z@2PaLl4vk1sXt-5bk>X{s%HQI&L76pR}ZDv@Arem(-QE+^%L~_!N5ZNULqY*Mv7lO zso&e#ckK0i`!>3v##s~R-p1KfL5yB)sw;c-Fo_v%Vyst>P@-5-zE`&buUw7HQNThaac@3Y$U_n&Ogof``n{Q6{4kJBbZ_>>I~>fuHy?q&ajY-3qBm14 zE9fYtixotJSwTk=re6FQBvC#80>CwEc>3z0^!mN|IPn}G@Wk~K^yU+Qh4>RidQurF ze;l~O2;7J=sL`El)TfC0RHN3f2V(;CT2oQkYdgf+X{^?3$0$*(5Z`N0175xMbn%`M z@}612OEs*_vxxV-_G}~~caB)9?}|8A_@X(~PLbykR@@bFK5(eb3jiW_A)damsJgr_ zUt}y7i{+Alh5F*Ye5sI^B}nw5%bBR|%gIm8t^nOccV=JIE5YnL^Hum8OO#ZL&P=iF z%-1MgtSnm0%DR@&x|@D#b{*2Fps@g0iNw=a5XIN;%{PeW#(*cTp`bV41T4hgEYe%b zNdG@KJGfg-{B06{yNUn*-W6emD2x|mbm6XuJ7me7W(h`9Jm0~V7i7if7qXe|5=Fk5 zF6}$BUthnQ1b%vS4-z=(S3LG(iu9h^`${Es)@TVE{C>jh`uYRNLZdtgfE&>8^leT( z*5=ts(!-*B#3*%kM9Ezdj{?o2Jtnez(NcpRCmrW6PvDQpJt^{zn%FyQRK;aUf_P&5 zlqm87Syw3D(~j2nVi8)7=baE9*13p=g{}2hB^vf)i zExb2^rA`au7vw({WufyY%P^miE4(-2Q)Hk(p8;SathlY|s9F8pugHHPk}m_2tO4AO% z^vkF}?^ddcN#Gk z^rUN?(~`CF-iYadMP*D6fW5Dh)lrMJ(K2)A=`P+GML3fY2L6j5B;{6T7OK*%&LXtA zRh?nnb+@_?-Ri91FLA50Avi^AImuk!WM(dq=w2!XJ7SSf$Fc&U zMdfT>*N8OAu_6F=!s6+j3RRd>Dei<7@yY?Ql_+%Xs}S2Y=e{aPZ6~bcuAaz+%UnZZ zCW~`tf74D_K-S!vfZn;Ug}<>A7Eh}#Sh|i9YCg9vNsG>XHDps#Pr{sYUk`a`hxGxl z6BbY34pcQk=f0uXdIfCRG3%ZCMxv-X#-+& z2Affp-~TEj3x!JGB%70Xf_F&t1r=Ig3jl0U4nR9hRBUME&~ z4uNFjtFQ&T5}&dy@&2<}KMC9}5r`hOeJMXSz9OI9Xb0l`yl_V(u<=zabVT6i4?Bx* za%?|EKKXYhEPOWG1-Yn(T>-H16;Iz0slhs8c1F0nDECMxp?Oaw@+D6-_Xl1vM6-AY zguDYQc&Ua~4L8nqySjjv+K-XXD<@`@%5EMjR_y%u zs$s@5Tr4937V3yshgyXknIKU)`!G?xIy4pD#oF=;vT$)IeeKuzUgb;I24=rF)Q-Qg z9!#xR9CCo{9Q!I=tREW8`q_^#UANyKNmS2h04xOK>8pp*t$M1yR~;yxg94toeuA~3 z2v~?eSfq!Pk#fStFHU@Ean)XKpwS&_jE9NwaAQ;~TBOA=HpRhuPCVC-S7R`JiSPM5 zLh_C@c^cjtblC8RtYGctC{g5VF}O|QXcG7_dJGaco>Q_xBwwu5m=4nMEzyZTA~#0l9W}9c z)~E&%R_LNn6GdKNe4E7Sq%YkYc?K{j;h6w9)>kqTEmVy{S~)A$Y|a+rImTEP^q(tK zWzc_~(6%>{hgx+#=0A`z|M_4qiTN);cH}OU?9!P3BB6qqzizmHF{lyl6NKUZB^2Vr z{Y#OE+-1x{ILyylnZ*k$8wLnXOM_z{>0d5BMEX|{ePI1a|4PuH&8`B#k~E&#NdKBx zMERyh8se@6NxeY-I^dH)e=HJMt!5TV#-(-2Kv7uav?xB#zd?kBj+nfYZzPvFCfRZm z(kRW%0Fk>z%+_SotM2EQP;M2;Z2?Kv0w3nzE{aME(j}BTB=F9Hz%a_bi`cG3*>{6f zQT9EOdv78alQQHdy+Q5~@A-FiDG1Hp@pz zj}Ydf>_?G@=6nnQM+oETT_#nTE2*=D@`Tu)4A`>c#YfpsiK4QJ-P6L;e?B9L&zi)E zyjJ2laG~O8)Fj`brm^rmHN`Ra3o^M-#5Cr9k;D^wv&2haLi4-~fO8|H0_R3h5;nyG z*no>e@K;3js!_?gTUCT1_-n!z%uI&+>%{w){u>hbW+D*X?X6ONtTrQ`ee7-G{p;)Kk{Bzl-t@qb!Tq{sf8<+g~Ed7b`VpJn86h{>C4Xn*u9-&|MRIXN_v` zt_%nGl%mKBjBl3s2aqV*ta#gIPcd{;0fQ1w4G_6$BqPy6)f&NdZkCuEp%GdH%o*8P;$9M1H-l%A)_R0n+e&Gn^_7Q5_e-!0X;9?jySXGA@!i}+H`I^s<^c^_cwPW( ztHm=L-_0M3P<)3~|6-tNS4=Dbx_Uw0g1{$1-a<%3ZeeDj3i4M>u!7P;`ABaOQ5QOJ z;`$dQSN@8L#gK`@H2`2Mt|VAf(*pHfAMPz7k|hI@tQkJsTS^qwX8eqS5^>Zqfu7e5J9)IqA2pE zOYP|aJnX5sVqzs=Vb;n3I4D`7thT8>G%NUh#;PJ-Eg-gf52NDMiS1fcyaq@W6|X6| zYbA0~xV0r_vP8uk9gK=uTDI#tfIcc-7k^{VFrLQvS{wb+be9<6#mn z?TiF=CW|Ewfp=9RuOHXpA)oxa5f)aVcSkO&VGjT-C*$e6BsEx<%tpceMcJHC!tw!1 zRBIjxy#MjWAhEZE?1L-VsfmW~MZDj}J_L!#4HZjV@R|}u^;AXvy$RXfhv5$#o-Fd1 zcZ3o}UaBE)EAf62d?XTBRu)U)mI4Xo-chWjEO3}(L=ehB`K z+@aKq@Rwrw8aqtsVkOaJR?^{w;VlzKAOlr&Bmg!Iejw-rd?E=_H)7;Y!&`yPFggq&yts$zTIO_*I#x(8XP^LqiX)QhKYQi``G z&AvhLzWKBM71i)gw~0klB}mqmO>`g{Fqu_WCdULo)Ja9z`^Yj&yv75)N@Eg z?s@U#zwEtGDyg$ZOIZ9D3A5`&FCh!%ei;Dkpm_Qgqn@%BdqtG58fDYs7(&@~nX=m@ zUIR5f#Ovb9mo&BS4bm}Ac@uwNNmS&x`Hb0E2_^8gX9uCYEsDIr_;!hRNZ-}lCEf)w z>ft>A?8ueaL@}*FRak8lzyD#%=nwGxkJvvjb~Sl=nZx_6fpJ1rt|@&ebbPx+>%hHR z+PiSO#B5wi`UspQD@h+C8|NEHtW9`RgS6@IQ=x*Dq~an{db`ADAjTRJLAZwWIc4}Y zq%V-bZEeiL2ByeH@ zvryE`Z4<18v=DRSzz4SeFCr~;*JOh9E4ebaP5g!&l;n2+oM#|*Yewo;pY*p){3(*Z zjHLWx2vly?u0>+I#*3@kuD^kYU5o^aw@pm3fJ~ec0EgV-={*Q7G85yIM5hwT)J9Tc zJr^wUOKQ`IsM?}wfrmwf#+wfLsITb(uvb??tiGt*jOlKtZ_Fr?nF5k*-S}0tnMF}; z$t=YCRkc|qbT$*(#5KwEG?lQwvop+ID!8*o!|1H%AhbhA%7wT&L4m@~1%N|o@$@xM zGt66M*V^V0<-A6z4r{}X=FF$ud^uBd<_A9Ro5ti8Kn~O|2!M^YVz;`cnoxbPrnaz% z7YT^1*26WmMTza&n%ZI@)tXv^c2NY)g2PeUO89|icS9ANQz;!zJ=Co<-WU7$9P>xpI0s#AzWokz)t|c}Y z8WJPuZFID)M6$J!DDbsfgkQJcylf*>W#GH5&=WcuFsQ)fJ8B!F-+o{(iGH_3Ha0g) zw!NBCs}%k2AXE_jx*d^I41t5A0e2$7_!>bN12<8UkAZha0&COELSVQpI&&BU>ky`H zs5(0u&`$qLx}i>8<4J*oTK4bRqu#NAEL|F7`apSCX+@yC8_{j`1LfU8g9hFM0BhfP zW&`E^v50gBUC;t{mQ*uH?BlB9=GhQjW$wus0DSUsbs!Rv8^kQs3)iK1A_j&WD=aOF z4+2|6SQs2hxICC#w&J66t@c71r5OT%1#&T4t5dJ~s{f=~6Up8IN!9`%{0$RDwFSe8 z_rc!?32il@O|zhMnKovSHL_G*XN~sIv+hGUw#e%o5GYz304@u})B95@wRe0r)Egzr zeT`BJ8QC62YxWa1U%J$q{eg!y+H1M#8;eELfcMK?C-oF5FT8G4$c{C$5F9?l~6Y=o@vGvI?G(LgY zu7$=Yf>fdLNs@bVA{P~Yio{Ho(3t*$p)pI#9)BvJ4~;wUcjP+pwB8L%$0(tuaHo;9 z7#g#Dlyo{_E;K#^d1!|-0kEqZPd{v^%G#k$XneNV&I#DEF4u>~=ZYfVU((R{JmDD{ zpD&3Qn8b?X051d<6-4EeWV2<#g>xWm=&qX|R0>iK~tSyc9@O_hkV1JRngW zwYWSiI%+&U4)6+5U1?Mb8LY_R7v-yjEtr$M0j?(Ae^I_h0ye1u4PxPF1^!`tcU3L}xHc{T5 zP(t$^N>ppU6L|kc`7W{F9kSn3!A?yy{9fYy_qY3yh}`{Ri3|RK5=He?Mg9i~*`puA zACY@l6?wp%6s(>#`2?BehOHqDDKri3;9ceM1T5~iRxa> zuL13&Mhac1oB%e=!zwGB;ef2EZRVolrs;ZHK@XTH!m_!bZW%m%^-y~K{@zVI%LY7g{RI7e zIbb1vd69N6Bju`yo%rWgFyclLuV}>jz+iavSyNEiXM2cqCF8U{yRs6+>hOJb72wrp zR~7GSA@AxHyi~)gT!VPuXV*jm$Lflu`ar<7g)f>z?G(8VVa0)f>jHGb|!s$N#DVw zYcJ4$DG;N@iclCWUE2$^qYT-}48d56=R0F+Hq%Rfpv1E_il;UN#{uq40zW<4MN)S) zskt90?N%zOvqnqU+`AKIH=gW)EHufU0FmpDr*CoUu@=uxlA1+1z$mrPzvMW;fk3nW z4H8+g|9OL2NXPlhVEloL%S7H$6FYvqPpq#l+i5aH6nTO1aezZfUwIs04Oow`1?_aU&G%Y ziO7v+7S^hD9AIF1V|pAQ?Mv6L{WAOkV#G51fkZD~e;NKD(4dDz09XyhGrJ6bNGw9j z@H!5#V2L{vH1*cu4+B0~hd&&N$Q{8flr20Ckflxw;}_zO6lJ0FC(AHLk;@`C>orFs z0|hz;0H;uh+nSD=)!+R}{IMcAE+EO8;8)_07e%EB>2KLjkiZiQ0>fq0lZfrwGU~}7 z)iUZSl6z_*7fz-_VkXNnDw~_j1S~BbY$u>!MjeB{BX=5}=2Btl=}M^f+!-V-E~B!1 zlyoLxZW;9~~7H1^R4#)pZL~$k-*+(X2rf$LeLdi z^0YACx85(xLT^lb>jUI6-)h!8hzu0yApk7Aird#ZGQ$drMn#9v9|l4R)tSqx%SW)D*3lh_zmKUZ{#y14{w|w9 zP3g~5|CGcNJPzuHfVd1mc zugFC;{00!Y-|_Svks7QcW@m(di1N>b5}N-~qFVEK;1xssE#4^>@>;+?CAlpWm(MT&#A(So&R1nqp{2+mYD+< z>WJ5dW)X7M1c?I9#zghnkUtJ^c94ZjL+NY3Vk07bl`q{KVD?KxbK-BT1yd`QhA5Vu zV{WC3)l7p~Kl2c##{tfZB&ugV04xII>3apGTlG|ZuUbGn3kE!K{RAsR3jqu93yXA- zGSZ6U02ejJ#l+ZPjEY711t5ELU|cH^O*vCceLVS!AJBmIJ_+Vmy7NQ+(M_>@La`5=yjlqY_24z1kIl z*HG*s-jzb$l`D9uh9<8fT(=wCFkm#_6m2ad+8f=fAVMKl1Hc|& zJW+`HENCbiqXJIo*IjE!?3yN4epu}>re-gQWRYzxQRJ&3xYK%V68Pp@M^e`{skueA zo~4pHYqW%wvL0b}k!^isp$awth}?#F`gWwAvUcnx%8iV&?9`p!KyegrERuY&Qe!qD z9bf00;t#A3i@c*I_RbpBAQTSYrF}$^7Z~4Zy*cSiPXX!+3`)2K02YoVBhfY;)YDQaKN@i!<2vs>d+g9iao!eM8Ia`{OvwmPNnVfBhY;0VW?9$2E4nhT! zv%2%L9YKwG89_KN+lfN_ysQZcT>Hi>3=^H(7+BrNmF{l*c@|AeXEA)^G9Wj}ZwUEo+AhKmJ(kRVd0FfIaW@|F)Rrm92T|-4u3rMmS`1#o0qNubW zUF#Yqfx`;|!|BinV!JjSY6YpLLn9@3pF}RkyOWs7G96-LGsIwN>F3%2{dA}uf8)eq zJk7Jg(tVXs?YaF(TAU8Ce3Z05VQxA!8hL2W0|2nK6;JOnsmfeQowcrm#1;i?+4171 zLkEkZvWeXx!qa~qDv5`g#ECq&@o;dV;%L+)-%6;la0E5QlcOVLa-oRnGTTukp4f96 zj|LN(=NJI2EK5a4EiNak$_89KS2|Wy#~GEJyH!OvS2|wUf|<#1KY@5ZS2|GwPf7%$ zyPaIh-&vz>_OVll_pkR;k-)mKSmL=-rxJPnoi(Z={}{q-baooDPzR?2;OGiGeHW#8 z>!R6-(wU+>E1`thXDd;y_8j2#{ytZ{=Y_oISMX8|O}>Dz>*qFJ2yztXA^@CafhXN` z*UxRFfhzQbBDPDU;8Ihd-k>%bQ?p*1L~NIdB40JZxs8{Tz&Gg?l6s{{%|&cil}hTY z(GphF)r8rI?HXjEGOh){_EkK6+fq+i+m03G^+s71vE2X^Beokwk}pDr(@W5A7qq-ZTBNPat}yBY1sClP(j${9zsst*zI8w zjIR-dvD+h*B*=RniO9XcEL1`M+(uSVS|}gsy(sEJ z2Tol7OXSL*+xRjvQMi8tV3Al7tf^^%`mPW6UKPn}0ZG;jAMU*_ifS|7Al|RPzbT<_ znb5Lx8{aOK)>)%9^f~Vk7SC;b7uhJ*djL590#EOEsL=dQ_6J7)5#_qN>mmNK_vXYKew^mgZ)i)aX381!mPAH+0t-$N)Vvh7s33rALgfR4b65w(O}m) zT)WQvH;;dS5N$CP09K$Swxbpoko96tC=P+A5!JLtrMIQkK^Ov0Cv3sA#1BqSybpnA zkiZ!ef#_Q^mGXDisGA*XX5xLkGz$`un^i1v2t1n-dHuM=7Ww3#ov`q^U=HM>8s-GR zA~T-8OHzY%$!runwpo}4|xA8oB74QK*+ve1v@p-@P&x?yRsKXB65p} zB`)})N)**o75Nt@4r?og#-?r5KH0Q#-){AltiVJ zv<#s|ss7x?ZpcF2FAEU48%uYwtPrqJP5jNGQOFe&BwDBk6V=}= z(sLVE0%7>oA`PtSe6{dJTp7&%tHmn#J94X1FTPq(EMH@*DP622n#@XCozOnh4<6Rq z-0s#u2C8UH0PHQs(^nDYTNPD(w^&;|>jXS;9R=Sl)&&;gdx~_uGSc#M8`n3!4aB#h z@l~GNXle_)P<@Z?B_SJ`5cn2UQ*R}T)#Q8h#=xsbZzA4JL*C6Qc&Ua}+=qDIqc=w) za(%^8es1Fy!WB)SW{TUAu;kpvt&oqJ-5LPL;^OHWjw;Lh_O`~-Pb}L7EYubE?d^r! zAwi;u1&FQvt5-gRunB}MeRmtT~B+p zcSjl(vi{OLz<GVf7qEm|aIY8d<1^V*s#Dil=W;>M3i{V?}wKQ8q1( znx62vj>m(V9^?dZY)<=rwK@GqL|j8Dy%k&-v=?JwEsg+hUuqC!s#Y~tv=+GA!CM|f$;upR>2uU z1Qxq9nWK&4!&?W98rHHxa&#Um)}00PkmFj0T)ewGn}7DE@q zF4JAYw}|{!BbQT&+wwj1u=iQlw+UCdta-c8<8&%Xrl&P@L%GramaXiIT+zG(?CODj z?;64uj@UbqAGy0EyrZcH+HV`zy6@0I*k!?58rnX(Vc@Xlwl<^(<9Acsn-`zPWz*HR zMt3)ulfK!s2}E?|&IC$t965UJL9GLEN9oWJdvSY5reJ<%eUFSQc5+`5cP|YX``;OV zA9&FV?gzlit~7Pj;u5iLtOxK2tOrH%kdXu}*tGrsti+95wc4p@8#~wP+{4i2d&eWv zTiH7v6?&Xb7Rm~Fj6#-W7kC_hl`LvMfovR!ECIImW<9eOtJh}nr-Tj`wu@`pT$642 zzv8|F&Wa-We*r;6vSLQo2q-LqIiLb!0uh1LHQ>6i58jTO?6)hRjyZtw+%@NThV$^w z9L}86d6?rFFo)AKo@e@hzu%so@ZOup;*Y<_XPKVvuBxu;uBxfm-P1F7W~P}(x0$Da zfN5qva_hDg|9ArDeVcO>ka0{N!}(b7<&D=G>Y8yGP5 zmQd0edmHs&j0Zy{DVlds1LodEf~jATvCNSd%Up06?0W)v--5WoP4<(Ur~g1e>Fj)n zda%Q>PU`kYr~o$~Bk|2AqGGvWMI!d*5^tlmkP)6wa+tp-d)zzwtIblpu`MmoIshcqV8uz~WhMc)W zNxxM_oo>D(XyJr0g(Ic!ndVIx{|9C0`X7*BGcT_0>B*+h_1O4WV#4@Gq5Tv?OPal# zF#cH(>6-D2>iHb|RTRrGyGjG)Ne#hKq3)#5(86*R}b~qr6qUzPexJk%8p-r2SBmjO5s9B;TLuLWMiU#4{_Q9z(G*65kBK)#)bLk#6Q4 zPP&R9SGACuEt}L7yn?{6r?n9u5LgYhk-7xWM!j#gy6{S<%Nj(rXKEGFT@#gHb}b~B zJr=1pFKCQ>$&CfSQy7MyvGc^QRSJjKP zHX9LGj|4_D{8%4%MZ%8_P>dszg`5aKf~FOI3|940gdanIfbfG!Jp33+IxhU!2pQ~t zW)YNAjJA7ZCwh{*@MD;O5Pl42_2?4eM+E>doFkB6avRrV_%SlTSNOpuQ^Su@s0_o8 zO_9NzHH(UcACx3w+JzsR3%o!t!|-DZViklRTcQ*KY=s2#+9F|xg*@12>KgW$x{W}# zwID@;1z1axF&BPpCzN!?Mx!2#6$wAKM-7-R>2Z_457+&h~>*Ov}GxB!cN&@r^6$-B^FKS88x#r~>i=y8B3PPY`7 zCiEaHd7;OFqEgUm6naz(AQ^fbgfetU4HA5+P5}9#2YC!akC_6i4Zx5rA@s-q1Y=7I z@z7%y2`r1yV>StQAoQS;VZz7-8vUsrS(Y)-sKbqKJY4C^#WED_VCAi%)$4wd$L5lO zMgvNcfd;#XNJt;NE7n{4I{{$g{&HhzQ@}{CR0AA2HOD| z%QO7hkCVj0Gte`i?Y-+4>q^cL|`yvS% zN0CMi!C1_pY%5kb*ig4w4ARt^}5)W5SARQO3oQRBXPGS*M zT#UARWG8y^yKrT`fDo=MV0BH2aOGqGU{Fs%f@ywSli|u~0lvZ&Hklf(oQ}#cTsZ?7 zoI=c^V&MuUiI{fb%9#Q$(B3dyX(LuaxYCYN2yhk>oQWY4c38-ReGUiV$~gi#*MbxY zE?`qh#$32^o>0;mJ0JC6tVpWAF)uE8L?1Qdip;hbrH)AxX0dXT&+6?n+ugupPL&AS{SiVI8yox z)4Yh~uP8&;--N_BH{xu5|V05}c(Wfc%JsJO&ZVeFD2b07J5bh~)u*U~EYt z9bCv*Zm@o%_Sq2 zCs2}%SlC4*|0L5A5zAAkN5?;n#5d32>NJt;NE7oSmcI+~SqoXUBb`bVvAEC0me0x7 z)o03E%sj5+=rB|l!XUQE4`BWQVi=x4mxAY}0+>Z=ri3m%N7RMOhK=Vz3tjO75^VHV z%WYo38>N;@jKwoA3GihL7>{T6L#HgGiI?3P53Q-MtKB1$%hk-z*s$gmwCKW`SJirI zSo4~y7whfLVx(RtsacF}-oRav=;lonPD{2>zGe1vNG9u#gA) z%nqWPuLSb71t}7Xz~GXMx#;E_p`FHmk+IB?7t34_-TWYs z|5^|?xJh4ShL6B31%|OvITVhRdNR!ma(bZ*UEdoCrucDn{mQ1$^`(QHzC!C4LrWUJ3v&7kB3(aL zQayv5l|^xYrMNUf4q3?ya#j(Qf>xs-XH@|tgPhe+h7MUBiEq{rKz@)z9)lofO@XZy zfMMj85abL5B*vB$;z7>ZB(N-koIxbqfgne&I+~VQm+DbYTn0Jo;0EVllP7p}u?%}y zPkF0o>+61z$L5kj&ITw+2082^lHZVNi6Cb%>e2B-koaaOu1*uljx;eZ$k|Ac8(T8suY$bZ}5QCg3yx3Y*CButwozrXsV1yP- z;-SU1q~St~?U3=!Xcpml-5r+YBrw~f5F34 zGY;2eoUv1YuQ-EErp6iLQ5nV=J0pX&1r~wt#OH@8QpB)}F?JPbfwqM)#%{z)e13R$ zlz{OGNPII<=ypulwtZX%@x>kjnPfqVL<8u>BvUTF*i$I!Oie~Tm?{!q?1dUIHwB4r zrizSZj=Wgrg7{*ZKq@VW7Yu5W9T#8hEueIE_CY<^NoWc87lV;~kzjYd2v|ngu4N<$ zD)tx10WlEEMLejO&f1Oz6$b)TK}EIb9u(4r6Ri=M-#@5e?=q;MsC33Nkh-8^Chl=I zH?G#>g3XLF>TffPpoKvNg(IceO!I<@EXvUJbx1J1kE?U#YzkdpI;c2UX!S9)q@}x{ zqCpVpO3|o#1{F=B*la0kFJ|60lcpISz5;R(I*5(ug%O7cub`bMj4%R7h7mcGp$l4& zU=zLo^1}#n6@(Fo3T#dQ)+ZK51e}?{vO(EC^dMK+HdMp7LJ6=axE zsIUmkbq-MoBVMU^kHbF-)z?v+SE= zQG)I~4vBA$$JJ>R8IVTh1qUYx@gqAHJCky`%qMQr@=)+TxVAVj)wRwSj z>@N94oo#=bKu)(HiaV@XgmK3is!EMJ{-A1mIP%nKV|E!|jq8+Ye+D6E0>4NQ(uQJuiBQC?E05Sx5OS8PN(Ld^4-htI&ISSk5hn3KUxkO)vj|eH2&t07Q0hn+_Z+@L@C8a5 z#wu45%N}D8BWJEcF(kVh3BEum8g~51g?$wFv%6ES5y-U`L@z6pk1pQ?otxyx#ZK1= zFrA<4Q4fCj&K~KQKOqlBZa{*y0wG&Q*sd5s^zH3ud08l^8)Hz(5q8g^zX&3giRf*D zzlz{ZF@ll)>ScnPRh4R1x2Srtw#?h^-Dk{h({`J*OGgZ=FAeKfP$*(px1rcKw~KsH z!@5INOJP`d0s)4_ByL!Dk&ZL0yOHtD-&h0{p~uz?TGy*UFJfJ>PeX&3uMZi1j%V94I3acI?PQ z!lJ$q$d?wxS=6WkcAQ21TY%~8e1-bRqDGmokq0B+Ai;UwLbi;s-F%DsPEg;+ppwJu zEb2dkNM$0js2@b|zcGS&7WJd5QZ4EyRmUxA;+|u6>d5n|7cJ^%pck>IUr>yN0?{sN zQDuXuB1>UWoqzy~ViLEg&ZOfkstYnW+J!~MEsCOH+{s;}hR&k83J(_54L8|dB`j)r z0AR$sBf(rhu1SmP5#Xm;6uBs6Q7ZyJw5XnHq!)`478Qs>kt0!@MfDbVs`i*Z#EM%K zshPegg;@QN_@=)|*s&uI35!}uAS+uCXHlD?XOrwWiy9!nbaqxjePmIanpKepBda0t z&FVt7jIiB&i&{faYsR3G!|N<+EkUF*5n0qg5nMY)Fwdd}sVdc?%2jO-%Cr8eax(k3 zgJIylG^=$$qlj6pi(<_4tAV0swZ5vB!mKs`0?dj@+^jYv9cNa9k@3wC7C{C1>6yF- zRVW`cfGkD|>1=DLkYQUJv3lPUwzV+;F!sZc_+~h+N!zLj@MT-2SSe*-BS0iHuuas` zNESgl&g|q38iZmGL_#?$8zr1njWU}OYhf{xW;0Yl%FU7BjCIkm<4JB3rnaR(wz443 z)HW;N$(h>L0!-&=8`MXpwwc)$c`&ja63pcb*)qa*^G$7gLG2KON{+TOwH*bK%0y&p zV?=Olj9{LrjZ;;ssqLid_`_?bJtvLt$ir(#TG@D@7qPOPQH%uw(JpFbyQ*p_tZX+R zz{;4!t!#JFaaJ|~87vmCsQAN+qG8<0U8IZ7!1fRx3~UmscPwFGdjbF>J{bw#AHX$f zU{eD8w1*eDC}mqyfgjq|G&NGmqQt{15QQQ~qByhKTi~hMWA-6d{NY7vrV6DHYhNT- zOb`h>cH|*pQTq$z01M(QYIF2#k{xGJ(*>B$&Vi_pENXL8jXW4R2nkjbglrjMyZIJ1 zLr^ngP|4wS7F8>VR3;*e%81~s7{NS?nyso-i^{5can%U;L42*eiKo}6+EcED-*^p= zcx|Ok)qy|}oAOYM7Y9VWs7=+YDrQrr0VQ_&J2?LDis{*(wExz&+kmgm;$(_Og8kw# ziQ85a={ehKMh0&Zun2m%Mf?dC2#He{hGEvZKEn@?4=ZmrO|vl-Y-iNWJb3h^ zrbbMDwtEx=I@<*^P_a2gBhoOx9IIPPm|qJ3pdPJAaOOI$N%NZ%;LH5@FbW^FmQgbo z0Hy429_quT&cl$wY3wY*V_(#|bo@o8wUrZn%6B^vek-0W&8e!ESz`TV~j{ zWoDS2HJmSy1u>9hkGS(?PZmTv52vu+oiBT;h@NJN>OdE06b~yny(pD-k6dsiC2KpjetZ=`wSIiH=>9RJ3jwbY zncsi?n0|rl#}t)%buCi2etaG7@lF7)R-3@)pOn!!m>UQ>4eC^ry>vP~E)P3u_b41G z{h4Xr`td@PVGwRa;+wzV>eQ4?*+D3AOu=7;c2f*3=~dlR?`A>dD@$~)?JcV3`thxz zc$=lDhgYQ@Ua^%#ewMs3IAmu;{yJiXxgEF=nylfZ+r6QG%Xk^FB5+i9u!Uer@lG*Z zAYim`eHVcj{w9I$1}cW=Z%BM|j~Z(80x8*D7$q1;aNO;^g1XN_$=}$HpnShgYHIR`zGnpa_Ye{-KdVf7%l|;VJMMOo z(4UK=Kc9lmmdN-EtapclzKD!(UJ^xZ5SPsm z_YKy&!$IFf2HVtyVs~`8hXVWmEtMCNVyh(eHq*Rk$vY@R@4t%#yU=lUz0am>@8=(Q z`<_L4Unn2MP}oke8{Acsc5M&vokGvBI7(P^9jIWTP?f> z6UzOawTF#G5WrqM_GzC;$?^KT?LY8+SB zJ)~~CC+)D?uZ8nX3@7NH*pZ;$q88-86X^HFKnK9jX-{Uj-y#Ts&3`QJ55oPg#jQ#O z4>}3IL+IKp=SO1tA0B3JB+$(tMd&9>$Qty|$`p2%)9YVQFTMU%xMk(8f6&pLlqtkz zGwkTjtap0d1sTi>3#CoxkQBrg9K5b6G}%09c0)Y|j|T)7;G5-9iN5ZR1arc;x}jv_ z#WlT$MOjfOJ!2?rFwpc~s_Y$Bg3Uh6q-(ljxz@&+Ixeg)V3%6moxJ^k?9{zK?r~f= zn})iREPHHaN<)|l-Bvxg|kKsC+Mk|&aa7D zkY7un1B-!fRE7g5f}eHevjVotTXUIOzG7uE%}u5y`~g^D*0ux(iD0=UShaLCU>%mx z0_*75VYln3?R9P2dOGWwd6s8miSXpq^#qYW99K=~?oP*Cp8)O=yMd@~XsPO_l&Pu1 zfrK2`!9^*xd+VT_13QGN{WUm6NabcIiqP>JA;IY{xVmv=J9b=?587dZ9Bv`2HYfuW z&n`?HMK(;QB~~O}xUB#Nc^o0kd}$*dHz6D!iz9L4n^6L9^Mu~+v32|kjz?pg3L>8% zyAKj?M)-wG!RF>bK!0q3#5Y@tbl5mKLYLTHS<(rrTZzKfmI6mVd4lRTs)%uIwq;2b zjeL;10*aDBq?p zOWPw(2-7oUkl&mf|VRaJn$<3DR2om3useSW2&c2z9a%k9INO1TIuFm4f zgmf#|av4~vJ4kh^#hWI)N{g2`X?1Uu1$`UMEbb%lDhn&`316O-0{0LpzcU5&L>jYVUV-N~zLtla5;==$+y zC{ANdZZr+HmzK|}X{f88S78nWxlpS+{Od3-T>6=;aVS&GhJs&*2T6uPn{fi08Uim| zRx-{2HK@}}B-m_@D>XO}oSiC%rQN3)fy}ZXF;xh6pUzfQswQMry;#n4KaNR}H(uhs zGBn#mQ_DarHnogmOf8G1oe8pvNp7_1v|d%QspZ01<*sFAWqRwzGyoXW$xPzY$&IAp zrjwhH@l7*}Fr7T8tgMVu3?a*-HyKvWDdf?E2M;UfL}_bo^d_1&26Qy*>XvN|5e>{6 z8&>xS=ZzU?hg)&uU14$n#3;2O!M1f=lk>-iqJ(rbf4p3o<;=`MsV0q!9mqNtmEnx> zJY;-x7>giUx3ZvH%Ax#}I+DQ68y_yv0woP+1&$zA;^i10C6M4qB)&OH=yurHwv@~r z#Co(qjrplXVG3rr&lltc7E;ftz`)r4g(}V$Bx?U6)T907%gV|EEORl6 zz`!L)aMC-jjsZ4QjDgDpdAWtuT)8uBa&U#p(>b^j_27U%%N&}y3T0s7Y9!chjjLmU zO~qM=&0$|7;A>;Rc4*^s*w?YPV{_Qo15|U^e-hmrLb?#?&myy|=dk(QFFa~DZpf9v zk-Ib=&bv@#D$zouZZ7*q++)faSKDV`_pi!m1k6nYEu71ykfd}o)4aLtTTq6ZpiuLY3*E)=;6<|G~z*h2wWpR(wcYWFVG z!>Ggf5hos;KSGo!I1eAX_E_C+Ae8zp)T1P|dV)>Fz`#d=!zi##$SV@B9+BZg;Ck__D0LDaUtGfliD^(;!z(f>e# z-PgD}T_Xe1wY;~ao)hHr7E+-`_?8sb-kTcv8g)(Z5;aY!!n^=j^u1M$s{PA4wvZ7w z!;Xcj75nkg^degeRPQBmSwi(*Ch)=zN%0Cm(NV7=!Hl*Dw|RkR>=X1Aw2=q*zAlhA zEQo^9K=hij|F5D~jGH)q%oOt`8b$}a%}2pM#YAe@`#cMl$2L|Z`ky@;f8}a- zM!##;Zr0y9R}BA!25YXM*(k- zG8^z(ChRteIRGep)#_g;4Yw(MfsAjyWDz8xThj1A2+9}<;o`S{3$j4b!uUCC1knb&s+nmJLtCF0!==(ncOy}eW)Ps}d%7WLc z{);>q`4Ne4e!|uHAGRw-Vy{>IET~^%Q19SA>JIm4`&AI>Oq8tyEI!#f;l?+eab-Vm zT!yWd`h|p}4r=RW!k_V!t1Qlj;K2~Ii1NA|K9iEcp$IrBybH;+d*li{1nR9fGnW&^ z0tTXIURRLiBhg;Eue+2XrO4X&7!~+IUy)xB!qKCg9KTi`k^Z-Czf?ZB4pM<0c2Pg33ieT z+m01mPPn4=1+sw!aV~@}q9r+Tu4qF6rgJhF^^q$YX@(#VMusB6w@`&_8DYEmu4rRH z4U0h~$JDu^;etqKq5}1DMI%IT6HBn8j$u|!Ykdn{(MXbM_sA87Bv5a;qEVt)z(C}R zHYHAnT~XNLWXt#h)(iMq` zQm$xspoOkzf@n`PAX9!xuQ{KZ{)$qK1h61C1lG8+s$`H`wD8m7*ujh zoh#a35a~=DfO@&2=^}WbC0I4OWK@LHp%4<);P6j<+N~~^YmJ=*%8;qTRFiPKM?Nt~ zfx^o<9i%o2Sc;re4RIDO10H685PEbb609Yt*)}g=jPmBYtBe3=S-_aPidGaPXl%lV>}(j_y(>>+a8IS(&PLOsw!!W z{Aq6|?al-+43SCP5Zg$@8Dcv!Sm9t1l(!dfW5Ns>YR*OtRD+B`k-Kz45}hh@j?iF_ z=d!wc2kh}Y0Al3NN8+0ca826dg#n#}JqA5%E<&Y@ve*LO#i$Gy_%1;P%N{HWEYhAf z2tg=sB#6`T%LJOLJLYm?B^LOuKnVo75(z$aD|96WVbhkEv7N-r%>ub424V*tb&4ajF!dT0|J%#`lzHg`CF8iRyBsOFAkkB5E zp(UNebfA*SM+A|sACIb@Q)Z9h4qM-qFSQtCo&X4Xi5$R&XLLdmOv^thI@=CAW@A4T$VV1LzbUM7R2}@gbVo%~W3{Gl%*SBCO@@3Tc2Xm! zPgT8Guc$iwQom$^u8%JkH8Y0#40MXbP@kh1FDa-I`(z3HMZluss4rAqGLA|v7JUf> z#8OP+vDCjw$Hh`#A>*5`S%k1-ki@E*g+sl z9tpHzCo9m;0xqzR@OREH#InyON6Y+*GKf^RE?et_t8*f3UwY3sy7ud&2%)o}y2PN8 zJ?kDt%LyW#k*=uMG(|TNT;3A2Yna$Xk4^J)vYAG$*x>!ux|tbloovBTt(>Khdy)-Q znC_(0?vX9@Mxbw+l~_R}3pj|LPd$iZT?O~;ceu$FfrtL;iNrU()CxY9OJeOFrEy*6 ze)jYhU>^$@cNh)7o5R36=PgYpWBQWIVE(k97)o^+{Z+lVYAdUD0fnV>8q?@BRsy9W zPGe;hV{t{zB%DUTq@2bos$L4Gu__SYG?>Jl#%iSFoW|r5wjPAmJRxx@u-UTqz(| zuVL(wP?SFs%DIm91zun;q3hUySoS^0h??0Dr4Vc|5}f5D5_T}jgR=zZJcbHtqZm}O zf1UH#SPumq*5OR!`u1J_{xHC9|WpuXoXYsB$-7M% zZ?*&j&Y^52W>Ou>)~a4ywHX++*h}e5s_0C%0hJ=oWLp&bW;->Ja3%qRawelyy%f%5 zdmzA>Fo`>p9Z1JHlO2)q%@`KJ*81l;6Duh6iVQ-p^0uvv6&f7LI96A6z>(|(KfmQk9)-IP06lDw>pFolub6hWr*G8OgU zg)?^|WTv42tW+ZL&ECSctgvOV68k~EkD#hzP|5Lij%;5+q;s(!>gCAx7r_H8L7j!h zM^braZgZWn8}eH0w^J+3bmFvoWC24E=(ilzfkH26Epk-V#93IH{6T<0Khz+>*NH{3 z%?sKjm-&uprT}X#V9XJPle!sIrMiV#s$N{RDMq5TxwfVylQfL}Z&ai7pYO3o)VBIBDT z7Qu4X1agdX9M~W!gKyIeHO+v-fRb4ZXcsDQG~auOh`>V_R&Un<50L{P2CxMQ)?aW< zdWb^H%WzEb1Oer@p7xkf=n1>8r?O;*hCM*?*#D0iGa&F>qfflG~=q8RJmUR;W zKR!wz(ve8;YKPG6aI$UdCWhIcCr1n9m>5WshY^8$I93qpJRFC5_nyM>qIrU)sV)D( z(9zGFSd>t^M@Beja}rZK2NqzN`6z-k3y}EcWL(j2G8{GpX~H)Z__J%QmFpA%pBe+U za>XZRPh)MzCT33us3vC55Zyn7bRp51BJ;nSn5FV@VwNJa2iuUkiP?7CW9bA}+h<_+ zY-Kc(<{W}fLysjVW+@~ooy# zp?_yhTwE)t>nxPa&2|qhXaGQH%-5^7fZxzF{R#E%B$^v=k5^iRLGuOr!lLNy9-F5A z-N<_Pn*3jo!8;~G3Gi=HCcpW1k4+K(W~K!v(cFSk^un!3@SX{-PJ`Kk)!+>}^Um84 z2~_NMl>6omTtg$eQa)SDY$HgT;I!jcVxzW$oS@dq1cK4m@j=m z#f4n3QBr!4Y0{TIgdzz4FcK_(;Oc~DLst0wgJ2%DD31x{@fZr52^JonQ00?hB?k8? zX2K8ZV<39fpJEHB0ezQGCNv)TYa&A@U~h zg3iWP1-dRP>Zr~XnkQ*&syn+O8$SZVzw8;Xrhft*hZx}+^j7j1g|}4^8yWKsOEl}0 ze~f~@S(r2L0w8;m4p3Ok+hL4sCv4yjPeNKeXWRiy_Frv16 z#>}FsGfU^0f02-WF_c_`n}n}*yY;vAspel0kLzz=;s#&f#g$ef_FyGnDKCl5*ScTi zu_^tw4US9r2KnUb8-*wFZ<*S#G#IGwPy&Vi9tqY0aCP>==A}f%4@&sK;{8{6KU%!R zK?y&hEa=Z@_sq`%|HXpq0TzsCcu>Nxs!RQ)Rkj{ET&$me;jRTMN_0d5Cm)OJC4Xmi z0tsoOJ1YSGl2J=%l>4TO8fdGk0FC79WI4W1HkqH~#Qc4@uGo@kXs*W(J}fLQ2h>nU zt9A#0jw~!%=F^uHZM};|x{AF*g?F-;Ze(KNZ()CVU_ukRBf%+6YNyQ$WMbby8SFsP zWAqTziWZ6kne-SvRS{#;^kRvIEq`Ph>=P$vdIKbTihM>N-cHac4R=1HuV~U|^urxa z;aA?yeOps@ltQnu63MiCWH#(D~_kW?Qep5a8)l>R1tQh6DIN~s}=Dm4vIdd0%VH$ zlo2TR%_eH3t!f;o>=DFQI7vir+)COjCp61Q|Z=OjGOZtV(b) zXXVtfc*O$rLba}%)Imq%_)T{;4#JFL1Htc~O~rhnv4kFHGXgJMX2NX_a!{Zxkl<`6 zHIBDA*aqI_Kq5D!O$=KJWNQl&8~hHRLF43Ia*tF5!)CT2Bf;Y1wrV+5wYF3BVtocY zKrgn-(=jnLyAw5OG_a^i?)MrVPT#_Ow@0yWb`VKB(P9cbp%>))s0!F($ z#{d{}fJ|b|nX#nd<^abbvR~YUXssa9naH5t zO^D7C&DoY_6*ujKD$O6G*`lP{J+i__UmeqhNj&4B5E31X#5eW0x@R97gG9w9MH>X% z7z4Jl#V19ZSlh8l(Pn^ZQuGkfH6dNdloOd{Jt@jbgTkXroL6(lmQZ;(9YAr}e=SJe zglH@7ao#_!w!gsY9Az|;W-dVsCqyYADa~V=Hz9f$$}kXzBk|1cJEEIN=qv6U{&#FM#AG z)e}&LE;tbh&iofZ{w7s&70eaQ7ubRTtk@>ilTnB9BThWbJ%uPym>WJ`I&f^ssU)@J zFxUE>C+*R)?uaX=Ugk6qVX&(sOHL<62D@kA#y5Y!6$9^ybtu)D%3Gys)BPfkOeD9i zwxc8&?y_^JX=gFD{yzAy^VujtC!d4FH|OH&^o$Hh&+@jeo+rrjEu>CL4S!>DQ&=EY z6a&`O*WlDOMS>OP0-#|C0u2cs{8}`yk3@nIu2@<>(p*GsQfD1|@ zCv9hv6p&pez{@RQEFj}j<=gbCSEwpAV!Be*_T8Ag$;Z->(>O*>R{^_7Y$454lcXeflDiRW=;ZU#VVD0K@e!%*s0WH3+9 zqWn;b!bgI*Q0jJp7AR;KO5H)ML@0G9N+8T#NPKg*(Cz54Z7H4$rT!+6dn`yw(1RXM zGUh_5dxe(H*nOx6V=1B3{ip?#4Rv0(mM1lI$NBQavq*bY`AGy$h-SE}G9; zn#s^e^ZP|fwR>cR?sXB<{E+H76hflskzhI>SLb2b7$hndQoShPmtw$Hws=VOGHW{) zQoRCDg;cMK?rR}kIJDPA=6@4XQHdB*QC#-l8%SM9^(O9d<`S;9zrgBS%4j6b+XO8P zsVE>Ry~8vwqLD4eDfZzZXno{9f%Sk)%!yGAcmH7crK*+P!Q?r_L1rtQhh9n zpIC||LMrnqK+sF%ATO@^OvnX|MRC>V0!YSH|3Vr1;R_@<7D)j4aTQq$;;MfO?5hB* zSX}ir>cAdx;&IhCMEPxT)wd+ofw)Re=t<8-Q2jab-w~G))c3f-dH}gV1SKY+Lq8~Q zb?CpkU*xg5WCZmiN|F&2yMg3?Vw#Acenttp^A{xeCN8c{t;m4XDldX6Tc41fa0O)5 zws?%CM^M2odn{#|OnuEf?nJ9;%<*J6I|p51I)hHA990K`T1TerUG&+3d82#}-GvPX zas6@pA-~jOzs&MZ&n=D8~04)PQ}aMXV`|>#M4gVO;XnoPIz+ zD90oo%JnB57s{=K3_j(+B4`_5&BTQfh>Y#%R#b05{ev2;)0U31z4b~ zVE{LXSi!Np{N!Xg@{na6B)(Z!$ad7&t`yE~id|12>st_aehK%)CK+*&?UR~@?c~L65k9JvSozrijmls*o_3WaSSRsuI@24Oc1F|MC%j7MX(}9Fw$E6 zA{wEpRD;??)pld)l<^bC>>Jx|-Vux1o)$F{M2c9{C=~l}p$9Z@&b)+73Wafze2C z?h&p@yV@b3A-hUtsFY#t2nwNLjZrgWSp)$&AtHew3q_A)ah5eskg2+4b|RMD?99`JqGFj$3-U&hb!DLe0B7w^n8 zwCCnDD%EzX1@Eou#Z?v* z;}I({fpIWOAVxhB-!ur_4j9|EX1a#m7u_h3CJT}>)quWDGUg^QnuV6m*deF~V<{6D z2DM-^hr~B6B4wE*PnOAG0;5$RhguMiJzc<(^JsGfl+MyzBHJJO(b&yHAvie<3BJlJ z3YHT#Y&i+0E{+h09|KADjGMYRQV{8E9EEx}b#b(49%E@1PF);ZlvKM%R`|Q-IHvhi z7ssOz5}kkqTkLU#swt*sW00uW)Wt~xo*x6Yvc;z^7O=KsQx_)#R8tqHi0-K&UHq0i zO=SKzQx{YpPF+x3_TTA9-PFYyxX0W*uC~9x>Y2)DBuyJZ3#Tq9AStyo&6~P73uPFH zvyu4b99-Q%uqitbC8jRU720_*w4{@B53chCk*;nRsGd_77mDIVmSTyi3v>`0hck+= z23;(?f_9==i%SHMoVBc|)WuljO-V8N_053gn*_#A8nvu;gN~ zw*-{V(%VF~uj9l9?;Vtam3NWg)5IcSSz*hTl^_^E>K8)=3cQ>egBH z492?P4&Ohv6iWnSrYk_uOXMIgBI_pPg2tkVY07e-bDFr5m_IS>Oe#${}V-I+IHTTxQxj9;Rajv$ps=ZF$o=7 zNqMV7E9-ud$L5j|*#MLzBQkaa6>AlyiHK}fl%P9TLxQ<;T%B5x0jX79M7D+?*R+s2 zvMG$n%JVkj)Ra$b!q+#Z)HKe{;96VPRAJTvVx$ehb6-K(K#?q=4QmtC9@(^1O%4Jc zL@Y<*n|0Jmn-}mwY2=q}T!yRO>snW^>seTaX34iS)>lQ0RkHy~vM1EweF(E5Z&zgW zGhuW03dUd|@D+?9xWjz9^7bI+sjV}b@%7xA*_oW#h`8+@n-7#xAG+OG;Ia0C_bx*E z!-!zd{*03wj$%k&fdrp67LhhDXoHMM@|m?wGx?F^Tt#D3Z6?=aW>Z6RQ)^>w53>nC z!173;kFw~BQzQN=yE|~RDFC=#VKV_*9o-!Fm3>;8X1172X80Ua)7+dfW($wnWv;TywUrac)ITZLQ@f!0%zULM<5D8i{YV!PO}%S+pHixqJX^wq+Uk*^Y3P z-5XmQW@PZq7c(0931yYN>KbR(x7KE|b+xsbMzcLi7hs$puk6uM*Mc(k4O=Y*B$??c7sO%Z= zF{=)Znw?QL-Ry#^N0ge%?hQ3_YctJwn_*YvcmEats99UWnqzuf!x@sw74dRpV-6pk zZ9pgQ2JlIhy=FBvwKO)hWN-r1ten{$h4_*%u9e+Uz^@nP%tRIL!NR_|c?~m~>Z=`A z&P+lvz81{Nel@KvO|Hh$o2=TsSi5o_ss)%LfT;vnVP;+M&W4$$(n?%8?v*`*ci5}z z>+tojy-_@=vVSN`wOg+-`v{F+cqRAzq&no>SK!_2YOC>nylFA}AwQv0Wv@81IkUe| z4Ia7n|kjQHA-brIi z2KKUdO?@lu$IL)|lbMMtj;SYXW&g0(X28-R<-s|VK@Ip^3GFqR+G>n3Xk;2^)?q|u zp>9%TPcv&~HQ)8GZZ-90Hp(j3%(k>NZ!=;X|bKtF#wv2Q4}l>q)RH)pwq0 z;C-)pxbjwbDj?$h=0=uvhVeAf-z`lHqFSBe~nRfJxrk99D=e57;8wHLqF>6 z9b*L8BU@A75`g6h*0r)%z+Zh$4quNqEriSdX;S4{81W`k4N;nEF&Nc0o7FL<#(LqJP!@Ns&CF<>ZRU_tW#0^(0X1eGj4qqOAv1GPzMyhoQ)^3eYfBpa zc_h@0tihoj#!Rmq)CI1kdM?e*9F8&!YMb;CEKW*RGq^kD`QRo(1OY?nZ`rSi6UkNZ_Z^}YawMry*Ww6eX)V033^-yLotmt z^*J+N<^9=vxz-u-xIwQh5X}{HO|52Th92QybFzSY(;Q-oe2Pl@sMYJ*Tb~F1j5h6S`OSPAaK6i-27#r|k@u&gT8{)s`o74s*jw%=JKHawEcL ziGhloOO!tFPA!?aEi_<^M2k5OrSmISn4N(Gt>NIFkAg{+y`_jzw_l*rp1B5i%IZT} z@m$E63sHv05cMr|HW#6+a!}xG=FFLc4LdE_rbam%oX9x>z_}6TVnX4Ofp_udR%h#G zXY295#azPTAB0f;mmEl9+TGDQvQ8^(0v1gw`*Ac0#vP)fU&RmasY-`4KNVc2TjHS2i z^4=pj7%JP{9*@6*_gWX^de{$6pJ2nkp59YkQP|7tG6+d;?{mDomF?@@y*9e*{Iw7z z<%Mnbk=4W8fOZfg{aKAJRHJqZ;%p!xM#2l8mEA0`xe?V2k^Ukuglw4K`YZ0$03)=@ zu5~$V`I?`-WO@*Cy0;e*DEIfy1vA;(yr9XOfa#l?MN3U)Z?f%quAN(A?c9p{>}^YI zWF_xW3VxD3!C+;t5pTg|2Y3q+V`ckzpW^+}?5f@z{IJWe<}JYc!P(Wl516ds-N9r{ zZ)NuPTHegANCtYn@WqAf+TPvRu8a!!f*_gV@ zp6I>Q6Uj)g6W>u8<#nSBn|Z5~^yc1Nin)b1mh5ig?Zy@spaZw^4klY$dyFcx+jy6t zO|Lh%DFwZL8~V{Vx8v%9VLPYFfet(V4prL$z7zMNu*AOK)BA{xZfB43Iu*ZxMtd6# zM9KDcBg78g#pHHJZvs_xjJGX&e5`j9c^_x@jqhaN#2fF`Qp0!lUdKmYvb%Usv*&j8 z-o|dM?8%-qb9ehS%8A~}q_T&1C?V&2`X0x&-oKVZZnAd;`*AOCFZR_G?``yq#{)B5 zU)-g>xI5Mt(J2XGU;HiB7x%C)NMVV6G1Y#pWtz7-ptF_U405@*w-Gtn$GeqdSY=Nm z+}9h-?%2O;H%t0HIY zqI}NVcXi0LU3t_i52{xliuH>9B1=M@ACC3PBkUDYSYofVcq7>XtzI+7=TPr5@;t}8 znLN++Zld|l^R{K-VcyWLNDlX|0<*1^{Sl%dW^KW*WIQVDkETb_tZyE}6>BM1(}_Ng x`ypA`7(Hh<`-sn;8~D!372J=2oOuGE)6J8(R(4}7frrFX$oS@ITw7;U{68EviKzep literal 149781 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ÌyY z<%Z^#QsXRCKv0N%McWUG2Af#TZkcEL5sf{raaP08EzKC_>5rJneRG48jnoVvVz1nc zy&%#+KKBXzl0kgiBKs#L8ce(`ZLL8I8BB_mv2|@{eqJa0FDjzbtc=*xbN%MzVNDuY zw?hztB2znzOMMl^4lK=upVM$;7kr+Q8HzZJWU;wLx@J|xUDjpS1d6AwG?*H@ zAuisvNW4Nzvss%DgHaT2Gg$|bXXMtkY9e3EOO2r#ItvZKM(Jisqob(x5rr;2NJSahfDOpIYgTUcav#9@kToRI zcwNbCh-cpn#~uEo_w^7M%|6~D%!Zc_X~&EE+3hd-d#7VGtT0duI6WR^;1$tPV4gP; zla0m1{&uD0p5LB3SL;%dk32<6jt*J+_`ym?=}W&cxN(L z(|eY|T7|a?YkQB-kzU8U248dw>v}toc0KP4d{Zq9^Y-N#$?JRLSbiILm*E72LXCGn z3wuNFgjEm>_iiA{Ms_~h#@y!X>H-%%0#yGPNUQpqI5=ij}lPp@%wIJw6`e}8slAy;|dBV;cLWLyKDJYUOUCw z+HMlGjrSbcZ0p@bHrsixVC$^H_TK9x+QD0aEOzw1Mls1bw?|Iw8{=; zB;C!Ple4>5!xA3vZA==2CgIIxyV%3qn4I_Yj%9gG@E)cN6YXmIy}bKT3f@n_G_3tC zRQp@TwQq|+qlQrf809p8T0D!xV%xyp-Z`xGeZ0vOXp*-*3w2+6Ox$Gqfqy@{_1OO2 zp{$Q7-i^%CAiFv0RIib_o@N&{9N>M(j7;|~VwoT44Pd#=@V;hi$$8V!y$T0;eHk3= z?ZW!6^KRkWA>L`^d8qd-nH}cMVf`O&&myh23m=d0uA+bq-iaib>21uG(&%l=^k#WQ zCe-A83jw=wLt(t&&2-}TDYS_FaWPsYI0knN?48PfIW{gX4w{w?5_RSJh3;X=Yz5SM Xvo-G8+?>BZx4{d(0O8&>tM>l^97bT* diff --git a/docs/_build/doctrees/pyad2usb.event.doctree b/docs/_build/doctrees/pyad2usb.event.doctree index 2233ef512d8ff166fd4e02d28d7dfa809dc9def5..450e6ded2d3163ba7302bf81570f937ee9e9a581 100644 GIT binary patch delta 446 zcmZ2ev$1A_ER(1a0|SG8aY<=fntpm_iGE^=QE73~W6jdfmYsyZ(sA$B= z1~dhto=eFZiRYu##LEJdODoMw&QPu`Ix+d7km%&EN`f3P(aplj>`arZb#x|ss5*h^ z9jX?SeRVA+JE=K=>1%49qG`BX$()v1G`UmVbaJeM_2l2`GbbA=Dooy}p*Fb)NPpK* zk>yCt=#LNtYIiM5%`5Rp%uC5hEz$$(N-bh#n(QYfF*!(6f*tG{ph?A=)^PTA%_d$> zpvKh1qI6ro{Jhl3j#}E2*_8P}l3IGt;jtu|+ delta 454 zcmdm3v!-T)ER%>K0|SG8Mt*LpesOYsNr`@PeoE?OZ)?TP!Aze-MN+WI{!t6uyjnt> zT_hE|Y}jOd1>?!B>eh^_Cm&Q7o4ie-X>z27!sJjzMMjRvA0_1{Pg7Kx{8&Spapz=z zDapwn6(!hNfJUWd7EKmXvWBz6l$v-sf#Ru&Md`MF`FW|6A1G;~ifk5EW@no0uA?{E zP1OlZZ&9_Fyiqr3vWl7$n4YKRDUy!eoq?=Hsk!-OlLORECnqV`PClSMbFzh^?Bq%f zHAWt=JNIj-Ox^_)`KMvT$p$n8qTXE78i`k_*~ANWeQ92DhH`C@$YcW}F^McbCI*HK zgV-Wb5N#O&Q?c1W3+P}eRUJnC$pyNSllyfvK)lIMbu1>o0XjWj*J*N^n#E>jJu_ZG aL-dH*>}~y-k#XZ>d)soxKa;oHRsjI2OOK8K diff --git a/docs/_build/html/_modules/index.html b/docs/_build/html/_modules/index.html index 5f6a0ea..b4d2a4d 100644 --- a/docs/_build/html/_modules/index.html +++ b/docs/_build/html/_modules/index.html @@ -48,7 +48,9 @@

diff --git a/docs/_build/html/_modules/pyad2usb/messages.html b/docs/_build/html/_modules/pyad2usb/messages.html new file mode 100644 index 0000000..ba68f3c --- /dev/null +++ b/docs/_build/html/_modules/pyad2usb/messages.html @@ -0,0 +1,289 @@ + + + + + + + + pyad2usb.messages — pyad2usb documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for pyad2usb.messages

+"""
+Message representations received from the panel through the AD2USB.
+"""
+
+import re
+
+
[docs]class Message(object): + """ + Represents a message from the alarm panel. + """ + + def __init__(self, data=None): + """ + Constructor + """ + self.ready = False + self.armed_away = False + self.armed_home = False + self.backlight_on = False + self.programming_mode = False + self.beeps = -1 + self.zone_bypassed = False + self.ac_power = False + self.chime_on = False + self.alarm_event_occurred = False + self.alarm_sounding = False + self.battery_low = False + self.entry_delay_off = False + self.fire_alarm = False + self.check_zone = False + self.perimeter_only = False + self.numeric_code = "" + self.text = "" + self.cursor_location = -1 + self.data = "" + self.mask = "" + self.bitfield = "" + self.panel_data = "" + + self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)') + + if data is not None: + self._parse_message(data) + + def _parse_message(self, data): + """ + Parse the message from the device. + """ + m = self._regex.match(data) + + if m is None: + raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) + + self.bitfield, self.numeric_code, self.panel_data, alpha = m.group(1, 2, 3, 4) + self.mask = int(self.panel_data[3:3+8], 16) + + self.data = data + self.ready = not self.bitfield[1:2] == "0" + self.armed_away = not self.bitfield[2:3] == "0" + self.armed_home = not self.bitfield[3:4] == "0" + self.backlight_on = not self.bitfield[4:5] == "0" + self.programming_mode = not self.bitfield[5:6] == "0" + self.beeps = int(self.bitfield[6:7], 16) + self.zone_bypassed = not self.bitfield[7:8] == "0" + self.ac_power = not self.bitfield[8:9] == "0" + self.chime_on = not self.bitfield[9:10] == "0" + self.alarm_event_occurred = not self.bitfield[10:11] == "0" + self.alarm_sounding = not self.bitfield[11:12] == "0" + self.battery_low = not self.bitfield[12:13] == "0" + self.entry_delay_off = not self.bitfield[13:14] == "0" + self.fire_alarm = not self.bitfield[14:15] == "0" + self.check_zone = not self.bitfield[15:16] == "0" + self.perimeter_only = not self.bitfield[16:17] == "0" + # bits 17-20 unused. + self.text = alpha.strip('"') + + if int(self.panel_data[19:21], 16) & 0x01 > 0: + self.cursor_location = int(self.bitfield[21:23], 16) # Alpha character index that the cursor is on. + + def __str__(self): + """ + String conversion operator. + """ + return 'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'.format(hex(self.mask), 1 if self.ready else 0, 1 if self.armed_away else 0, 1 if self.armed_home else 0, self.numeric_code, self.text) +
+
[docs]class ExpanderMessage(object): + """ + Represents a message from a zone or relay expansion module. + """ + + ZONE = 0 + RELAY = 1 + + def __init__(self, data=None): + """ + Constructor + """ + self.type = None + self.address = None + self.channel = None + self.value = None + self.raw = None + + if data is not None: + self._parse_message(data) + + def __str__(self): + """ + String conversion operator. + """ + expander_type = 'UNKWN' + if self.type == ExpanderMessage.ZONE: + expander_type = 'ZONE' + elif self.type == ExpanderMessage.RELAY: + expander_type = 'RELAY' + + return 'exp > [{0: <5}] {1}/{2} -- {3}'.format(expander_type, self.address, self.channel, self.value) + + def _parse_message(self, data): + """ + Parse the raw message from the device. + """ + header, values = data.split(':') + address, channel, value = values.split(',') + + self.raw = data + self.address = address + self.channel = channel + self.value = value + + if header == '!EXP': + self.type = ExpanderMessage.ZONE + elif header == '!REL': + self.type = ExpanderMessage.RELAY +
+
[docs]class RFMessage(object): + """ + Represents a message from an RF receiver. + """ + + def __init__(self, data=None): + """ + Constructor + """ + self.raw = None + self.serial_number = None + self.value = None + + if data is not None: + self._parse_message(data) + + def __str__(self): + """ + String conversion operator. + """ + return 'rf > {0}: {1}'.format(self.serial_number, self.value) + + def _parse_message(self, data): + """ + Parses the raw message from the device. + """ + self.raw = data + + _, values = data.split(':') + self.serial_number, self.value = values.split(',') +
+
[docs]class LRRMessage(object): + """ + Represent a message from a Long Range Radio. + """ + + def __init__(self, data=None): + """ + Constructor + """ + self.raw = None + self._event_data = None + self._partition = None + self._event_type = None + + if data is not None: + self._parse_message(data) + + def __str__(self): + """ + String conversion operator. + """ + return 'lrr > {0} @ {1} -- {2}'.format() + + def _parse_message(self, data): + """ + Parses the raw message from the device. + """ + self.raw = data + + _, values = data.split(':') + self._event_data, self._partition, self._event_type = values.split(',')
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_modules/pyad2usb/zonetracking.html b/docs/_build/html/_modules/pyad2usb/zonetracking.html new file mode 100644 index 0000000..f9e8e3b --- /dev/null +++ b/docs/_build/html/_modules/pyad2usb/zonetracking.html @@ -0,0 +1,368 @@ + + + + + + + + pyad2usb.zonetracking — pyad2usb documentation + + + + + + + + + + + + + + +
+
+
+
+ +

Source code for pyad2usb.zonetracking

+"""
+Provides zone tracking functionality for the AD2USB device family.
+"""
+
+import time
+from .event import event
+from . import messages
+
+
[docs]class Zone(object): + """ + Representation of a panel zone. + """ + + CLEAR = 0 + """Status indicating that the zone is cleared.""" + FAULT = 1 + """Status indicating that the zone is faulted.""" + CHECK = 2 # Wire fault + """Status indicating that there is a wiring issue with the zone.""" + + STATUS = { CLEAR: 'CLEAR', FAULT: 'FAULT', CHECK: 'CHECK' } + + def __init__(self, zone=0, name='', status=CLEAR): + """ + Constructor + + :param zone: The zone number. + :type zone: int + :param name: Human readable zone name. + :type name: str + :param status: Initial zone state. + :type status: int + """ + self.zone = zone + self.name = name + self.status = status + self.timestamp = time.time() + + def __str__(self): + """ + String conversion operator. + """ + return 'Zone {0} {1}'.format(self.zone, self.name) + + def __repr__(self): + """ + Human readable representation operator. + """ + return 'Zone({0}, {1}, ts {2})'.format(self.zone, Zone.STATUS[self.status], self.timestamp) +
+
[docs]class Zonetracker(object): + """ + Handles tracking of zone and their statuses. + """ + + on_fault = event.Event('Called when the device detects a zone fault.') + on_restore = event.Event('Called when the device detects that a fault is restored.') + + EXPIRE = 30 + """Zone expiration timeout.""" + + def __init__(self): + """ + Constructor + """ + self._zones = {} + self._zones_faulted = [] + self._last_zone_fault = 0 + +
[docs] def update(self, message): + """ + Update zone statuses based on the current message. + + :param message: Message to use to update the zone tracking. + :type message: Message or ExpanderMessage + """ + zone = -1 + + if isinstance(message, messages.ExpanderMessage): + if message.type == messages.ExpanderMessage.ZONE: + zone = self._expander_to_zone(int(message.address), int(message.channel)) + + status = Zone.CLEAR + if int(message.value) == 1: + status = Zone.FAULT + elif int(message.value) == 2: + status = Zone.CHECK + + try: + self._update_zone(zone, status=status) + except IndexError: + self._add_zone(zone, status=status) + + else: + # Panel is ready, restore all zones. + if message.ready: + for idx, z in enumerate(self._zones_faulted): + self._update_zone(z, Zone.CLEAR) + + self._last_zone_fault = 0 + + # Process fault + elif "FAULT" in message.text or message.check_zone: + # Apparently this representation can be both base 10 + # or base 16, depending on where the message came + # from. + try: + zone = int(message.numeric_code) + except ValueError: + zone = int(message.numeric_code, 16) + + # Add new zones and clear expired ones. + if zone in self._zones_faulted: + self._update_zone(zone) + self._clear_zones(zone) + else: + status = Zone.FAULT + if message.check_zone: + status = Zone.CHECK + + self._add_zone(zone, status=status) + self._zones_faulted.append(zone) + self._zones_faulted.sort() + + # Save our spot for the next message. + self._last_zone_fault = zone + + self._clear_expired_zones() +
+ def _clear_zones(self, zone): + """ + Clear all expired zones from our status list. + + :param zone: current zone being processed. + :type zone: int + """ + cleared_zones = [] + found_last = found_new = at_end = False + + # First pass: Find our start spot. + it = iter(self._zones_faulted) + try: + while not found_last: + z = it.next() + + if z == self._last_zone_fault: + found_last = True + break + + except StopIteration: + at_end = True + + # Continue until we find our end point and add zones in + # between to our clear list. + try: + while not at_end and not found_new: + z = it.next() + + if z == zone: + found_new = True + break + else: + cleared_zones += [z] + + except StopIteration: + pass + + # Second pass: roll through the list again if we didn't find + # our end point and remove everything until we do. + if not found_new: + it = iter(self._zones_faulted) + + try: + while not found_new: + z = it.next() + + if z == zone: + found_new = True + break + else: + cleared_zones += [z] + + except StopIteration: + pass + + # Actually remove the zones and trigger the restores. + for idx, z in enumerate(cleared_zones): + self._update_zone(z, Zone.CLEAR) + + def _clear_expired_zones(self): + """ + Update zone status for all expired zones. + """ + zones = [] + + for z in self._zones.keys(): + zones += [z] + + for z in zones: + if self._zones[z].status != Zone.CLEAR and self._zone_expired(z): + self._update_zone(z, Zone.CLEAR) + + def _add_zone(self, zone, name='', status=Zone.CLEAR): + """ + Adds a zone to the internal zone list. + + :param zone: The zone number. + :type zone: int + :param name: Human readable zone name. + :type name: str + :param status: The zone status. + :type status: int + """ + if not zone in self._zones: + self._zones[zone] = Zone(zone=zone, name=name, status=status) + + if status != Zone.CLEAR: + self.on_fault(zone) + + def _update_zone(self, zone, status=None): + """ + Updates a zones status. + + :param zone: The zone number. + :type zone: int + :param status: The zone status. + :type status: int + + :raises: IndexError + """ + if not zone in self._zones: + raise IndexError('Zone does not exist and cannot be updated: %d', zone) + + if status is not None: + self._zones[zone].status = status + + self._zones[zone].timestamp = time.time() + + if status == Zone.CLEAR: + if zone in self._zones_faulted: + self._zones_faulted.remove(zone) + + self.on_restore(zone) + + def _zone_expired(self, zone): + """ + Determine if a zone is expired or not. + + :param zone: The zone number. + :type zone: int + + :returns: Whether or not the zone is expired. + """ + if time.time() > self._zones[zone].timestamp + Zonetracker.EXPIRE: + return True + + return False + + def _expander_to_zone(self, address, channel): + """ + Convert an address and channel into a zone number. + + :param address: The expander address + :type address: int + :param channel: The channel + :type channel: int + + :returns: The zone number associated with an address and channel. + """ + + # TODO: This is going to need to be reworked to support the larger + # panels without fixed addressing on the expanders. + + idx = address - 7 # Expanders start at address 7. + + return address + channel + (idx * 7) + 1
+
+ +
+
+
+
+
+ + +
+
+
+
+ + + + \ No newline at end of file diff --git a/docs/_build/html/_sources/pyad2usb.txt b/docs/_build/html/_sources/pyad2usb.txt index 08dfd6b..2e8b746 100644 --- a/docs/_build/html/_sources/pyad2usb.txt +++ b/docs/_build/html/_sources/pyad2usb.txt @@ -1,14 +1,6 @@ pyad2usb Package ================ -:mod:`pyad2usb` Package ------------------------ - -.. automodule:: pyad2usb.__init__ - :members: - :undoc-members: - :show-inheritance: - :mod:`ad2usb` Module -------------------- @@ -33,6 +25,30 @@ pyad2usb Package :undoc-members: :show-inheritance: +:mod:`zonetracking` Module +-------------------------- + +.. automodule:: pyad2usb.zonetracking + :members: + :undoc-members: + :show-inheritance: + +:mod:`panels` Module +-------------------- + +.. automodule:: pyad2usb.panels + :members: + :undoc-members: + :show-inheritance: + +:mod:`messages` Module +---------------------- + +.. automodule:: pyad2usb.messages + :members: + :undoc-members: + :show-inheritance: + Subpackages ----------- diff --git a/docs/_build/html/genindex.html b/docs/_build/html/genindex.html index e28beaf..3a840cb 100644 --- a/docs/_build/html/genindex.html +++ b/docs/_build/html/genindex.html @@ -90,6 +90,12 @@ +
+
BATTERY_TIMEOUT (pyad2usb.ad2usb.AD2USB attribute) +
+ +
+
BAUDRATE (pyad2usb.devices.SerialDevice attribute)
@@ -106,6 +112,20 @@ + - @@ -200,6 +222,16 @@ +
FAULT (pyad2usb.zonetracking.Zone attribute) +
+ + +
fault_zone() (pyad2usb.ad2usb.AD2USB method) +
+ + + -
+
CHECK (pyad2usb.zonetracking.Zone attribute) +
+ + +
CLEAR (pyad2usb.zonetracking.Zone attribute) +
+ + +
clear_zone() (pyad2usb.ad2usb.AD2USB method) +
+ +
+
close() (pyad2usb.ad2usb.AD2USB method)
@@ -131,8 +151,6 @@
CommError
-
create() (pyad2usb.ad2usb.Overseer class method)
@@ -174,7 +192,11 @@
-
ExpanderMessage (class in pyad2usb.ad2usb) +
ExpanderMessage (class in pyad2usb.messages) +
+ + +
EXPIRE (pyad2usb.zonetracking.Zonetracker attribute)
+
find_all() (pyad2usb.ad2usb.Overseer class method)
@@ -213,13 +245,15 @@
-
fire() (pyad2usb.event.event.EventHandler method)
+
FIRE_TIMEOUT (pyad2usb.ad2usb.AD2USB attribute) +
+ +
Firmware (class in pyad2usb.util)
@@ -280,7 +314,7 @@ @@ -290,7 +324,7 @@
-
LRRMessage (class in pyad2usb.ad2usb) +
LRRMessage (class in pyad2usb.messages)
@@ -314,6 +348,10 @@ +
on_arm (pyad2usb.ad2usb.AD2USB attribute) +
+ +
on_attached (pyad2usb.ad2usb.Overseer attribute)
@@ -344,12 +382,32 @@ -
on_message (pyad2usb.ad2usb.AD2USB attribute) +
on_disarm (pyad2usb.ad2usb.AD2USB attribute) +
+ + +
on_fault (pyad2usb.zonetracking.Zonetracker attribute) +
+ + +
on_fire (pyad2usb.ad2usb.AD2USB attribute) +
+ + +
on_low_battery (pyad2usb.ad2usb.AD2USB attribute) +
+ + +
on_lrr_message (pyad2usb.ad2usb.AD2USB attribute)
-
Message (class in pyad2usb.ad2usb) +
Message (class in pyad2usb.messages)
+
on_message (pyad2usb.ad2usb.AD2USB attribute) +
+ +
on_open (pyad2usb.ad2usb.AD2USB attribute)
@@ -360,6 +418,10 @@
+
on_panic (pyad2usb.ad2usb.AD2USB attribute) +
+ +
on_power_changed (pyad2usb.ad2usb.AD2USB attribute)
@@ -374,7 +436,7 @@ -
on_status_changed (pyad2usb.ad2usb.AD2USB attribute) +
on_restore (pyad2usb.zonetracking.Zonetracker attribute)
@@ -388,6 +450,14 @@ +
on_zone_fault (pyad2usb.ad2usb.AD2USB attribute) +
+ + +
on_zone_restore (pyad2usb.ad2usb.AD2USB attribute) +
+ +
open() (pyad2usb.ad2usb.AD2USB method)
@@ -420,31 +490,39 @@
-
pyad2usb.__init__ (module) +
pyad2usb.ad2usb (module)
-
pyad2usb.ad2usb (module) +
pyad2usb.devices (module)
-
pyad2usb.devices (module) +
pyad2usb.event (module) +
+ + +
pyad2usb.event.event (module)
-
pyad2usb.event (module) +
pyad2usb.messages (module)
-
pyad2usb.event.event (module) +
pyad2usb.panels (module)
pyad2usb.util (module)
+ +
pyad2usb.zonetracking (module) +
+
@@ -490,7 +568,7 @@
-
RELAY (pyad2usb.ad2usb.ExpanderMessage attribute) +
RELAY (pyad2usb.messages.ExpanderMessage attribute)
@@ -498,7 +576,7 @@ -
RFMessage (class in pyad2usb.ad2usb) +
RFMessage (class in pyad2usb.messages)
@@ -518,11 +596,11 @@ - +
-
SerialDevice (class in pyad2usb.devices) +
save_config() (pyad2usb.ad2usb.AD2USB method)
-
set_config() (pyad2usb.ad2usb.AD2USB method) +
SerialDevice (class in pyad2usb.devices)
@@ -541,12 +619,12 @@
STAGE_LOAD (pyad2usb.util.Firmware attribute)
-
STAGE_START (pyad2usb.util.Firmware attribute)
+
STAGE_UPLOADING (pyad2usb.util.Firmware attribute)
@@ -560,6 +638,10 @@ +
STATUS (pyad2usb.zonetracking.Zone attribute) +
+ +
stop() (pyad2usb.ad2usb.Overseer method)
@@ -594,6 +676,10 @@
+
update() (pyad2usb.zonetracking.Zonetracker method) +
+ +
upload() (pyad2usb.util.Firmware static method)
@@ -630,7 +716,17 @@ + diff --git a/docs/_build/html/index.html b/docs/_build/html/index.html index ffdf6a7..8e5c95b 100644 --- a/docs/_build/html/index.html +++ b/docs/_build/html/index.html @@ -54,10 +54,12 @@
  • pyad2usb Package
      -
    • pyad2usb Package
    • ad2usb Module
    • devices Module
    • util Module
    • +
    • zonetracking Module
    • +
    • panels Module
    • +
    • messages Module
    • Subpackages
      • event Package
        • event Package
        • diff --git a/docs/_build/html/modules.html b/docs/_build/html/modules.html index 7855c9a..60a4cea 100644 --- a/docs/_build/html/modules.html +++ b/docs/_build/html/modules.html @@ -49,10 +49,12 @@
          • pyad2usb Package
              -
            • pyad2usb Package
            • ad2usb Module
            • devices Module
            • util Module
            • +
            • zonetracking Module
            • +
            • panels Module
            • +
            • messages Module
            • Subpackages
              • event Package
                • event Package
                • diff --git a/docs/_build/html/objects.inv b/docs/_build/html/objects.inv index 324d2e48bd849909cec5c1994f0bb08806c50ed9..36d48dfc4e7f40db337ca030aa171f1e2d614fd7 100644 GIT binary patch delta 1121 zcmV-n1fKi;2gwPLcYj$+bE8HOzVEM4RdO{IJ2~wQ8?;MBwp<8pvU{OM(3Yka7-|?~ zdw+d~my7^8bdN8h1oUJ2@%4jL#5{}PWl^a3bHa9zEUvB>`Ri5MKClidO@3S4i?~c+ z;Z?Uj?ID{W>h87_&8r1486D1FZ0@zMZJHMz*&aUSuPnYPi+`OJ!;wc&Xgxlsjo?2P zr-wCNbNlM|#nl_tFOh+gEc(f_J(4tM86;SF%>_x6LQ&|mVr9V*GBr(8Ke|j=DxOe; z8Hj8zwsW)H+*(V|cf-KDch}pXV#kz{d{-)1Tn}_PW75WewGq)zP)_~NlEC6H;ThC= zfjWrzeJ=f&uz!AZe?V6BQNoJiee(9QK7uR&q*W-9lSR*z*|WaoR=;0a7AIP`gj5_a zoV@3ecU&Q|kjWI`gerKfC70Z{*0zISG15TfkQu7*kL?BC!xt)-nU0u} ztbhH$i@D2Ls{0 zmKz)@>8Mm30Ma$tfy+PXq&IZZzmSpML+$xuNFG5FZ9sCC5JGqarq~5 zyK7FZmG9rb6)9?hqhycWfFd6lkXBx}QN-us8Dtn8ShhDy9X*Zkh|J*D4g%NzZqRa% zi>>e4jyXeo^EdQQ(RLm>JNeNdv}(+K^w-YzE`K0_?kQ0nP!K6XPcoiyNrQ}4<}p*V zO;Ll?ok&wGK%Jn$ebM2mUC`o#4vm%l-6Yy~uX&ZHW)p$4esE2cAXf2lrpPiwqwT2>yFIZoQQ)y$a7{Zo0-w?T2HAn$tz6qj$h)wgLUw4K zyMIWLUa%vyO&)o8?A8%aTq2hd!;KPt_M^?a7 z5T(L4Zc|ZtyIy13_=#^8_ySEEs?S{zCBP)A;TX9Pzk96>=w(Mea>Q*C5vTiB3)GZ( zvHY?)##P^O5yJKoqpxH*({~NS2TWR|)Hm5D)Eh0OSablQ_i%mBQ2ZWL7@ts&yjl&S zG(WwMUrZ{~4{voK5E1kYPf$lWRYQMC+-vo%h^Zmd=#K*a6L^<-A{tsMfJ*4PBVrE3 nfX;!@z^M(O0M*Q#AEL?y+zj*X(grcHU;KvfKMei@r)8HcF6$#* delta 917 zcmV;G18V%q3H}F=cYjz-Z<|06z4uojwO6Ai?I|}BaB3+r5yq|B3tGd(UKLohEKc(8 zyL|W)oG`P!7#WzE-Pt#9=8=hn=Lx)8rAls6wu01}Tv^52Btw)hmDOj`m z)~7Y(14g^Mokja<2~5VD(-+%&-D`{Xg(tR#PsJNcuB&ooCx5WzF_d~8H(49_tF?dF z*tNGOU#!W&s=XkMU<Fnw!Z~g0!X`5q8Mv?v~k<3e}Aw%NwpIRnb=-f!cj6l%EG(B>w~hV zTxKs!g1rcxdw(x_@Ey0dXG%%FsuYacyW?Ij7q_;^BT+z(upe5&FJ~6c=J!-DwOyRD zvcyN$zd?xK{X-BuLRsoc9T|IvJDsx*bi1^XFf$nS5=eHjyTCPAqZ;xc$HpJ38sx^i z;DL@CZtCc$qB#ZK^ooqv={LIRHQn?(653*WomDXVFh@?)pJAGa|xRka_J{Pd`jC`WPMcdwP+gOt3JpU# zxpkIq;DjEfvmCP;!B0<-j@frG#ZB4$mb}Z?$bVH{6lc#|BBj~6w8anV2gs3|@r&dN z+dsV5LT?%*P2d~|cORQtuviC!P^Dzxu!NNm%8<5}Pqo0tsoV3iKc1;ZPc)aXOwx|W zIi(dNLMwC^Q-zII7tQg7JOfcFY_l6W`di-*P4P<`r-w_~{$toev%`sCDq@yz_0*Jf ztA8*XBkH1jD{3_S2UcfEf+O`l%V9grds7^#uuLREBQ=#`@dh=m4}ZHIk-qcrYdsJp zdrl$CGz!NbeY<5+nYBnQQXZV&CWTd3c2yb(r;~h8zRR4_CWC<)ulqh ruHzEXoB$fly%}34Kmn@No^E1oJm#NBI}U{0xcHIn0|);AwisEWpJ%&E diff --git a/docs/_build/html/py-modindex.html b/docs/_build/html/py-modindex.html index 21081cd..6aa07ba 100644 --- a/docs/_build/html/py-modindex.html +++ b/docs/_build/html/py-modindex.html @@ -64,11 +64,6 @@
- - - + + + + + + + + +
-
ZONE (pyad2usb.ad2usb.ExpanderMessage attribute) +
Zone (class in pyad2usb.zonetracking) +
+ + +
ZONE (pyad2usb.messages.ExpanderMessage attribute) +
+ +
+ +
Zonetracker (class in pyad2usb.zonetracking)
pyad2usb
    - pyad2usb.__init__ -
    @@ -89,11 +84,26 @@     pyad2usb.event.event
    + pyad2usb.messages +
    + pyad2usb.panels +
    pyad2usb.util
    + pyad2usb.zonetracking +
diff --git a/docs/_build/html/pyad2usb.event.html b/docs/_build/html/pyad2usb.event.html index a4ede97..a729413 100644 --- a/docs/_build/html/pyad2usb.event.html +++ b/docs/_build/html/pyad2usb.event.html @@ -75,6 +75,13 @@ You can add handler also by using ‘+=’ operator.

+
+
+remove(func)[source]
+

Remove existing event handler function.

+

You can remove handler also by using ‘-=’ operator.

+
+
fire(earg=None)[source]
@@ -83,13 +90,6 @@ You can add handler also by using ‘+=’ operator.

e.fire(earg).

-
-
-remove(func)[source]
-

Remove existing event handler function.

-

You can remove handler also by using ‘-=’ operator.

-
- diff --git a/docs/_build/html/pyad2usb.html b/docs/_build/html/pyad2usb.html index 2989540..f6ea00a 100644 --- a/docs/_build/html/pyad2usb.html +++ b/docs/_build/html/pyad2usb.html @@ -54,54 +54,149 @@

pyad2usb Package

-
-

pyad2usb Package

-

The PyAD2USB module.

-

ad2usb Module

Provides the full AD2USB class and factory.

-
-class pyad2usb.ad2usb.AD2USB(device)[source]
+
+class pyad2usb.ad2usb.Overseer(attached_event=None, detached_event=None)[source]

Bases: object

-

High-level wrapper around AD2USB/AD2SERIAL devices.

+

Factory for creation of AD2USB devices as well as provide4s attach/detach events.”

-
-F1 = u'\x01\x01\x01'
-
+
+on_attached
+

Called when an AD2USB device has been detected.

+
-
-F2 = u'\x02\x02\x02'
-
+
+on_detached
+

Called when an AD2USB device has been removed.

+
-
-
-F3 = u'\x03\x03\x03'
-
+
+
+classmethod find_all()[source]
+

Returns all AD2USB devices located on the system.

+ +++ + + + + + +
Returns:list of devices found
Raises :util.CommError
+
-
-
-F4 = u'\x04\x04\x04'
-
+
+
+classmethod devices()[source]
+

Returns a cached list of AD2USB devices located on the system.

+ +++ + + + +
Returns:cached list of devices found.
+
+ +
+
+classmethod create(device=None)[source]
+

Factory method that returns the requested AD2USB device, or the first device.

+ +++ + + + + + + + +
Parameters:device (tuple) – Tuple describing the USB device to open, as returned by find_all().
Returns:AD2USB object utilizing the specified device.
Raises :util.NoDeviceError
+
-
-close()[source]
-

Closes the device.

+
+close()[source]
+

Clean up and shut down.

-
-get_config()[source]
-

Retrieves the configuration from the device.

+
+start()[source]
+

Starts the detection thread, if not already running.

+
+
+stop()[source]
+

Stops the detection thread.

+
+ +
+
+get_device(device=None)[source]
+

Factory method that returns the requested AD2USB device, or the first device.

+ +++ + + + +
Parameters:device (tuple) – Tuple describing the USB device to open, as returned by find_all().
+
+ +
+
+class DetectThread(overseer)[source]
+

Bases: threading.Thread

+

Thread that handles detection of added/removed devices.

+
+
+stop()[source]
+

Stops the thread.

+
+ +
+
+run()[source]
+

The actual detection process.

+
+ +
+ + + +
+
+class pyad2usb.ad2usb.AD2USB(device)[source]
+

Bases: object

+

High-level wrapper around AD2USB/AD2SERIAL devices.

-
-id[source]
-
+
+on_arm
+

Called when the panel is armed.

+
+ +
+
+on_disarm
+

Called when the panel is disarmed.

+
+ +
+
+on_power_changed
+

Called when panel power switches between AC and DC.

+
@@ -110,9 +205,9 @@
-
-on_boot
-

Called when the device finishes bootings.

+
+on_fire
+

Called when a fire is detected.

@@ -122,9 +217,9 @@
-
-on_close
-

Called when the device has been closed.

+
+on_boot
+

Called when the device finishes bootings.

@@ -133,12 +228,42 @@

Called when the device receives its configuration.

+
+
+on_zone_fault
+

Called when the device detects a zone fault.

+
+ +
+
+on_zone_restore
+

Called when the device detects that a fault is restored.

+
+ +
+
+on_low_battery
+

Called when the device detects a low battery.

+
+ +
+
+on_panic
+

Called when the device detects a panic.

+
+
on_message

Called when a message has been received from the device.

+
+
+on_lrr_message
+

Called when an LRR message is received.

+
+
on_open
@@ -146,9 +271,9 @@
-
-on_power_changed
-

Called when panel power switches between AC and DC.

+
+on_close
+

Called when the device has been closed.

@@ -157,165 +282,207 @@

Called when a line has been read from the device.

-
-
-on_status_changed
-

Called when the panel status changes.

-
-
on_write

Called when data has been written to the device.

-
-
-open(baudrate=None, interface=None, index=None, no_reader_thread=False)[source]
-

Opens the device.

+
+
+F1 = u'\x01\x01\x01'
+

Represents panel function key #1

-
-
-reboot()[source]
-

Reboots the device.

+
+
+F2 = u'\x02\x02\x02'
+

Represents panel function key #2

-
-
-set_config(settings)[source]
-

Sets configuration entries on the device.

+
+
+F3 = u'\x03\x03\x03'
+

Represents panel function key #3

+
+
+F4 = u'\x04\x04\x04'
+

Represents panel function key #4

-
-
-class pyad2usb.ad2usb.ExpanderMessage(data=None)[source]
-

Bases: object

-

Represents a message from a zone or relay expansion module.

-
-RELAY = 1
-
+
+BATTERY_TIMEOUT = 30
+

Timeout before the battery status reverts.

+
-
-ZONE = 0
-
- +
+FIRE_TIMEOUT = 30
+

Timeout before the fire status reverts.

-
-
-class pyad2usb.ad2usb.LRRMessage(data=None)[source]
-

Bases: object

-

Represent a message from a Long Range Radio.

+
+
+id[source]
+

The ID of the AD2USB device.

+ +++ + + + +
Returns:The identification string for the device.
-
-
-class pyad2usb.ad2usb.Message(data=None)[source]
-

Bases: object

-

Represents a message from the alarm panel.

+
+
+open(baudrate=None, interface=None, index=None, no_reader_thread=False)[source]
+

Opens the device.

+ +++ + + + +
Parameters:
    +
  • baudrate (int) – The baudrate used for the device.
  • +
  • interface (varies depends on device type.. FIXME) – The interface used for the device.
  • +
  • index (int) – Interface index.. can probably remove. FIXME
  • +
  • no_reader_thread (bool) – Specifies whether or not the automatic reader thread should be started or not
  • +
+
-
-
-class pyad2usb.ad2usb.Overseer(attached_event=None, detached_event=None)[source]
-

Bases: object

-

Factory for creation of AD2USB devices as well as provide4s attach/detach events.”

-
-
-class DetectThread(overseer)[source]
-

Bases: threading.Thread

-

Thread that handles detection of added/removed devices.

-
-run()[source]
-

The actual detection process.

+
+close()[source]
+

Closes the device.

-
-stop()[source]
-

Stops the thread.

+
+get_config()[source]
+

Retrieves the configuration from the device.

+
+
+save_config()
+

Sets configuration entries on the device.

-
-Overseer.close()[source]
-

Clean up and shut down.

+
+reboot()[source]
+

Reboots the device.

-
-
-classmethod Overseer.create(device=None)[source]
-

Factory method that returns the requested AD2USB device, or the first device.

+
+
+fault_zone(zone, simulate_wire_problem=False)
+

Faults a zone if we are emulating a zone expander.

+ +++ + + + +
Parameters:
    +
  • zone (int) – The zone to fault.
  • +
  • simulate_wire_problem (bool) – Whether or not to simulate a wire fault.
  • +
+
-
-
-classmethod Overseer.devices()[source]
-

Returns a cached list of AD2USB devices located on the system.

+
+
+clear_zone(zone)
+

Clears a zone if we are emulating a zone expander.

+ +++ + + + +
Parameters:zone (int) – The zone to clear.
-
-
-classmethod Overseer.find_all()[source]
-

Returns all AD2USB devices located on the system.

-
-
-Overseer.get_device(device=None)[source]
-

Factory method that returns the requested AD2USB device, or the first device.

+
+
+

devices Module

+

Contains different types of devices belonging to the AD2USB family.

+
+
+class pyad2usb.devices.Device[source]
+

Bases: object

+

Generic parent device to all AD2USB products.

+
+
+on_open
+

Called when the device has been opened

-
-Overseer.on_attached
-

Called when an AD2USB device has been detected.

+
+on_close
+

Called when the device has been closed

-
-Overseer.on_detached
-

Called when an AD2USB device has been removed.

+
+on_read
+

Called when a line has been read from the device

-
-
-Overseer.start()[source]
-

Starts the detection thread, if not already running.

+
+
+on_write
+

Called when data has been written to the device

-
-
-Overseer.stop()[source]
-

Stops the detection thread.

+
+
+id[source]
+

Retrieve the device ID.

+ +++ + + + +
Returns:The identification string for the device.
+
+
+is_reader_alive()[source]
+

Indicates whether or not the reader thread is alive.

+ +++ + + + +
Returns:Whether or not the reader thread is alive.
-
-
-class pyad2usb.ad2usb.RFMessage(data=None)[source]
-

Bases: object

-

Represents a message from an RF receiver.

+
+
+stop_reader()[source]
+

Stops the reader thread.

-
-
-

devices Module

-

Contains different types of devices belonging to the AD2USB family.

-
-
-class pyad2usb.devices.Device[source]
-

Bases: object

-

Generic parent device to all AD2USB products.

class ReadThread(device)[source]
@@ -324,7 +491,14 @@
READ_TIMEOUT = 10
-
+

Timeout for the reader thread.

+
+ +
+
+stop()[source]
+

Stops the running thread.

+
@@ -332,53 +506,131 @@

The actual read process.

-
-
-stop()[source]
-

Stops the running thread.

+
+
+class pyad2usb.devices.USBDevice(vid=1027, pid=24577, serial=None, description=None, interface=0)[source]
+

Bases: pyad2usb.devices.Device

+

AD2USB device exposed with PyFTDI’s interface.

+
+
+FTDI_VENDOR_ID = 1027
+

Vendor ID used to recognize AD2USB devices.

+
+ +
+
+FTDI_PRODUCT_ID = 24577
+

Product ID used to recognize AD2USB devices.

+
+
-
-Device.id[source]
-
+
+BAUDRATE = 115200
+

Default baudrate for AD2USB devices.

+
-
-
-Device.is_reader_alive()[source]
-

Indicates whether or not the reader thread is alive.

+
+
+static find_all()[source]
+

Returns all FTDI devices matching our vendor and product IDs.

+ +++ + + + + + +
Returns:list of devices
Raises :util.CommError
-
-
-Device.on_close
-

Called when the device has been closed

+
+
+open(baudrate=115200, interface=None, index=0, no_reader_thread=False)[source]
+

Opens the device.

+ +++ + + + + + +
Parameters:
    +
  • baudrate (int) – The baudrate to use.
  • +
  • interface (int) – The interface to use.
  • +
  • no_reader_thread (bool) – Whether or not to automatically start the reader thread.
  • +
+
Raises :

util.NoDeviceError

+
-
-
-Device.on_open
-

Called when the device has been opened

+
+
+close()[source]
+

Closes the device.

-
-
-Device.on_read
-

Called when a line has been read from the device

+
+
+write(data)[source]
+

Writes data to the device.

+ +++ + + + + + +
Parameters:data (str) – Data to write
Raises :util.CommError
-
-
-Device.on_write
-

Called when data has been written to the device

+
+
+read()[source]
+

Reads a single character from the device.

+ +++ + + + + + +
Returns:The character read from the device.
Raises :util.CommError
-
-Device.stop_reader()[source]
-

Stops the reader thread.

+
+read_line(timeout=0.0, purge_buffer=False)[source]
+

Reads a line from the device.

+ +++ + + + + + + + +
Parameters:
    +
  • timeout (float) – Read timeout
  • +
  • purge_buffer (bool) – Indicates whether to purge the buffer prior to reading.
  • +
+
Returns:

The line that was read.

+
Raises :

util.CommError, util.TimeoutError

+
@@ -391,42 +643,110 @@
BAUDRATE = 19200
-
- -
-
-close()[source]
-

Closes the device.

+

Default baudrate for Serial devices.

static find_all(pattern=None)[source]

Returns all serial ports present.

+ +++ + + + + + + + +
Parameters:pattern (str) – Pattern to search for when retrieving serial ports.
Returns:list of devices
Raises :util.CommError
open(baudrate=19200, interface=None, index=None, no_reader_thread=False)[source]

Opens the device.

+ +++ + + + + + +
Parameters:
    +
  • baudrate (int) – The baudrate to use with the device.
  • +
  • interface (str) – The device to open.
  • +
  • index (int) – Unused.
  • +
  • no_reader_thread (bool) – Whether or not to automatically start the reader thread.
  • +
+
Raises :

util.NoDeviceError

+
+
+ +
+
+close()[source]
+

Closes the device.

+
+ +
+
+write(data)[source]
+

Writes data to the device.

+ +++ + + + + + +
Parameters:data (str) – The data to write.
Raises :util.CommError
read()[source]

Reads a single character from the device.

+ +++ + + + + + +
Returns:The character read from the device.
Raises :util.CommError
-read_line(timeout=0.0)[source]
+read_line(timeout=0.0, purge_buffer=False)[source]

Reads a line from the device.

-
- -
-
-write(data)[source]
-

Writes data to the device.

+ +++ + + + + + + + +
Parameters:
    +
  • timeout (float) – The read timeout.
  • +
  • purge_buffer (bool) – Indicates whether to purge the buffer prior to reading.
  • +
+
Returns:

The line read.

+
Raises :

util.CommError, util.TimeoutError

+
@@ -437,92 +757,91 @@

Bases: pyad2usb.devices.Device

Device that supports communication with an AD2USB that is exposed via ser2sock or another Serial to IP interface.

-
-
-close()[source]
-

Closes the device.

-
-
open(baudrate=None, interface=None, index=0, no_reader_thread=False)[source]

Opens the device.

+ +++ + + + + + +
Parameters:
    +
  • baudrate (int) – The baudrate to use
  • +
  • interface (tuple) – The hostname and port to connect to.
  • +
  • index (int) – Unused
  • +
  • no_reader_thread (bool) – Whether or not to automatically open the reader thread.
  • +
+
Raises :

util.NoDeviceError

+
-
-read()[source]
-

Reads a single character from the device.

-
- -
-
-read_line(timeout=0.0)[source]
-

Reads a line from the device.

+
+close()[source]
+

Closes the device.

write(data)[source]

Writes data to the device.

-
- -
- -
-
-class pyad2usb.devices.USBDevice(vid=1027, pid=24577, serial=None, description=None, interface=0)[source]
-

Bases: pyad2usb.devices.Device

-

AD2USB device exposed with PyFTDI’s interface.

-
-
-BAUDRATE = 115200
-
- -
-
-FTDI_PRODUCT_ID = 24577
-
- -
-
-FTDI_VENDOR_ID = 1027
-
- -
-
-close()[source]
-

Closes the device.

-
- -
-
-static find_all()[source]
-

Returns all FTDI devices matching our vendor and product IDs.

-
- -
-
-open(baudrate=115200, interface=None, index=0, no_reader_thread=False)[source]
-

Opens the device.

+ +++ + + + + + + + +
Parameters:data (str) – The data to write.
Returns:The number of bytes sent.
Raises :util.CommError
-
-read()[source]
+
+read()[source]

Reads a single character from the device.

+ +++ + + + + + +
Returns:The character read from the device.
Raises :util.CommError
-
-read_line(timeout=0.0)[source]
+
+read_line(timeout=0.0, purge_buffer=False)[source]

Reads a line from the device.

-
- -
-
-write(data)[source]
-

Writes data to the device.

+ +++ + + + + + + + +
Parameters:
    +
  • timeout (float) – The read timeout.
  • +
  • purge_buffer (bool) – Indicates whether to purge the buffer prior to reading.
  • +
+
Returns:

The line read from the device.

+
Raises :

util.CommError, util.TimeoutError

+
@@ -531,6 +850,13 @@ Serial to IP interface.

util Module

Provides utility classes for the AD2USB devices.

+
+
+exception pyad2usb.util.NoDeviceError[source]
+

Bases: exceptions.Exception

+

No devices found.

+
+
exception pyad2usb.util.CommError[source]
@@ -538,29 +864,43 @@ Serial to IP interface.

There was an error communicating with the device.

+
+
+exception pyad2usb.util.TimeoutError[source]
+

Bases: exceptions.Exception

+

There was a timeout while trying to communicate with the device.

+
+ +
+
+exception pyad2usb.util.InvalidMessageError[source]
+

Bases: exceptions.Exception

+

The format of the panel message was invalid.

+
+
class pyad2usb.util.Firmware[source]

Bases: object

Represents firmware for the AD2USB/AD2SERIAL devices.

-
-STAGE_BOOT = 2
+
+STAGE_START = 0
-
-STAGE_DONE = 5
+
+STAGE_WAITING = 1
-
-STAGE_LOAD = 3
+
+STAGE_BOOT = 2
-
-STAGE_START = 0
+
+STAGE_LOAD = 3
@@ -569,37 +909,150 @@ Serial to IP interface.

-
-STAGE_WAITING = 1
+
+STAGE_DONE = 5
static upload(dev, filename, progress_callback=None)[source]

Uploads firmware to an AD2USB/AD2SERIAL device.

+ +++ + + + + + +
Parameters:
    +
  • filename (str) – The firmware filename
  • +
  • progress_callback (function) – Callback function used to report progress.
  • +
+
Raises :

util.NoDeviceError, util.TimeoutError

+
-
-
-exception pyad2usb.util.InvalidMessageError[source]
-

Bases: exceptions.Exception

-

The format of the panel message was invalid.

+
+
+

zonetracking Module

+

Provides zone tracking functionality for the AD2USB device family.

+
+
+class pyad2usb.zonetracking.Zone(zone=0, name='', status=0)[source]
+

Bases: object

+

Representation of a panel zone.

+
+
+CLEAR = 0
+

Status indicating that the zone is cleared.

-
-
-exception pyad2usb.util.NoDeviceError[source]
-

Bases: exceptions.Exception

-

No devices found.

+
+
+FAULT = 1
+

Status indicating that the zone is faulted.

-
-
-exception pyad2usb.util.TimeoutError[source]
-

Bases: exceptions.Exception

-

There was a timeout while trying to communicate with the device.

+
+
+CHECK = 2
+

Status indicating that there is a wiring issue with the zone.

+
+ +
+
+STATUS = {0: 'CLEAR', 1: 'FAULT', 2: 'CHECK'}
+
+ +
+ +
+
+class pyad2usb.zonetracking.Zonetracker[source]
+

Bases: object

+

Handles tracking of zone and their statuses.

+
+
+on_fault
+

Called when the device detects a zone fault.

+
+ +
+
+on_restore
+

Called when the device detects that a fault is restored.

+
+ +
+
+EXPIRE = 30
+

Zone expiration timeout.

+
+ +
+
+update(message)[source]
+

Update zone statuses based on the current message.

+ +++ + + + +
Parameters:message (Message or ExpanderMessage) – Message to use to update the zone tracking.
+
+ +
+ +
+
+

panels Module

+

Representations of Panels and their templates.

+
+
+

messages Module

+

Message representations received from the panel through the AD2USB.

+
+
+class pyad2usb.messages.Message(data=None)[source]
+

Bases: object

+

Represents a message from the alarm panel.

+
+ +
+
+class pyad2usb.messages.ExpanderMessage(data=None)[source]
+

Bases: object

+

Represents a message from a zone or relay expansion module.

+
+
+ZONE = 0
+
+ +
+
+RELAY = 1
+
+ +
+ +
+
+class pyad2usb.messages.RFMessage(data=None)[source]
+

Bases: object

+

Represents a message from an RF receiver.

+
+ +
+
+class pyad2usb.messages.LRRMessage(data=None)[source]
+

Bases: object

+

Represent a message from a Long Range Radio.

@@ -626,10 +1079,12 @@ Serial to IP interface.

Table Of Contents

  • pyad2usb Package
      -
    • pyad2usb Package
    • ad2usb Module
    • devices Module
    • util Module
    • +
    • zonetracking Module
    • +
    • panels Module
    • +
    • messages Module
    • Subpackages
    • diff --git a/docs/_build/html/searchindex.js b/docs/_build/html/searchindex.js index 07d020d..7ab97e2 100644 --- a/docs/_build/html/searchindex.js +++ b/docs/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{all:[1,3],socketdevic:1,func:3,boot:1,radio:1,on_boot:1,stage_don:1,baudrat:1,locat:1,zone:1,also:3,configur:1,except:1,on_attach:1,add:3,present:1,bypass:1,x03:1,on_read:1,x01:1,match:1,x04:1,sourc:[1,3],"return":1,around:1,format:1,fals:1,on_messag:1,stop:1,util:[],on_bypass:1,detach:1,like:3,level:1,earg:3,list:1,upload:1,method:1,"try":1,whether:1,stage_wait:1,timeout:1,contain:1,found:1,expandermessag:1,page:0,set:1,nodeviceerror:1,on_open:1,creation:1,"static":1,close:1,read_lin:1,event:[],stop_read:1,pyseri:1,index:[0,1],statu:1,detect:1,parent:1,pattern:1,ad2seri:1,reboot:1,content:0,written:1,between:1,"new":3,factori:1,localhost:1,can:3,ser2sock:1,shut:1,full:1,run:1,timeouterror:1,power:1,detached_ev:1,gener:1,usbdevic:1,on_clos:1,base:[1,3],on_config_receiv:1,on_status_chang:1,on_detach:1,panel:1,search:0,actual:1,expos:1,thread:1,readthread:1,set_config:1,stage_start:1,provide4:1,descript:1,chang:1,find_al:1,ad2usb:[],first:1,oper:3,rang:1,via:1,vid:1,attached_ev:1,modul:[],down:1,filenam:1,alreadi:1,messag:1,famili:1,on_writ:1,open:1,on_power_chang:1,differ:1,"long":1,from:1,commun:1,detectthread:1,support:1,devic:[],system:1,been:1,get_devic:1,trigger:1,call:[1,3],interfac:1,type:1,start:1,"function":3,wrapper:1,no_reader_thread:1,stage_load:1,fire:3,handler:3,commerror:1,stage_boot:1,rfmessag:1,relai:1,x02:1,obj:3,line:1,cach:1,serialdevic:1,must:3,none:[1,3],sender:3,retriev:1,provid:1,remov:[1,3],on_alarm:1,dev:1,charact:1,defin:3,"while":1,doc:3,stage_upload:1,error:1,aliv:1,creat:1,process:1,request:1,pid:1,reader:1,repres:1,high:1,packag:[],itself:3,exist:3,ftdi_vendor_id:1,our:1,read_timeout:1,vendor:1,ftdi_product_id:1,attach:1,progress_callback:1,receiv:1,anoth:1,belong:1,when:1,invalid:1,port:1,write:1,handl:1,read:1,which:1,instead:3,you:3,singl:1,product:1,finish:1,firmwar:1,pyftdi:1,expans:1,object:[1,3],ftdi:1,get_config:1,eventhandl:3,data:1,"class":[1,3],serial:1,subpackag:[],classmethod:1,entri:1,alarm:1,well:1,lrrmessag:1,"switch":1,is_reader_al:1,clean:1,invalidmessageerror:1,overs:1},objtypes:{"0":"py:module","1":"py:method","2":"py:attribute","3":"py:class","4":"py:staticmethod","5":"py:exception","6":"py:classmethod"},objnames:{"0":["py","module","Python module"],"1":["py","method","Python method"],"2":["py","attribute","Python attribute"],"3":["py","class","Python class"],"4":["py","staticmethod","Python static method"],"5":["py","exception","Python exception"],"6":["py","classmethod","Python class method"]},filenames:["index","pyad2usb","modules","pyad2usb.event"],titles:["Welcome to pyad2usb’s documentation!","pyad2usb Package","pyad2usb","event Package"],objects:{"pyad2usb.devices":{Device:[1,3,1,""],SocketDevice:[1,3,1,""],USBDevice:[1,3,1,""],SerialDevice:[1,3,1,""]},"pyad2usb.util.Firmware":{STAGE_LOAD:[1,2,1,""],upload:[1,4,1,""],STAGE_BOOT:[1,2,1,""],STAGE_START:[1,2,1,""],STAGE_UPLOADING:[1,2,1,""],STAGE_WAITING:[1,2,1,""],STAGE_DONE:[1,2,1,""]},"pyad2usb.devices.SerialDevice":{write:[1,1,1,""],BAUDRATE:[1,2,1,""],read:[1,1,1,""],read_line:[1,1,1,""],find_all:[1,4,1,""],close:[1,1,1,""],open:[1,1,1,""]},"pyad2usb.ad2usb.Overseer.DetectThread":{run:[1,1,1,""],stop:[1,1,1,""]},"pyad2usb.devices.Device":{on_open:[1,2,1,""],on_write:[1,2,1,""],ReadThread:[1,3,1,""],on_close:[1,2,1,""],on_read:[1,2,1,""],stop_reader:[1,1,1,""],is_reader_alive:[1,1,1,""],id:[1,2,1,""]},pyad2usb:{util:[1,0,1,""],"__init__":[1,0,1,""],ad2usb:[1,0,1,""],devices:[1,0,1,""],event:[3,0,1,""]},"pyad2usb.ad2usb":{RFMessage:[1,3,1,""],LRRMessage:[1,3,1,""],ExpanderMessage:[1,3,1,""],Overseer:[1,3,1,""],Message:[1,3,1,""],AD2USB:[1,3,1,""]},"pyad2usb.event":{event:[3,0,1,""]},"pyad2usb.devices.Device.ReadThread":{READ_TIMEOUT:[1,2,1,""],run:[1,1,1,""],stop:[1,1,1,""]},"pyad2usb.util":{CommError:[1,5,1,""],Firmware:[1,3,1,""],TimeoutError:[1,5,1,""],NoDeviceError:[1,5,1,""],InvalidMessageError:[1,5,1,""]},"pyad2usb.ad2usb.AD2USB":{on_power_changed:[1,2,1,""],F1:[1,2,1,""],F2:[1,2,1,""],F3:[1,2,1,""],F4:[1,2,1,""],on_message:[1,2,1,""],on_config_received:[1,2,1,""],on_open:[1,2,1,""],on_status_changed:[1,2,1,""],on_alarm:[1,2,1,""],get_config:[1,1,1,""],set_config:[1,1,1,""],on_close:[1,2,1,""],on_bypass:[1,2,1,""],reboot:[1,1,1,""],on_boot:[1,2,1,""],on_write:[1,2,1,""],close:[1,1,1,""],on_read:[1,2,1,""],open:[1,1,1,""],id:[1,2,1,""]},"pyad2usb.ad2usb.ExpanderMessage":{RELAY:[1,2,1,""],ZONE:[1,2,1,""]},"pyad2usb.event.event.EventHandler":{fire:[3,1,1,""],add:[3,1,1,""],remove:[3,1,1,""]},"pyad2usb.event.event":{EventHandler:[3,3,1,""],Event:[3,3,1,""]},"pyad2usb.ad2usb.Overseer":{on_attached:[1,2,1,""],get_device:[1,1,1,""],DetectThread:[1,3,1,""],create:[1,6,1,""],stop:[1,1,1,""],devices:[1,6,1,""],on_detached:[1,2,1,""],start:[1,1,1,""],find_all:[1,6,1,""],close:[1,1,1,""]},"pyad2usb.devices.SocketDevice":{read_line:[1,1,1,""],read:[1,1,1,""],write:[1,1,1,""],open:[1,1,1,""],close:[1,1,1,""]},"pyad2usb.devices.USBDevice":{read_line:[1,1,1,""],BAUDRATE:[1,2,1,""],read:[1,1,1,""],write:[1,1,1,""],find_all:[1,4,1,""],FTDI_VENDOR_ID:[1,2,1,""],close:[1,1,1,""],FTDI_PRODUCT_ID:[1,2,1,""],open:[1,1,1,""]}},titleterms:{subpackag:1,welcom:0,pyad2usb:[0,1,2],devic:1,indic:0,event:3,util:1,packag:[1,3],tabl:0,modul:[1,3],document:0,ad2usb:1}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{represent:1,all:[1,3],socketdevic:1,func:3,boot:1,sent:1,disarm:1,arm:1,scott:[],on_boot:1,stage_don:1,simulate_wire_problem:1,vari:1,paramet:1,current:1,baudrat:1,locat:1,zone:1,on_disarm:1,configur:1,except:1,should:1,on_attach:1,whether:1,add:3,present:1,bypass:1,x03:1,on_read:1,x01:1,match:1,x04:1,sourc:[1,3],"return":1,string:1,clear_zon:1,format:1,read:1,on_messag:1,stop:1,util:[],on_bypass:1,automat:1,"new":3,report:1,detach:1,name:1,like:3,level:1,earg:3,list:1,upload:1,method:1,"try":1,emul:1,stage_wait:1,timeout:1,contain:1,found:1,expandermessag:1,page:0,set:1,detect:1,nodeviceerror:1,on_open:1,creation:1,on_pan:1,"static":1,connect:1,fire_timeout:1,close:1,read_lin:1,event:[],stop_read:1,firmwar:1,pyseri:1,index:[0,1],statu:1,wire:1,parent:1,defin:3,pattern:1,ad2seri:1,reboot:1,callback:1,content:0,buffer:1,written:1,com:[],between:1,progress:1,factori:1,localhost:1,ser2sock:1,shut:1,full:1,run:1,timeouterror:1,power:1,detached_ev:1,gener:1,usbdevic:1,lrr:1,on_clos:1,base:[1,3],on_config_receiv:1,depend:1,"byte":1,on_status_chang:[],on_detach:1,panel:[],search:[0,1],actual:1,expos:1,thread:1,fault:1,fixm:1,through:1,set_config:[],stage_start:1,provide4:1,"int":1,get_config:1,aliv:1,fals:1,chang:[],find_al:1,ad2usb:[],first:1,oper:3,revert:1,rang:1,via:1,vid:1,attached_ev:1,modul:[],"float":1,number:1,zonetrack:[],fault_zon:1,down:1,filenam:1,alreadi:1,"long":1,famili:1,batteri:1,on_writ:1,open:1,on_power_chang:1,kei:1,identif:1,differ:1,from:1,usb:1,messag:[],commun:1,detectthread:1,support:1,devic:[],system:1,been:1,get_devic:1,trigger:1,call:[1,3],low:1,handl:1,interfac:1,stage_upload:1,type:1,start:1,"function":[1,3],wrapper:1,no_reader_thread:1,stage_load:1,fire:[1,3],handler:3,commerror:1,specifi:1,stage_boot:1,rfmessag:1,serial:1,relai:1,x02:1,obj:3,line:1,on_fir:1,cach:1,serialdevic:1,must:3,descript:1,on_zone_restor:1,none:[1,3],sender:3,retriev:1,describ:1,on_restor:1,restor:1,provid:1,remov:[1,3],purg:1,on_alarm:1,dev:1,charact:1,purge_buff:1,"while":1,can:[1,3],str:1,doc:3,petersen:[],clear:1,radio:1,expir:1,creat:1,process:1,request:1,save_config:1,pid:1,reader:1,templat:1,repres:1,high:1,packag:[],on_fault:1,itself:3,exist:3,readthread:1,ftdi_vendor_id:1,our:1,read_timeout:1,vendor:1,ftdi_product_id:1,simul:1,attach:1,around:1,progress_callback:1,moduleauthor:[],prior:1,receiv:1,anoth:1,belong:1,when:1,"switch":1,invalid:1,port:1,write:1,also:3,bool:1,on_zone_fault:1,tupl:1,instead:3,you:3,probabl:1,panic:1,singl:1,updat:1,status:1,product:1,finish:1,recogn:1,hostnam:1,"default":1,pyftdi:1,expans:1,object:[1,3],unus:1,ftdi:1,befor:1,rais:1,track:1,battery_timeout:1,on_arm:1,eventhandl:3,data:1,"class":[1,3],expand:1,nutech:[],subpackag:[],classmethod:1,entri:1,alarm:1,well:1,issu:1,lrrmessag:1,which:1,is_reader_al:1,on_lrr_messag:1,error:1,clean:1,check:1,invalidmessageerror:1,overs:1,on_low_batteri:1},objtypes:{"0":"py:module","1":"py:attribute","2":"py:method","3":"py:class","4":"py:staticmethod","5":"py:exception","6":"py:classmethod"},objnames:{"0":["py","module","Python module"],"1":["py","attribute","Python attribute"],"2":["py","method","Python method"],"3":["py","class","Python class"],"4":["py","staticmethod","Python static method"],"5":["py","exception","Python exception"],"6":["py","classmethod","Python class method"]},filenames:["index","pyad2usb","modules","pyad2usb.event"],titles:["Welcome to pyad2usb’s documentation!","pyad2usb Package","pyad2usb","event Package"],objects:{"pyad2usb.devices":{Device:[1,3,1,""],SocketDevice:[1,3,1,""],USBDevice:[1,3,1,""],SerialDevice:[1,3,1,""]},"pyad2usb.util.Firmware":{STAGE_LOAD:[1,1,1,""],upload:[1,4,1,""],STAGE_BOOT:[1,1,1,""],STAGE_START:[1,1,1,""],STAGE_UPLOADING:[1,1,1,""],STAGE_WAITING:[1,1,1,""],STAGE_DONE:[1,1,1,""]},"pyad2usb.zonetracking":{Zonetracker:[1,3,1,""],Zone:[1,3,1,""]},"pyad2usb.devices.SerialDevice":{write:[1,2,1,""],BAUDRATE:[1,1,1,""],read:[1,2,1,""],read_line:[1,2,1,""],find_all:[1,4,1,""],close:[1,2,1,""],open:[1,2,1,""]},"pyad2usb.zonetracking.Zonetracker":{on_restore:[1,1,1,""],EXPIRE:[1,1,1,""],update:[1,2,1,""],on_fault:[1,1,1,""]},"pyad2usb.ad2usb.Overseer.DetectThread":{run:[1,2,1,""],stop:[1,2,1,""]},"pyad2usb.devices.Device":{on_open:[1,1,1,""],on_write:[1,1,1,""],ReadThread:[1,3,1,""],on_close:[1,1,1,""],on_read:[1,1,1,""],stop_reader:[1,2,1,""],is_reader_alive:[1,2,1,""],id:[1,1,1,""]},pyad2usb:{zonetracking:[1,0,1,""],messages:[1,0,1,""],devices:[1,0,1,""],ad2usb:[1,0,1,""],util:[1,0,1,""],panels:[1,0,1,""],event:[3,0,1,""]},"pyad2usb.ad2usb":{AD2USB:[1,3,1,""],Overseer:[1,3,1,""]},"pyad2usb.messages":{Message:[1,3,1,""],RFMessage:[1,3,1,""],ExpanderMessage:[1,3,1,""],LRRMessage:[1,3,1,""]},"pyad2usb.event":{event:[3,0,1,""]},"pyad2usb.devices.Device.ReadThread":{READ_TIMEOUT:[1,1,1,""],run:[1,2,1,""],stop:[1,2,1,""]},"pyad2usb.util":{CommError:[1,5,1,""],Firmware:[1,3,1,""],TimeoutError:[1,5,1,""],NoDeviceError:[1,5,1,""],InvalidMessageError:[1,5,1,""]},"pyad2usb.ad2usb.AD2USB":{fault_zone:[1,2,1,""],on_open:[1,1,1,""],save_config:[1,2,1,""],on_boot:[1,1,1,""],close:[1,2,1,""],open:[1,2,1,""],id:[1,1,1,""],on_power_changed:[1,1,1,""],BATTERY_TIMEOUT:[1,1,1,""],on_message:[1,1,1,""],reboot:[1,2,1,""],get_config:[1,2,1,""],on_zone_restore:[1,1,1,""],on_disarm:[1,1,1,""],on_fire:[1,1,1,""],on_write:[1,1,1,""],on_read:[1,1,1,""],on_lrr_message:[1,1,1,""],clear_zone:[1,2,1,""],on_zone_fault:[1,1,1,""],on_config_received:[1,1,1,""],on_close:[1,1,1,""],on_panic:[1,1,1,""],on_low_battery:[1,1,1,""],on_arm:[1,1,1,""],F1:[1,1,1,""],F2:[1,1,1,""],F3:[1,1,1,""],F4:[1,1,1,""],on_alarm:[1,1,1,""],on_bypass:[1,1,1,""],FIRE_TIMEOUT:[1,1,1,""]},"pyad2usb.messages.ExpanderMessage":{ZONE:[1,1,1,""],RELAY:[1,1,1,""]},"pyad2usb.event.event.EventHandler":{fire:[3,2,1,""],add:[3,2,1,""],remove:[3,2,1,""]},"pyad2usb.event.event":{EventHandler:[3,3,1,""],Event:[3,3,1,""]},"pyad2usb.ad2usb.Overseer":{on_attached:[1,1,1,""],get_device:[1,2,1,""],DetectThread:[1,3,1,""],create:[1,6,1,""],stop:[1,2,1,""],devices:[1,6,1,""],on_detached:[1,1,1,""],start:[1,2,1,""],find_all:[1,6,1,""],close:[1,2,1,""]},"pyad2usb.zonetracking.Zone":{STATUS:[1,1,1,""],FAULT:[1,1,1,""],CLEAR:[1,1,1,""],CHECK:[1,1,1,""]},"pyad2usb.devices.SocketDevice":{read_line:[1,2,1,""],read:[1,2,1,""],write:[1,2,1,""],open:[1,2,1,""],close:[1,2,1,""]},"pyad2usb.devices.USBDevice":{read_line:[1,2,1,""],BAUDRATE:[1,1,1,""],read:[1,2,1,""],write:[1,2,1,""],find_all:[1,4,1,""],FTDI_VENDOR_ID:[1,1,1,""],close:[1,2,1,""],FTDI_PRODUCT_ID:[1,1,1,""],open:[1,2,1,""]}},titleterms:{subpackag:1,welcom:0,pyad2usb:[0,1,2],devic:1,messag:1,event:3,util:1,packag:[1,3],zonetrack:1,indic:0,tabl:0,modul:[1,3],document:0,ad2usb:1,panel:1}}) \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 5bfd805..f92113e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -304,3 +304,5 @@ epub_copyright = u'2013, Author' # If false, no index is generated. #epub_use_index = True + +autodoc_member_order = 'bysource' diff --git a/docs/pyad2usb.rst b/docs/pyad2usb.rst index 08dfd6b..2e8b746 100644 --- a/docs/pyad2usb.rst +++ b/docs/pyad2usb.rst @@ -1,14 +1,6 @@ pyad2usb Package ================ -:mod:`pyad2usb` Package ------------------------ - -.. automodule:: pyad2usb.__init__ - :members: - :undoc-members: - :show-inheritance: - :mod:`ad2usb` Module -------------------- @@ -33,6 +25,30 @@ pyad2usb Package :undoc-members: :show-inheritance: +:mod:`zonetracking` Module +-------------------------- + +.. automodule:: pyad2usb.zonetracking + :members: + :undoc-members: + :show-inheritance: + +:mod:`panels` Module +-------------------- + +.. automodule:: pyad2usb.panels + :members: + :undoc-members: + :show-inheritance: + +:mod:`messages` Module +---------------------- + +.. automodule:: pyad2usb.messages + :members: + :undoc-members: + :show-inheritance: + Subpackages ----------- diff --git a/pyad2usb/__init__.py b/pyad2usb/__init__.py index 6937a83..4db13b1 100644 --- a/pyad2usb/__init__.py +++ b/pyad2usb/__init__.py @@ -1,5 +1 @@ -""" -The PyAD2USB module. -""" - __all__ = ['ad2usb', 'devices', 'util'] diff --git a/pyad2usb/ad2usb.py b/pyad2usb/ad2usb.py index ea6c717..617645a 100644 --- a/pyad2usb/ad2usb.py +++ b/pyad2usb/ad2usb.py @@ -1,5 +1,9 @@ """ + Provides the full AD2USB class and factory. + +.. moduleauthor:: Scott Petersen + """ import time @@ -28,6 +32,9 @@ class Overseer(object): def find_all(cls): """ Returns all AD2USB devices located on the system. + + :returns: list of devices found + :raises: util.CommError """ cls.__devices = devices.USBDevice.find_all() @@ -37,6 +44,8 @@ class Overseer(object): def devices(cls): """ Returns a cached list of AD2USB devices located on the system. + + :returns: cached list of devices found. """ return cls.__devices @@ -44,6 +53,12 @@ class Overseer(object): def create(cls, device=None): """ Factory method that returns the requested AD2USB device, or the first device. + + :param device: Tuple describing the USB device to open, as returned by find_all(). + :type device: tuple + + :returns: AD2USB object utilizing the specified device. + :raises: util.NoDeviceError """ cls.find_all() @@ -61,6 +76,11 @@ class Overseer(object): def __init__(self, attached_event=None, detached_event=None): """ Constructor + + :param attached_event: Event to trigger when a device is attached. + :type attached_event: function + :param detached_event: Event to trigger when a device is detached. + :type detached_event: function """ self._detect_thread = Overseer.DetectThread(self) @@ -96,6 +116,9 @@ class Overseer(object): def get_device(self, device=None): """ Factory method that returns the requested AD2USB device, or the first device. + + :param device: Tuple describing the USB device to open, as returned by find_all(). + :type device: tuple """ return Overseer.create(device) @@ -106,6 +129,9 @@ class Overseer(object): def __init__(self, overseer): """ Constructor + + :param overseer: Overseer object to use with the thread. + :type overseer: Overseer """ threading.Thread.__init__(self) @@ -178,16 +204,25 @@ class AD2USB(object): # Constants F1 = unichr(1) + unichr(1) + unichr(1) + """Represents panel function key #1""" F2 = unichr(2) + unichr(2) + unichr(2) + """Represents panel function key #2""" F3 = unichr(3) + unichr(3) + unichr(3) + """Represents panel function key #3""" F4 = unichr(4) + unichr(4) + unichr(4) + """Represents panel function key #4""" BATTERY_TIMEOUT = 30 + """Timeout before the battery status reverts.""" FIRE_TIMEOUT = 30 + """Timeout before the fire status reverts.""" def __init__(self, device): """ Constructor + + :param device: The low-level device used for this AD2USB interface. + :type device: devices.Device """ self._device = device self._zonetracker = zonetracking.Zonetracker() @@ -212,12 +247,23 @@ class AD2USB(object): def id(self): """ The ID of the AD2USB device. + + :returns: The identification string for the device. """ return self._device.id def open(self, baudrate=None, interface=None, index=None, no_reader_thread=False): """ Opens the device. + + :param baudrate: The baudrate used for the device. + :type baudrate: int + :param interface: The interface used for the device. + :type interface: varies depends on device type.. FIXME + :param index: Interface index.. can probably remove. FIXME + :type index: int + :param no_reader_thread: Specifies whether or not the automatic reader thread should be started or not + :type no_reader_thread: bool """ self._wire_events() self._device.open(baudrate=baudrate, interface=interface, index=index, no_reader_thread=no_reader_thread) @@ -274,6 +320,11 @@ class AD2USB(object): def fault_zone(self, zone, simulate_wire_problem=False): """ Faults a zone if we are emulating a zone expander. + + :param zone: The zone to fault. + :type zone: int + :param simulate_wire_problem: Whether or not to simulate a wire fault. + :type simulate_wire_problem: bool """ # Allow ourselves to also be passed an address/channel combination # for zone expanders. @@ -289,6 +340,9 @@ class AD2USB(object): def clear_zone(self, zone): """ Clears a zone if we are emulating a zone expander. + + :param zone: The zone to clear. + :type zone: int """ self._device.write("L{0:02}0\r".format(zone)) @@ -306,6 +360,11 @@ class AD2USB(object): def _handle_message(self, data): """ Parses messages from the panel. + + :param data: Panel data to parse. + :type data: str + + :returns: An object representing the message. """ if data is None: return None @@ -338,6 +397,11 @@ class AD2USB(object): def _handle_lrr(self, data): """ Handle Long Range Radio messages. + + :param data: LRR message to parse. + :type data: str + + :returns: An object representing the LRR message. """ msg = messages.LRRMessage(data) @@ -358,6 +422,9 @@ class AD2USB(object): def _handle_config(self, data): """ Handles received configuration data. + + :param data: Configuration string to parse. + :type data: str """ _, config_string = data.split('>') for setting in config_string.split('&'): @@ -385,6 +452,9 @@ class AD2USB(object): def _update_internal_states(self, message): """ Updates internal device states. + + :param message: Message to update internal states with. + :type message: Message, ExpanderMessage, LRRMessage, or RFMessage """ if isinstance(message, messages.Message): if message.ac_power != self._power_status: @@ -447,6 +517,9 @@ class AD2USB(object): def _update_zone_tracker(self, message): """ Trigger an update of the zonetracker. + + :param message: The message to update the zonetracker with. + :type message: Message, ExpanderMessage, LRRMessage, or RFMessage """ # Retrieve a list of faults. diff --git a/pyad2usb/devices.py b/pyad2usb/devices.py index 458c9b1..897896a 100644 --- a/pyad2usb/devices.py +++ b/pyad2usb/devices.py @@ -1,5 +1,7 @@ """ Contains different types of devices belonging to the AD2USB family. + +.. moduleauthor:: Scott Petersen """ import usb.core @@ -40,6 +42,8 @@ class Device(object): def id(self): """ Retrieve the device ID. + + :returns: The identification string for the device. """ return self._id @@ -47,12 +51,17 @@ class Device(object): def id(self, value): """ Sets the device ID. + + :param value: The device identification. + :type value: str """ self._id = value def is_reader_alive(self): """ Indicates whether or not the reader thread is alive. + + :returns: Whether or not the reader thread is alive. """ return self._read_thread.is_alive() @@ -68,10 +77,14 @@ class Device(object): """ READ_TIMEOUT = 10 + """Timeout for the reader thread.""" def __init__(self, device): """ Constructor + + :param device: The device used by the reader thread. + :type device: devices.Device """ threading.Thread.__init__(self) self._device = device @@ -105,13 +118,19 @@ class USBDevice(Device): # Constants FTDI_VENDOR_ID = 0x0403 + """Vendor ID used to recognize AD2USB devices.""" FTDI_PRODUCT_ID = 0x6001 + """Product ID used to recognize AD2USB devices.""" BAUDRATE = 115200 + """Default baudrate for AD2USB devices.""" @staticmethod def find_all(): """ Returns all FTDI devices matching our vendor and product IDs. + + :returns: list of devices + :raises: util.CommError """ devices = [] @@ -126,6 +145,17 @@ class USBDevice(Device): def __init__(self, vid=FTDI_VENDOR_ID, pid=FTDI_PRODUCT_ID, serial=None, description=None, interface=0): """ Constructor + + :param vid: Vendor ID + :type vid: int + :param pid: Product ID + :type pid: int + :param serial: The serial number + :type serial: str + :param description: Description of the device. + :type description: str + :param interface: The interface to use + :type interface: int """ Device.__init__(self) @@ -139,6 +169,15 @@ class USBDevice(Device): def open(self, baudrate=BAUDRATE, interface=None, index=0, no_reader_thread=False): """ Opens the device. + + :param baudrate: The baudrate to use. + :type baudrate: int + :param interface: The interface to use. + :type interface: int + :param no_reader_thread: Whether or not to automatically start the reader thread. + :type no_reader_thread: bool + + :raises: util.NoDeviceError """ # Set up defaults if baudrate is None: @@ -197,6 +236,11 @@ class USBDevice(Device): def write(self, data): """ Writes data to the device. + + :param data: Data to write + :type data: str + + :raises: util.CommError """ try: self._device.write_data(data) @@ -208,6 +252,9 @@ class USBDevice(Device): def read(self): """ Reads a single character from the device. + + :returns: The character read from the device. + :raises: util.CommError """ ret = None @@ -222,6 +269,14 @@ class USBDevice(Device): def read_line(self, timeout=0.0, purge_buffer=False): """ Reads a line from the device. + + :param timeout: Read timeout + :type timeout: float + :param purge_buffer: Indicates whether to purge the buffer prior to reading. + :type purge_buffer: bool + + :returns: The line that was read. + :raises: util.CommError, util.TimeoutError """ if purge_buffer: @@ -287,11 +342,18 @@ class SerialDevice(Device): # Constants BAUDRATE = 19200 + """Default baudrate for Serial devices.""" @staticmethod def find_all(pattern=None): """ Returns all serial ports present. + + :param pattern: Pattern to search for when retrieving serial ports. + :type pattern: str + + :returns: list of devices + :raises: util.CommError """ devices = [] @@ -309,6 +371,9 @@ class SerialDevice(Device): def __init__(self, interface=None): """ Constructor + + :param interface: The device to open. + :type interface: str """ Device.__init__(self) @@ -319,6 +384,17 @@ class SerialDevice(Device): def open(self, baudrate=BAUDRATE, interface=None, index=None, no_reader_thread=False): """ Opens the device. + + :param baudrate: The baudrate to use with the device. + :type baudrate: int + :param interface: The device to open. + :type interface: str + :param index: Unused. + :type index: int + :param no_reader_thread: Whether or not to automatically start the reader thread. + :type no_reader_thread: bool + + :raises: util.NoDeviceError """ # Set up the defaults if baudrate is None: @@ -370,6 +446,11 @@ class SerialDevice(Device): def write(self, data): """ Writes data to the device. + + :param data: The data to write. + :type data: str + + :raises: util.CommError """ try: self._device.write(data) @@ -386,6 +467,9 @@ class SerialDevice(Device): def read(self): """ Reads a single character from the device. + + :returns: The character read from the device. + :raises: util.CommError """ ret = None @@ -400,6 +484,14 @@ class SerialDevice(Device): def read_line(self, timeout=0.0, purge_buffer=False): """ Reads a line from the device. + + :param timeout: The read timeout. + :type timeout: float + :param purge_buffer: Indicates whether to purge the buffer prior to reading. + :type purge_buffer: bool + + :returns: The line read. + :raises: util.CommError, util.TimeoutError """ def timeout_event(): timeout_event.reading = False @@ -471,6 +563,17 @@ class SocketDevice(Device): def open(self, baudrate=None, interface=None, index=0, no_reader_thread=False): """ Opens the device. + + :param baudrate: The baudrate to use + :type baudrate: int + :param interface: The hostname and port to connect to. + :type interface: tuple + :param index: Unused + :type index: int + :param no_reader_thread: Whether or not to automatically open the reader thread. + :type no_reader_thread: bool + + :raises: util.NoDeviceError """ if interface is not None: self._interface = interface @@ -512,6 +615,12 @@ class SocketDevice(Device): def write(self, data): """ Writes data to the device. + + :param data: The data to write. + :type data: str + + :returns: The number of bytes sent. + :raises: util.CommError """ data_sent = None @@ -531,6 +640,9 @@ class SocketDevice(Device): def read(self): """ Reads a single character from the device. + + :returns: The character read from the device. + :raises: util.CommError """ data = None @@ -545,6 +657,14 @@ class SocketDevice(Device): def read_line(self, timeout=0.0, purge_buffer=False): """ Reads a line from the device. + + :param timeout: The read timeout. + :type timeout: float + :param purge_buffer: Indicates whether to purge the buffer prior to reading. + :type purge_buffer: bool + + :returns: The line read from the device. + :raises: util.CommError, util.TimeoutError """ if purge_buffer: diff --git a/pyad2usb/messages.py b/pyad2usb/messages.py index 86e6e54..e5f4ca8 100644 --- a/pyad2usb/messages.py +++ b/pyad2usb/messages.py @@ -12,6 +12,9 @@ class Message(object): def __init__(self, data=None): """ Constructor + + :param data: Message data to parse. + :type data: str """ self.ready = False self.armed_away = False @@ -45,6 +48,11 @@ class Message(object): def _parse_message(self, data): """ Parse the message from the device. + + :param data: The message data. + :type data: str + + :raises: util.InvalidMessageError """ m = self._regex.match(data) @@ -94,6 +102,9 @@ class ExpanderMessage(object): def __init__(self, data=None): """ Constructor + + :param data: The message data to parse. + :type data: str """ self.type = None self.address = None @@ -119,6 +130,9 @@ class ExpanderMessage(object): def _parse_message(self, data): """ Parse the raw message from the device. + + :param data: The message data + :type data: str """ header, values = data.split(':') address, channel, value = values.split(',') @@ -141,6 +155,9 @@ class RFMessage(object): def __init__(self, data=None): """ Constructor + + :param data: The message data to parse + :type data: str """ self.raw = None self.serial_number = None @@ -158,6 +175,9 @@ class RFMessage(object): def _parse_message(self, data): """ Parses the raw message from the device. + + :param data: The message data. + :type data: str """ self.raw = data @@ -172,6 +192,9 @@ class LRRMessage(object): def __init__(self, data=None): """ Constructor + + :param data: The message data to parse. + :type data: str """ self.raw = None self._event_data = None @@ -190,6 +213,9 @@ class LRRMessage(object): def _parse_message(self, data): """ Parses the raw message from the device. + + :param data: The message data. + :type data: str """ self.raw = data diff --git a/pyad2usb/util.py b/pyad2usb/util.py index 4e55a4e..5f6aa83 100644 --- a/pyad2usb/util.py +++ b/pyad2usb/util.py @@ -48,6 +48,13 @@ class Firmware(object): def upload(dev, filename, progress_callback=None): """ Uploads firmware to an AD2USB/AD2SERIAL device. + + :param filename: The firmware filename + :type filename: str + :param progress_callback: Callback function used to report progress. + :type progress_callback: function + + :raises: util.NoDeviceError, util.TimeoutError """ def do_upload(): diff --git a/pyad2usb/zonetracking.py b/pyad2usb/zonetracking.py index 3878658..45d3224 100644 --- a/pyad2usb/zonetracking.py +++ b/pyad2usb/zonetracking.py @@ -12,21 +12,40 @@ class Zone(object): """ CLEAR = 0 + """Status indicating that the zone is cleared.""" FAULT = 1 + """Status indicating that the zone is faulted.""" CHECK = 2 # Wire fault + """Status indicating that there is a wiring issue with the zone.""" STATUS = { CLEAR: 'CLEAR', FAULT: 'FAULT', CHECK: 'CHECK' } def __init__(self, zone=0, name='', status=CLEAR): + """ + Constructor + + :param zone: The zone number. + :type zone: int + :param name: Human readable zone name. + :type name: str + :param status: Initial zone state. + :type status: int + """ self.zone = zone self.name = name self.status = status self.timestamp = time.time() def __str__(self): + """ + String conversion operator. + """ return 'Zone {0} {1}'.format(self.zone, self.name) def __repr__(self): + """ + Human readable representation operator. + """ return 'Zone({0}, {1}, ts {2})'.format(self.zone, Zone.STATUS[self.status], self.timestamp) class Zonetracker(object): @@ -38,6 +57,7 @@ class Zonetracker(object): on_restore = event.Event('Called when the device detects that a fault is restored.') EXPIRE = 30 + """Zone expiration timeout.""" def __init__(self): """ @@ -50,6 +70,9 @@ class Zonetracker(object): def update(self, message): """ Update zone statuses based on the current message. + + :param message: Message to use to update the zone tracking. + :type message: Message or ExpanderMessage """ zone = -1 @@ -107,6 +130,9 @@ class Zonetracker(object): def _clear_zones(self, zone): """ Clear all expired zones from our status list. + + :param zone: current zone being processed. + :type zone: int """ cleared_zones = [] found_last = found_new = at_end = False @@ -177,6 +203,13 @@ class Zonetracker(object): def _add_zone(self, zone, name='', status=Zone.CLEAR): """ Adds a zone to the internal zone list. + + :param zone: The zone number. + :type zone: int + :param name: Human readable zone name. + :type name: str + :param status: The zone status. + :type status: int """ if not zone in self._zones: self._zones[zone] = Zone(zone=zone, name=name, status=status) @@ -187,6 +220,13 @@ class Zonetracker(object): def _update_zone(self, zone, status=None): """ Updates a zones status. + + :param zone: The zone number. + :type zone: int + :param status: The zone status. + :type status: int + + :raises: IndexError """ if not zone in self._zones: raise IndexError('Zone does not exist and cannot be updated: %d', zone) @@ -205,6 +245,11 @@ class Zonetracker(object): def _zone_expired(self, zone): """ Determine if a zone is expired or not. + + :param zone: The zone number. + :type zone: int + + :returns: Whether or not the zone is expired. """ if time.time() > self._zones[zone].timestamp + Zonetracker.EXPIRE: return True @@ -214,6 +259,13 @@ class Zonetracker(object): def _expander_to_zone(self, address, channel): """ Convert an address and channel into a zone number. + + :param address: The expander address + :type address: int + :param channel: The channel + :type channel: int + + :returns: The zone number associated with an address and channel. """ # TODO: This is going to need to be reworked to support the larger