├── .gitignore
├── LICENSE
├── OscScreenGrabLAN.py
├── README.md
├── Rigol_functions.py
├── captures
├── .gitignore
├── DS1104Z_DS1ZA164658712_2015-05-10_23.14.43.png
├── DS1104Z_DS1ZA164658712_2015-05-10_23.40.57.png
├── DS1104Z_DS1ZA164658712_2015-05-25_00.48.34.png
├── DS1104Z_DS1ZA164658712_2015-05-25_00.49.07.csv
└── Spreadsheet look for CSV.png
└── telnetlib_receive_all.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # *** START section for manually edited lines
2 |
3 | # ignore debugging log generated by this project
4 | *.py.log
5 |
6 | # *** STOP section for manually edited lines
7 |
8 |
9 |
10 | # Byte-compiled / optimized / DLL files
11 | __pycache__/
12 | *.py[cod]
13 | *$py.class
14 |
15 | # C extensions
16 | *.so
17 |
18 | # Distribution / packaging
19 | .Python
20 | env/
21 | build/
22 | develop-eggs/
23 | dist/
24 | downloads/
25 | eggs/
26 | .eggs/
27 | lib/
28 | lib64/
29 | parts/
30 | sdist/
31 | var/
32 | *.egg-info/
33 | .installed.cfg
34 | *.egg
35 |
36 | # PyInstaller
37 | # Usually these files are written by a python script from a template
38 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
39 | *.manifest
40 | *.spec
41 |
42 | # Installer logs
43 | pip-log.txt
44 | pip-delete-this-directory.txt
45 |
46 | # Unit test / coverage reports
47 | htmlcov/
48 | .tox/
49 | .coverage
50 | .coverage.*
51 | .cache
52 | nosetests.xml
53 | coverage.xml
54 | *,cover
55 | .hypothesis/
56 |
57 | # Translations
58 | *.mo
59 | *.pot
60 |
61 | # Django stuff:
62 | *.log
63 | local_settings.py
64 |
65 | # Flask stuff:
66 | instance/
67 | .webassets-cache
68 |
69 | # Scrapy stuff:
70 | .scrapy
71 |
72 | # Sphinx documentation
73 | docs/_build/
74 |
75 | # PyBuilder
76 | target/
77 |
78 | # IPython Notebook
79 | .ipynb_checkpoints
80 |
81 | # pyenv
82 | .python-version
83 |
84 | # celery beat schedule file
85 | celerybeat-schedule
86 |
87 | # dotenv
88 | .env
89 |
90 | # virtualenv
91 | venv/
92 | ENV/
93 |
94 | # Spyder project settings
95 | .spyderproject
96 |
97 | # Rope project settings
98 | .ropeproject
99 |
--------------------------------------------------------------------------------
/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 |
341 |
--------------------------------------------------------------------------------
/OscScreenGrabLAN.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from telnetlib_receive_all import Telnet
4 | from Rigol_functions import *
5 | import time
6 | from PIL import Image
7 | import StringIO
8 | import sys
9 | import os
10 | import platform
11 | import logging
12 |
13 | __version__ = 'v1.1.0'
14 | # Added TMC Blockheader decoding
15 | # Added possibility to manually allow run for scopes other then DS1000Z
16 | __author__ = 'RoGeorge'
17 |
18 | #
19 | # TODO: Write all SCPI commands in their short name, with capitals
20 | # TODO: Add ignore instrument model switch instead of asking
21 | #
22 | # TODO: Detect if the scope is in RUN or in STOP mode (looking at the length of data extracted)
23 | # TODO: Add logic for 1200/mdep points to avoid displaying the 'Invalid Input!' message
24 | # TODO: Add message for csv data points: mdep (all) or 1200 (screen), depending on RUN/STOP state, MATH and WAV:MODE
25 | # TODO: Add STOP scope switch
26 | #
27 | # TODO: Add debug switch
28 | # TODO: Clarify info, warning, error, debug and print messages
29 | #
30 | # TODO: Add automated version increase
31 | #
32 | # TODO: Extract all memory datapoints. For the moment, CSV is limited to the displayed 1200 datapoints.
33 | # TODO: Use arrays instead of strings and lists for csv mode.
34 | #
35 | # TODO: variables/functions name refactoring
36 | # TODO: Fine tune maximum chunk size request
37 | # TODO: Investigate scaling. Sometimes 3.0e-008 instead of expected 3.0e-000
38 | # TODO: Add timestamp and mark the trigger point as t0
39 | # TODO: Use channels label instead of chan1, chan2, chan3, chan4, math
40 | # TODO: Add command line parameters file path
41 | # TODO: Speed-up the transfer, try to replace Telnet with direct TCP
42 | # TODO: Add GUI
43 | # TODO: Add browse and custom filename selection
44 | # TODO: Create executable distributions
45 | #
46 |
47 | # Set the desired logging level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
48 | logging.basicConfig(level=logging.INFO,
49 | format='%(asctime)s - %(levelname)s - %(message)s',
50 | filename=os.path.basename(sys.argv[0]) + '.log',
51 | filemode='w')
52 |
53 | logging.info("***** New run started...")
54 | logging.info("OS Platform: " + str(platform.uname()))
55 | log_running_python_versions()
56 |
57 | # Update the next lines for your own default settings:
58 | path_to_save = "captures/"
59 | save_format = "PNG"
60 | IP_DS1104Z = "192.168.1.3"
61 |
62 | # Rigol/LXI specific constants
63 | port = 5555
64 |
65 | big_wait = 10
66 | smallWait = 1
67 |
68 | company = 0
69 | model = 1
70 | serial = 2
71 |
72 | # Check command line parameters
73 | script_name = os.path.basename(sys.argv[0])
74 |
75 |
76 | def print_help():
77 | print
78 | print "Usage:"
79 | print " " + "python " + script_name + " png|bmp|csv [oscilloscope_IP [save_path]]"
80 | print
81 | print "Usage examples:"
82 | print " " + "python " + script_name + " png"
83 | print " " + "python " + script_name + " csv 192.168.1.3"
84 | print
85 | print "The following usage cases are not yet implemented:"
86 | print " " + "python " + script_name + " bmp 192.168.1.3 my_place_for_captures"
87 | print
88 | print "This program captures either the waveform or the whole screen"
89 | print " of a Rigol DS1000Z series oscilloscope, then save it on the computer"
90 | print " as a CSV, PNG or BMP file with a timestamp in the file name."
91 | print
92 | print " The program is using LXI protocol, so the computer"
93 | print " must have LAN connection with the oscilloscope."
94 | print " USB and/or GPIB connections are not used by this software."
95 | print
96 | print " No VISA, IVI or Rigol drivers are needed."
97 | print
98 |
99 | # Read/verify file type
100 | if len(sys.argv) <= 1:
101 | print_help()
102 | sys.exit("Warning - wrong command line parameters.")
103 | elif sys.argv[1].lower() not in ["png", "bmp", "csv"]:
104 | print_help()
105 | print "This file type is not supported: ", sys.argv[1]
106 | sys.exit("ERROR")
107 |
108 | file_format = sys.argv[1].lower()
109 |
110 | # Read IP
111 | if len(sys.argv) > 1:
112 | IP_DS1104Z = sys.argv[2]
113 |
114 | # Check network response (ping)
115 | if platform.system() == "Windows":
116 | response = os.system("ping -n 1 " + IP_DS1104Z + " > nul")
117 | else:
118 | response = os.system("ping -c 1 " + IP_DS1104Z + " > /dev/null")
119 |
120 | if response != 0:
121 | print
122 | print "WARNING! No response pinging " + IP_DS1104Z
123 | print "Check network cables and settings."
124 | print "You should be able to ping the oscilloscope."
125 |
126 | # Open a modified telnet session
127 | # The default telnetlib drops 0x00 characters,
128 | # so a modified library 'telnetlib_receive_all' is used instead
129 | tn = Telnet(IP_DS1104Z, port)
130 | instrument_id = command(tn, "*IDN?") # ask for instrument ID
131 |
132 | # Check if instrument is set to accept LAN commands
133 | if instrument_id == "command error":
134 | print "Instrument reply:", instrument_id
135 | print "Check the oscilloscope settings."
136 | print "Utility -> IO Setting -> RemoteIO -> LAN must be ON"
137 | sys.exit("ERROR")
138 |
139 | # Check if instrument is indeed a Rigol DS1000Z series
140 | id_fields = instrument_id.split(",")
141 | if (id_fields[company] != "RIGOL TECHNOLOGIES") or \
142 | (id_fields[model][:3] != "DS1") or (id_fields[model][-1] != "Z"):
143 | print "Found instrument model", "'" + id_fields[model] + "'", "from", "'" + id_fields[company] + "'"
144 | print "WARNING: No Rigol from series DS1000Z found at", IP_DS1104Z
145 | print
146 | typed = raw_input("ARE YOU SURE YOU WANT TO CONTINUE? (No/Yes):")
147 | if typed != 'Yes':
148 | sys.exit('Nothing done. Bye!')
149 |
150 | print "Instrument ID:",
151 | print instrument_id
152 |
153 | # Prepare filename as C:\MODEL_SERIAL_YYYY-MM-DD_HH.MM.SS
154 | timestamp = time.strftime("%Y-%m-%d_%H.%M.%S", time.localtime())
155 | filename = path_to_save + id_fields[model] + "_" + id_fields[serial] + "_" + timestamp
156 |
157 | if file_format in ["png", "bmp"]:
158 | # Ask for an oscilloscope display print screen
159 | print "Receiving screen capture..."
160 | buff = command(tn, ":DISP:DATA?")
161 |
162 | expectedBuffLen = expected_buff_bytes(buff)
163 | # Just in case the transfer did not complete in the expected time, read the remaining 'buff' chunks
164 | while len(buff) < expectedBuffLen:
165 | logging.warning("Received LESS data then expected! (" +
166 | str(len(buff)) + " out of " + str(expectedBuffLen) + " expected 'buff' bytes.)")
167 | tmp = tn.read_until("\n", smallWait)
168 | if len(tmp) == 0:
169 | break
170 | buff += tmp
171 | logging.warning(str(len(tmp)) + " leftover bytes added to 'buff'.")
172 |
173 | if len(buff) < expectedBuffLen:
174 | logging.error("After reading all data chunks, 'buff' is still shorter then expected! (" +
175 | str(len(buff)) + " out of " + str(expectedBuffLen) + " expected 'buff' bytes.)")
176 | sys.exit("ERROR")
177 |
178 | # Strip TMC Blockheader and keep only the data
179 | tmcHeaderLen = tmc_header_bytes(buff)
180 | expectedDataLen = expected_data_bytes(buff)
181 | buff = buff[tmcHeaderLen: tmcHeaderLen+expectedDataLen]
182 |
183 | # Save as PNG or BMP according to file_format
184 | im = Image.open(StringIO.StringIO(buff))
185 | im.save(filename + "." + file_format, file_format)
186 | print "Saved file:", "'" + filename + "." + file_format + "'"
187 |
188 | # TODO: Change WAV:FORM from ASC to BYTE
189 | elif file_format == "csv":
190 | # Put the scope in STOP mode - for the moment, deal with it by manually stopping the scope
191 | # TODO: Add command line switch and code logic for 1200 vs ALL memory data points
192 | # tn.write("stop")
193 | # response = tn.read_until("\n", 1)
194 |
195 | # Scan for displayed channels
196 | chanList = []
197 | for channel in ["CHAN1", "CHAN2", "CHAN3", "CHAN4", "MATH"]:
198 | response = command(tn, ":" + channel + ":DISP?")
199 |
200 | # If channel is active
201 | if response == '1\n':
202 | chanList += [channel]
203 |
204 | # the meaning of 'max' is - will read only the displayed data when the scope is in RUN mode,
205 | # or when the MATH channel is selected
206 | # - will read all the acquired data points when the scope is in STOP mode
207 | # TODO: Change mode to MAX
208 | # TODO: Add command line switch for MAX/NORM
209 | command(tn, ":WAV:MODE NORM")
210 | command(tn, ":WAV:STAR 0")
211 | command(tn, ":WAV:MODE NORM")
212 |
213 | csv_buff = ""
214 |
215 | # for each active channel
216 | for channel in chanList:
217 | print
218 |
219 | # Set WAVE parameters
220 | command(tn, ":WAV:SOUR " + channel)
221 | command(tn, ":WAV:FORM ASC")
222 |
223 | # MATH channel does not allow START and STOP to be set. They are always 0 and 1200
224 | if channel != "MATH":
225 | command(tn, ":WAV:STAR 1")
226 | command(tn, ":WAV:STOP 1200")
227 |
228 | buff = ""
229 | print "Data from channel '" + str(channel) + "', points " + str(1) + "-" + str(1200) + ": Receiving..."
230 | buffChunk = command(tn, ":WAV:DATA?")
231 |
232 | # Just in case the transfer did not complete in the expected time
233 | while buffChunk[-1] != "\n":
234 | logging.warning("The data transfer did not complete in the expected time of " +
235 | str(smallWait) + " second(s).")
236 |
237 | tmp = tn.read_until("\n", smallWait)
238 | if len(tmp) == 0:
239 | break
240 | buffChunk += tmp
241 | logging.warning(str(len(tmp)) + " leftover bytes added to 'buff_chunks'.")
242 |
243 | # Append data chunks
244 | # Strip TMC Blockheader and terminator bytes
245 | buff += buffChunk[tmc_header_bytes(buffChunk):-1] + ","
246 |
247 | # Strip the last \n char
248 | buff = buff[:-1]
249 |
250 | # Process data
251 | buff_list = buff.split(",")
252 | buff_rows = len(buff_list)
253 |
254 | # Put read data into csv_buff
255 | csv_buff_list = csv_buff.split(os.linesep)
256 | csv_rows = len(csv_buff_list)
257 |
258 | current_row = 0
259 | if csv_buff == "":
260 | csv_first_column = True
261 | csv_buff = str(channel) + os.linesep
262 | else:
263 | csv_first_column = False
264 | csv_buff = str(csv_buff_list[current_row]) + "," + str(channel) + os.linesep
265 |
266 | for point in buff_list:
267 | current_row += 1
268 | if csv_first_column:
269 | csv_buff += str(point) + os.linesep
270 | else:
271 | if current_row < csv_rows:
272 | csv_buff += str(csv_buff_list[current_row]) + "," + str(point) + os.linesep
273 | else:
274 | csv_buff += "," + str(point) + os.linesep
275 |
276 | # Save data as CSV
277 | scr_file = open(filename + "." + file_format, "wb")
278 | scr_file.write(csv_buff)
279 | scr_file.close()
280 |
281 | print "Saved file:", "'" + filename + "." + file_format + "'"
282 |
283 | tn.close()
284 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DS1054Z_screen_capture
2 | 'OscScreenGrabLAN.py' is a Python script that captures
3 | whatever is displayed on the screen of a Rigol DS1000Z series oscilloscope.
4 |
5 | It can save data as a WYSIWYG (What You See Is What You Get) picture of the oscilloscope screen,
6 | or as a text file in CSV (Comma Separated Values) format.
7 |
8 | To achieve this, SCPI (Standard Commands for Programmable Instruments) are sent from the computer
9 | to the oscilloscope, using the LXI (LAN-based eXtensions for Instrumentation) protocol over a Telnet connection.
10 | The computer and the oscilloscope are connected together by a LAN (Local Area Network).
11 | No USB (Universal Serial Bus), no VISA (Virtual Instrument Software Architecture),
12 | no IVI (Interchangeable Virtual Instrument) and no Rigol drivers are required.
13 | Python 2 is required. Python 3 is not supported.
14 |
15 | Tested with Windows 10, Python 2.7.12, pillow and Rigol DS1104Z (a fully upgraded DS1054Z oscilloscope).
16 | Tested with Linux Ubuntu 16.04.1, Python 2.7.12 and pillow.
17 |
18 |
19 | User Manual:
20 | -----------
21 | This program captures either the waveform or the whole screen
22 | of a Rigol DS1000Z series oscilloscope, then save it on the computer
23 | as a CSV, PNG or BMP file with a timestamp in the file name.
24 |
25 | The program is using LXI protocol, so the computer
26 | must have LAN connection with the oscilloscope.
27 | USB and/or GPIB connections are not used by this software.
28 |
29 | No VISA, IVI or Rigol drivers are needed.
30 |
31 | Installation:
32 |
33 | Installation on a clean Windows 10 machine
34 | 1. download and install Python 2.7.12 from https://www.python.org/downloads/
35 | 2. to install pillow, open a Command Prompt and type
36 | pip install pillow
37 | 3. download and unzip 'DS1054Z_screen_capture-master.zip' from https://github.com/RoGeorge/DS1054Z_screen_capture
38 | 4. connect the oscilloscope to the LAN (in this example, the oscilloscope have fix IP=192.168.1.3)
39 | 5. in the Command Prompt, change the directory (CD) to the path were 'OscScreenGrabLAN.py' was un-zipped
40 | cd path_where_the_OscScreenGrabLAN.py_was_unzipped
41 | 6. to run the OscScreenGrabLAN.py in the Command Prompt, type
42 | python OscScreenGrabLAN.py png 192.168.1.3
43 |
44 | Installation on a clean Ubuntu 16.04.1
45 | 1. Python is already installed in Ubuntu 16.04.1 desktop
46 | 2. to install pillow, open a Terminal and type:
47 | sudo add-apt-repository universe
48 | sudo apt-get update
49 | sudo apt-get install python-pip
50 | pip install pillow
51 | 3. download and unzip 'DS1054Z_screen_capture-master.zip' from https://github.com/RoGeorge/DS1054Z_screen_capture
52 | 4. connect the oscilloscope to the LAN (in this example, the oscilloscope have fix IP=192.168.1.3)
53 | 5. in the Terminal, change the directory (CD) to the path were 'OscScreenGrabLAN.py' was un-zipped
54 | cd path_where_the_OscScreenGrabLAN.py_was_unzipped
55 | 6. to run the OscScreenGrabLAN.py in the Terminal, type
56 | python OscScreenGrabLAN.py png 192.168.1.3
57 |
58 | Other usages syntax:
59 |
60 | python OscScreenGrabLAN.py png|bmp|csv oscilloscope_IP
61 |
62 | Usage examples:
63 |
64 | python OscScreenGrabLAN.py png 192.168.1.3
65 | python OscScreenGrabLAN.py csv 192.168.1.3
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/Rigol_functions.py:
--------------------------------------------------------------------------------
1 | import pip
2 | import sys
3 | import logging
4 |
5 | __author__ = 'RoGeorge'
6 |
7 |
8 | def log_running_python_versions():
9 | logging.info("Python version: " + str(sys.version) + ", " + str(sys.version_info)) # () required in Python 3.
10 |
11 | installed_packages = pip.get_installed_distributions()
12 | installed_packages_list = sorted(["%s==%s" % (i.key, i.version) for i in installed_packages])
13 | logging.info("Installed Python modules: " + str(installed_packages_list))
14 |
15 |
16 | def command(tn, scpi):
17 | logging.info("SCPI to be sent: " + scpi)
18 | answer_wait_s = 1
19 | response = ""
20 | while response != "1\n":
21 | tn.write("*OPC?\n") # previous operation(s) has completed ?
22 | logging.info("Send SCPI: *OPC? # May I send a command? 1==yes")
23 | response = tn.read_until("\n", 1) # wait max 1s for an answer
24 | logging.info("Received response: " + response)
25 |
26 | tn.write(scpi + "\n")
27 | logging.info("Sent SCPI: " + scpi)
28 | response = tn.read_until("\n", answer_wait_s)
29 | logging.info("Received response: " + response)
30 | return response
31 |
32 |
33 | # first TMC byte is '#'
34 | # second is '0'..'9', and tells how many of the next ASCII chars
35 | # should be converted into an integer.
36 | # The integer will be the length of the data stream (in bytes)
37 | # after all the data bytes, the last char is '\n'
38 | def tmc_header_bytes(buff):
39 | return 2 + int(buff[1])
40 |
41 |
42 | def expected_data_bytes(buff):
43 | return int(buff[2:tmc_header_bytes(buff)])
44 |
45 |
46 | def expected_buff_bytes(buff):
47 | return tmc_header_bytes(buff) + expected_data_bytes(buff) + 1
48 |
49 |
50 | def get_memory_depth(tn):
51 | # Define number of horizontal grid divisions for DS1054Z
52 | h_grid = 12
53 |
54 | # ACQuire:MDEPth
55 | mdep = command(tn, ":ACQ:MDEP?")
56 |
57 | # if mdep is "AUTO"
58 | if mdep == "AUTO\n":
59 | # ACQuire:SRATe
60 | srate = command(tn, ":ACQ:SRAT?")
61 |
62 | # TIMebase[:MAIN]:SCALe
63 | scal = command(tn, ":TIM:SCAL?")
64 |
65 | # mdep = h_grid * scal * srate
66 | mdep = h_grid * float(scal) * float(srate)
67 |
68 | # return mdep
69 | return int(mdep)
70 |
--------------------------------------------------------------------------------
/captures/.gitignore:
--------------------------------------------------------------------------------
1 | # *** START section for manually edited lines
2 |
3 | # 'captures' is a mandatory directory for this project,
4 | # but git can add only files, and can not add an empty directory.
5 | # We want to preserve 'captures' in the repository tree structure,
6 | # so we will ignore everything except the 'captures/.gitignore' file.
7 | # This trick will always add the 'captures' directory in the repository,
8 | # even when there are no other files in 'captures'.
9 | *
10 | !.gitignore
11 |
12 | # *** STOP section for manually edited lines
13 |
--------------------------------------------------------------------------------
/captures/DS1104Z_DS1ZA164658712_2015-05-10_23.14.43.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoGeorge/DS1054Z_screen_capture/570ad8ed5beaf1ba41cf6641721b513a39bb3cdc/captures/DS1104Z_DS1ZA164658712_2015-05-10_23.14.43.png
--------------------------------------------------------------------------------
/captures/DS1104Z_DS1ZA164658712_2015-05-10_23.40.57.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoGeorge/DS1054Z_screen_capture/570ad8ed5beaf1ba41cf6641721b513a39bb3cdc/captures/DS1104Z_DS1ZA164658712_2015-05-10_23.40.57.png
--------------------------------------------------------------------------------
/captures/DS1104Z_DS1ZA164658712_2015-05-25_00.48.34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoGeorge/DS1054Z_screen_capture/570ad8ed5beaf1ba41cf6641721b513a39bb3cdc/captures/DS1104Z_DS1ZA164658712_2015-05-25_00.48.34.png
--------------------------------------------------------------------------------
/captures/DS1104Z_DS1ZA164658712_2015-05-25_00.49.07.csv:
--------------------------------------------------------------------------------
1 | chan1,chan4,math
2 | 3.039992e+00,3.079998e+00,-1.799976e+01
3 | 2.879992e+00,2.959998e+00,-2.279975e+01
4 | 3.039992e+00,2.959998e+00,-3.359975e+01
5 | 2.879992e+00,3.119998e+00,-3.359975e+01
6 | 3.039992e+00,2.959998e+00,-3.479975e+01
7 | 2.879992e+00,3.079998e+00,-4.679980e+01
8 | 3.039992e+00,3.039998e+00,-3.679976e+01
9 | 2.879992e+00,2.959998e+00,-5.079981e+01
10 | 3.039992e+00,3.079998e+00,-4.079977e+01
11 | -7.271767e-06,-1.788139e-07,-4.279978e+01
12 | 7.999273e-02,-4.000018e-02,-4.759980e+01
13 | -8.000727e-02,7.999982e-02,-4.279978e+01
14 | -8.000727e-02,7.999982e-02,-6.879988e+01
15 | 7.999273e-02,-4.000018e-02,-4.359978e+01
16 | 7.999273e-02,7.999982e-02,-4.959981e+01
17 | -8.000727e-02,-4.000018e-02,-4.879980e+01
18 | 7.999273e-02,-4.000018e-02,-4.559979e+01
19 | -8.000727e-02,7.999982e-02,-6.079985e+01
20 | -8.000727e-02,-8.000018e-02,-4.679980e+01
21 | 2.959992e+00,3.039998e+00,-5.679984e+01
22 | 3.039992e+00,3.079998e+00,-4.959981e+01
23 | 2.879992e+00,2.959998e+00,-4.959981e+01
24 | 3.039992e+00,3.079998e+00,-5.679984e+01
25 | 2.879992e+00,2.959998e+00,-4.879980e+01
26 | 3.039992e+00,3.079998e+00,-6.559987e+01
27 | 2.879992e+00,2.959998e+00,-4.959981e+01
28 | 3.039992e+00,3.079998e+00,-5.359982e+01
29 | 2.879992e+00,2.959998e+00,-5.479983e+01
30 | 3.039992e+00,3.079998e+00,-5.079981e+01
31 | 7.999273e-02,-1.788139e-07,-7.079989e+01
32 | 7.999273e-02,7.999982e-02,-5.079981e+01
33 | -8.000727e-02,-4.000018e-02,-5.759984e+01
34 | 7.999273e-02,-4.000018e-02,-5.359982e+01
35 | -8.000727e-02,7.999982e-02,-5.279982e+01
36 | -8.000727e-02,-4.000018e-02,-6.159985e+01
37 | 7.999273e-02,7.999982e-02,-5.159982e+01
38 | 7.999273e-02,7.999982e-02,-6.359986e+01
39 | -8.000727e-02,-4.000018e-02,-5.279982e+01
40 | -8.000727e-02,-4.000018e-02,-5.559983e+01
41 | 2.959992e+00,3.039998e+00,-5.879984e+01
42 | 3.039992e+00,3.079998e+00,-5.279982e+01
43 | 2.879992e+00,2.959998e+00,-8.279993e+01
44 | 3.039992e+00,3.079998e+00,-5.279982e+01
45 | 2.879992e+00,2.959998e+00,-5.679984e+01
46 | 3.039992e+00,2.959998e+00,-5.479983e+01
47 | 2.879992e+00,3.079998e+00,-6.679987e+01
48 | 3.039992e+00,2.959998e+00,-5.359982e+01
49 | 2.879992e+00,3.079998e+00,-6.279986e+01
50 | 3.039992e+00,3.079998e+00,-5.559983e+01
51 | -7.271767e-06,3.999982e-02,-5.679984e+01
52 | 7.999273e-02,-4.000018e-02,-6.159985e+01
53 | -8.000727e-02,7.999982e-02,-5.479983e+01
54 | 7.999273e-02,7.999982e-02,-7.159989e+01
55 | -8.000727e-02,-4.000018e-02,-5.479983e+01
56 | -8.000727e-02,-4.000018e-02,-5.879984e+01
57 | 7.999273e-02,7.999982e-02,-5.879984e+01
58 | 7.999273e-02,7.999982e-02,-5.559983e+01
59 | -8.000727e-02,-4.000018e-02,-7.359990e+01
60 | -8.000727e-02,-4.000018e-02,-5.479983e+01
61 | 2.959992e+00,3.039998e+00,-6.079985e+01
62 | 3.039992e+00,3.079998e+00,-5.679984e+01
63 | 2.879992e+00,2.959998e+00,-5.679984e+01
64 | 2.879992e+00,3.079998e+00,-6.559987e+01
65 | 3.039992e+00,2.959998e+00,-5.359982e+01
66 | 3.039992e+00,3.079998e+00,-6.759988e+01
67 | 2.879992e+00,2.959998e+00,-5.479983e+01
68 | 3.039992e+00,3.079998e+00,-5.759984e+01
69 | 2.879992e+00,2.959998e+00,-5.959985e+01
70 | 3.039992e+00,3.079998e+00,-5.479983e+01
71 | -7.271767e-06,3.999982e-02,-7.879992e+01
72 | 7.999273e-02,7.999982e-02,-5.359982e+01
73 | -8.000727e-02,-4.000018e-02,-5.879984e+01
74 | -8.000727e-02,-4.000018e-02,-5.559983e+01
75 | 7.999273e-02,7.999982e-02,-5.359982e+01
76 | -8.000727e-02,7.999982e-02,-6.559987e+01
77 | 7.999273e-02,-4.000018e-02,-5.279982e+01
78 | 7.999273e-02,-4.000018e-02,-6.159985e+01
79 | -8.000727e-02,7.999982e-02,-5.359982e+01
80 | -8.000727e-02,-4.000018e-02,-5.359982e+01
81 | 2.959992e+00,3.079998e+00,-5.959985e+01
82 | 3.039992e+00,2.959998e+00,-5.159982e+01
83 | 2.879992e+00,3.079998e+00,-6.879988e+01
84 | 3.039992e+00,2.999998e+00,-5.159982e+01
85 | 2.879992e+00,3.079998e+00,-5.359982e+01
86 | 3.039992e+00,3.079998e+00,-5.479983e+01
87 | 2.879992e+00,2.959998e+00,-7.079989e+01
88 | 3.039992e+00,2.959998e+00,-4.879980e+01
89 | 2.879992e+00,3.079998e+00,-5.479983e+01
90 | 3.039992e+00,3.079998e+00,-4.959981e+01
91 | 7.999273e-02,-1.788139e-07,-4.759980e+01
92 | 7.999273e-02,7.999982e-02,-5.559983e+01
93 | -8.000727e-02,-4.000018e-02,-4.479979e+01
94 | 7.999273e-02,-4.000018e-02,-5.559983e+01
95 | -8.000727e-02,7.999982e-02,-4.359978e+01
96 | 7.999273e-02,7.999982e-02,-4.479979e+01
97 | -8.000727e-02,-4.000018e-02,-4.559979e+01
98 | -8.000727e-02,7.999982e-02,-3.879977e+01
99 | 7.999273e-02,-4.000018e-02,-6.959988e+01
100 | -8.000727e-02,-4.000018e-02,-3.359975e+01
101 | 2.959992e+00,3.039998e+00,-3.359975e+01
102 | 3.039992e+00,3.079998e+00,-2.199975e+01
103 | 2.879992e+00,2.999998e+00,-2.279975e+01
104 | 3.039992e+00,3.079998e+00,-4.359978e+01
105 | 2.879992e+00,2.959998e+00,-3.359975e+01
106 | 3.039992e+00,2.959998e+00,-4.559979e+01
107 | 2.879992e+00,3.079998e+00,-3.959977e+01
108 | 3.039992e+00,3.079998e+00,-4.279978e+01
109 | 2.879992e+00,2.959998e+00,-4.959981e+01
110 | 3.039992e+00,3.079998e+00,-4.279978e+01
111 | -7.271767e-06,-1.788139e-07,-6.159985e+01
112 | 7.999273e-02,7.999982e-02,-4.559979e+01
113 | -8.000727e-02,-4.000018e-02,-4.959981e+01
114 | -8.000727e-02,7.999982e-02,-5.079981e+01
115 | 7.999273e-02,-4.000018e-02,-4.759980e+01
116 | -8.000727e-02,-4.000018e-02,-6.959988e+01
117 | 7.999273e-02,7.999982e-02,-4.879980e+01
118 | -8.000727e-02,7.999982e-02,-5.559983e+01
119 | 7.999273e-02,-4.000018e-02,-5.159982e+01
120 | -8.000727e-02,-4.000018e-02,-5.159982e+01
121 | 2.959992e+00,3.039998e+00,-6.079985e+01
122 | 3.039992e+00,3.079998e+00,-5.079981e+01
123 | 2.879992e+00,2.959998e+00,-6.359986e+01
124 | 3.039992e+00,2.959998e+00,-5.279982e+01
125 | 2.879992e+00,3.119998e+00,-5.559983e+01
126 | 3.039992e+00,2.999998e+00,-5.879984e+01
127 | 2.879992e+00,3.079998e+00,-5.279982e+01
128 | 3.039992e+00,2.959998e+00,-8.879996e+01
129 | 2.879992e+00,3.079998e+00,-5.879984e+01
130 | 3.039992e+00,3.079998e+00,-5.679984e+01
131 | -7.271767e-06,-1.788139e-07,-5.559983e+01
132 | 7.999273e-02,7.999982e-02,-6.759988e+01
133 | -8.000727e-02,-4.000018e-02,-5.479983e+01
134 | -8.000727e-02,-4.000018e-02,-6.359986e+01
135 | 7.999273e-02,7.999982e-02,-5.679984e+01
136 | 7.999273e-02,-4.000018e-02,-5.759984e+01
137 | -8.000727e-02,7.999982e-02,-6.359986e+01
138 | -8.000727e-02,7.999982e-02,-5.559983e+01
139 | 7.999273e-02,-4.000018e-02,-7.759991e+01
140 | -8.000727e-02,-4.000018e-02,-5.679984e+01
141 | 2.959992e+00,3.039998e+00,-6.079985e+01
142 | 3.039992e+00,3.079998e+00,-6.079985e+01
143 | 2.879992e+00,2.959998e+00,-5.759984e+01
144 | 3.039992e+00,2.959998e+00,-7.559991e+01
145 | 2.879992e+00,3.079998e+00,-5.759984e+01
146 | 2.879992e+00,3.079998e+00,-6.559987e+01
147 | 3.039992e+00,2.959998e+00,-5.959985e+01
148 | 3.039992e+00,3.079998e+00,-5.959985e+01
149 | 2.879992e+00,2.959998e+00,-6.759988e+01
150 | 3.039992e+00,3.079998e+00,-5.759984e+01
151 | -7.271767e-06,-1.788139e-07,-7.279990e+01
152 | 7.999273e-02,7.999982e-02,-6.079985e+01
153 | -8.000727e-02,-4.000018e-02,-6.079985e+01
154 | 7.999273e-02,7.999982e-02,-6.279986e+01
155 | -8.000727e-02,-4.000018e-02,-5.959985e+01
156 | -8.000727e-02,-4.000018e-02,-8.279993e+01
157 | 7.999273e-02,7.999982e-02,-5.879984e+01
158 | -8.000727e-02,-4.000018e-02,-6.559987e+01
159 | 7.999273e-02,7.999982e-02,-6.159985e+01
160 | -8.000727e-02,-4.000018e-02,-6.079985e+01
161 | 2.959992e+00,3.079998e+00,-7.159989e+01
162 | 3.039992e+00,2.959998e+00,-5.959985e+01
163 | 2.879992e+00,3.079998e+00,-7.279990e+01
164 | 3.039992e+00,3.079998e+00,-6.079985e+01
165 | 2.879992e+00,2.959998e+00,-6.359986e+01
166 | 3.039992e+00,3.079998e+00,-6.679987e+01
167 | 2.879992e+00,2.959998e+00,-6.079985e+01
168 | 2.879992e+00,2.959998e+00,-7.959992e+01
169 | 3.039992e+00,3.079998e+00,-6.279986e+01
170 | 3.039992e+00,3.079998e+00,-6.479987e+01
171 | -7.271767e-06,3.999982e-02,-6.279986e+01
172 | 7.999273e-02,-4.000018e-02,-8.079993e+01
173 | -8.000727e-02,7.999982e-02,-6.159985e+01
174 | 7.999273e-02,-4.000018e-02,-6.959988e+01
175 | -8.000727e-02,7.999982e-02,-6.279986e+01
176 | 7.999273e-02,-4.000018e-02,-6.479987e+01
177 | -8.000727e-02,7.999982e-02,-6.959988e+01
178 | 7.999273e-02,7.999982e-02,-6.159985e+01
179 | -8.000727e-02,-4.000018e-02,-7.759991e+01
180 | -8.000727e-02,-4.000018e-02,-6.359986e+01
181 | 2.959992e+00,2.999998e+00,-6.679987e+01
182 | 3.039992e+00,3.079998e+00,-6.679987e+01
183 | 2.879992e+00,2.959998e+00,-6.279986e+01
184 | 3.039992e+00,3.079998e+00,-7.559991e+01
185 | 2.879992e+00,2.959998e+00,-6.359986e+01
186 | 3.039992e+00,2.999998e+00,-6.959988e+01
187 | 2.879992e+00,3.079998e+00,-6.679987e+01
188 | 3.039992e+00,3.079998e+00,-6.479987e+01
189 | 2.879992e+00,2.959998e+00,-7.479990e+01
190 | 3.039992e+00,3.079998e+00,-6.359986e+01
191 | -7.271767e-06,3.999982e-02,-7.479990e+01
192 | 7.999273e-02,7.999982e-02,-6.479987e+01
193 | -8.000727e-02,-4.000018e-02,-6.679987e+01
194 | 7.999273e-02,7.999982e-02,-6.959988e+01
195 | -8.000727e-02,-4.000018e-02,-6.359986e+01
196 | 7.999273e-02,7.999982e-02,-8.959996e+01
197 | -8.000727e-02,-4.000018e-02,-6.359986e+01
198 | -8.000727e-02,-4.000018e-02,-6.959988e+01
199 | 7.999273e-02,7.999982e-02,-6.679987e+01
200 | -8.000727e-02,-4.000018e-02,-6.679987e+01
201 | 2.959992e+00,3.039998e+00,-8.359994e+01
202 | 3.039992e+00,3.079998e+00,-6.559987e+01
203 | 2.879992e+00,2.959998e+00,-6.479987e+01
204 | 3.039992e+00,2.959998e+00,-6.359986e+01
205 | 2.879992e+00,3.079998e+00,-6.479987e+01
206 | 3.039992e+00,2.959998e+00,-7.079989e+01
207 | 2.879992e+00,3.079998e+00,-6.679987e+01
208 | 3.039992e+00,3.079998e+00,-7.759991e+01
209 | 2.879992e+00,2.959998e+00,-6.559987e+01
210 | 3.039992e+00,3.079998e+00,-6.879988e+01
211 | -7.271767e-06,7.999982e-02,-6.959988e+01
212 | 7.999273e-02,-4.000018e-02,-6.359986e+01
213 | -8.000727e-02,7.999982e-02,-6.479987e+01
214 | -8.000727e-02,-4.000018e-02,-7.959992e+01
215 | 7.999273e-02,7.999982e-02,-6.879988e+01
216 | 7.999273e-02,7.999982e-02,-6.879988e+01
217 | -8.000727e-02,-4.000018e-02,-7.279990e+01
218 | -8.000727e-02,-4.000018e-02,-6.679987e+01
219 | 7.999273e-02,7.999982e-02,-7.759991e+01
220 | -8.000727e-02,-4.000018e-02,-6.759988e+01
221 | 2.959992e+00,3.039998e+00,-7.159989e+01
222 | 3.039992e+00,2.959998e+00,-7.079989e+01
223 | 2.879992e+00,3.079998e+00,-7.079989e+01
224 | 3.039992e+00,2.959998e+00,-7.879992e+01
225 | 2.879992e+00,3.079998e+00,-6.959988e+01
226 | 3.039992e+00,3.079998e+00,-7.159989e+01
227 | 2.879992e+00,2.959998e+00,-6.959988e+01
228 | 3.039992e+00,2.999998e+00,-7.159989e+01
229 | 2.879992e+00,3.079998e+00,-8.959996e+01
230 | 3.039992e+00,3.079998e+00,-6.879988e+01
231 | -7.271767e-06,-1.788139e-07,-7.879992e+01
232 | 7.999273e-02,-4.000018e-02,-7.079989e+01
233 | -8.000727e-02,7.999982e-02,-7.359990e+01
234 | -8.000727e-02,7.999982e-02,-7.679991e+01
235 | 7.999273e-02,-4.000018e-02,-7.079989e+01
236 | 7.999273e-02,-4.000018e-02,-7.159989e+01
237 | -8.000727e-02,7.999982e-02,-6.679987e+01
238 | -8.000727e-02,-4.000018e-02,-7.359990e+01
239 | 7.999273e-02,7.999982e-02,-7.279990e+01
240 | -8.000727e-02,-4.000018e-02,-7.079989e+01
241 | 2.959992e+00,3.039998e+00,-7.679991e+01
242 | 3.039992e+00,2.999998e+00,-7.159989e+01
243 | 2.879992e+00,3.079998e+00,-7.479990e+01
244 | 3.039992e+00,2.959998e+00,-7.359990e+01
245 | 2.879992e+00,3.079998e+00,-7.359990e+01
246 | 3.039992e+00,2.959998e+00,-8.479994e+01
247 | 2.879992e+00,3.079998e+00,-7.279990e+01
248 | 3.039992e+00,3.079998e+00,-7.559991e+01
249 | 2.879992e+00,2.959998e+00,-7.759991e+01
250 | 3.039992e+00,3.079998e+00,-6.959988e+01
251 | -7.271767e-06,-1.788139e-07,-7.559991e+01
252 | 7.999273e-02,-4.000018e-02,-6.759988e+01
253 | -8.000727e-02,7.999982e-02,-7.359990e+01
254 | 7.999273e-02,7.999982e-02,-7.159989e+01
255 | -8.000727e-02,-4.000018e-02,-8.159993e+01
256 | -8.000727e-02,7.999982e-02,-7.159989e+01
257 | 7.999273e-02,-4.000018e-02,-7.159989e+01
258 | 7.999273e-02,-4.000018e-02,-8.679995e+01
259 | -8.000727e-02,7.999982e-02,-8.079993e+01
260 | -8.000727e-02,-4.000018e-02,-7.279990e+01
261 | 2.959992e+00,3.039998e+00,-7.759991e+01
262 | 3.039992e+00,3.079998e+00,-7.359990e+01
263 | 2.879992e+00,2.959998e+00,-8.479994e+01
264 | 2.879992e+00,3.079998e+00,-8.879996e+01
265 | 3.039992e+00,2.959998e+00,-7.679991e+01
266 | 3.039992e+00,3.079998e+00,-8.159993e+01
267 | 2.879992e+00,2.959998e+00,-7.879992e+01
268 | 3.039992e+00,3.079998e+00,-7.679991e+01
269 | 2.879992e+00,2.959998e+00,-9.559998e+01
270 | 3.039992e+00,3.079998e+00,-7.359990e+01
271 | 7.999273e-02,3.999982e-02,-8.279993e+01
272 | 7.999273e-02,7.999982e-02,-8.079993e+01
273 | -8.000727e-02,-4.000018e-02,-7.279990e+01
274 | 7.999273e-02,-4.000018e-02,-8.479994e+01
275 | -8.000727e-02,7.999982e-02,-7.359990e+01
276 | -8.000727e-02,-4.000018e-02,-7.959992e+01
277 | 7.999273e-02,7.999982e-02,-6.959988e+01
278 | -8.000727e-02,-4.000018e-02,-7.479990e+01
279 | 7.999273e-02,7.999982e-02,-8.279993e+01
280 | -8.000727e-02,-4.000018e-02,-6.759988e+01
281 | 2.959992e+00,3.039998e+00,-7.559991e+01
282 | 3.039992e+00,3.079998e+00,-6.479987e+01
283 | 2.879992e+00,2.959998e+00,-7.079989e+01
284 | 3.039992e+00,3.079998e+00,-6.679987e+01
285 | 2.879992e+00,2.959998e+00,-6.679987e+01
286 | 3.039992e+00,3.079998e+00,-7.879992e+01
287 | 2.879992e+00,2.959998e+00,-6.279986e+01
288 | 3.039992e+00,3.079998e+00,-7.079989e+01
289 | 2.879992e+00,2.959998e+00,-6.279986e+01
290 | 3.039992e+00,3.079998e+00,-6.079985e+01
291 | 7.999273e-02,-1.788139e-07,-6.359986e+01
292 | 7.999273e-02,1.199998e-01,-5.879984e+01
293 | -8.000727e-02,-4.000018e-02,-7.879992e+01
294 | 7.999273e-02,-4.000018e-02,-5.679984e+01
295 | -8.000727e-02,7.999982e-02,-5.959985e+01
296 | -8.000727e-02,-4.000018e-02,-5.759984e+01
297 | 7.999273e-02,7.999982e-02,-6.559987e+01
298 | -8.000727e-02,-4.000018e-02,-4.759980e+01
299 | 7.999273e-02,7.999982e-02,-5.279982e+01
300 | -8.000727e-02,-4.000018e-02,-4.359978e+01
301 | 2.959992e+00,3.079998e+00,-3.759976e+01
302 | 3.039992e+00,2.959998e+00,-2.959974e+01
303 | 2.879992e+00,3.079998e+00,-3.279974e+01
304 | 3.039992e+00,3.079998e+00,-5.559983e+01
305 | 2.879992e+00,2.959998e+00,-4.359978e+01
306 | 3.039992e+00,3.079998e+00,-4.959981e+01
307 | 2.879992e+00,2.959998e+00,-5.279982e+01
308 | 3.039992e+00,2.959998e+00,-4.959981e+01
309 | 2.879992e+00,3.119998e+00,-9.279997e+01
310 | 3.039992e+00,3.119998e+00,-5.079981e+01
311 | -7.271767e-06,3.999982e-02,-5.879984e+01
312 | 7.999273e-02,-4.000018e-02,-5.559983e+01
313 | -8.000727e-02,7.999982e-02,-5.479983e+01
314 | -8.000727e-02,7.999982e-02,-6.679987e+01
315 | 7.999273e-02,-4.000018e-02,-5.479983e+01
316 | 7.999273e-02,7.999982e-02,-6.559987e+01
317 | -8.000727e-02,-4.000018e-02,-5.679984e+01
318 | -8.000727e-02,7.999982e-02,-5.879984e+01
319 | 7.999273e-02,-4.000018e-02,-6.159985e+01
320 | -8.000727e-02,-4.000018e-02,-5.679984e+01
321 | 2.959992e+00,3.039998e+00,-8.159993e+01
322 | 3.039992e+00,3.079998e+00,-5.759984e+01
323 | 2.879992e+00,2.959998e+00,-6.359986e+01
324 | 3.039992e+00,3.079998e+00,-6.359986e+01
325 | 2.879992e+00,2.959998e+00,-5.879984e+01
326 | 3.039992e+00,3.079998e+00,-7.959992e+01
327 | 2.879992e+00,2.959998e+00,-5.879984e+01
328 | 3.039992e+00,2.959998e+00,-6.879988e+01
329 | 2.879992e+00,3.079998e+00,-6.079985e+01
330 | 3.039992e+00,3.079998e+00,-6.279986e+01
331 | -7.271767e-06,-1.788139e-07,-6.959988e+01
332 | 7.999273e-02,-4.000018e-02,-5.879984e+01
333 | -8.000727e-02,7.999982e-02,-7.159989e+01
334 | -8.000727e-02,7.999982e-02,-5.959985e+01
335 | 7.999273e-02,-4.000018e-02,-6.559987e+01
336 | 7.999273e-02,7.999982e-02,-6.359986e+01
337 | -8.000727e-02,-4.000018e-02,-6.359986e+01
338 | -8.000727e-02,-4.000018e-02,-7.279990e+01
339 | 7.999273e-02,7.999982e-02,-6.879988e+01
340 | -8.000727e-02,-4.000018e-02,-6.559987e+01
341 | 2.959992e+00,3.039998e+00,-6.279986e+01
342 | 3.039992e+00,3.079998e+00,-6.959988e+01
343 | 2.879992e+00,2.959998e+00,-6.279986e+01
344 | 3.039992e+00,2.959998e+00,-7.279990e+01
345 | 2.879992e+00,3.079998e+00,-6.279986e+01
346 | 3.039992e+00,3.119998e+00,-6.679987e+01
347 | 2.879992e+00,2.959998e+00,-6.959988e+01
348 | 3.039992e+00,3.079998e+00,-6.279986e+01
349 | 2.879992e+00,2.959998e+00,-7.879992e+01
350 | 3.039992e+00,3.079998e+00,-6.359986e+01
351 | -7.271767e-06,-1.788139e-07,-6.559987e+01
352 | 7.999273e-02,7.999982e-02,-6.479987e+01
353 | -8.000727e-02,-4.000018e-02,-6.359986e+01
354 | -8.000727e-02,7.999982e-02,-6.959988e+01
355 | 7.999273e-02,-4.000018e-02,-6.359986e+01
356 | -8.000727e-02,-4.000018e-02,-7.559991e+01
357 | 7.999273e-02,7.999982e-02,-6.559987e+01
358 | -8.000727e-02,-4.000018e-02,-6.559987e+01
359 | 7.999273e-02,7.999982e-02,-7.359990e+01
360 | -8.000727e-02,-4.000018e-02,-6.159985e+01
361 | 2.959992e+00,2.999998e+00,-8.279993e+01
362 | 3.039992e+00,3.079998e+00,-6.359986e+01
363 | 2.879992e+00,2.959998e+00,-7.279990e+01
364 | 3.039992e+00,3.079998e+00,-6.879988e+01
365 | 2.879992e+00,2.959998e+00,-6.879988e+01
366 | 3.039992e+00,3.079998e+00,-7.879992e+01
367 | 2.879992e+00,2.959998e+00,-6.759988e+01
368 | 3.039992e+00,2.999998e+00,-6.879988e+01
369 | 2.879992e+00,3.079998e+00,-6.679987e+01
370 | 3.039992e+00,3.079998e+00,-6.759988e+01
371 | -7.271767e-06,-1.788139e-07,-7.479990e+01
372 | 7.999273e-02,-4.000018e-02,-6.759988e+01
373 | -8.000727e-02,7.999982e-02,-7.479990e+01
374 | 7.999273e-02,-4.000018e-02,-6.879988e+01
375 | -8.000727e-02,7.999982e-02,-6.479987e+01
376 | -8.000727e-02,-4.000018e-02,-6.759988e+01
377 | 7.999273e-02,7.999982e-02,-6.679987e+01
378 | 7.999273e-02,7.999982e-02,-8.279993e+01
379 | -8.000727e-02,-4.000018e-02,-6.759988e+01
380 | -8.000727e-02,-4.000018e-02,-7.079989e+01
381 | 2.959992e+00,3.039998e+00,-6.679987e+01
382 | 3.039992e+00,2.959998e+00,-7.559991e+01
383 | 2.879992e+00,3.079998e+00,-6.879988e+01
384 | 3.039992e+00,2.959998e+00,-6.959988e+01
385 | 2.879992e+00,3.079998e+00,-6.679987e+01
386 | 3.039992e+00,2.959998e+00,-6.679987e+01
387 | 2.879992e+00,3.079998e+00,-7.359990e+01
388 | 3.039992e+00,3.079998e+00,-6.479987e+01
389 | 2.879992e+00,2.959998e+00,-8.079993e+01
390 | 3.039992e+00,3.079998e+00,-6.679987e+01
391 | 7.999273e-02,3.999982e-02,-7.159989e+01
392 | 7.999273e-02,7.999982e-02,-6.959988e+01
393 | -8.000727e-02,-4.000018e-02,-6.879988e+01
394 | -8.000727e-02,-4.000018e-02,-7.559991e+01
395 | 7.999273e-02,7.999982e-02,-7.279990e+01
396 | -8.000727e-02,-4.000018e-02,-7.279990e+01
397 | 7.999273e-02,7.999982e-02,-7.159989e+01
398 | -8.000727e-02,-4.000018e-02,-6.879988e+01
399 | 7.999273e-02,7.999982e-02,-7.759991e+01
400 | -8.000727e-02,-4.000018e-02,-7.079989e+01
401 | 2.959992e+00,2.999998e+00,-9.880000e+01
402 | 3.039992e+00,3.079998e+00,-6.559987e+01
403 | 2.879992e+00,2.959998e+00,-5.879984e+01
404 | 3.039992e+00,3.039998e+00,-6.759988e+01
405 | 2.879992e+00,2.959998e+00,-6.559987e+01
406 | 2.879992e+00,3.079998e+00,-7.359990e+01
407 | 3.039992e+00,2.959998e+00,-6.279986e+01
408 | 3.039992e+00,3.079998e+00,-8.159993e+01
409 | 2.879992e+00,2.959998e+00,-7.359990e+01
410 | 3.039992e+00,3.079998e+00,-6.679987e+01
411 | 7.999273e-02,7.999982e-02,-8.279993e+01
412 | 7.999273e-02,-4.000018e-02,-6.359986e+01
413 | -8.000727e-02,7.999982e-02,-7.479990e+01
414 | -8.000727e-02,-4.000018e-02,-6.759988e+01
415 | 7.999273e-02,7.999982e-02,-6.679987e+01
416 | 7.999273e-02,-4.000018e-02,-6.959988e+01
417 | -8.000727e-02,7.999982e-02,-6.479987e+01
418 | 7.999273e-02,-4.000018e-02,-7.959992e+01
419 | -8.000727e-02,7.999982e-02,-6.679987e+01
420 | -8.000727e-02,-4.000018e-02,-7.959992e+01
421 | 2.959992e+00,2.999998e+00,-7.359990e+01
422 | 3.039992e+00,3.079998e+00,-6.679987e+01
423 | 2.879992e+00,2.959998e+00,-8.279993e+01
424 | 3.039992e+00,2.959998e+00,-7.359990e+01
425 | 2.879992e+00,3.079998e+00,-6.759988e+01
426 | 3.039992e+00,2.959998e+00,-6.959988e+01
427 | 2.879992e+00,3.079998e+00,-6.959988e+01
428 | 2.879992e+00,3.119998e+00,-6.879988e+01
429 | 3.039992e+00,2.959998e+00,-7.279990e+01
430 | 3.039992e+00,3.119998e+00,-6.359986e+01
431 | -7.271767e-06,-1.788139e-07,-8.079993e+01
432 | 7.999273e-02,7.999982e-02,-7.279990e+01
433 | -8.000727e-02,-4.000018e-02,-6.559987e+01
434 | 7.999273e-02,-4.000018e-02,-7.279990e+01
435 | -8.000727e-02,7.999982e-02,-6.959988e+01
436 | -8.000727e-02,-4.000018e-02,-8.159993e+01
437 | 7.999273e-02,7.999982e-02,-7.159989e+01
438 | 7.999273e-02,-4.000018e-02,-7.479990e+01
439 | -8.000727e-02,7.999982e-02,-7.079989e+01
440 | -8.000727e-02,-4.000018e-02,-8.079993e+01
441 | 2.959992e+00,3.039998e+00,-7.279990e+01
442 | 3.039992e+00,3.079998e+00,-7.679991e+01
443 | 2.879992e+00,2.959998e+00,-7.279990e+01
444 | 3.039992e+00,3.079998e+00,-8.279993e+01
445 | 2.879992e+00,2.959998e+00,-6.679987e+01
446 | 3.039992e+00,3.039998e+00,-8.679995e+01
447 | 2.879992e+00,2.959998e+00,-6.679987e+01
448 | 3.039992e+00,2.959998e+00,-7.559991e+01
449 | 2.879992e+00,3.079998e+00,-7.879992e+01
450 | 3.039992e+00,3.079998e+00,-7.159989e+01
451 | -7.271767e-06,3.999982e-02,-7.959992e+01
452 | 7.999273e-02,-4.000018e-02,-6.959988e+01
453 | -8.000727e-02,7.999982e-02,-7.479990e+01
454 | -8.000727e-02,-4.000018e-02,-7.879992e+01
455 | 7.999273e-02,7.999982e-02,-7.479990e+01
456 | -8.000727e-02,-4.000018e-02,-8.279993e+01
457 | 7.999273e-02,7.999982e-02,-7.159989e+01
458 | -8.000727e-02,7.999982e-02,-7.759991e+01
459 | 7.999273e-02,-4.000018e-02,-8.079993e+01
460 | -8.000727e-02,-4.000018e-02,-7.959992e+01
461 | 2.959992e+00,3.039998e+00,-7.879992e+01
462 | 3.039992e+00,3.079998e+00,-8.159993e+01
463 | 2.879992e+00,2.959998e+00,-7.879992e+01
464 | 3.039992e+00,3.079998e+00,-7.079989e+01
465 | 2.879992e+00,2.959998e+00,-8.159993e+01
466 | 3.039992e+00,2.959998e+00,-6.959988e+01
467 | 2.879992e+00,3.079998e+00,-7.159989e+01
468 | 3.039992e+00,2.959998e+00,-7.079989e+01
469 | 2.879992e+00,3.079998e+00,-7.159989e+01
470 | 3.039992e+00,3.119998e+00,-6.959988e+01
471 | -7.271767e-06,-1.788139e-07,-7.479990e+01
472 | 7.999273e-02,1.199998e-01,-7.479990e+01
473 | -8.000727e-02,-4.000018e-02,-7.559991e+01
474 | -8.000727e-02,7.999982e-02,-7.679991e+01
475 | 7.999273e-02,-4.000018e-02,-7.679991e+01
476 | -8.000727e-02,-4.000018e-02,-8.359994e+01
477 | 7.999273e-02,7.999982e-02,-8.679995e+01
478 | -8.000727e-02,-4.000018e-02,-8.159993e+01
479 | 7.999273e-02,7.999982e-02,-7.879992e+01
480 | -8.000727e-02,-4.000018e-02,-7.479990e+01
481 | 2.959992e+00,3.079998e+00,-7.679991e+01
482 | 3.039992e+00,3.079998e+00,-7.159989e+01
483 | 2.879992e+00,2.959998e+00,-7.879992e+01
484 | 3.039992e+00,3.079998e+00,-6.759988e+01
485 | 2.879992e+00,2.959998e+00,-7.079989e+01
486 | 3.039992e+00,2.959998e+00,-7.079989e+01
487 | 2.879992e+00,3.079998e+00,-7.079989e+01
488 | 3.039992e+00,2.959998e+00,-6.959988e+01
489 | 2.879992e+00,3.079998e+00,-7.559991e+01
490 | 3.039992e+00,3.079998e+00,-6.359986e+01
491 | -7.271767e-06,-1.788139e-07,-6.959988e+01
492 | 7.999273e-02,-4.000018e-02,-6.159985e+01
493 | -8.000727e-02,7.999982e-02,-6.359986e+01
494 | 7.999273e-02,7.999982e-02,-5.959985e+01
495 | -8.000727e-02,-4.000018e-02,-5.959985e+01
496 | -8.000727e-02,-4.000018e-02,-6.359986e+01
497 | 7.999273e-02,7.999982e-02,-5.559983e+01
498 | -8.000727e-02,-4.000018e-02,-6.879988e+01
499 | 7.999273e-02,7.999982e-02,-5.159982e+01
500 | -8.000727e-02,-4.000018e-02,-5.359982e+01
501 | 2.959992e+00,3.079998e+00,-5.079981e+01
502 | 3.039992e+00,3.079998e+00,-3.959977e+01
503 | 2.879992e+00,2.959998e+00,-3.359975e+01
504 | 3.039992e+00,3.079998e+00,-3.879977e+01
505 | 2.879992e+00,2.959998e+00,-4.959981e+01
506 | 3.039992e+00,3.079998e+00,-5.159982e+01
507 | 2.879992e+00,2.959998e+00,-4.959981e+01
508 | 3.039992e+00,3.079998e+00,-5.279982e+01
509 | 2.879992e+00,2.959998e+00,-6.279986e+01
510 | 3.039992e+00,3.079998e+00,-5.559983e+01
511 | 7.999273e-02,-1.788139e-07,-5.679984e+01
512 | 7.999273e-02,-4.000018e-02,-5.959985e+01
513 | -8.000727e-02,7.999982e-02,-5.679984e+01
514 | -8.000727e-02,7.999982e-02,-6.959988e+01
515 | 7.999273e-02,-4.000018e-02,-5.759984e+01
516 | -8.000727e-02,-4.000018e-02,-6.479987e+01
517 | 7.999273e-02,7.999982e-02,-6.159985e+01
518 | -8.000727e-02,-4.000018e-02,-6.079985e+01
519 | 7.999273e-02,7.999982e-02,-7.079989e+01
520 | -8.000727e-02,-4.000018e-02,-6.159985e+01
521 | 2.959992e+00,3.039998e+00,-6.679987e+01
522 | 3.039992e+00,3.079998e+00,-6.559987e+01
523 | 2.879992e+00,2.959998e+00,-6.159985e+01
524 | 3.039992e+00,2.959998e+00,-7.079989e+01
525 | 2.879992e+00,3.079998e+00,-6.079985e+01
526 | 3.039992e+00,2.959998e+00,-7.479990e+01
527 | 2.879992e+00,3.119998e+00,-6.359986e+01
528 | 3.039992e+00,2.959998e+00,-6.479987e+01
529 | 2.879992e+00,3.079998e+00,-6.759988e+01
530 | 3.039992e+00,3.079998e+00,-6.279986e+01
531 | -7.271767e-06,-1.788139e-07,-7.359990e+01
532 | 7.999273e-02,-4.000018e-02,-6.559987e+01
533 | -8.000727e-02,7.999982e-02,-6.759988e+01
534 | 7.999273e-02,-4.000018e-02,-7.159989e+01
535 | -8.000727e-02,7.999982e-02,-6.159985e+01
536 | 7.999273e-02,-4.000018e-02,-7.879992e+01
537 | -8.000727e-02,7.999982e-02,-6.159985e+01
538 | 7.999273e-02,-4.000018e-02,-6.559987e+01
539 | -8.000727e-02,7.999982e-02,-5.959985e+01
540 | -8.000727e-02,-4.000018e-02,-6.959988e+01
541 | 2.959992e+00,3.039998e+00,-6.759988e+01
542 | 2.879992e+00,3.079998e+00,-6.479987e+01
543 | 3.039992e+00,2.959998e+00,-7.479990e+01
544 | 3.039992e+00,3.079998e+00,-6.279986e+01
545 | 2.879992e+00,2.959998e+00,-6.879988e+01
546 | 3.039992e+00,3.079998e+00,-6.559987e+01
547 | 2.879992e+00,2.959998e+00,-6.679987e+01
548 | 3.039992e+00,3.079998e+00,-7.159989e+01
549 | 2.879992e+00,2.959998e+00,-6.679987e+01
550 | 3.039992e+00,3.079998e+00,-6.559987e+01
551 | -7.271767e-06,3.999982e-02,-6.679987e+01
552 | 7.999273e-02,7.999982e-02,-6.759988e+01
553 | -8.000727e-02,-4.000018e-02,-6.679987e+01
554 | -8.000727e-02,7.999982e-02,-8.559995e+01
555 | 7.999273e-02,-4.000018e-02,-6.879988e+01
556 | -8.000727e-02,-4.000018e-02,-6.759988e+01
557 | 7.999273e-02,7.999982e-02,-6.479987e+01
558 | 7.999273e-02,-4.000018e-02,-7.359990e+01
559 | -8.000727e-02,7.999982e-02,-7.959992e+01
560 | -8.000727e-02,-4.000018e-02,-7.359990e+01
561 | 2.959992e+00,3.039998e+00,-6.879988e+01
562 | 3.039992e+00,2.959998e+00,-7.079989e+01
563 | 2.879992e+00,3.079998e+00,-6.759988e+01
564 | 3.039992e+00,3.079998e+00,-7.959992e+01
565 | 2.879992e+00,2.959998e+00,-6.159985e+01
566 | 3.039992e+00,3.039998e+00,-7.479990e+01
567 | 2.879992e+00,2.959998e+00,-6.759988e+01
568 | 2.879992e+00,3.079998e+00,-6.559987e+01
569 | 3.039992e+00,2.959998e+00,-6.679987e+01
570 | 3.039992e+00,3.079998e+00,-6.759988e+01
571 | 7.999273e-02,-1.788139e-07,-6.879988e+01
572 | 7.999273e-02,-4.000018e-02,-6.359986e+01
573 | -8.000727e-02,7.999982e-02,-7.559991e+01
574 | 7.999273e-02,-4.000018e-02,-6.479987e+01
575 | -8.000727e-02,7.999982e-02,-6.679987e+01
576 | -8.000727e-02,7.999982e-02,-7.279990e+01
577 | 7.999273e-02,-4.000018e-02,-6.959988e+01
578 | 7.999273e-02,7.999982e-02,-8.359994e+01
579 | -8.000727e-02,-4.000018e-02,-7.159989e+01
580 | -8.000727e-02,-4.000018e-02,-6.759988e+01
581 | 2.959992e+00,3.039998e+00,-7.159989e+01
582 | 3.039992e+00,3.079998e+00,-7.359990e+01
583 | 2.879992e+00,2.959998e+00,-7.279990e+01
584 | 3.039992e+00,2.999998e+00,-7.279990e+01
585 | 2.879992e+00,3.079998e+00,-6.679987e+01
586 | 3.039992e+00,3.079998e+00,-6.879988e+01
587 | 2.879992e+00,2.959998e+00,-7.079989e+01
588 | 3.039992e+00,2.999998e+00,-7.479990e+01
589 | 2.879992e+00,3.119998e+00,-7.159989e+01
590 | 3.039992e+00,3.079998e+00,-7.359990e+01
591 | -7.271767e-06,3.999982e-02,-7.359990e+01
592 | 7.999273e-02,7.999982e-02,-7.679991e+01
593 | -8.000727e-02,-4.000018e-02,-6.759988e+01
594 | -8.000727e-02,-4.000018e-02,-7.079989e+01
595 | 7.999273e-02,7.999982e-02,-7.479990e+01
596 | -8.000727e-02,-4.000018e-02,-6.759988e+01
597 | 7.999273e-02,7.999982e-02,-7.159989e+01
598 | 7.999273e-02,-4.000018e-02,-6.759988e+01
599 | -8.000727e-02,7.999982e-02,-7.159989e+01
600 | -8.000727e-02,-4.000018e-02,-7.679991e+01
601 | 2.959992e+00,2.999998e+00,-7.359990e+01
602 | 3.039992e+00,2.959998e+00,-6.159985e+01
603 | 2.879992e+00,3.079998e+00,-5.679984e+01
604 | 3.039992e+00,3.079998e+00,-7.359990e+01
605 | 2.879992e+00,2.959998e+00,-6.679987e+01
606 | 3.039992e+00,2.959998e+00,-7.879992e+01
607 | 2.879992e+00,3.079998e+00,-7.359990e+01
608 | 3.039992e+00,2.959998e+00,-6.559987e+01
609 | 2.879992e+00,3.119998e+00,-7.159989e+01
610 | 3.039992e+00,3.079998e+00,-6.479987e+01
611 | 7.999273e-02,-1.788139e-07,-7.479990e+01
612 | 7.999273e-02,-4.000018e-02,-6.759988e+01
613 | -8.000727e-02,7.999982e-02,-6.759988e+01
614 | 7.999273e-02,-4.000018e-02,-7.079989e+01
615 | -8.000727e-02,7.999982e-02,-6.759988e+01
616 | 7.999273e-02,7.999982e-02,-7.479990e+01
617 | -8.000727e-02,-4.000018e-02,-6.959988e+01
618 | -8.000727e-02,7.999982e-02,-7.159989e+01
619 | 7.999273e-02,-4.000018e-02,-6.679987e+01
620 | -8.000727e-02,-4.000018e-02,-7.759991e+01
621 | 2.959992e+00,3.039998e+00,-7.079989e+01
622 | 3.039992e+00,3.079998e+00,-6.879988e+01
623 | 2.879992e+00,2.959998e+00,-7.159989e+01
624 | 3.039992e+00,3.119998e+00,-7.159989e+01
625 | 2.879992e+00,2.959998e+00,-6.759988e+01
626 | 3.039992e+00,2.959998e+00,-7.559991e+01
627 | 2.879992e+00,3.119998e+00,-6.479987e+01
628 | 3.039992e+00,3.119998e+00,-7.879992e+01
629 | 2.879992e+00,2.959998e+00,-6.679987e+01
630 | 3.039992e+00,3.079998e+00,-7.959992e+01
631 | -7.271767e-06,-1.788139e-07,-6.959988e+01
632 | 7.999273e-02,7.999982e-02,-6.759988e+01
633 | -8.000727e-02,-4.000018e-02,-7.879992e+01
634 | -8.000727e-02,7.999982e-02,-7.279990e+01
635 | 7.999273e-02,-4.000018e-02,-6.759988e+01
636 | -8.000727e-02,7.999982e-02,-7.079989e+01
637 | 7.999273e-02,-4.000018e-02,-7.279990e+01
638 | -8.000727e-02,7.999982e-02,-6.479987e+01
639 | 7.999273e-02,-4.000018e-02,-8.679995e+01
640 | -8.000727e-02,-4.000018e-02,-6.479987e+01
641 | 2.959992e+00,3.039998e+00,-7.679991e+01
642 | 3.039992e+00,3.079998e+00,-6.559987e+01
643 | 2.879992e+00,2.959998e+00,-7.159989e+01
644 | 3.039992e+00,3.079998e+00,-7.079989e+01
645 | 2.959992e+00,2.959998e+00,-6.879988e+01
646 | 3.039992e+00,3.079998e+00,-7.559991e+01
647 | 2.879992e+00,2.959998e+00,-7.159989e+01
648 | 3.039992e+00,3.079998e+00,-7.279990e+01
649 | 2.879992e+00,2.959998e+00,-7.479990e+01
650 | 3.039992e+00,3.079998e+00,-6.479987e+01
651 | 7.999273e-02,3.999982e-02,-7.159989e+01
652 | 7.999273e-02,-4.000018e-02,-7.879992e+01
653 | -8.000727e-02,7.999982e-02,-7.359990e+01
654 | 7.999273e-02,-4.000018e-02,-7.279990e+01
655 | -8.000727e-02,7.999982e-02,-7.159989e+01
656 | 7.999273e-02,-4.000018e-02,-7.159989e+01
657 | -8.000727e-02,7.999982e-02,-6.879988e+01
658 | -8.000727e-02,-4.000018e-02,-7.359990e+01
659 | 7.999273e-02,7.999982e-02,-7.279990e+01
660 | -8.000727e-02,-4.000018e-02,-6.479987e+01
661 | 2.959992e+00,3.039998e+00,-7.559991e+01
662 | 3.039992e+00,2.999998e+00,-6.479987e+01
663 | 2.879992e+00,3.079998e+00,-7.279990e+01
664 | 3.039992e+00,3.079998e+00,-8.559995e+01
665 | 2.879992e+00,2.959998e+00,-6.679987e+01
666 | 3.039992e+00,3.079998e+00,-7.359990e+01
667 | 2.879992e+00,2.959998e+00,-6.679987e+01
668 | 3.039992e+00,2.959998e+00,-7.359990e+01
669 | 2.879992e+00,3.079998e+00,-7.079989e+01
670 | 3.039992e+00,3.079998e+00,-6.759988e+01
671 | 7.999273e-02,-1.788139e-07,-7.079989e+01
672 | 7.999273e-02,7.999982e-02,-6.879988e+01
673 | -8.000727e-02,-4.000018e-02,-7.279990e+01
674 | -8.000727e-02,-4.000018e-02,-6.479987e+01
675 | 7.999273e-02,7.999982e-02,-7.079989e+01
676 | -8.000727e-02,7.999982e-02,-6.759988e+01
677 | 7.999273e-02,-4.000018e-02,-6.759988e+01
678 | -8.000727e-02,7.999982e-02,-6.959988e+01
679 | 7.999273e-02,-4.000018e-02,-7.759991e+01
680 | -8.000727e-02,-4.000018e-02,-6.959988e+01
681 | 2.959992e+00,3.039998e+00,-6.879988e+01
682 | 3.039992e+00,2.999998e+00,-6.479987e+01
683 | 2.879992e+00,3.079998e+00,-7.079989e+01
684 | 3.039992e+00,2.959998e+00,-8.079993e+01
685 | 2.879992e+00,3.079998e+00,-6.879988e+01
686 | 3.039992e+00,2.959998e+00,-7.079989e+01
687 | 2.879992e+00,3.079998e+00,-6.559987e+01
688 | 3.039992e+00,3.079998e+00,-6.879988e+01
689 | 2.879992e+00,2.959998e+00,-7.359990e+01
690 | 3.039992e+00,3.079998e+00,-6.559987e+01
691 | -7.271767e-06,-1.788139e-07,-7.479990e+01
692 | 7.999273e-02,-4.000018e-02,-6.279986e+01
693 | -8.000727e-02,7.999982e-02,-6.679987e+01
694 | -8.000727e-02,-4.000018e-02,-6.559987e+01
695 | 7.999273e-02,7.999982e-02,-5.959985e+01
696 | 7.999273e-02,-4.000018e-02,-7.079989e+01
697 | -8.000727e-02,7.999982e-02,-5.959985e+01
698 | 7.999273e-02,-4.000018e-02,-5.959985e+01
699 | -8.000727e-02,7.999982e-02,-5.759984e+01
700 | -8.000727e-02,-4.000018e-02,-5.079981e+01
701 | 2.959992e+00,3.039998e+00,-6.359986e+01
702 | 3.039992e+00,3.079998e+00,-3.879977e+01
703 | 2.879992e+00,2.959998e+00,-3.479975e+01
704 | 3.039992e+00,2.999998e+00,-4.359978e+01
705 | 2.879992e+00,3.079998e+00,-4.759980e+01
706 | 3.039992e+00,3.079998e+00,-5.559983e+01
707 | 2.879992e+00,2.959998e+00,-5.359982e+01
708 | 3.039992e+00,3.079998e+00,-6.959988e+01
709 | 2.879992e+00,2.959998e+00,-5.559983e+01
710 | 3.039992e+00,3.079998e+00,-5.959985e+01
711 | -7.271767e-06,-1.788139e-07,-6.159985e+01
712 | 7.999273e-02,7.999982e-02,-5.959985e+01
713 | -8.000727e-02,-4.000018e-02,-7.559991e+01
714 | 7.999273e-02,7.999982e-02,-6.079985e+01
715 | -8.000727e-02,-4.000018e-02,-6.159985e+01
716 | 7.999273e-02,7.999982e-02,-5.959985e+01
717 | -8.000727e-02,-4.000018e-02,-5.959985e+01
718 | -8.000727e-02,-4.000018e-02,-6.079985e+01
719 | 7.999273e-02,7.999982e-02,-7.479990e+01
720 | -8.000727e-02,-4.000018e-02,-6.479987e+01
721 | 2.959992e+00,3.039998e+00,-6.159985e+01
722 | 3.039992e+00,3.079998e+00,-6.479987e+01
723 | 2.879992e+00,2.959998e+00,-6.079985e+01
724 | 3.039992e+00,2.959998e+00,-6.959988e+01
725 | 2.879992e+00,3.079998e+00,-6.159985e+01
726 | 3.039992e+00,2.959998e+00,-6.879988e+01
727 | 2.959992e+00,3.119998e+00,-6.359986e+01
728 | 3.039992e+00,2.959998e+00,-6.679987e+01
729 | 2.879992e+00,3.079998e+00,-7.359990e+01
730 | 3.039992e+00,3.079998e+00,-6.559987e+01
731 | 7.999273e-02,-1.788139e-07,-7.359990e+01
732 | 7.999273e-02,-4.000018e-02,-6.759988e+01
733 | -8.000727e-02,7.999982e-02,-6.479987e+01
734 | -8.000727e-02,-4.000018e-02,-6.759988e+01
735 | 7.999273e-02,7.999982e-02,-6.559987e+01
736 | -8.000727e-02,7.999982e-02,-7.079989e+01
737 | 7.999273e-02,-4.000018e-02,-6.479987e+01
738 | 7.999273e-02,7.999982e-02,-6.679987e+01
739 | -8.000727e-02,-4.000018e-02,-6.879988e+01
740 | -8.000727e-02,-4.000018e-02,-6.479987e+01
741 | 2.959992e+00,3.039998e+00,-9.159997e+01
742 | 3.039992e+00,2.999998e+00,-6.159985e+01
743 | 2.879992e+00,3.079998e+00,-7.159989e+01
744 | 3.039992e+00,3.079998e+00,-6.679987e+01
745 | 2.879992e+00,2.959998e+00,-6.879988e+01
746 | 3.039992e+00,2.999998e+00,-7.679991e+01
747 | 2.879992e+00,3.079998e+00,-6.159985e+01
748 | 3.039992e+00,2.959998e+00,-6.879988e+01
749 | 2.879992e+00,3.079998e+00,-7.479990e+01
750 | 3.039992e+00,3.079998e+00,-6.559987e+01
751 | -7.271767e-06,3.999982e-02,-6.679987e+01
752 | 7.999273e-02,-4.000018e-02,-6.959988e+01
753 | -8.000727e-02,7.999982e-02,-6.959988e+01
754 | -8.000727e-02,-4.000018e-02,-6.479987e+01
755 | 7.999273e-02,7.999982e-02,-6.959988e+01
756 | 7.999273e-02,-4.000018e-02,-7.559991e+01
757 | -8.000727e-02,7.999982e-02,-6.479987e+01
758 | -8.000727e-02,7.999982e-02,-6.759988e+01
759 | 7.999273e-02,-4.000018e-02,-6.559987e+01
760 | -8.000727e-02,-4.000018e-02,-6.759988e+01
761 | 2.959992e+00,2.999998e+00,-6.479987e+01
762 | 3.039992e+00,2.959998e+00,-6.559987e+01
763 | 2.879992e+00,3.079998e+00,-6.559987e+01
764 | 2.879992e+00,2.999998e+00,-7.359990e+01
765 | 3.039992e+00,3.079998e+00,-6.959988e+01
766 | 3.039992e+00,3.079998e+00,-7.359990e+01
767 | 2.879992e+00,2.959998e+00,-7.079989e+01
768 | 3.039992e+00,3.079998e+00,-7.759991e+01
769 | 2.879992e+00,2.959998e+00,-6.759988e+01
770 | 3.039992e+00,3.079998e+00,-6.559987e+01
771 | -7.271767e-06,-1.788139e-07,-6.559987e+01
772 | 7.999273e-02,-4.000018e-02,-6.679987e+01
773 | -8.000727e-02,7.999982e-02,-6.479987e+01
774 | 7.999273e-02,7.999982e-02,-7.479990e+01
775 | -8.000727e-02,-4.000018e-02,-6.679987e+01
776 | 7.999273e-02,-4.000018e-02,-7.279990e+01
777 | -8.000727e-02,7.999982e-02,-6.359986e+01
778 | 7.999273e-02,7.999982e-02,-7.559991e+01
779 | -8.000727e-02,-4.000018e-02,-7.079989e+01
780 | -8.000727e-02,-4.000018e-02,-6.359986e+01
781 | 2.959992e+00,3.039998e+00,-6.959988e+01
782 | 3.039992e+00,2.959998e+00,-6.479987e+01
783 | 2.879992e+00,3.079998e+00,-7.759991e+01
784 | 3.039992e+00,2.999998e+00,-6.679987e+01
785 | 2.879992e+00,3.079998e+00,-7.679991e+01
786 | 2.879992e+00,3.079998e+00,-8.759995e+01
787 | 3.039992e+00,2.959998e+00,-6.559987e+01
788 | 2.879992e+00,3.079998e+00,-7.959992e+01
789 | 3.039992e+00,2.959998e+00,-6.879988e+01
790 | 3.039992e+00,3.079998e+00,-6.879988e+01
791 | -7.271767e-06,3.999982e-02,-6.679987e+01
792 | 7.999273e-02,7.999982e-02,-7.479990e+01
793 | -8.000727e-02,-4.000018e-02,-7.759991e+01
794 | -8.000727e-02,7.999982e-02,-7.359990e+01
795 | 7.999273e-02,-4.000018e-02,-7.159989e+01
796 | -8.000727e-02,7.999982e-02,-6.879988e+01
797 | 7.999273e-02,-4.000018e-02,-7.079989e+01
798 | -8.000727e-02,7.999982e-02,-7.479990e+01
799 | 7.999273e-02,-4.000018e-02,-6.479987e+01
800 | -8.000727e-02,-4.000018e-02,-8.159993e+01
801 | 2.959992e+00,3.039998e+00,-7.479990e+01
802 | 3.039992e+00,3.079998e+00,-6.679987e+01
803 |
--------------------------------------------------------------------------------
/captures/Spreadsheet look for CSV.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoGeorge/DS1054Z_screen_capture/570ad8ed5beaf1ba41cf6641721b513a39bb3cdc/captures/Spreadsheet look for CSV.png
--------------------------------------------------------------------------------
/telnetlib_receive_all.py:
--------------------------------------------------------------------------------
1 | # This whole file is a copy of the 'telnetlib.py' that came with Python 2.7.12 distribution.
2 | # A patch was applied to this file, in order to stop dropping null (0x00) characters.
3 |
4 | r"""TELNET client class.
5 |
6 | Based on RFC 854: TELNET Protocol Specification, by J. Postel and
7 | J. Reynolds
8 |
9 | Example:
10 |
11 | >>> from telnetlib import Telnet
12 | >>> tn = Telnet('www.python.org', 79) # connect to finger port
13 | >>> tn.write('guido\r\n')
14 | >>> print tn.read_all()
15 | Login Name TTY Idle When Where
16 | guido Guido van Rossum pts/2 snag.cnri.reston..
17 |
18 | >>>
19 |
20 | Note that read_all() won't read until eof -- it just reads some data
21 | -- but it guarantees to read at least one byte unless EOF is hit.
22 |
23 | It is possible to pass a Telnet object to select.select() in order to
24 | wait until more data is available. Note that in this case,
25 | read_eager() may return '' even if there was data on the socket,
26 | because the protocol negotiation may have eaten the data. This is why
27 | EOFError is needed in some cases to distinguish between "no data" and
28 | "connection closed" (since the socket also appears ready for reading
29 | when it is closed).
30 |
31 | To do:
32 | - option negotiation
33 | - timeout should be intrinsic to the connection object instead of an
34 | option on one of the read calls only
35 |
36 | """
37 |
38 |
39 | # Imported modules
40 | import errno
41 | import sys
42 | import socket
43 | import select
44 |
45 | __all__ = ["Telnet"]
46 |
47 | # Tunable parameters
48 | DEBUGLEVEL = 0
49 |
50 | # Telnet protocol defaults
51 | TELNET_PORT = 23
52 |
53 | # Telnet protocol characters (don't change)
54 | IAC = chr(255) # "Interpret As Command"
55 | DONT = chr(254)
56 | DO = chr(253)
57 | WONT = chr(252)
58 | WILL = chr(251)
59 | theNULL = chr(0)
60 |
61 | SE = chr(240) # Subnegotiation End
62 | NOP = chr(241) # No Operation
63 | DM = chr(242) # Data Mark
64 | BRK = chr(243) # Break
65 | IP = chr(244) # Interrupt process
66 | AO = chr(245) # Abort output
67 | AYT = chr(246) # Are You There
68 | EC = chr(247) # Erase Character
69 | EL = chr(248) # Erase Line
70 | GA = chr(249) # Go Ahead
71 | SB = chr(250) # Subnegotiation Begin
72 |
73 |
74 | # Telnet protocol options code (don't change)
75 | # These ones all come from arpa/telnet.h
76 | BINARY = chr(0) # 8-bit data path
77 | ECHO = chr(1) # echo
78 | RCP = chr(2) # prepare to reconnect
79 | SGA = chr(3) # suppress go ahead
80 | NAMS = chr(4) # approximate message size
81 | STATUS = chr(5) # give status
82 | TM = chr(6) # timing mark
83 | RCTE = chr(7) # remote controlled transmission and echo
84 | NAOL = chr(8) # negotiate about output line width
85 | NAOP = chr(9) # negotiate about output page size
86 | NAOCRD = chr(10) # negotiate about CR disposition
87 | NAOHTS = chr(11) # negotiate about horizontal tabstops
88 | NAOHTD = chr(12) # negotiate about horizontal tab disposition
89 | NAOFFD = chr(13) # negotiate about formfeed disposition
90 | NAOVTS = chr(14) # negotiate about vertical tab stops
91 | NAOVTD = chr(15) # negotiate about vertical tab disposition
92 | NAOLFD = chr(16) # negotiate about output LF disposition
93 | XASCII = chr(17) # extended ascii character set
94 | LOGOUT = chr(18) # force logout
95 | BM = chr(19) # byte macro
96 | DET = chr(20) # data entry terminal
97 | SUPDUP = chr(21) # supdup protocol
98 | SUPDUPOUTPUT = chr(22) # supdup output
99 | SNDLOC = chr(23) # send location
100 | TTYPE = chr(24) # terminal type
101 | EOR = chr(25) # end or record
102 | TUID = chr(26) # TACACS user identification
103 | OUTMRK = chr(27) # output marking
104 | TTYLOC = chr(28) # terminal location number
105 | VT3270REGIME = chr(29) # 3270 regime
106 | X3PAD = chr(30) # X.3 PAD
107 | NAWS = chr(31) # window size
108 | TSPEED = chr(32) # terminal speed
109 | LFLOW = chr(33) # remote flow control
110 | LINEMODE = chr(34) # Linemode option
111 | XDISPLOC = chr(35) # X Display Location
112 | OLD_ENVIRON = chr(36) # Old - Environment variables
113 | AUTHENTICATION = chr(37) # Authenticate
114 | ENCRYPT = chr(38) # Encryption option
115 | NEW_ENVIRON = chr(39) # New - Environment variables
116 | # the following ones come from
117 | # http://www.iana.org/assignments/telnet-options
118 | # Unfortunately, that document does not assign identifiers
119 | # to all of them, so we are making them up
120 | TN3270E = chr(40) # TN3270E
121 | XAUTH = chr(41) # XAUTH
122 | CHARSET = chr(42) # CHARSET
123 | RSP = chr(43) # Telnet Remote Serial Port
124 | COM_PORT_OPTION = chr(44) # Com Port Control Option
125 | SUPPRESS_LOCAL_ECHO = chr(45) # Telnet Suppress Local Echo
126 | TLS = chr(46) # Telnet Start TLS
127 | KERMIT = chr(47) # KERMIT
128 | SEND_URL = chr(48) # SEND-URL
129 | FORWARD_X = chr(49) # FORWARD_X
130 | PRAGMA_LOGON = chr(138) # TELOPT PRAGMA LOGON
131 | SSPI_LOGON = chr(139) # TELOPT SSPI LOGON
132 | PRAGMA_HEARTBEAT = chr(140) # TELOPT PRAGMA HEARTBEAT
133 | EXOPL = chr(255) # Extended-Options-List
134 | NOOPT = chr(0)
135 |
136 | class Telnet:
137 |
138 | """Telnet interface class.
139 |
140 | An instance of this class represents a connection to a telnet
141 | server. The instance is initially not connected; the open()
142 | method must be used to establish a connection. Alternatively, the
143 | host name and optional port number can be passed to the
144 | constructor, too.
145 |
146 | Don't try to reopen an already connected instance.
147 |
148 | This class has many read_*() methods. Note that some of them
149 | raise EOFError when the end of the connection is read, because
150 | they can return an empty string for other reasons. See the
151 | individual doc strings.
152 |
153 | read_until(expected, [timeout])
154 | Read until the expected string has been seen, or a timeout is
155 | hit (default is no timeout); may block.
156 |
157 | read_all()
158 | Read all data until EOF; may block.
159 |
160 | read_some()
161 | Read at least one byte or EOF; may block.
162 |
163 | read_very_eager()
164 | Read all data available already queued or on the socket,
165 | without blocking.
166 |
167 | read_eager()
168 | Read either data already queued or some data available on the
169 | socket, without blocking.
170 |
171 | read_lazy()
172 | Read all data in the raw queue (processing it first), without
173 | doing any socket I/O.
174 |
175 | read_very_lazy()
176 | Reads all data in the cooked queue, without doing any socket
177 | I/O.
178 |
179 | read_sb_data()
180 | Reads available data between SB ... SE sequence. Don't block.
181 |
182 | set_option_negotiation_callback(callback)
183 | Each time a telnet option is read on the input flow, this callback
184 | (if set) is called with the following parameters :
185 | callback(telnet socket, command, option)
186 | option will be chr(0) when there is no option.
187 | No other action is done afterwards by telnetlib.
188 |
189 | """
190 |
191 | def __init__(self, host=None, port=0,
192 | timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
193 | """Constructor.
194 |
195 | When called without arguments, create an unconnected instance.
196 | With a hostname argument, it connects the instance; port number
197 | and timeout are optional.
198 | """
199 | self.debuglevel = DEBUGLEVEL
200 | self.host = host
201 | self.port = port
202 | self.timeout = timeout
203 | self.sock = None
204 | self.rawq = ''
205 | self.irawq = 0
206 | self.cookedq = ''
207 | self.eof = 0
208 | self.iacseq = '' # Buffer for IAC sequence.
209 | self.sb = 0 # flag for SB and SE sequence.
210 | self.sbdataq = ''
211 | self.option_callback = None
212 | self._has_poll = hasattr(select, 'poll')
213 | if host is not None:
214 | self.open(host, port, timeout)
215 |
216 | def open(self, host, port=0, timeout=socket._GLOBAL_DEFAULT_TIMEOUT):
217 | """Connect to a host.
218 |
219 | The optional second argument is the port number, which
220 | defaults to the standard telnet port (23).
221 |
222 | Don't try to reopen an already connected instance.
223 | """
224 | self.eof = 0
225 | if not port:
226 | port = TELNET_PORT
227 | self.host = host
228 | self.port = port
229 | self.timeout = timeout
230 | self.sock = socket.create_connection((host, port), timeout)
231 |
232 | def __del__(self):
233 | """Destructor -- close the connection."""
234 | self.close()
235 |
236 | def msg(self, msg, *args):
237 | """Print a debug message, when the debug level is > 0.
238 |
239 | If extra arguments are present, they are substituted in the
240 | message using the standard string formatting operator.
241 |
242 | """
243 | if self.debuglevel > 0:
244 | print 'Telnet(%s,%s):' % (self.host, self.port),
245 | if args:
246 | print msg % args
247 | else:
248 | print msg
249 |
250 | def set_debuglevel(self, debuglevel):
251 | """Set the debug level.
252 |
253 | The higher it is, the more debug output you get (on sys.stdout).
254 |
255 | """
256 | self.debuglevel = debuglevel
257 |
258 | def close(self):
259 | """Close the connection."""
260 | sock = self.sock
261 | self.sock = 0
262 | self.eof = 1
263 | self.iacseq = ''
264 | self.sb = 0
265 | if sock:
266 | sock.close()
267 |
268 | def get_socket(self):
269 | """Return the socket object used internally."""
270 | return self.sock
271 |
272 | def fileno(self):
273 | """Return the fileno() of the socket object used internally."""
274 | return self.sock.fileno()
275 |
276 | def write(self, buffer):
277 | """Write a string to the socket, doubling any IAC characters.
278 |
279 | Can block if the connection is blocked. May raise
280 | socket.error if the connection is closed.
281 |
282 | """
283 | if IAC in buffer:
284 | buffer = buffer.replace(IAC, IAC+IAC)
285 | self.msg("send %r", buffer)
286 | self.sock.sendall(buffer)
287 |
288 | def read_until(self, match, timeout=None):
289 | """Read until a given string is encountered or until timeout.
290 |
291 | When no match is found, return whatever is available instead,
292 | possibly the empty string. Raise EOFError if the connection
293 | is closed and no cooked data is available.
294 |
295 | """
296 | if self._has_poll:
297 | return self._read_until_with_poll(match, timeout)
298 | else:
299 | return self._read_until_with_select(match, timeout)
300 |
301 | def _read_until_with_poll(self, match, timeout):
302 | """Read until a given string is encountered or until timeout.
303 |
304 | This method uses select.poll() to implement the timeout.
305 | """
306 | n = len(match)
307 | call_timeout = timeout
308 | if timeout is not None:
309 | from time import time
310 | time_start = time()
311 | self.process_rawq()
312 | i = self.cookedq.find(match)
313 | if i < 0:
314 | poller = select.poll()
315 | poll_in_or_priority_flags = select.POLLIN | select.POLLPRI
316 | poller.register(self, poll_in_or_priority_flags)
317 | while i < 0 and not self.eof:
318 | try:
319 | # Poll takes its timeout in milliseconds.
320 | ready = poller.poll(None if timeout is None
321 | else 1000 * call_timeout)
322 | except select.error as e:
323 | if e.errno == errno.EINTR:
324 | if timeout is not None:
325 | elapsed = time() - time_start
326 | call_timeout = timeout-elapsed
327 | continue
328 | raise
329 | for fd, mode in ready:
330 | if mode & poll_in_or_priority_flags:
331 | i = max(0, len(self.cookedq)-n)
332 | self.fill_rawq()
333 | self.process_rawq()
334 | i = self.cookedq.find(match, i)
335 | if timeout is not None:
336 | elapsed = time() - time_start
337 | if elapsed >= timeout:
338 | break
339 | call_timeout = timeout-elapsed
340 | poller.unregister(self)
341 | if i >= 0:
342 | i = i + n
343 | buf = self.cookedq[:i]
344 | self.cookedq = self.cookedq[i:]
345 | return buf
346 | return self.read_very_lazy()
347 |
348 | def _read_until_with_select(self, match, timeout=None):
349 | """Read until a given string is encountered or until timeout.
350 |
351 | The timeout is implemented using select.select().
352 | """
353 | n = len(match)
354 | self.process_rawq()
355 | i = self.cookedq.find(match)
356 | if i >= 0:
357 | i = i+n
358 | buf = self.cookedq[:i]
359 | self.cookedq = self.cookedq[i:]
360 | return buf
361 | s_reply = ([self], [], [])
362 | s_args = s_reply
363 | if timeout is not None:
364 | s_args = s_args + (timeout,)
365 | from time import time
366 | time_start = time()
367 | while not self.eof and select.select(*s_args) == s_reply:
368 | i = max(0, len(self.cookedq)-n)
369 | self.fill_rawq()
370 | self.process_rawq()
371 | i = self.cookedq.find(match, i)
372 | if i >= 0:
373 | i = i+n
374 | buf = self.cookedq[:i]
375 | self.cookedq = self.cookedq[i:]
376 | return buf
377 | if timeout is not None:
378 | elapsed = time() - time_start
379 | if elapsed >= timeout:
380 | break
381 | s_args = s_reply + (timeout-elapsed,)
382 | return self.read_very_lazy()
383 |
384 | def read_all(self):
385 | """Read all data until EOF; block until connection closed."""
386 | self.process_rawq()
387 | while not self.eof:
388 | self.fill_rawq()
389 | self.process_rawq()
390 | buf = self.cookedq
391 | self.cookedq = ''
392 | return buf
393 |
394 | def read_some(self):
395 | """Read at least one byte of cooked data unless EOF is hit.
396 |
397 | Return '' if EOF is hit. Block if no data is immediately
398 | available.
399 |
400 | """
401 | self.process_rawq()
402 | while not self.cookedq and not self.eof:
403 | self.fill_rawq()
404 | self.process_rawq()
405 | buf = self.cookedq
406 | self.cookedq = ''
407 | return buf
408 |
409 | def read_very_eager(self):
410 | """Read everything that's possible without blocking in I/O (eager).
411 |
412 | Raise EOFError if connection closed and no cooked data
413 | available. Return '' if no cooked data available otherwise.
414 | Don't block unless in the midst of an IAC sequence.
415 |
416 | """
417 | self.process_rawq()
418 | while not self.eof and self.sock_avail():
419 | self.fill_rawq()
420 | self.process_rawq()
421 | return self.read_very_lazy()
422 |
423 | def read_eager(self):
424 | """Read readily available data.
425 |
426 | Raise EOFError if connection closed and no cooked data
427 | available. Return '' if no cooked data available otherwise.
428 | Don't block unless in the midst of an IAC sequence.
429 |
430 | """
431 | self.process_rawq()
432 | while not self.cookedq and not self.eof and self.sock_avail():
433 | self.fill_rawq()
434 | self.process_rawq()
435 | return self.read_very_lazy()
436 |
437 | def read_lazy(self):
438 | """Process and return data that's already in the queues (lazy).
439 |
440 | Raise EOFError if connection closed and no data available.
441 | Return '' if no cooked data available otherwise. Don't block
442 | unless in the midst of an IAC sequence.
443 |
444 | """
445 | self.process_rawq()
446 | return self.read_very_lazy()
447 |
448 | def read_very_lazy(self):
449 | """Return any data available in the cooked queue (very lazy).
450 |
451 | Raise EOFError if connection closed and no data available.
452 | Return '' if no cooked data available otherwise. Don't block.
453 |
454 | """
455 | buf = self.cookedq
456 | self.cookedq = ''
457 | if not buf and self.eof and not self.rawq:
458 | raise EOFError, 'telnet connection closed'
459 | return buf
460 |
461 | def read_sb_data(self):
462 | """Return any data available in the SB ... SE queue.
463 |
464 | Return '' if no SB ... SE available. Should only be called
465 | after seeing a SB or SE command. When a new SB command is
466 | found, old unread SB data will be discarded. Don't block.
467 |
468 | """
469 | buf = self.sbdataq
470 | self.sbdataq = ''
471 | return buf
472 |
473 | def set_option_negotiation_callback(self, callback):
474 | """Provide a callback function called after each receipt of a telnet option."""
475 | self.option_callback = callback
476 |
477 | def process_rawq(self):
478 | """Transfer from raw queue to cooked queue.
479 |
480 | Set self.eof when connection is closed. Don't block unless in
481 | the midst of an IAC sequence.
482 |
483 | """
484 | buf = ['', '']
485 | try:
486 | while self.rawq:
487 | c = self.rawq_getchar()
488 | if not self.iacseq:
489 | #if c == theNULL:
490 | # continue
491 | #if c == "\021":
492 | # continue
493 | if c != IAC:
494 | buf[self.sb] = buf[self.sb] + c
495 | continue
496 | else:
497 | self.iacseq += c
498 | elif len(self.iacseq) == 1:
499 | # 'IAC: IAC CMD [OPTION only for WILL/WONT/DO/DONT]'
500 | if c in (DO, DONT, WILL, WONT):
501 | self.iacseq += c
502 | continue
503 |
504 | self.iacseq = ''
505 | if c == IAC:
506 | buf[self.sb] = buf[self.sb] + c
507 | else:
508 | if c == SB: # SB ... SE start.
509 | self.sb = 1
510 | self.sbdataq = ''
511 | elif c == SE:
512 | self.sb = 0
513 | self.sbdataq = self.sbdataq + buf[1]
514 | buf[1] = ''
515 | if self.option_callback:
516 | # Callback is supposed to look into
517 | # the sbdataq
518 | self.option_callback(self.sock, c, NOOPT)
519 | else:
520 | # We can't offer automatic processing of
521 | # suboptions. Alas, we should not get any
522 | # unless we did a WILL/DO before.
523 | self.msg('IAC %d not recognized' % ord(c))
524 | elif len(self.iacseq) == 2:
525 | cmd = self.iacseq[1]
526 | self.iacseq = ''
527 | opt = c
528 | if cmd in (DO, DONT):
529 | self.msg('IAC %s %d',
530 | cmd == DO and 'DO' or 'DONT', ord(opt))
531 | if self.option_callback:
532 | self.option_callback(self.sock, cmd, opt)
533 | else:
534 | self.sock.sendall(IAC + WONT + opt)
535 | elif cmd in (WILL, WONT):
536 | self.msg('IAC %s %d',
537 | cmd == WILL and 'WILL' or 'WONT', ord(opt))
538 | if self.option_callback:
539 | self.option_callback(self.sock, cmd, opt)
540 | else:
541 | self.sock.sendall(IAC + DONT + opt)
542 | except EOFError: # raised by self.rawq_getchar()
543 | self.iacseq = '' # Reset on EOF
544 | self.sb = 0
545 | pass
546 | self.cookedq = self.cookedq + buf[0]
547 | self.sbdataq = self.sbdataq + buf[1]
548 |
549 | def rawq_getchar(self):
550 | """Get next char from raw queue.
551 |
552 | Block if no data is immediately available. Raise EOFError
553 | when connection is closed.
554 |
555 | """
556 | if not self.rawq:
557 | self.fill_rawq()
558 | if self.eof:
559 | raise EOFError
560 | c = self.rawq[self.irawq]
561 | self.irawq = self.irawq + 1
562 | if self.irawq >= len(self.rawq):
563 | self.rawq = ''
564 | self.irawq = 0
565 | return c
566 |
567 | def fill_rawq(self):
568 | """Fill raw queue from exactly one recv() system call.
569 |
570 | Block if no data is immediately available. Set self.eof when
571 | connection is closed.
572 |
573 | """
574 | if self.irawq >= len(self.rawq):
575 | self.rawq = ''
576 | self.irawq = 0
577 | # The buffer size should be fairly small so as to avoid quadratic
578 | # behavior in process_rawq() above
579 | buf = self.sock.recv(50)
580 | self.msg("recv %r", buf)
581 | self.eof = (not buf)
582 | self.rawq = self.rawq + buf
583 |
584 | def sock_avail(self):
585 | """Test whether data is available on the socket."""
586 | return select.select([self], [], [], 0) == ([self], [], [])
587 |
588 | def interact(self):
589 | """Interaction function, emulates a very dumb telnet client."""
590 | if sys.platform == "win32":
591 | self.mt_interact()
592 | return
593 | while 1:
594 | rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
595 | if self in rfd:
596 | try:
597 | text = self.read_eager()
598 | except EOFError:
599 | print '*** Connection closed by remote host ***'
600 | break
601 | if text:
602 | sys.stdout.write(text)
603 | sys.stdout.flush()
604 | if sys.stdin in rfd:
605 | line = sys.stdin.readline()
606 | if not line:
607 | break
608 | self.write(line)
609 |
610 | def mt_interact(self):
611 | """Multithreaded version of interact()."""
612 | import thread
613 | thread.start_new_thread(self.listener, ())
614 | while 1:
615 | line = sys.stdin.readline()
616 | if not line:
617 | break
618 | self.write(line)
619 |
620 | def listener(self):
621 | """Helper for mt_interact() -- this executes in the other thread."""
622 | while 1:
623 | try:
624 | data = self.read_eager()
625 | except EOFError:
626 | print '*** Connection closed by remote host ***'
627 | return
628 | if data:
629 | sys.stdout.write(data)
630 | else:
631 | sys.stdout.flush()
632 |
633 | def expect(self, list, timeout=None):
634 | """Read until one from a list of a regular expressions matches.
635 |
636 | The first argument is a list of regular expressions, either
637 | compiled (re.RegexObject instances) or uncompiled (strings).
638 | The optional second argument is a timeout, in seconds; default
639 | is no timeout.
640 |
641 | Return a tuple of three items: the index in the list of the
642 | first regular expression that matches; the match object
643 | returned; and the text read up till and including the match.
644 |
645 | If EOF is read and no text was read, raise EOFError.
646 | Otherwise, when nothing matches, return (-1, None, text) where
647 | text is the text received so far (may be the empty string if a
648 | timeout happened).
649 |
650 | If a regular expression ends with a greedy match (e.g. '.*')
651 | or if more than one expression can match the same input, the
652 | results are undeterministic, and may depend on the I/O timing.
653 |
654 | """
655 | if self._has_poll:
656 | return self._expect_with_poll(list, timeout)
657 | else:
658 | return self._expect_with_select(list, timeout)
659 |
660 | def _expect_with_poll(self, expect_list, timeout=None):
661 | """Read until one from a list of a regular expressions matches.
662 |
663 | This method uses select.poll() to implement the timeout.
664 | """
665 | re = None
666 | expect_list = expect_list[:]
667 | indices = range(len(expect_list))
668 | for i in indices:
669 | if not hasattr(expect_list[i], "search"):
670 | if not re: import re
671 | expect_list[i] = re.compile(expect_list[i])
672 | call_timeout = timeout
673 | if timeout is not None:
674 | from time import time
675 | time_start = time()
676 | self.process_rawq()
677 | m = None
678 | for i in indices:
679 | m = expect_list[i].search(self.cookedq)
680 | if m:
681 | e = m.end()
682 | text = self.cookedq[:e]
683 | self.cookedq = self.cookedq[e:]
684 | break
685 | if not m:
686 | poller = select.poll()
687 | poll_in_or_priority_flags = select.POLLIN | select.POLLPRI
688 | poller.register(self, poll_in_or_priority_flags)
689 | while not m and not self.eof:
690 | try:
691 | ready = poller.poll(None if timeout is None
692 | else 1000 * call_timeout)
693 | except select.error as e:
694 | if e.errno == errno.EINTR:
695 | if timeout is not None:
696 | elapsed = time() - time_start
697 | call_timeout = timeout-elapsed
698 | continue
699 | raise
700 | for fd, mode in ready:
701 | if mode & poll_in_or_priority_flags:
702 | self.fill_rawq()
703 | self.process_rawq()
704 | for i in indices:
705 | m = expect_list[i].search(self.cookedq)
706 | if m:
707 | e = m.end()
708 | text = self.cookedq[:e]
709 | self.cookedq = self.cookedq[e:]
710 | break
711 | if timeout is not None:
712 | elapsed = time() - time_start
713 | if elapsed >= timeout:
714 | break
715 | call_timeout = timeout-elapsed
716 | poller.unregister(self)
717 | if m:
718 | return (i, m, text)
719 | text = self.read_very_lazy()
720 | if not text and self.eof:
721 | raise EOFError
722 | return (-1, None, text)
723 |
724 | def _expect_with_select(self, list, timeout=None):
725 | """Read until one from a list of a regular expressions matches.
726 |
727 | The timeout is implemented using select.select().
728 | """
729 | re = None
730 | list = list[:]
731 | indices = range(len(list))
732 | for i in indices:
733 | if not hasattr(list[i], "search"):
734 | if not re: import re
735 | list[i] = re.compile(list[i])
736 | if timeout is not None:
737 | from time import time
738 | time_start = time()
739 | while 1:
740 | self.process_rawq()
741 | for i in indices:
742 | m = list[i].search(self.cookedq)
743 | if m:
744 | e = m.end()
745 | text = self.cookedq[:e]
746 | self.cookedq = self.cookedq[e:]
747 | return (i, m, text)
748 | if self.eof:
749 | break
750 | if timeout is not None:
751 | elapsed = time() - time_start
752 | if elapsed >= timeout:
753 | break
754 | s_args = ([self.fileno()], [], [], timeout-elapsed)
755 | r, w, x = select.select(*s_args)
756 | if not r:
757 | break
758 | self.fill_rawq()
759 | text = self.read_very_lazy()
760 | if not text and self.eof:
761 | raise EOFError
762 | return (-1, None, text)
763 |
764 |
765 | def test():
766 | """Test program for telnetlib.
767 |
768 | Usage: python telnetlib.py [-d] ... [host [port]]
769 |
770 | Default host is localhost; default port is 23.
771 |
772 | """
773 | debuglevel = 0
774 | while sys.argv[1:] and sys.argv[1] == '-d':
775 | debuglevel = debuglevel+1
776 | del sys.argv[1]
777 | host = 'localhost'
778 | if sys.argv[1:]:
779 | host = sys.argv[1]
780 | port = 0
781 | if sys.argv[2:]:
782 | portstr = sys.argv[2]
783 | try:
784 | port = int(portstr)
785 | except ValueError:
786 | port = socket.getservbyname(portstr, 'tcp')
787 | tn = Telnet()
788 | tn.set_debuglevel(debuglevel)
789 | tn.open(host, port, timeout=0.5)
790 | tn.interact()
791 | tn.close()
792 |
793 | if __name__ == '__main__':
794 | test()
795 |
--------------------------------------------------------------------------------