├── .DS_Store ├── .gitignore ├── LICENSE ├── LICENSE.txt ├── MANIFEST ├── README.md ├── README.txt ├── setup.py ├── zklib ├── .DS_Store ├── __init__.py ├── zkAtt.py ├── zkAttdev.py ├── zkDBRrq.py ├── zkRegevent.py ├── zkattendance.py ├── zkconnect.py ├── zkconst.py ├── zkdevice.py ├── zkextendfmt.py ├── zkextendoplog.py ├── zkface.py ├── zkfreedata.py ├── zklib.py ├── zkos.py ├── zkpin.py ├── zkplatform.py ├── zkprepare.py ├── zkrefreshdata ├── zkrefreshdata.py ├── zkrestart.py ├── zkserialnumber.py ├── zksoapAtt.py ├── zkssr.py ├── zktime.py ├── zkuser.py ├── zkversion.py └── zkworkcode.py └── zktest.py /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlSayedGamal/python_zklib/65ce3656e372dbe80d79d105a59c3de692ee5c22/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | 47 | # Translations 48 | *.mo 49 | *.pot 50 | 51 | # Django stuff: 52 | *.log 53 | 54 | # Sphinx documentation 55 | docs/_build/ 56 | 57 | # PyBuilder 58 | target/ 59 | 60 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /MANIFEST: -------------------------------------------------------------------------------- 1 | # file GENERATED by distutils, do NOT edit 2 | README.txt 3 | setup.py 4 | zklib/__init__.py 5 | zklib/zkattendance.py 6 | zklib/zkconnect.py 7 | zklib/zkconst.py 8 | zklib/zkdevice.py 9 | zklib/zkextendfmt.py 10 | zklib/zkextendoplog.py 11 | zklib/zkface.py 12 | zklib/zklib.py 13 | zklib/zkos.py 14 | zklib/zkpin.py 15 | zklib/zkplatform.py 16 | zklib/zkserialnumber.py 17 | zklib/zkssr.py 18 | zklib/zktime.py 19 | zklib/zkuser.py 20 | zklib/zkversion.py 21 | zklib/zkworkcode.py 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python ZKLib # 2 | 3 | ZK fingerprint Attendance Machine Library for python with a connection to the network using the UDP protocol and port 4370 4 | 5 | ## Getting started 6 | 7 | Login as admin to attendance machine and set the ip address for example (to 192.168.0.201) and connect the machine with ethernet to your network 8 | 9 | 10 | Connect to the machine 11 | 12 | ```python 13 | import sys 14 | from zklib import zklib 15 | 16 | import time 17 | from zklib import zkconst 18 | 19 | 20 | 21 | 22 | zk = zklib.ZKLib("192.168.0.201", 4370) 23 | ret = zk.connect() 24 | print "connection:", ret 25 | ``` 26 | 27 | If result was 28 | ``` 29 | connection True 30 | ``` 31 | Then you are connected. 32 | 33 | More examples on how to use the Library available in the 34 | zktest.py file 35 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | # Python ZKLib # 2 | 3 | ZK fingerprint Attendance Machine Library for python with a connection to the network using the UDP protocol and port 4370 4 | 5 | ## Getting started 6 | 7 | Login as admin to attendance machine and set the ip address for example (to 192.168.0.201) and connect the machine with ethernet to your network 8 | 9 | 10 | Connect to the machine 11 | 12 | ```python 13 | import sys 14 | from zklib import zklib 15 | 16 | import time 17 | from zklib import zkconst 18 | 19 | 20 | 21 | 22 | zk = zklib.ZKLib("192.168.0.201", 4370) 23 | ret = zk.connect() 24 | print "connection:", ret 25 | ``` 26 | 27 | If result was 28 | ``` 29 | connection True 30 | ``` 31 | Then you are connected. 32 | 33 | More examples on how to use the Library available in the 34 | zktest.py file 35 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from distutils.core import setup 2 | 3 | setup( 4 | # Application name: 5 | name="zklib", 6 | # Version number (initial): 7 | version="0.1.1", 8 | # Application author details: 9 | url="https://github.com/AlSayedGamal/python_zklib", 10 | author="AlSayed Gamal", 11 | author_email="mail.gamal@gmail.com", 12 | packages=["zklib"], 13 | license="LICENSE.txt", 14 | description="Zk Attendance Machine lib", 15 | long_description=open("README.txt").read(), 16 | 17 | ) 18 | -------------------------------------------------------------------------------- /zklib/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlSayedGamal/python_zklib/65ce3656e372dbe80d79d105a59c3de692ee5c22/zklib/.DS_Store -------------------------------------------------------------------------------- /zklib/__init__.py: -------------------------------------------------------------------------------- 1 | import zkattendance 2 | import zkconst 3 | import zkdevice 4 | import zkconnect 5 | import zkextendfmt 6 | import zkextendoplog 7 | import zkface 8 | import zklib 9 | import zkos 10 | import zkpin 11 | import zkpin 12 | import zkplatform 13 | import zkserialnumber 14 | import zkssr 15 | import zktime 16 | import zkuser 17 | import zkversion 18 | import zkworkcode 19 | import zkprepare 20 | import zkrefreshdata 21 | import zkfreedata 22 | import zkrestart 23 | import zkAtt 24 | import zkDBRrq 25 | import zkRegevent 26 | import zksoapAtt 27 | -------------------------------------------------------------------------------- /zklib/zkAtt.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | import sys 4 | 5 | from zkconst import * 6 | 7 | 8 | 9 | def acmOK(self): 10 | """send CMD_ACK_OK""" 11 | """ try cmd_ack_data""" 12 | command = CMD_ACK_DATA 13 | command_string = '' 14 | chksum = 0 15 | session_id = 0 16 | reply_id = -1 + USHRT_MAX 17 | 18 | buf = self.createHeader(command, chksum, session_id, 19 | reply_id, command_string) 20 | 21 | self.zkclient.sendto(buf, self.address) 22 | 23 | try: 24 | self.data_recv, addr = self.zkclient.recvfrom(1024) 25 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 26 | 27 | return self.checkValid( self.data_recv ) 28 | except: 29 | return False 30 | 31 | 32 | 33 | def reverseHex(hexstr): 34 | tmp = '' 35 | for i in reversed( xrange( len(hexstr)/2 ) ): 36 | tmp += hexstr[i*2:(i*2)+2] 37 | 38 | return tmp 39 | 40 | #assume a socket disconnect (data returned is empty string) means all data was #done being sent. 41 | def recv_basic(the_socket): 42 | total_data=[] 43 | while True: 44 | data = the_socket.recv(8192) 45 | if not data: break 46 | total_data.append(data) 47 | return ''.join(total_data) 48 | 49 | def recv_timeout(the_socket,timeout=2): 50 | the_socket.setblocking(0) 51 | total_data=[];data='';begin=time.time() 52 | while 1: 53 | #if you got some data, then break after wait sec 54 | if total_data and time.time()-begin>timeout: 55 | break 56 | #if you got no data at all, wait a little longer 57 | elif time.time()-begin>timeout*2: 58 | break 59 | try: 60 | data=the_socket.recv(8192) 61 | if data: 62 | total_data.append(data) 63 | begin=time.time() 64 | else: 65 | time.sleep(0.1) 66 | except: 67 | pass 68 | return ''.join(total_data) 69 | 70 | End= 2000 71 | def recv_end(the_socket): 72 | total_data=[];data='' 73 | while True: 74 | data=the_socket.recv(8192) 75 | if End in data: 76 | total_data.append(data[:data.find(End)]) 77 | break 78 | total_data.append(data) 79 | if len(total_data)>1: 80 | #check if end_of_data was split 81 | last_pair=total_data[-2]+total_data[-1] 82 | if End in last_pair: 83 | total_data[-2]=last_pair[:last_pair.find(End)] 84 | total_data.pop() 85 | break 86 | return ''.join(total_data) 87 | 88 | def recv_size(the_socket): 89 | #data length is packed into 4 bytes 90 | total_len=0;total_data=[];size=sys.maxint 91 | size_data=sock_data='';recv_size=8192 92 | while total_len4: 96 | size_data+=sock_data 97 | size=struct.unpack('>i', size_data[:4])[0] 98 | recv_size=size 99 | if recv_size>524288:recv_size=524288 100 | total_data.append(size_data[4:]) 101 | else: 102 | size_data+=sock_data 103 | else: 104 | total_data.append(sock_data) 105 | total_len=sum([len(i) for i in total_data ]) 106 | return ''.join(total_data) 107 | 108 | 109 | 110 | 111 | def zkAtt(self): 112 | 113 | 114 | 115 | atti = [] 116 | i = 0 117 | command = CMD_ATTLOG_RRQ 118 | comand_string = '' 119 | chksum = 0 120 | session_id = self.session_id 121 | reply_id = unpack('4H',self.data_recv[:8])[3] 122 | 123 | buf = self.createHeader(command,chksum,session_id, reply_id, comand_string) 124 | 125 | for x in xrange(10): 126 | 127 | self.zkclient.sendto(buf,self.address) 128 | 129 | 130 | 131 | size = None 132 | attendance = [] 133 | data_recv, addr = self.zkclient.recvfrom(3094) 134 | 135 | #print "size", sys.getsizeof(data_recv) 136 | #print "size", len(data_recv) 137 | lensi = len(data_recv) / 2 138 | fstri = str(lensi) + "H" 139 | #print "first unpack ", unpack (fstri, data_recv) 140 | 141 | 142 | if unpack('4H',data_recv[:8])[0] == CMD_PREPARE_DATA: 143 | #print "received CMD_PREPARE_DATA" 144 | size = unpack('I', data_recv[8:12])[0] 145 | 146 | 147 | 148 | #print 'Receiving %s %s' % (size,"bytes") 149 | #data_recv, addr = self.zkclient.recvfrom(43773) 150 | #lens = len(self.data_recv) / 2 151 | #fstr = str(lens) + "H" 152 | #print "second unpack", unpack(fstr, self.data_recv) 153 | 154 | 155 | 156 | 157 | 158 | 159 | while unpack('4H', data_recv[:8])[0] != CMD_ACK_OK or unpack('4H', data_recv[:8])[0] == CMD_DATA: 160 | 161 | 162 | #print "COUNTER", i 163 | 164 | data_recv, addr = self.zkclient.recvfrom(size) 165 | 166 | lens = len(data_recv[:8]) / 2 167 | fstr = str(lens) + "H" 168 | if unpack(fstr, data_recv[:8])[0] == CMD_DATA: 169 | i = i +1 170 | #print "data package " , unpack(fstr, data_recv[:8])[0] 171 | lens = len(data_recv) / 2 172 | fstr = str(lens) + "H" 173 | 174 | #print "data unpack", unpack(fstr, data_recv) 175 | if i == 1: 176 | 177 | 178 | self.attendancedata.append(data_recv) 179 | elif i == 2: 180 | #atti.append(data_recv) 181 | self.attendancedata.append(data_recv) 182 | 183 | 184 | 185 | 186 | #acmOK(self) 187 | if unpack('4H', data_recv[:8])[0] == CMD_ACK_OK: 188 | print "CMD_ACK_OK" 189 | 190 | 191 | 192 | 193 | print "length of att data", len(self.attendancedata) 194 | print "length of atti data", len(self.attendancedata) 195 | #data_recv = self.zkclient.recvfrom(8) 196 | 197 | for x in xrange(len(self.attendancedata)): 198 | 199 | 200 | #print self.attendancedata[x][8:] 201 | #self.attendancedata[x] = self.attendancedata[x][8:] 202 | #print self.attendancedata[x][0:] 203 | self.attendancedata[x] = self.attendancedata[x][0:] 204 | 205 | 206 | 207 | #atti = atti 208 | 209 | attendancedata = ''.join(self.attendancedata) 210 | 211 | attendancedata = attendancedata[14:] 212 | #attendancedata = attendancedata[14:] 213 | 214 | #test = getData(self) 215 | 216 | print "len attendancedata", len(attendancedata) 217 | 218 | while len(attendancedata): 219 | 220 | 221 | #print "att loop" 222 | 223 | 224 | 225 | 226 | 227 | 228 | if len(attendancedata[29:30]) == 1: 229 | 230 | pls = unpack('c',attendancedata[29:30])#[3] 231 | 232 | 233 | #statev = unpack('=2c',attendancedata[21:23]) 234 | #datem = unpack('ii',attendancedata[:8])[1] 235 | 236 | 237 | 238 | uid, state, timestamp, space = unpack( '24s1s4s11s', attendancedata.ljust(40)[:40] ) 239 | #ord(pls[0]) 240 | 241 | #print "%s, %s, %s, %s" % (uid, ord(pls[0]), ord(space[0]), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) 242 | #print "%s, %s, %s, %s" % (uid, ord(pls[0]), ord(space[0]), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) 243 | #print "%s, %s, %s, %s" % (uid, state, space, timestamp) 244 | attendance.append( ( uid, ord(pls[0]), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) ) 245 | #test.append( ( uid, 1 , decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) ) 246 | attendancedata = attendancedata[40:] 247 | #print "len attendancedata", len(attendancedata) 248 | 249 | return attendance 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | def zkclearattendance(self): 258 | """Start a connection with the time clock""" 259 | command = CMD_CLEAR_ATTLOG 260 | command_string = '' 261 | chksum = 0 262 | session_id = self.session_id 263 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 264 | 265 | buf = self.createHeader(command, chksum, session_id, 266 | reply_id, command_string) 267 | self.zkclient.sendto(buf, self.address) 268 | #print buf.encode("hex") 269 | try: 270 | self.data_recv, addr = self.zkclient.recvfrom(1024) 271 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 272 | return self.data_recv[8:] 273 | except: 274 | return False -------------------------------------------------------------------------------- /zklib/zkAttdev.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | import sys 4 | 5 | from zkconst import * 6 | 7 | 8 | 9 | def reverseHex(hexstr): 10 | tmp = '' 11 | for i in reversed( xrange( len(hexstr)/2 ) ): 12 | tmp += hexstr[i*2:(i*2)+2] 13 | 14 | return tmp 15 | 16 | 17 | def zkAtt(self): 18 | 19 | print "testing" 20 | file = open("binw", "w") 21 | 22 | command = CMD_ATTLOG_RRQ 23 | comand_string = '' 24 | chksum = 0 25 | session_id = self.session_id 26 | reply_id = unpack('4H',self.data_recv[:8])[3] 27 | 28 | buf = self.createHeader(command,chksum,session_id, reply_id, comand_string) 29 | self.zkclient.sendto(buf,self.address) 30 | #file.write(self.data_recv[0:]) 31 | #print "reply_id", reply_id 32 | 33 | attendance = [] 34 | self.data_recv, addr = self.zkclient.recvfrom(1024) 35 | #print "unpack HcHc :7", unpack('HcHc',self.data_recv[:7]) 36 | #print "unpack HHHH :8", unpack('HHHH',self.data_recv[:8]) 37 | #print "unpack HHHH :8 [1]", unpack('4H',self.data_recv[:8])[0] 38 | #print "length", len(self.data_recv) 39 | #print "unpack 4I ", unpack ('4I', self.data_recv) 40 | #print "unpack 8H", unpack('8H', self.data_recv) 41 | #print "unpack I 8:12 [0]", unpack ('I', self.data_recv[8:12])[0] 42 | 43 | if unpack('4H',self.data_recv[:8])[0] == CMD_PREPARE_DATA: 44 | print "received CMD_PREPARE_DATA" 45 | 46 | while unpack('4H', self.data_recv[:8])[0] != 2000: 47 | 48 | data_recv, addr = self.zkclient.recvfrom(1024) 49 | #print "length of reiceived data packet", len(data_recv) 50 | #print "unpack 126H", unpack('126H', data_recv) 51 | self.attendancedata.append(data_recv) 52 | file.write(data_recv) 53 | if unpack('4H', data_recv[:8])[0] == 1501: 54 | print "receiving Data packet" 55 | #print "trying to unpack data", unpack('i', data_recv[:8])[1] 56 | 57 | self.data_recv, addr = self.zkclient.recvfrom(1024) 58 | #print "length of reiceived data packet", len(self.data_recv) 59 | #print unpack('4H', self.data_recv) 60 | if unpack('4H', self.data_recv)[0] == 2000: 61 | print "received CMD_ACK_OK" 62 | try: 63 | 64 | self.data_recv, addr = self.zkclient.recvfrom(1024) 65 | #print len(self.data_recv) 66 | except: 67 | print "socket timeout - no more data to receive" 68 | #print "length of att data", len(self.attendancedata) 69 | 70 | for x in xrange(len(self.attendancedata)): 71 | #print self.attendancedata[x][8:] 72 | #self.attendancedata[x] = self.attendancedata[x][8:] 73 | #print self.attendancedata[x][0:] 74 | self.attendancedata[x] = self.attendancedata[x][0:] 75 | 76 | 77 | attendancedata = self.attendancedata 78 | 79 | 80 | 81 | attendancedata = ''.join( self.attendancedata) 82 | 83 | attendancedata = attendancedata[14:] 84 | 85 | while len(attendancedata): 86 | 87 | #print "length att", len(attendancedata) 88 | uidm = unpack('24s1s4s11s',attendancedata.ljust(40)[:40]) 89 | #print "length att40", len(attendancedata[:38]) 90 | uidt = unpack('38s',attendancedata[:38]) 91 | #print "uidt", uidt 92 | #print "sizeof", sys.getsizeof(attendancedata[:40]) 93 | #try unpacking the state bits in reverse order 94 | #try unpacking using different endianness 95 | #timestamp = int.from_bytes(ba_object[:4], byteorder='big') 96 | #print "LENNY", len(attendancedata[30:]) 97 | uidmn = unpack('16s',attendancedata[:16])[0] 98 | pls = unpack('c',attendancedata[29:30])#[3] 99 | #print "pls wo ord", pls 100 | #statem = unpack('=5c',attendancedata[:10])[3] 101 | statev = unpack('=2c',attendancedata[21:23]) 102 | datem = unpack('ii',attendancedata[:8])[1] 103 | #print "uidm", uidm 104 | #print "uidmn", uidmn 105 | #print "pls w ord", ord(pls[0]) 106 | #print "statem", ord(statem) 107 | #print "statev", ord(statev[0]) 108 | #print "statev", statev[0] 109 | #print "datem",datem 110 | 111 | 112 | 113 | uid, state, timestamp, space = unpack( '24s1s4s11s', attendancedata.ljust(40)[:40] ) 114 | print "%s, %s, %s, %s" % (uid, ord(pls[0]), ord(space[0]), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) 115 | #print "%s, %s, %s, %s" % (uid, state, space, timestamp) 116 | attendance.append( ( uid, ord(pls[0]), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) ) 117 | attendancedata = attendancedata[40:] 118 | 119 | return attendance 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | def zkclearattendance(self): 128 | """Start a connection with the time clock""" 129 | command = CMD_CLEAR_ATTLOG 130 | command_string = '' 131 | chksum = 0 132 | session_id = self.session_id 133 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 134 | 135 | buf = self.createHeader(command, chksum, session_id, 136 | reply_id, command_string) 137 | self.zkclient.sendto(buf, self.address) 138 | #print buf.encode("hex") 139 | try: 140 | self.data_recv, addr = self.zkclient.recvfrom(1024) 141 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 142 | return self.data_recv[8:] 143 | except: 144 | return False -------------------------------------------------------------------------------- /zklib/zkDBRrq.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | import sys 4 | from zkconst import * 5 | 6 | def reverseHex(hexstr): 7 | tmp = '' 8 | for i in reversed( xrange( len(hexstr)/2 ) ): 9 | tmp += hexstr[i*2:(i*2)+2] 10 | 11 | return tmp 12 | 13 | def zkDBRrq(self): 14 | """Tell device to send us all attlog data""" 15 | attendance = [] 16 | command = CMD_DB_RRQ 17 | command_string = '\x01' 18 | chksum = 0 19 | session_id = self.session_id 20 | 21 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 22 | 23 | buf = self.createHeader(command,chksum, session_id,reply_id, command_string) 24 | self.zkclient.sendto(buf,self.address) 25 | 26 | 27 | self.data_recv, addr = self.zkclient.recvfrom(1024) 28 | 29 | print "dbrrq length", sys.getsizeof(self.data_recv) 30 | 31 | 32 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 33 | 34 | lensi = len(self.data_recv) / 2 35 | fstri = str(lensi) + "H" 36 | print "unpack all ", unpack (fstri, self.data_recv) 37 | 38 | self.data_recv, addr = self.zkclient.recvfrom(56781) 39 | 40 | if unpack('HHHH', self.data_recv[:8])[0] == CMD_DATA or unpack('HHHH', self.data_recv[:8])[0] == CMD_PREPARE_DATA: 41 | 42 | 43 | print "received CMD_ACK_OK or CMD_PREPARE_DATA" 44 | size = unpack('I', self.data_recv[8:12])[0] 45 | print "size %s", size 46 | dat_recvm, addr = self.zkclient.recvfrom(43773) 47 | lensi = len(dat_recvm) / 2 48 | fstri = str(lensi) + "H" 49 | print "unpack all first ", unpack (fstri, dat_recvm) 50 | 51 | self.attendancedata.append(dat_recvm) 52 | 53 | #print unpack('4H',dat_recvm[:8]) 54 | 55 | dat_recvm, addr = self.zkclient.recvfrom(43773) 56 | 57 | 58 | 59 | lensi = len(dat_recvm) / 2 60 | fstri = str(lensi) + "H" 61 | print "unpack all second ", unpack (fstri, dat_recvm) 62 | print "len self.attendancedata", len(self.attendancedata) 63 | 64 | 65 | 66 | for x in xrange(len(self.attendancedata)): 67 | print "inda loop" 68 | 69 | 70 | 71 | #print self.attendancedata[x][8:] 72 | #self.attendancedata[x] = self.attendancedata[x][8:] 73 | #print self.attendancedata[x][0:] 74 | self.attendancedata[x] = self.attendancedata[x][0:] 75 | 76 | print "outta loop" 77 | 78 | attendancedata = self.attendancedata 79 | 80 | attendancedata = ''.join(self.attendancedata) 81 | 82 | attendancedata = attendancedata[0:] 83 | 84 | print "len attendancedata", len(attendancedata) 85 | 86 | while len(attendancedata): 87 | print "in finale loop" 88 | 89 | #pls = unpack('c',self.attendancedata[29:30]) 90 | 91 | uid, state, timestamp, space = unpack('24s1s4s11s', attendancedata.ljust(40)[:40]) 92 | print "%s, %s, %s, %s" % (uid, 1, ord(space[0]), decode_time(int(reverseHex(timestamp.encode('hex')), 16 ))) 93 | attendancedata = attendancedata[40:] 94 | 95 | return attendance 96 | 97 | 98 | """ 99 | print "outta loop" 100 | attendancedata = self.attendancedata 101 | 102 | attendancedata = ''.join( self.attendancedata) 103 | 104 | attendancedata = attendancedata[14:] 105 | 106 | 107 | 108 | 109 | print "len attendancedata", len(attendancedata) 110 | 111 | while len(attendancedata): 112 | 113 | 114 | 115 | print "in finale loop" 116 | #pls = unpack('c',self.attendancedata[29:30]) 117 | uid, state, timestamp, space = unpack( '24s1s4s11s', attendancedata.ljust(40)[:40] ) 118 | print "%s, %s, %s, %s" % (uid, 1, ord(space[0]), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) 119 | attendancedata = attendancedata[40:] 120 | 121 | """ 122 | 123 | 124 | -------------------------------------------------------------------------------- /zklib/zkRegevent.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | import sys 4 | 5 | from zkconst import * 6 | 7 | def reverseHex(hexstr): 8 | tmp = '' 9 | for i in reversed( xrange( len(hexstr)/2 ) ): 10 | tmp += hexstr[i*2:(i*2)+2] 11 | 12 | return tmp 13 | 14 | 15 | def zkRegevent(self): 16 | """register for live events""" 17 | print "reg event" 18 | command = CMD_REG_EVENT 19 | command_string = '' 20 | chksum = 0 21 | session_id = 0 22 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 23 | 24 | buf = self.createHeader(command, chksum, session_id,reply_id, command_string) 25 | self.zkclient.sendto(buf, self.address) 26 | #print buf.encode("hex") 27 | 28 | self.data_recv, addr = self.zkclient.recvfrom(1024) 29 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 30 | 31 | 32 | print "size", sys.getsizeof(data_recv) 33 | print "size", len(data_recv) 34 | lensi = len(data_recv) / 2 35 | fstri = str(lensi) + "H" 36 | print "first unpack ", unpack (fstri, data_recv) 37 | 38 | 39 | if unpack('4H',data_recv[:8])[0] == CMD_PREPARE_DATA: 40 | 41 | print "received CMD_PREPARE_DATA" 42 | size = unpack('I', data_recv[8:12])[0] 43 | 44 | if unpack('4H', data_recv[:8])[0] == CMD_ACK_OK: 45 | print "CMD_ACK_OK from regevent" 46 | 47 | 48 | 49 | print 'Receiving %s %s' % (size,"bytes") 50 | #data_recv, addr = self.zkclient.recvfrom(43773) 51 | #lens = len(self.data_recv) / 2 52 | #fstr = str(lens) + "H" 53 | #print "second unpack", unpack(fstr, self.data_recv) 54 | 55 | 56 | 57 | 58 | 59 | 60 | while True: #unpack('4H', data_recv[:8])[0] != CMD_ACK_OK or unpack('4H', data_recv[:8])[0] == CMD_DATA: 61 | 62 | 63 | 64 | print "COUNTER", i 65 | 66 | data_recv, addr = self.zkclient.recvfrom(size) 67 | 68 | lens = len(data_recv[:8]) / 2 69 | fstr = str(lens) + "H" 70 | if unpack(fstr, data_recv[:8])[0] == CMD_DATA: 71 | 72 | i = i +1 73 | print "data package " , unpack(fstr, data_recv[:8])[0] 74 | lens = len(data_recv) / 2 75 | fstr = str(lens) + "H" 76 | 77 | print "data unpack", unpack(fstr, data_recv) 78 | if i == 1: 79 | 80 | 81 | 82 | self.attendancedata.append(data_recv) 83 | elif i == 2: 84 | #atti.append(data_recv) 85 | self.attendancedata.append(data_recv) 86 | if unpack('4H', data_recv[:8])[0] == CMD_ACK_OK: 87 | print "CMD_ACK_OK" 88 | 89 | 90 | 91 | 92 | #acmOK(self) 93 | if unpack('4H', data_recv[:8])[0] == CMD_ACK_OK: 94 | print "CMD_ACK_OK" 95 | 96 | -------------------------------------------------------------------------------- /zklib/zkattendance.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | import xml.etree.cElementTree as et 6 | 7 | import pprint 8 | pp = pprint.PrettyPrinter(indent=4) 9 | 10 | def getSizeAttendance(self): 11 | """Checks a returned packet to see if it returned CMD_PREPARE_DATA, 12 | indicating that data packets are to be sent 13 | 14 | Returns the amount of bytes that are going to be sent""" 15 | command = unpack('HHHH', self.data_recv[:8])[0] 16 | #file = open("binw", "w") 17 | #file.write(command) 18 | if command == CMD_PREPARE_DATA: 19 | print command 20 | size = unpack('I', self.data_recv[8:12])[0] 21 | print "size:" 22 | pp.pprint(size) 23 | return size 24 | else: 25 | return False 26 | 27 | 28 | def reverseHex(hexstr): 29 | tmp = '' 30 | for i in reversed( xrange( len(hexstr)/2 ) ): 31 | tmp += hexstr[i*2:(i*2)+2] 32 | 33 | return tmp 34 | 35 | def zkgetattendance(self): 36 | """Start a connection with the time clock""" 37 | 38 | 39 | 40 | command = CMD_ATTLOG_RRQ 41 | command_string = '' 42 | chksum = 0 43 | session_id = self.session_id 44 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 45 | #file.write(self.data_recv[0:]) 46 | print "reply_id", reply_id 47 | 48 | buf = self.createHeader(command, chksum, session_id, 49 | reply_id, command_string) 50 | 51 | self.zkclient.sendto(buf, self.address) 52 | #print buf.encode("hex") 53 | try: 54 | self.data_recv, addr = self.zkclient.recvfrom(1024) 55 | 56 | if getSizeAttendance(self): 57 | bytes = getSizeAttendance(self) 58 | #bytes = bytes + 10 59 | while bytes > 0: 60 | data_recv, addr = self.zkclient.recvfrom(1032) 61 | #pp.pprint(data_recv) 62 | self.attendancedata.append(data_recv) 63 | bytes -= 1024#1024 64 | 65 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 66 | data_recv = self.zkclient.recvfrom(8) 67 | #pp.pprint(data_recv) 68 | 69 | attendance = [] 70 | if len(self.attendancedata) > 0: 71 | # The first 4 bytes don't seem to be related to the user 72 | for x in xrange(len(self.attendancedata)): 73 | if x > 0: 74 | self.attendancedata[x] = self.attendancedata[x][8:] 75 | 76 | attendancedata = ''.join( self.attendancedata ) 77 | 78 | attendancedata = attendancedata[14:] 79 | 80 | while len(attendancedata) > 0: 81 | 82 | uid, state, timestamp, space = unpack( '24s1s4s11s', attendancedata.ljust(40)[:40] ) 83 | pls = unpack('c',attendancedata[29:30]) 84 | #print "space", space 85 | #uid, state, timestamp, space = unpack(attendancedata.ljust(40)[:40] ) 86 | 87 | #print "state" 88 | #pp.pprint(state) 89 | #print int( state.encode('hex'), 16 ) 90 | 91 | 92 | # Clean up some messy characters from the user name 93 | #uid = unicode(uid.strip('\x00|\x01\x10x'), errors='ignore') 94 | uid = uid.split('\x00', 1)[0] 95 | print "%s, %s, %s" % (uid, ord(pls), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) 96 | 97 | attendance.append( ( uid, int( state.encode('hex'), 16), decode_time( int( reverseHex( timestamp.encode('hex') ), 16 ) ) ) ) 98 | 99 | attendancedata = attendancedata[40:] 100 | 101 | return attendance 102 | except: 103 | return False 104 | 105 | 106 | def zkclearattendance(self): 107 | """Start a connection with the time clock""" 108 | command = CMD_CLEAR_ATTLOG 109 | command_string = '' 110 | chksum = 0 111 | session_id = self.session_id 112 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 113 | 114 | buf = self.createHeader(command, chksum, session_id, 115 | reply_id, command_string) 116 | self.zkclient.sendto(buf, self.address) 117 | #print buf.encode("hex") 118 | try: 119 | self.data_recv, addr = self.zkclient.recvfrom(1024) 120 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 121 | return self.data_recv[8:] 122 | except: 123 | return False 124 | -------------------------------------------------------------------------------- /zklib/zkconnect.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkconnect(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_CONNECT 9 | command_string = '' 10 | chksum = 0 11 | session_id = 0 12 | reply_id = -1 + USHRT_MAX 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | 17 | self.zkclient.sendto(buf, self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | 23 | return self.checkValid( self.data_recv ) 24 | except: 25 | return False 26 | 27 | 28 | def zkdisconnect(self): 29 | """Disconnect from the clock""" 30 | command = CMD_EXIT 31 | command_string = '' 32 | chksum = 0 33 | session_id = self.session_id 34 | 35 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 36 | 37 | buf = self.createHeader(command, chksum, session_id, 38 | reply_id, command_string) 39 | 40 | self.zkclient.sendto(buf, self.address) 41 | 42 | self.data_recv, addr = self.zkclient.recvfrom(1024) 43 | return self.checkValid( self.data_recv ) 44 | 45 | -------------------------------------------------------------------------------- /zklib/zkconst.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime, date 2 | 3 | USHRT_MAX = 65535 4 | 5 | 6 | CMD_CONNECT = 1000 7 | CMD_EXIT = 1001 8 | CMD_ENABLEDEVICE = 1002 9 | CMD_DISABLEDEVICE = 1003 10 | 11 | CMD_ACK_OK = 2000 12 | CMD_ACK_ERROR = 2001 13 | CMD_ACK_DATA = 2002 14 | 15 | CMD_PREPARE_DATA = 1500 16 | CMD_DATA = 1501 17 | 18 | CMD_USERTEMP_RRQ = 9 19 | CMD_ATTLOG_RRQ = 13 20 | CMD_CLEAR_DATA = 14 21 | CMD_CLEAR_ATTLOG = 15 22 | 23 | CMD_WRITE_LCD = 66 24 | 25 | CMD_GET_TIME = 201 26 | CMD_SET_TIME = 202 27 | 28 | CMD_VERSION = 1100 29 | CMD_DEVICE = 11 30 | 31 | CMD_CLEAR_ADMIN = 20 32 | CMD_SET_USER = 8 33 | 34 | CMD_REFRESHOPTION = 1014 35 | CMD_FREE_DATA = 1502 36 | CMD_RESTART = 1004 37 | CMD_REFRESHDATA = 1013 38 | CMD_DB_RRQ = 7 39 | 40 | CMD_REG_EVENT = 500 41 | 42 | FCT_ATTLOG = '\x01' #1 & 0xFF 43 | 44 | LEVEL_USER = 0 45 | LEVEL_ADMIN = 14 46 | 47 | def encode_time(t): 48 | """Encode a timestamp send at the timeclock 49 | 50 | copied from zkemsdk.c - EncodeTime""" 51 | d = ( (t.year % 100) * 12 * 31 + ((t.month - 1) * 31) + t.day - 1) *\ 52 | (24 * 60 * 60) + (t.hour * 60 + t.minute) * 60 + t.second 53 | 54 | return d 55 | 56 | 57 | def decode_time(t): 58 | """Decode a timestamp retrieved from the timeclock 59 | 60 | copied from zkemsdk.c - DecodeTime""" 61 | second = t % 60 62 | t = t / 60 63 | 64 | minute = t % 60 65 | t = t / 60 66 | 67 | hour = t % 24 68 | t = t / 24 69 | 70 | day = t % 31+1 71 | t = t / 31 72 | 73 | month = t % 12+1 74 | t = t / 12 75 | 76 | year = t + 2000 77 | 78 | d = datetime(year, month, day, hour, minute, second) 79 | 80 | return d 81 | 82 | -------------------------------------------------------------------------------- /zklib/zkdevice.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkdevicename(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = '~DeviceName' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | 26 | def zkenabledevice(self): 27 | """Start a connection with the time clock""" 28 | command = CMD_ENABLEDEVICE 29 | command_string = '' 30 | chksum = 0 31 | session_id = self.session_id 32 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 33 | 34 | buf = self.createHeader(command, chksum, session_id, 35 | reply_id, command_string) 36 | self.zkclient.sendto(buf, self.address) 37 | #print buf.encode("hex") 38 | try: 39 | self.data_recv, addr = self.zkclient.recvfrom(1024) 40 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 41 | return self.data_recv[8:] 42 | except: 43 | return False 44 | 45 | def zkdisabledevice(self): 46 | """Start a connection with the time clock""" 47 | command = CMD_DISABLEDEVICE 48 | command_string = '\x00\x00' 49 | chksum = 0 50 | session_id = self.session_id 51 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 52 | 53 | buf = self.createHeader(command, chksum, session_id, 54 | reply_id, command_string) 55 | self.zkclient.sendto(buf, self.address) 56 | #print buf.encode("hex") 57 | try: 58 | self.data_recv, addr = self.zkclient.recvfrom(1024) 59 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 60 | return self.data_recv[8:] 61 | except: 62 | return False 63 | -------------------------------------------------------------------------------- /zklib/zkextendfmt.py: -------------------------------------------------------------------------------- 1 | def zkextendfmt(self): 2 | try: 3 | test = self.exttrynumber 4 | except: 5 | self.exttrynumber = 1 6 | 7 | data_seq=[ self.data_recv.encode("hex")[4:6], self.data_recv.encode("hex")[6:8] ] 8 | print data_seq 9 | if self.exttrynumber == 1: 10 | plus1 = 0 11 | plus2 = 0 12 | else: 13 | plus1 = -1 14 | plus2 = +1 15 | 16 | 17 | desc = ": +"+hex( int('99', 16)+plus1 ).lstrip('0x')+", +"+hex(int('b1', 16)+plus2).lstrip("0x") 18 | self.data_seq1 = hex( int( data_seq[0], 16 ) + int( '99', 16 ) + plus1 ).lstrip("0x") 19 | self.data_seq2 = hex( int( data_seq[1], 16 ) + int( 'b1', 16 ) + plus2 ).lstrip("0x") 20 | 21 | if len(self.data_seq1) >= 3: 22 | #self.data_seq2 = hex( int( self.data_seq2, 16 ) + int( self.data_seq1[:1], 16) ).lstrip("0x") 23 | self.data_seq1 = self.data_seq1[-2:] 24 | 25 | if len(self.data_seq2) >= 3: 26 | #self.data_seq1 = hex( int( self.data_seq1, 16 ) + int( self.data_seq2[:1], 16) ).lstrip("0x") 27 | self.data_seq2 = self.data_seq2[-2:] 28 | 29 | 30 | if len(self.data_seq1) <= 1: 31 | self.data_seq1 = "0"+self.data_seq1 32 | 33 | if len(self.data_seq2) <= 1: 34 | self.data_seq2 = "0"+self.data_seq2 35 | 36 | 37 | counter = hex( self.counter ).lstrip("0x") 38 | if len(counter): 39 | counter = "0" + counter 40 | print self.data_seq1+" "+self.data_seq2+desc 41 | data = "0b00"+self.data_seq1+self.data_seq2+self.id_com+counter+"007e457874656e64466d7400" 42 | self.zkclient.sendto(data.decode("hex"), self.address) 43 | print data 44 | try: 45 | self.data_recv, addr = self.zkclient.recvfrom(1024) 46 | except: 47 | if self.exttrynumber == 1: 48 | self.exttrynumber = 2 49 | tmp = zkextendfmt(self) 50 | if len(tmp) < 1: 51 | self.exttrynumber = 1 52 | 53 | self.id_com = self.data_recv.encode("hex")[8:12] 54 | self.counter = self.counter+1 55 | print self.data_recv.encode("hex") 56 | return self.data_recv[8:] 57 | -------------------------------------------------------------------------------- /zklib/zkextendoplog.py: -------------------------------------------------------------------------------- 1 | def zkextendoplog(self, index=0): 2 | try: 3 | test = self.extlogtrynumber 4 | except: 5 | self.extlogtrynumber = 1 6 | 7 | data_seq=[ self.data_recv.encode("hex")[4:6], self.data_recv.encode("hex")[6:8] ] 8 | print data_seq 9 | 10 | if index==0: 11 | self.data_seq1 = hex( int( data_seq[0], 16 ) + int( '104', 16 ) ).lstrip("0x") 12 | self.data_seq2 = hex( int( data_seq[1], 16 ) + int( '19', 16 ) ).lstrip("0x") 13 | desc = ": +104, +19" 14 | header="0b00" 15 | elif index==1: 16 | self.data_seq1 = hex( abs( int( data_seq[0], 16 ) - int( '2c', 16 ) ) ).lstrip("0x") 17 | self.data_seq2 = hex( abs( int( data_seq[1], 16 ) - int( '2', 16 ) ) ).lstrip("0x") 18 | desc = ": -2c, -2" 19 | header="d107" 20 | elif index>=2: 21 | self.data_seq1 = hex( abs( int( data_seq[0], 16 ) - int( '2c', 16 ) ) ).lstrip("0x") 22 | self.data_seq2 = hex( abs( int( data_seq[1], 16 ) - int( '2', 16 ) ) ).lstrip("0x") 23 | desc = ": -2c, -2" 24 | header="ffff" 25 | 26 | 27 | print self.data_seq1+" "+self.data_seq2 28 | if len(self.data_seq1) >= 3: 29 | self.data_seq2 = hex( int( self.data_seq2, 16 ) + int( self.data_seq1[:1], 16) ).lstrip("0x") 30 | self.data_seq1 = self.data_seq1[-2:] 31 | 32 | if len(self.data_seq2) >= 3: 33 | self.data_seq1 = hex( int( self.data_seq1, 16 ) + int( self.data_seq2[:1], 16) ).lstrip("0x") 34 | self.data_seq2 = self.data_seq2[-2:] 35 | 36 | if len(self.data_seq1) <= 1: 37 | self.data_seq1 = "0"+self.data_seq1 38 | 39 | if len(self.data_seq2) <= 1: 40 | self.data_seq2 = "0"+self.data_seq2 41 | 42 | 43 | counter = hex( self.counter ).lstrip("0x") 44 | if len(counter): 45 | counter = "0" + counter 46 | 47 | print self.data_seq1+" "+self.data_seq2+desc 48 | data = header+self.data_seq1+self.data_seq2+self.id_com+counter+"00457874656e644f504c6f6700" 49 | self.zkclient.sendto(data.decode("hex"), self.address) 50 | print data 51 | try: 52 | self.data_recv, addr = self.zkclient.recvfrom(1024) 53 | except: 54 | bingung=1 55 | if self.extlogtrynumber == 1: 56 | self.extlogtrynumber = 2 57 | zkextendoplog(self) 58 | 59 | self.id_com = self.data_recv.encode("hex")[8:12] 60 | self.counter = self.counter+1 61 | print self.data_recv.encode("hex") 62 | return self.data_recv[8:] 63 | -------------------------------------------------------------------------------- /zklib/zkface.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkfaceon(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = 'FaceFunOn' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | -------------------------------------------------------------------------------- /zklib/zkfreedata.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | 7 | def zkfreedata(self): 8 | """Tell device to free data for transmisison""" 9 | command = CMD_FREE_DATA 10 | command_string = '' 11 | chksum = 0 12 | session_id = self.session_id 13 | 14 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 15 | 16 | buf = self.createHeader(command,chksum, session_id,reply_id, command_string) 17 | self.zkclient.sendto(buf,self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | return self.data_recv[8:] 23 | except: 24 | return False -------------------------------------------------------------------------------- /zklib/zklib.py: -------------------------------------------------------------------------------- 1 | from socket import * 2 | 3 | import sys 4 | import select 5 | import errno 6 | import time 7 | 8 | from struct import pack, unpack 9 | from datetime import datetime, date 10 | 11 | from zkconnect import * 12 | from zkversion import * 13 | from zkos import * 14 | from zkextendfmt import * 15 | from zkextendoplog import * 16 | from zkplatform import * 17 | from zkworkcode import * 18 | from zkssr import * 19 | from zkpin import * 20 | from zkface import * 21 | from zkserialnumber import * 22 | from zkdevice import * 23 | from zkuser import * 24 | from zkattendance import * 25 | from zktime import * 26 | from zkprepare import * 27 | from zkrefreshdata import * 28 | from zkfreedata import * 29 | from zkrestart import * 30 | from zkAtt import * 31 | from zkDBRrq import * 32 | from zkRegevent import * 33 | from zksoapAtt import * 34 | 35 | class ZKLib: 36 | 37 | def __init__(self, ip, port): 38 | self.address = (ip, port) 39 | self.ip = ip 40 | self.zkclient = socket(AF_INET, SOCK_DGRAM) 41 | self.zkclient.settimeout(5) 42 | self.session_id = 0 43 | self.userdata = [] 44 | self.attendancedata = [] 45 | self.datas = [] 46 | #self.attendancedataa = [] 47 | 48 | 49 | def createChkSum(self, p): 50 | """This function calculates the chksum of the packet to be sent to the 51 | time clock 52 | 53 | Copied from zkemsdk.c""" 54 | l = len(p) 55 | chksum = 0 56 | while l > 1: 57 | chksum += unpack('H', pack('BB', p[0], p[1]))[0] 58 | 59 | p = p[2:] 60 | if chksum > USHRT_MAX: 61 | chksum -= USHRT_MAX 62 | l -= 2 63 | 64 | 65 | if l: 66 | chksum = chksum + p[-1] 67 | 68 | while chksum > USHRT_MAX: 69 | chksum -= USHRT_MAX 70 | 71 | chksum = ~chksum 72 | 73 | while chksum < 0: 74 | chksum += USHRT_MAX 75 | 76 | return pack('H', chksum) 77 | 78 | 79 | def createHeader(self, command, chksum, session_id, reply_id, 80 | command_string): 81 | """This function puts a the parts that make up a packet together and 82 | packs them into a byte string""" 83 | buf = pack('HHHH', command, chksum, 84 | session_id, reply_id) + command_string 85 | 86 | buf = unpack('8B'+'%sB' % len(command_string), buf) 87 | 88 | chksum = unpack('H', self.createChkSum(buf))[0] 89 | #print unpack('H', self.createChkSum(buf)) 90 | reply_id += 1 91 | if reply_id >= USHRT_MAX: 92 | reply_id -= USHRT_MAX 93 | 94 | buf = pack('HHHH', command, chksum, session_id, reply_id) 95 | return buf + command_string 96 | 97 | 98 | def checkValid(self, reply): 99 | """Checks a returned packet to see if it returned CMD_ACK_OK, 100 | indicating success""" 101 | command = unpack('HHHH', reply[:8])[0] 102 | 103 | if command == CMD_ACK_OK: 104 | print "CMD_ACK_OK" 105 | return True 106 | else: 107 | return False 108 | 109 | def connect(self): 110 | return zkconnect(self) 111 | 112 | def disconnect(self): 113 | return zkdisconnect(self) 114 | 115 | def version(self): 116 | return zkversion(self) 117 | 118 | def osversion(self): 119 | return zkos(self) 120 | 121 | def extendFormat(self): 122 | return zkextendfmt(self) 123 | 124 | def extendOPLog(self, index=0): 125 | return zkextendoplog(self, index) 126 | 127 | def platform(self): 128 | return zkplatform(self) 129 | 130 | def fmVersion(self): 131 | return zkplatformVersion(self) 132 | 133 | def workCode(self): 134 | return zkworkcode(self) 135 | 136 | def ssr(self): 137 | return zkssr(self) 138 | 139 | def pinWidth(self): 140 | return zkpinwidth(self) 141 | 142 | def faceFunctionOn(self): 143 | return zkfaceon(self) 144 | 145 | def serialNumber(self): 146 | return zkserialnumber(self) 147 | 148 | def deviceName(self): 149 | return zkdevicename(self) 150 | 151 | def disableDevice(self): 152 | return zkdisabledevice(self) 153 | 154 | def enableDevice(self): 155 | return zkenabledevice(self) 156 | 157 | def getUser(self): 158 | return zkgetuser(self) 159 | 160 | def setUser(self, uid, userid, name, password, role): 161 | return zksetuser(self, uid, userid, name, password, role) 162 | 163 | def clearUser(self): 164 | return zkclearuser(self) 165 | 166 | def clearAdmin(self): 167 | return zkclearadmin(self) 168 | 169 | def getAttendance(self): 170 | return zkgetattendance(self) 171 | 172 | def clearAttendance(self): 173 | return zkclearattendance(self) 174 | 175 | def setTime(self, t): 176 | return zksettime(self, t) 177 | 178 | def getTime(self): 179 | return zkgettime(self) 180 | 181 | def prepareData(self): 182 | return zkprepare(self) 183 | 184 | 185 | def refreshData(self): 186 | return zkrefreshdata(self) 187 | 188 | def freeData(self): 189 | return zkfreedata(self) 190 | 191 | def reboot(self): 192 | return zkrestart(self) 193 | 194 | def testatt(self): 195 | return zkAtt(self) 196 | 197 | def getData(self): 198 | return zkDBRrq(self) 199 | 200 | def regEvent(self): 201 | return zkRegevent(self) 202 | 203 | def getsAtt(self, ip): 204 | return zksoapAtt(self) 205 | 206 | 207 | -------------------------------------------------------------------------------- /zklib/zkos.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkos(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = '~OS' 10 | chksum = 0 11 | session_id = self.session_id 12 | 13 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 14 | 15 | buf = self.createHeader(command, chksum, session_id, 16 | reply_id, command_string) 17 | self.zkclient.sendto(buf, self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | return self.data_recv[8:] 23 | except: 24 | return False 25 | -------------------------------------------------------------------------------- /zklib/zkpin.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkpinwidth(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = '~PIN2Width' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | -------------------------------------------------------------------------------- /zklib/zkplatform.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkplatform(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = '~Platform' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | 26 | def zkplatformVersion(self): 27 | """Start a connection with the time clock""" 28 | command = CMD_DEVICE 29 | command_string = '~ZKFPVersion' 30 | chksum = 0 31 | session_id = self.session_id 32 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 33 | 34 | buf = self.createHeader(command, chksum, session_id, 35 | reply_id, command_string) 36 | self.zkclient.sendto(buf, self.address) 37 | #print buf.encode("hex") 38 | try: 39 | self.data_recv, addr = self.zkclient.recvfrom(1024) 40 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 41 | return self.data_recv[8:] 42 | except: 43 | return False 44 | -------------------------------------------------------------------------------- /zklib/zkprepare.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | 7 | def zkprepare(self): 8 | """Tell device to prepare for data transmisison""" 9 | command = CMD_PREPARE_DATA 10 | command_string = '' 11 | chksum = 0 12 | session_id = self.session_id 13 | 14 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 15 | 16 | buf = self.createHeader(command,chksum, session_id,reply_id, command_string) 17 | self.zkclient.sendto(buf,self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | return self.data_recv[8:] 23 | except: 24 | return False -------------------------------------------------------------------------------- /zklib/zkrefreshdata: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | 7 | def zkrefreshdata(self): 8 | """Tell device to prepare for data transmisison""" 9 | command = CMD_REFRESHDATA 10 | command_string = '' 11 | chksum = 0 12 | session_id = self.session_id 13 | 14 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 15 | 16 | buf = self.createHeader(command,chksum, session_id,reply_id, command_string) 17 | self.zkclient.sendto(buf,self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | return self.data_recv[8:] 23 | except: 24 | return False -------------------------------------------------------------------------------- /zklib/zkrefreshdata.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | 7 | def zkrefreshdata(self): 8 | """Tell device to refresh data for transmisison""" 9 | command = CMD_REFRESHDATA 10 | command_string = '' 11 | chksum = 0 12 | session_id = self.session_id 13 | 14 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 15 | 16 | buf = self.createHeader(command,chksum, session_id,reply_id, command_string) 17 | self.zkclient.sendto(buf,self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | return self.data_recv[8:] 23 | except: 24 | return False -------------------------------------------------------------------------------- /zklib/zkrestart.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | 7 | def zkrestart(self): 8 | """Tell device to reboot""" 9 | command = CMD_RESTART 10 | command_string = '' 11 | chksum = 0 12 | session_id = self.session_id 13 | 14 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 15 | 16 | buf = self.createHeader(command,chksum, session_id,reply_id, command_string) 17 | self.zkclient.sendto(buf,self.address) 18 | 19 | try: 20 | self.data_recv, addr = self.zkclient.recvfrom(1024) 21 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 22 | return self.data_recv[8:] 23 | except: 24 | return False -------------------------------------------------------------------------------- /zklib/zkserialnumber.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkserialnumber(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = '~SerialNumber' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | -------------------------------------------------------------------------------- /zklib/zksoapAtt.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | import xml.etree.cElementTree as et 6 | import requests 7 | import datetime 8 | 9 | 10 | 11 | 12 | def zksoapAtt(self): 13 | 14 | data = [] 15 | url = "http://" + str(self.ip) + "/iWsService" 16 | headers = {'content-type': 'text/xml'} 17 | body = """ 0All""" 20 | response = requests.post(url,data=body,headers=headers) 21 | #print response.text 22 | temp = response.text 23 | 24 | if temp: 25 | tree = et.fromstring(temp) 26 | container = tree.findall("Row") 27 | 28 | for elem in container: 29 | 30 | uid = elem.findtext("PIN") 31 | DateTime = elem.findtext("DateTime") 32 | ver = elem.findtext("Verified") 33 | state = elem.findtext("Status") 34 | workCode = elem.findtext("WorkCode") 35 | data.append((int(uid),datetime.datetime.strptime(str(DateTime),'%Y-%m-%d %H:%M:%S'),int(ver),int(state),int(workCode))) 36 | 37 | return data 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /zklib/zkssr.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkssr(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = '~SSR' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | -------------------------------------------------------------------------------- /zklib/zktime.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def reverseHex(hexstr): 7 | tmp = '' 8 | for i in reversed( xrange( len(hexstr)/2 ) ): 9 | tmp += hexstr[i*2:(i*2)+2] 10 | 11 | return tmp 12 | 13 | def zksettime(self, t): 14 | """Start a connection with the time clock""" 15 | command = CMD_SET_TIME 16 | command_string = pack('I',encode_time(t)) 17 | chksum = 0 18 | session_id = self.session_id 19 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 20 | 21 | buf = self.createHeader(command, chksum, session_id, 22 | reply_id, command_string) 23 | self.zkclient.sendto(buf, self.address) 24 | #print buf.encode("hex") 25 | try: 26 | self.data_recv, addr = self.zkclient.recvfrom(1024) 27 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 28 | return self.data_recv[8:] 29 | except: 30 | return False 31 | 32 | 33 | def zkgettime(self): 34 | """Start a connection with the time clock""" 35 | command = CMD_GET_TIME 36 | command_string = '' 37 | chksum = 0 38 | session_id = self.session_id 39 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 40 | 41 | buf = self.createHeader(command, chksum, session_id, 42 | reply_id, command_string) 43 | self.zkclient.sendto(buf, self.address) 44 | #print buf.encode("hex") 45 | try: 46 | self.data_recv, addr = self.zkclient.recvfrom(1024) 47 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 48 | return decode_time( int( reverseHex( self.data_recv[8:].encode("hex") ), 16 ) ) 49 | except: 50 | return False 51 | -------------------------------------------------------------------------------- /zklib/zkuser.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def getSizeUser(self): 7 | """Checks a returned packet to see if it returned CMD_PREPARE_DATA, 8 | indicating that data packets are to be sent 9 | 10 | Returns the amount of bytes that are going to be sent""" 11 | command = unpack('HHHH', self.data_recv[:8])[0] 12 | if command == CMD_PREPARE_DATA: 13 | size = unpack('I', self.data_recv[8:12])[0] 14 | return size 15 | else: 16 | return False 17 | 18 | 19 | def zksetuser(self, uid, userid, name, password, role): 20 | """Start a connection with the time clock""" 21 | command = CMD_SET_USER 22 | command_string = pack('sxs8s28ss7sx8s16s', chr( uid ), chr(role), password, name, chr(1), '', userid, '' ) 23 | chksum = 0 24 | session_id = self.session_id 25 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 26 | 27 | buf = self.createHeader(command, chksum, session_id, 28 | reply_id, command_string) 29 | self.zkclient.sendto(buf, self.address) 30 | #print buf.encode("hex") 31 | try: 32 | self.data_recv, addr = self.zkclient.recvfrom(1024) 33 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 34 | return self.data_recv[8:] 35 | except: 36 | return False 37 | 38 | 39 | def zkgetuser(self): 40 | """Start a connection with the time clock""" 41 | command = CMD_USERTEMP_RRQ 42 | command_string = '\x05' 43 | chksum = 0 44 | session_id = self.session_id 45 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 46 | 47 | buf = self.createHeader(command, chksum, session_id, 48 | reply_id, command_string) 49 | self.zkclient.sendto(buf, self.address) 50 | #print buf.encode("hex") 51 | try: 52 | self.data_recv, addr = self.zkclient.recvfrom(1024) 53 | 54 | 55 | if getSizeUser(self): 56 | bytes = getSizeUser(self) 57 | 58 | while bytes > 0: 59 | data_recv, addr = self.zkclient.recvfrom(1032) 60 | self.userdata.append(data_recv) 61 | bytes -= 1024 62 | 63 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 64 | data_recv = self.zkclient.recvfrom(8) 65 | 66 | users = {} 67 | if len(self.userdata) > 0: 68 | # The first 4 bytes don't seem to be related to the user 69 | for x in xrange(len(self.userdata)): 70 | if x > 0: 71 | self.userdata[x] = self.userdata[x][8:] 72 | 73 | userdata = ''.join( self.userdata ) 74 | 75 | userdata = userdata[11:] 76 | 77 | while len(userdata) > 72: 78 | 79 | uid, role, password, name, userid = unpack( '2s2s8s28sx31s', userdata.ljust(72)[:72] ) 80 | 81 | uid = int( uid.encode("hex"), 16) 82 | # Clean up some messy characters from the user name 83 | password = password.split('\x00', 1)[0] 84 | password = unicode(password.strip('\x00|\x01\x10x'), errors='ignore') 85 | 86 | #uid = uid.split('\x00', 1)[0] 87 | userid = unicode(userid.strip('\x00|\x01\x10x'), errors='ignore') 88 | 89 | name = name.split('\x00', 1)[0] 90 | 91 | if name.strip() == "": 92 | name = uid 93 | 94 | users[uid] = (userid, name, int( role.encode("hex"), 16 ), password) 95 | 96 | #print("%d, %s, %s, %s, %s" % (uid, userid, name, int( role.encode("hex"), 16 ), password)) 97 | userdata = userdata[72:] 98 | 99 | return users 100 | except: 101 | return False 102 | 103 | 104 | def zkclearuser(self): 105 | """Start a connection with the time clock""" 106 | command = CMD_CLEAR_DATA 107 | command_string = '' 108 | chksum = 0 109 | session_id = self.session_id 110 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 111 | 112 | buf = self.createHeader(command, chksum, session_id, 113 | reply_id, command_string) 114 | self.zkclient.sendto(buf, self.address) 115 | #print buf.encode("hex") 116 | try: 117 | self.data_recv, addr = self.zkclient.recvfrom(1024) 118 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 119 | return self.data_recv[8:] 120 | except: 121 | return False 122 | 123 | 124 | def zkclearadmin(self): 125 | """Start a connection with the time clock""" 126 | command = CMD_CLEAR_ADMIN 127 | command_string = '' 128 | chksum = 0 129 | session_id = self.session_id 130 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 131 | 132 | buf = self.createHeader(command, chksum, session_id, 133 | reply_id, command_string) 134 | self.zkclient.sendto(buf, self.address) 135 | #print buf.encode("hex") 136 | try: 137 | self.data_recv, addr = self.zkclient.recvfrom(1024) 138 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 139 | return self.data_recv[8:] 140 | except: 141 | return False 142 | -------------------------------------------------------------------------------- /zklib/zkversion.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkversion(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_VERSION 9 | command_string = '' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | 25 | -------------------------------------------------------------------------------- /zklib/zkworkcode.py: -------------------------------------------------------------------------------- 1 | from struct import pack, unpack 2 | from datetime import datetime, date 3 | 4 | from zkconst import * 5 | 6 | def zkworkcode(self): 7 | """Start a connection with the time clock""" 8 | command = CMD_DEVICE 9 | command_string = 'WorkCode' 10 | chksum = 0 11 | session_id = self.session_id 12 | reply_id = unpack('HHHH', self.data_recv[:8])[3] 13 | 14 | buf = self.createHeader(command, chksum, session_id, 15 | reply_id, command_string) 16 | self.zkclient.sendto(buf, self.address) 17 | #print buf.encode("hex") 18 | try: 19 | self.data_recv, addr = self.zkclient.recvfrom(1024) 20 | self.session_id = unpack('HHHH', self.data_recv[:8])[2] 21 | return self.data_recv[8:] 22 | except: 23 | return False 24 | -------------------------------------------------------------------------------- /zktest.py: -------------------------------------------------------------------------------- 1 | import sys 2 | sys.path.append("zklib") 3 | 4 | import zklib 5 | import time 6 | import zkconst 7 | 8 | zk = zklib.ZKLib("192.168.1.201", 4370) 9 | 10 | ret = zk.connect() 11 | print "connection:", ret 12 | 13 | if ret == True: 14 | print "Disable Device", zk.disableDevice() 15 | 16 | print "ZK Version:", zk.version() 17 | print "OS Version:", zk.osversion() 18 | """ 19 | print "Extend Format:", zk.extendFormat() 20 | print "Extend OP Log:", zk.extendOPLog() 21 | """ 22 | 23 | print "Platform:", zk.platform() 24 | print "Platform Version:", zk.fmVersion() 25 | print "Work Code:", zk.workCode() 26 | print "Work Code:", zk.workCode() 27 | print "SSR:", zk.ssr() 28 | print "Pin Width:", zk.pinWidth() 29 | print "Face Function On:", zk.faceFunctionOn() 30 | print "Serial Number:", zk.serialNumber() 31 | print "Device Name:", zk.deviceName() 32 | 33 | data_user = zk.getUser() 34 | print "Get User:" 35 | if data_user: 36 | for uid in data_user: 37 | 38 | if data_user[uid][2] == 14: 39 | level = 'Admin' 40 | else: 41 | level = 'User' 42 | print "[UID %d]: ID: %s, Name: %s, Level: %s, Password: %s" % (uid, data_user[uid][0], data_user[uid][1], level, data_user[uid][3]) 43 | 44 | # print "Clear Admin:", zk.clearAdmin() 45 | #zk.setUser(uid=61, userid='41', name='Dony Wahyu Isp', password='123456', role=zkconst.LEVEL_ADMIN) 46 | 47 | 48 | attendance = zk.getsAtt('192.168.1.201') 49 | print "Get Attendance:" 50 | 51 | if (attendance): 52 | for lattendance in attendance: 53 | if lattendance[1] == 15: 54 | state = 'Check In' 55 | elif lattendance[1] == 0: 56 | state = 'Check Out' 57 | else: 58 | state = 'Undefined' 59 | 60 | print "date %s, Jam %s: %s, Status: %s" % (lattendance[2].date(), lattendance[2].time(), lattendance[0], state) 61 | 62 | # print "Clear Attendance:", zk.clearAttendance() 63 | 64 | print "Get Time:", zk.getTime() 65 | 66 | print "Enable Device", zk.enableDevice() 67 | 68 | print "Disconnect:", zk.disconnect() 69 | --------------------------------------------------------------------------------