| @@ -0,0 +1,3 @@ | |||||
| [submodule "libs/pyftdi"] | |||||
| path = libs/pyftdi | |||||
| url = git@git.corp.nutech.com:nutech/pyftdi | |||||
| @@ -0,0 +1,177 @@ | |||||
| # Makefile for Sphinx documentation | |||||
| # | |||||
| # You can set these variables from the command line. | |||||
| SPHINXOPTS = | |||||
| SPHINXBUILD = sphinx-build | |||||
| PAPER = | |||||
| BUILDDIR = _build | |||||
| # User-friendly check for sphinx-build | |||||
| ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) | |||||
| $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) | |||||
| endif | |||||
| # Internal variables. | |||||
| PAPEROPT_a4 = -D latex_paper_size=a4 | |||||
| PAPEROPT_letter = -D latex_paper_size=letter | |||||
| ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . | |||||
| # the i18n builder cannot share the environment and doctrees with the others | |||||
| I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . | |||||
| .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext | |||||
| help: | |||||
| @echo "Please use \`make <target>' where <target> is one of" | |||||
| @echo " html to make standalone HTML files" | |||||
| @echo " dirhtml to make HTML files named index.html in directories" | |||||
| @echo " singlehtml to make a single large HTML file" | |||||
| @echo " pickle to make pickle files" | |||||
| @echo " json to make JSON files" | |||||
| @echo " htmlhelp to make HTML files and a HTML help project" | |||||
| @echo " qthelp to make HTML files and a qthelp project" | |||||
| @echo " devhelp to make HTML files and a Devhelp project" | |||||
| @echo " epub to make an epub" | |||||
| @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | |||||
| @echo " latexpdf to make LaTeX files and run them through pdflatex" | |||||
| @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" | |||||
| @echo " text to make text files" | |||||
| @echo " man to make manual pages" | |||||
| @echo " texinfo to make Texinfo files" | |||||
| @echo " info to make Texinfo files and run them through makeinfo" | |||||
| @echo " gettext to make PO message catalogs" | |||||
| @echo " changes to make an overview of all changed/added/deprecated items" | |||||
| @echo " xml to make Docutils-native XML files" | |||||
| @echo " pseudoxml to make pseudoxml-XML files for display purposes" | |||||
| @echo " linkcheck to check all external links for integrity" | |||||
| @echo " doctest to run all doctests embedded in the documentation (if enabled)" | |||||
| clean: | |||||
| rm -rf $(BUILDDIR)/* | |||||
| html: | |||||
| $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html | |||||
| @echo | |||||
| @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." | |||||
| dirhtml: | |||||
| $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml | |||||
| @echo | |||||
| @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." | |||||
| singlehtml: | |||||
| $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml | |||||
| @echo | |||||
| @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." | |||||
| pickle: | |||||
| $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle | |||||
| @echo | |||||
| @echo "Build finished; now you can process the pickle files." | |||||
| json: | |||||
| $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json | |||||
| @echo | |||||
| @echo "Build finished; now you can process the JSON files." | |||||
| htmlhelp: | |||||
| $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp | |||||
| @echo | |||||
| @echo "Build finished; now you can run HTML Help Workshop with the" \ | |||||
| ".hhp project file in $(BUILDDIR)/htmlhelp." | |||||
| qthelp: | |||||
| $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp | |||||
| @echo | |||||
| @echo "Build finished; now you can run "qcollectiongenerator" with the" \ | |||||
| ".qhcp project file in $(BUILDDIR)/qthelp, like this:" | |||||
| @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pyad2usb.qhcp" | |||||
| @echo "To view the help file:" | |||||
| @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyad2usb.qhc" | |||||
| devhelp: | |||||
| $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp | |||||
| @echo | |||||
| @echo "Build finished." | |||||
| @echo "To view the help file:" | |||||
| @echo "# mkdir -p $$HOME/.local/share/devhelp/pyad2usb" | |||||
| @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pyad2usb" | |||||
| @echo "# devhelp" | |||||
| epub: | |||||
| $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub | |||||
| @echo | |||||
| @echo "Build finished. The epub file is in $(BUILDDIR)/epub." | |||||
| latex: | |||||
| $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | |||||
| @echo | |||||
| @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." | |||||
| @echo "Run \`make' in that directory to run these through (pdf)latex" \ | |||||
| "(use \`make latexpdf' here to do that automatically)." | |||||
| latexpdf: | |||||
| $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | |||||
| @echo "Running LaTeX files through pdflatex..." | |||||
| $(MAKE) -C $(BUILDDIR)/latex all-pdf | |||||
| @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." | |||||
| latexpdfja: | |||||
| $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex | |||||
| @echo "Running LaTeX files through platex and dvipdfmx..." | |||||
| $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja | |||||
| @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." | |||||
| text: | |||||
| $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text | |||||
| @echo | |||||
| @echo "Build finished. The text files are in $(BUILDDIR)/text." | |||||
| man: | |||||
| $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man | |||||
| @echo | |||||
| @echo "Build finished. The manual pages are in $(BUILDDIR)/man." | |||||
| texinfo: | |||||
| $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo | |||||
| @echo | |||||
| @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." | |||||
| @echo "Run \`make' in that directory to run these through makeinfo" \ | |||||
| "(use \`make info' here to do that automatically)." | |||||
| info: | |||||
| $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo | |||||
| @echo "Running Texinfo files through makeinfo..." | |||||
| make -C $(BUILDDIR)/texinfo info | |||||
| @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." | |||||
| gettext: | |||||
| $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale | |||||
| @echo | |||||
| @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." | |||||
| changes: | |||||
| $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes | |||||
| @echo | |||||
| @echo "The overview file is in $(BUILDDIR)/changes." | |||||
| linkcheck: | |||||
| $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck | |||||
| @echo | |||||
| @echo "Link check complete; look for any errors in the above output " \ | |||||
| "or in $(BUILDDIR)/linkcheck/output.txt." | |||||
| doctest: | |||||
| $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest | |||||
| @echo "Testing of doctests in the sources finished, look at the " \ | |||||
| "results in $(BUILDDIR)/doctest/output.txt." | |||||
| xml: | |||||
| $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml | |||||
| @echo | |||||
| @echo "Build finished. The XML files are in $(BUILDDIR)/xml." | |||||
| pseudoxml: | |||||
| $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml | |||||
| @echo | |||||
| @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." | |||||
| @@ -0,0 +1,4 @@ | |||||
| # Sphinx build info version 1 | |||||
| # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. | |||||
| config: 0c889eb1b3df3f34fd7989e7aaada34f | |||||
| tags: a205e9ed8462ae86fdd2f73488852ba9 | |||||
| @@ -0,0 +1,93 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>Overview: module code — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="../_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: '../', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="../_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="../_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="../_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="../index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1>All modules for which code is available</h1> | |||||
| <ul><li><a href="pyad2usb/ad2usb.html">pyad2usb.ad2usb</a></li> | |||||
| <li><a href="pyad2usb/devices.html">pyad2usb.devices</a></li> | |||||
| <li><a href="pyad2usb/event/event.html">pyad2usb.event.event</a></li> | |||||
| <li><a href="pyad2usb/util.html">pyad2usb.util</a></li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="../search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,588 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>pyad2usb.ad2usb — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="../../_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: '../../', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="../../_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="../../_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="../../_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="../../index.html" /> | |||||
| <link rel="up" title="Module code" href="../index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1>Source code for pyad2usb.ad2usb</h1><div class="highlight"><pre> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd">Provides the full AD2USB class and factory.</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="kn">import</span> <span class="nn">time</span> | |||||
| <span class="kn">import</span> <span class="nn">threading</span> | |||||
| <span class="kn">import</span> <span class="nn">re</span> | |||||
| <span class="kn">from</span> <span class="nn">.event</span> <span class="kn">import</span> <span class="n">event</span> | |||||
| <span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">devices</span> | |||||
| <span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">util</span> | |||||
| <div class="viewcode-block" id="Overseer"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer">[docs]</a><span class="k">class</span> <span class="nc">Overseer</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Factory for creation of AD2USB devices as well as provide4s attach/detach events."</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Factory events</span> | |||||
| <span class="n">on_attached</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when an AD2USB device has been detected.'</span><span class="p">)</span> | |||||
| <span class="n">on_detached</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when an AD2USB device has been removed.'</span><span class="p">)</span> | |||||
| <span class="n">__devices</span> <span class="o">=</span> <span class="p">[]</span> | |||||
| <span class="nd">@classmethod</span> | |||||
| <div class="viewcode-block" id="Overseer.find_all"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.find_all">[docs]</a> <span class="k">def</span> <span class="nf">find_all</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Returns all AD2USB devices located on the system.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">cls</span><span class="o">.</span><span class="n">__devices</span> <span class="o">=</span> <span class="n">devices</span><span class="o">.</span><span class="n">USBDevice</span><span class="o">.</span><span class="n">find_all</span><span class="p">()</span> | |||||
| <span class="k">return</span> <span class="n">cls</span><span class="o">.</span><span class="n">__devices</span> | |||||
| </div> | |||||
| <span class="nd">@classmethod</span> | |||||
| <div class="viewcode-block" id="Overseer.devices"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.devices">[docs]</a> <span class="k">def</span> <span class="nf">devices</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Returns a cached list of AD2USB devices located on the system.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="n">cls</span><span class="o">.</span><span class="n">__devices</span> | |||||
| </div> | |||||
| <span class="nd">@classmethod</span> | |||||
| <div class="viewcode-block" id="Overseer.create"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.create">[docs]</a> <span class="k">def</span> <span class="nf">create</span><span class="p">(</span><span class="n">cls</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Factory method that returns the requested AD2USB device, or the first device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">cls</span><span class="o">.</span><span class="n">find_all</span><span class="p">()</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">cls</span><span class="o">.</span><span class="n">__devices</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">NoDeviceError</span><span class="p">(</span><span class="s">'No AD2USB devices present.'</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">device</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="n">device</span> <span class="o">=</span> <span class="n">cls</span><span class="o">.</span><span class="n">__devices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> | |||||
| <span class="n">vendor</span><span class="p">,</span> <span class="n">product</span><span class="p">,</span> <span class="n">sernum</span><span class="p">,</span> <span class="n">ifcount</span><span class="p">,</span> <span class="n">description</span> <span class="o">=</span> <span class="n">device</span> | |||||
| <span class="n">device</span> <span class="o">=</span> <span class="n">devices</span><span class="o">.</span><span class="n">USBDevice</span><span class="p">(</span><span class="n">serial</span><span class="o">=</span><span class="n">sernum</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="n">description</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="n">AD2USB</span><span class="p">(</span><span class="n">device</span><span class="p">)</span> | |||||
| </div> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">attached_event</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">detached_event</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_detect_thread</span> <span class="o">=</span> <span class="n">Overseer</span><span class="o">.</span><span class="n">DetectThread</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">attached_event</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_attached</span> <span class="o">+=</span> <span class="n">attached_event</span> | |||||
| <span class="k">if</span> <span class="n">detached_event</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_detached</span> <span class="o">+=</span> <span class="n">detached_event</span> | |||||
| <span class="n">Overseer</span><span class="o">.</span><span class="n">find_all</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| <div class="viewcode-block" id="Overseer.close"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Clean up and shut down.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Overseer.start"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.start">[docs]</a> <span class="k">def</span> <span class="nf">start</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Starts the detection thread, if not already running.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">_detect_thread</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_detect_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Overseer.stop"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.stop">[docs]</a> <span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Stops the detection thread.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_detect_thread</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Overseer.get_device"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.get_device">[docs]</a> <span class="k">def</span> <span class="nf">get_device</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">device</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Factory method that returns the requested AD2USB device, or the first device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="n">Overseer</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">device</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Overseer.DetectThread"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.DetectThread">[docs]</a> <span class="k">class</span> <span class="nc">DetectThread</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Thread that handles detection of added/removed devices.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">overseer</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_overseer</span> <span class="o">=</span> <span class="n">overseer</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <div class="viewcode-block" id="Overseer.DetectThread.stop"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.DetectThread.stop">[docs]</a> <span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Stops the thread.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Overseer.DetectThread.run"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Overseer.DetectThread.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> The actual detection process.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="n">last_devices</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span> | |||||
| <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">_running</span><span class="p">:</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="n">Overseer</span><span class="o">.</span><span class="n">find_all</span><span class="p">()</span> | |||||
| <span class="n">current_devices</span> <span class="o">=</span> <span class="nb">set</span><span class="p">(</span><span class="n">Overseer</span><span class="o">.</span><span class="n">devices</span><span class="p">())</span> | |||||
| <span class="n">new_devices</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">current_devices</span> <span class="k">if</span> <span class="n">d</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">last_devices</span><span class="p">]</span> | |||||
| <span class="n">removed_devices</span> <span class="o">=</span> <span class="p">[</span><span class="n">d</span> <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">last_devices</span> <span class="k">if</span> <span class="n">d</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">current_devices</span><span class="p">]</span> | |||||
| <span class="n">last_devices</span> <span class="o">=</span> <span class="n">current_devices</span> | |||||
| <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">new_devices</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_overseer</span><span class="o">.</span><span class="n">on_attached</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> | |||||
| <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="n">removed_devices</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_overseer</span><span class="o">.</span><span class="n">on_detached</span><span class="p">(</span><span class="n">d</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.25</span><span class="p">)</span> | |||||
| </div></div></div> | |||||
| <div class="viewcode-block" id="AD2USB"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB">[docs]</a><span class="k">class</span> <span class="nc">AD2USB</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> High-level wrapper around AD2USB/AD2SERIAL devices.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># High-level Events</span> | |||||
| <span class="n">on_status_changed</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the panel status changes.'</span><span class="p">)</span> | |||||
| <span class="n">on_power_changed</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when panel power switches between AC and DC.'</span><span class="p">)</span> | |||||
| <span class="n">on_alarm</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the alarm is triggered.'</span><span class="p">)</span> | |||||
| <span class="n">on_bypass</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when a zone is bypassed.'</span><span class="p">)</span> | |||||
| <span class="n">on_boot</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the device finishes bootings.'</span><span class="p">)</span> | |||||
| <span class="n">on_config_received</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the device receives its configuration.'</span><span class="p">)</span> | |||||
| <span class="c"># Mid-level Events</span> | |||||
| <span class="n">on_message</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when a message has been received from the device.'</span><span class="p">)</span> | |||||
| <span class="c"># Low-level Events</span> | |||||
| <span class="n">on_open</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the device has been opened.'</span><span class="p">)</span> | |||||
| <span class="n">on_close</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the device has been closed.'</span><span class="p">)</span> | |||||
| <span class="n">on_read</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when a line has been read from the device.'</span><span class="p">)</span> | |||||
| <span class="n">on_write</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when data has been written to the device.'</span><span class="p">)</span> | |||||
| <span class="c"># Constants</span> | |||||
| <span class="n">F1</span> <span class="o">=</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| <span class="n">F2</span> <span class="o">=</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> | |||||
| <span class="n">F3</span> <span class="o">=</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span> | |||||
| <span class="n">F4</span> <span class="o">=</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> <span class="o">+</span> <span class="nb">unichr</span><span class="p">(</span><span class="mi">4</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">device</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="n">device</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_power_status</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_alarm_status</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_bypass_status</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_settings</span> <span class="o">=</span> <span class="p">{}</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_address_mask</span> <span class="o">=</span> <span class="mh">0xFF80</span> <span class="c"># TEMP</span> | |||||
| <div class="viewcode-block" id="AD2USB.open"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB.open">[docs]</a> <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">baudrate</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">no_reader_thread</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Opens the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_wire_events</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">baudrate</span><span class="o">=</span><span class="n">baudrate</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="n">interface</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="n">index</span><span class="p">,</span> <span class="n">no_reader_thread</span><span class="o">=</span><span class="n">no_reader_thread</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="AD2USB.close"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Closes the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="AD2USB.get_config"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB.get_config">[docs]</a> <span class="k">def</span> <span class="nf">get_config</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Retrieves the configuration from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"C</span><span class="se">\r</span><span class="s">"</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="AD2USB.set_config"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB.set_config">[docs]</a> <span class="k">def</span> <span class="nf">set_config</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">settings</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Sets configuration entries on the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">pass</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="AD2USB.reboot"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB.reboot">[docs]</a> <span class="k">def</span> <span class="nf">reboot</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reboots the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">'='</span><span class="p">)</span> | |||||
| </div> | |||||
| <span class="nd">@property</span> | |||||
| <div class="viewcode-block" id="AD2USB.id"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.AD2USB.id">[docs]</a> <span class="k">def</span> <span class="nf">id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">id</span> | |||||
| </div> | |||||
| <span class="k">def</span> <span class="nf">_wire_events</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Wires up the internal device events.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">on_open</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_on_open</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">on_close</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_on_close</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">on_read</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_on_read</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">on_write</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_on_write</span> | |||||
| <span class="k">def</span> <span class="nf">_handle_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Parses messages from the panel.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="k">return</span> <span class="bp">None</span> | |||||
| <span class="n">msg</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">!=</span> <span class="s">'!'</span><span class="p">:</span> | |||||
| <span class="n">msg</span> <span class="o">=</span> <span class="n">Message</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_address_mask</span> <span class="o">&</span> <span class="n">msg</span><span class="o">.</span><span class="n">mask</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_update_internal_states</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> | |||||
| <span class="k">else</span><span class="p">:</span> <span class="c"># specialty messages</span> | |||||
| <span class="n">header</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="mi">4</span><span class="p">]</span> | |||||
| <span class="k">if</span> <span class="n">header</span> <span class="o">==</span> <span class="s">'!EXP'</span> <span class="ow">or</span> <span class="n">header</span> <span class="o">==</span> <span class="s">'!REL'</span><span class="p">:</span> | |||||
| <span class="n">msg</span> <span class="o">=</span> <span class="n">ExpanderMessage</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">elif</span> <span class="n">header</span> <span class="o">==</span> <span class="s">'!RFX'</span><span class="p">:</span> | |||||
| <span class="n">msg</span> <span class="o">=</span> <span class="n">RFMessage</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">elif</span> <span class="n">header</span> <span class="o">==</span> <span class="s">'!LRR'</span><span class="p">:</span> | |||||
| <span class="n">msg</span> <span class="o">=</span> <span class="n">LRRMessage</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">elif</span> <span class="n">data</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'!Ready'</span><span class="p">):</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_boot</span><span class="p">()</span> | |||||
| <span class="k">elif</span> <span class="n">data</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s">'!CONFIG'</span><span class="p">):</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_handle_config</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="n">msg</span> | |||||
| <span class="k">def</span> <span class="nf">_handle_config</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="n">_</span><span class="p">,</span> <span class="n">config_string</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'>'</span><span class="p">)</span> | |||||
| <span class="k">for</span> <span class="n">setting</span> <span class="ow">in</span> <span class="n">config_string</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'&'</span><span class="p">):</span> | |||||
| <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="o">=</span> <span class="n">setting</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">'='</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_settings</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">v</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_config_received</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_settings</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_update_internal_states</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span> | |||||
| <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">ac_power</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_power_status</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_power_status</span><span class="p">,</span> <span class="n">old_status</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">ac_power</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_power_status</span> | |||||
| <span class="k">if</span> <span class="n">old_status</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_power_changed</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_power_status</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">alarm_sounding</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alarm_status</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_alarm_status</span><span class="p">,</span> <span class="n">old_status</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">alarm_sounding</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_alarm_status</span> | |||||
| <span class="k">if</span> <span class="n">old_status</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_alarm</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_alarm_status</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">message</span><span class="o">.</span><span class="n">zone_bypassed</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bypass_status</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_bypass_status</span><span class="p">,</span> <span class="n">old_status</span> <span class="o">=</span> <span class="n">message</span><span class="o">.</span><span class="n">zone_bypassed</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_bypass_status</span> | |||||
| <span class="k">if</span> <span class="n">old_status</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_bypass</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_bypass_status</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_on_open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Internal handler for opening the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_open</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_on_close</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Internal handler for closing the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_on_read</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Internal handler for reading from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_read</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> | |||||
| <span class="n">msg</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_handle_message</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">msg</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_message</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_on_write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">sender</span><span class="p">,</span> <span class="n">args</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Internal handler for writing to the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_write</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Message"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.Message">[docs]</a><span class="k">class</span> <span class="nc">Message</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Represents a message from the alarm panel.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">armed_away</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">armed_home</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">backlight_on</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">programming_mode</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">beeps</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">zone_bypassed</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">ac_power</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">chime_on</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">alarm_event_occurred</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">alarm_sounding</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">numeric_code</span> <span class="o">=</span> <span class="s">""</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="s">""</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">cursor_location</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="s">""</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">mask</span> <span class="o">=</span> <span class="s">""</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span> <span class="o">=</span> <span class="s">""</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">panel_data</span> <span class="o">=</span> <span class="s">""</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_regex</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s">'("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)'</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_parse_message</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_parse_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Parse the message from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">m</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_regex</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">m</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">InvalidMessageError</span><span class="p">(</span><span class="s">'Received invalid message: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">numeric_code</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">panel_data</span><span class="p">,</span> <span class="n">alpha</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">mask</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">panel_data</span><span class="p">[</span><span class="mi">3</span><span class="p">:</span><span class="mi">3</span><span class="o">+</span><span class="mi">8</span><span class="p">],</span> <span class="mi">16</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">data</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">1</span><span class="p">:</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">armed_away</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">armed_home</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">3</span><span class="p">:</span><span class="mi">4</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">backlight_on</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">4</span><span class="p">:</span><span class="mi">5</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">programming_mode</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">5</span><span class="p">:</span><span class="mi">6</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">beeps</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">6</span><span class="p">:</span><span class="mi">7</span><span class="p">],</span> <span class="mi">16</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">zone_bypassed</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">7</span><span class="p">:</span><span class="mi">8</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">ac_power</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">8</span><span class="p">:</span><span class="mi">9</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">chime_on</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">9</span><span class="p">:</span><span class="mi">10</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">alarm_event_occurred</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">10</span><span class="p">:</span><span class="mi">11</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">alarm_sounding</span> <span class="o">=</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">11</span><span class="p">:</span><span class="mi">12</span><span class="p">]</span> <span class="o">==</span> <span class="s">"0"</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">text</span> <span class="o">=</span> <span class="n">alpha</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s">'"'</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">panel_data</span><span class="p">[</span><span class="mi">19</span><span class="p">:</span><span class="mi">21</span><span class="p">],</span> <span class="mi">16</span><span class="p">)</span> <span class="o">&</span> <span class="mh">0x01</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">cursor_location</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">bitfield</span><span class="p">[</span><span class="mi">21</span><span class="p">:</span><span class="mi">23</span><span class="p">],</span> <span class="mi">16</span><span class="p">)</span> <span class="c"># Alpha character index that the cursor is on.</span> | |||||
| <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> String conversion operator.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="s">'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">hex</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">mask</span><span class="p">),</span> <span class="mi">1</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">ready</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">armed_away</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">armed_home</span> <span class="k">else</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">numeric_code</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">text</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="ExpanderMessage"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.ExpanderMessage">[docs]</a><span class="k">class</span> <span class="nc">ExpanderMessage</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Represents a message from a zone or relay expansion module.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">ZONE</span> <span class="o">=</span> <span class="mi">0</span> | |||||
| <span class="n">RELAY</span> <span class="o">=</span> <span class="mi">1</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">raw</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_parse_message</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> String conversion operator.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">expander_type</span> <span class="o">=</span> <span class="s">'UNKWN'</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">ExpanderMessage</span><span class="o">.</span><span class="n">ZONE</span><span class="p">:</span> | |||||
| <span class="n">expander_type</span> <span class="o">=</span> <span class="s">'ZONE'</span> | |||||
| <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">==</span> <span class="n">ExpanderMessage</span><span class="o">.</span><span class="n">RELAY</span><span class="p">:</span> | |||||
| <span class="n">expander_type</span> <span class="o">=</span> <span class="s">'RELAY'</span> | |||||
| <span class="k">return</span> <span class="s">'exp > [{0: <5}] {1}/{2} -- {3}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">expander_type</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">address</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">channel</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_parse_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Parse the raw message from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">header</span><span class="p">,</span> <span class="n">values</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">)</span> | |||||
| <span class="n">address</span><span class="p">,</span> <span class="n">channel</span><span class="p">,</span> <span class="n">value</span> <span class="o">=</span> <span class="n">values</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">raw</span> <span class="o">=</span> <span class="n">data</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">address</span> <span class="o">=</span> <span class="n">address</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">channel</span> <span class="o">=</span> <span class="n">channel</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span> | |||||
| <span class="k">if</span> <span class="n">header</span> <span class="o">==</span> <span class="s">'!EXP'</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">ExpanderMessage</span><span class="o">.</span><span class="n">ZONE</span> | |||||
| <span class="k">elif</span> <span class="n">header</span> <span class="o">==</span> <span class="s">'!REL'</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">type</span> <span class="o">=</span> <span class="n">ExpanderMessage</span><span class="o">.</span><span class="n">RELAY</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="RFMessage"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.RFMessage">[docs]</a><span class="k">class</span> <span class="nc">RFMessage</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Represents a message from an RF receiver.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">raw</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">serial_number</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_parse_message</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> String conversion operator.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="s">'rf > {0}: {1}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">serial_number</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">_parse_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Parses the raw message from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">raw</span> <span class="o">=</span> <span class="n">data</span> | |||||
| <span class="n">_</span><span class="p">,</span> <span class="n">values</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">serial_number</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">values</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="LRRMessage"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.ad2usb.LRRMessage">[docs]</a><span class="k">class</span> <span class="nc">LRRMessage</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Represent a message from a Long Range Radio.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">raw</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_event_data</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_partition</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_event_type</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">data</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_parse_message</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> String conversion operator.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="s">'lrr > {0} @ {1} -- {2}'</span><span class="o">.</span><span class="n">format</span><span class="p">()</span> | |||||
| <span class="k">def</span> <span class="nf">_parse_message</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Parses the raw message from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">raw</span> <span class="o">=</span> <span class="n">data</span> | |||||
| <span class="n">_</span><span class="p">,</span> <span class="n">values</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">':'</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_event_data</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_partition</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_event_type</span> <span class="o">=</span> <span class="n">values</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s">','</span><span class="p">)</span></div> | |||||
| </pre></div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="../../search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../index.html" >Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,652 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>pyad2usb.devices — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="../../_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: '../../', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="../../_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="../../_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="../../_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="../../index.html" /> | |||||
| <link rel="up" title="Module code" href="../index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1>Source code for pyad2usb.devices</h1><div class="highlight"><pre> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd">Contains different types of devices belonging to the AD2USB family.</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="kn">import</span> <span class="nn">usb.core</span> | |||||
| <span class="kn">import</span> <span class="nn">usb.util</span> | |||||
| <span class="kn">import</span> <span class="nn">time</span> | |||||
| <span class="kn">import</span> <span class="nn">threading</span> | |||||
| <span class="kn">import</span> <span class="nn">serial</span> | |||||
| <span class="kn">import</span> <span class="nn">serial.tools.list_ports</span> | |||||
| <span class="kn">import</span> <span class="nn">socket</span> | |||||
| <span class="kn">from</span> <span class="nn">pyftdi.pyftdi.ftdi</span> <span class="kn">import</span> <span class="o">*</span> | |||||
| <span class="kn">from</span> <span class="nn">pyftdi.pyftdi.usbtools</span> <span class="kn">import</span> <span class="o">*</span> | |||||
| <span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">util</span> | |||||
| <span class="kn">from</span> <span class="nn">.event</span> <span class="kn">import</span> <span class="n">event</span> | |||||
| <div class="viewcode-block" id="Device"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device">[docs]</a><span class="k">class</span> <span class="nc">Device</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Generic parent device to all AD2USB products.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Generic device events</span> | |||||
| <span class="n">on_open</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the device has been opened'</span><span class="p">)</span> | |||||
| <span class="n">on_close</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when the device has been closed'</span><span class="p">)</span> | |||||
| <span class="n">on_read</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when a line has been read from the device'</span><span class="p">)</span> | |||||
| <span class="n">on_write</span> <span class="o">=</span> <span class="n">event</span><span class="o">.</span><span class="n">Event</span><span class="p">(</span><span class="s">'Called when data has been written to the device'</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="s">''</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="s">''</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span> <span class="o">=</span> <span class="n">Device</span><span class="o">.</span><span class="n">ReadThread</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="c"># NOTE: not sure this is going to work..</span> | |||||
| <span class="k">def</span> <span class="nf">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="nd">@property</span> | |||||
| <span class="k">def</span> <span class="nf">id</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> | |||||
| <span class="nd">@id.setter</span> | |||||
| <div class="viewcode-block" id="Device.id"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device.id">[docs]</a> <span class="k">def</span> <span class="nf">id</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="n">value</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Device.is_reader_alive"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device.is_reader_alive">[docs]</a> <span class="k">def</span> <span class="nf">is_reader_alive</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Indicates whether or not the reader thread is alive.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">is_alive</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Device.stop_reader"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device.stop_reader">[docs]</a> <span class="k">def</span> <span class="nf">stop_reader</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Stops the reader thread.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Device.ReadThread"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device.ReadThread">[docs]</a> <span class="k">class</span> <span class="nc">ReadThread</span><span class="p">(</span><span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reader thread which processes messages from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">READ_TIMEOUT</span> <span class="o">=</span> <span class="mi">10</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">device</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="n">device</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <div class="viewcode-block" id="Device.ReadThread.stop"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device.ReadThread.stop">[docs]</a> <span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Stops the running thread.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Device.ReadThread.run"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.Device.ReadThread.run">[docs]</a> <span class="k">def</span> <span class="nf">run</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> The actual read process.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">_running</span><span class="p">:</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">read_line</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">READ_TIMEOUT</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">util</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.01</span><span class="p">)</span> | |||||
| </div></div></div> | |||||
| <div class="viewcode-block" id="USBDevice"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice">[docs]</a><span class="k">class</span> <span class="nc">USBDevice</span><span class="p">(</span><span class="n">Device</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> AD2USB device exposed with PyFTDI's interface.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Constants</span> | |||||
| <span class="n">FTDI_VENDOR_ID</span> <span class="o">=</span> <span class="mh">0x0403</span> | |||||
| <span class="n">FTDI_PRODUCT_ID</span> <span class="o">=</span> <span class="mh">0x6001</span> | |||||
| <span class="n">BAUDRATE</span> <span class="o">=</span> <span class="mi">115200</span> | |||||
| <span class="nd">@staticmethod</span> | |||||
| <div class="viewcode-block" id="USBDevice.find_all"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice.find_all">[docs]</a> <span class="k">def</span> <span class="nf">find_all</span><span class="p">():</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Returns all FTDI devices matching our vendor and product IDs.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">devices</span> <span class="o">=</span> <span class="p">[]</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="n">devices</span> <span class="o">=</span> <span class="n">Ftdi</span><span class="o">.</span><span class="n">find_all</span><span class="p">([(</span><span class="n">USBDevice</span><span class="o">.</span><span class="n">FTDI_VENDOR_ID</span><span class="p">,</span> <span class="n">USBDevice</span><span class="o">.</span><span class="n">FTDI_PRODUCT_ID</span><span class="p">)],</span> <span class="n">nocache</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="p">(</span><span class="n">usb</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">USBError</span><span class="p">,</span> <span class="n">FtdiError</span><span class="p">),</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error enumerating AD2USB devices: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">return</span> <span class="n">devices</span> | |||||
| </div> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vid</span><span class="o">=</span><span class="n">FTDI_VENDOR_ID</span><span class="p">,</span> <span class="n">pid</span><span class="o">=</span><span class="n">FTDI_PRODUCT_ID</span><span class="p">,</span> <span class="n">serial</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">Device</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="n">Ftdi</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_vendor_id</span> <span class="o">=</span> <span class="n">vid</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_product_id</span> <span class="o">=</span> <span class="n">pid</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_serial_number</span> <span class="o">=</span> <span class="n">serial</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_description</span> <span class="o">=</span> <span class="n">description</span> | |||||
| <div class="viewcode-block" id="USBDevice.open"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice.open">[docs]</a> <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">baudrate</span><span class="o">=</span><span class="n">BAUDRATE</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">no_reader_thread</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Opens the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Set up defaults</span> | |||||
| <span class="k">if</span> <span class="n">baudrate</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="n">baudrate</span> <span class="o">=</span> <span class="n">USBDevice</span><span class="o">.</span><span class="n">BAUDRATE</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">interface</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="mi">0</span> | |||||
| <span class="k">if</span> <span class="n">interface</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="k">if</span> <span class="n">index</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="n">index</span> <span class="o">=</span> <span class="mi">0</span> | |||||
| <span class="c"># Open the device and start up the thread.</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_vendor_id</span><span class="p">,</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_product_id</span><span class="p">,</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span><span class="p">,</span> | |||||
| <span class="n">index</span><span class="p">,</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_serial_number</span><span class="p">,</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_description</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">set_baudrate</span><span class="p">(</span><span class="n">baudrate</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="s">'USB {0}:{1}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">usb_dev</span><span class="o">.</span><span class="n">bus</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">usb_dev</span><span class="o">.</span><span class="n">address</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="p">(</span><span class="n">usb</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">USBError</span><span class="p">,</span> <span class="n">FtdiError</span><span class="p">),</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">()</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">NoDeviceError</span><span class="p">(</span><span class="s">'Error opening AD2USB device: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="k">if</span> <span class="ow">not</span> <span class="n">no_reader_thread</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_open</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">_serial_number</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_description</span><span class="p">))</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="USBDevice.close"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Closes the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |||||
| <span class="c"># HACK: Probably should fork pyftdi and make this call in .close().</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">usb_dev</span><span class="o">.</span><span class="n">attach_kernel_driver</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_interface</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="p">(</span><span class="n">FtdiError</span><span class="p">,</span> <span class="n">usb</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">USBError</span><span class="p">):</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="USBDevice.write"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Writes data to the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">write_data</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">FtdiError</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error writing to AD2USB device.'</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="USBDevice.read"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reads a single character from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">read_data</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="USBDevice.read_line"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.USBDevice.read_line">[docs]</a> <span class="k">def</span> <span class="nf">read_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">0.0</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reads a line from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">timeout_event</span><span class="p">():</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="n">got_line</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">ret</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">timeout</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Timer</span><span class="p">(</span><span class="n">timeout</span><span class="p">,</span> <span class="n">timeout_event</span><span class="p">)</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="k">while</span> <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span><span class="p">:</span> | |||||
| <span class="n">buf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">read_data</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">buf</span> <span class="o">!=</span> <span class="s">''</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">+=</span> <span class="n">buf</span> | |||||
| <span class="k">if</span> <span class="n">buf</span> <span class="o">==</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s">"</span><span class="se">\r</span><span class="s">"</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> | |||||
| <span class="c"># ignore if we just got \r\n with nothing else in the buffer.</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">got_line</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="k">break</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.001</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="p">(</span><span class="n">usb</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">USBError</span><span class="p">,</span> <span class="n">FtdiError</span><span class="p">),</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error reading from AD2USB device: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">got_line</span><span class="p">:</span> | |||||
| <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="s">''</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_read</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">(</span><span class="s">'Timeout while waiting for line terminator.'</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="n">ret</span> | |||||
| </div></div> | |||||
| <div class="viewcode-block" id="SerialDevice"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice">[docs]</a><span class="k">class</span> <span class="nc">SerialDevice</span><span class="p">(</span><span class="n">Device</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> AD2USB or AD2SERIAL device exposed with the pyserial interface.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Constants</span> | |||||
| <span class="n">BAUDRATE</span> <span class="o">=</span> <span class="mi">19200</span> | |||||
| <span class="nd">@staticmethod</span> | |||||
| <div class="viewcode-block" id="SerialDevice.find_all"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice.find_all">[docs]</a> <span class="k">def</span> <span class="nf">find_all</span><span class="p">(</span><span class="n">pattern</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Returns all serial ports present.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">devices</span> <span class="o">=</span> <span class="p">[]</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">pattern</span><span class="p">:</span> | |||||
| <span class="n">devices</span> <span class="o">=</span> <span class="n">serial</span><span class="o">.</span><span class="n">tools</span><span class="o">.</span><span class="n">list_ports</span><span class="o">.</span><span class="n">grep</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="n">devices</span> <span class="o">=</span> <span class="n">serial</span><span class="o">.</span><span class="n">tools</span><span class="o">.</span><span class="n">list_ports</span><span class="o">.</span><span class="n">comports</span><span class="p">()</span> | |||||
| <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error enumerating AD2SERIAL devices: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">return</span> <span class="n">devices</span> | |||||
| </div> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">Device</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="n">serial</span><span class="o">.</span><span class="n">Serial</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">writeTimeout</span><span class="o">=</span><span class="mi">0</span><span class="p">)</span> <span class="c"># Timeout = non-blocking to match pyftdi.</span> | |||||
| <div class="viewcode-block" id="SerialDevice.open"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice.open">[docs]</a> <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">baudrate</span><span class="o">=</span><span class="n">BAUDRATE</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">no_reader_thread</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Opens the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Set up the defaults</span> | |||||
| <span class="k">if</span> <span class="n">baudrate</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="n">baudrate</span> <span class="o">=</span> <span class="n">SerialDevice</span><span class="o">.</span><span class="n">BAUDRATE</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="ow">is</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">interface</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">NoDeviceError</span><span class="p">(</span><span class="s">'No AD2SERIAL device interface specified.'</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">interface</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> | |||||
| <span class="c"># Open the device and start up the reader thread.</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">open</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">baudrate</span> <span class="o">=</span> <span class="n">baudrate</span> <span class="c"># NOTE: Setting the baudrate before opening the</span> | |||||
| <span class="c"># port caused issues with Moschip 7840/7820</span> | |||||
| <span class="c"># USB Serial Driver converter. (mos7840)</span> | |||||
| <span class="c">#</span> | |||||
| <span class="c"># Moving it to this point seems to resolve</span> | |||||
| <span class="c"># all issues with it.</span> | |||||
| <span class="k">except</span> <span class="p">(</span><span class="n">serial</span><span class="o">.</span><span class="n">SerialException</span><span class="p">,</span> <span class="ne">ValueError</span><span class="p">),</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">()</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">NoDeviceError</span><span class="p">(</span><span class="s">'Error opening AD2SERIAL device on port {0}.'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">interface</span><span class="p">))</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_open</span><span class="p">((</span><span class="s">'N/A'</span><span class="p">,</span> <span class="s">"AD2SERIAL"</span><span class="p">))</span> | |||||
| <span class="k">if</span> <span class="ow">not</span> <span class="n">no_reader_thread</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SerialDevice.close"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Closes the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |||||
| <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SerialDevice.write"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Writes data to the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">serial</span><span class="o">.</span><span class="n">SerialTimeoutException</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="k">except</span> <span class="n">serial</span><span class="o">.</span><span class="n">SerialException</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error writing to serial device.'</span><span class="p">)</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SerialDevice.read"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reads a single character from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SerialDevice.read_line"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SerialDevice.read_line">[docs]</a> <span class="k">def</span> <span class="nf">read_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">0.0</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reads a line from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">timeout_event</span><span class="p">():</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="n">got_line</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">ret</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">timeout</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Timer</span><span class="p">(</span><span class="n">timeout</span><span class="p">,</span> <span class="n">timeout_event</span><span class="p">)</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="k">while</span> <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span><span class="p">:</span> | |||||
| <span class="n">buf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">buf</span> <span class="o">!=</span> <span class="s">''</span> <span class="ow">and</span> <span class="n">buf</span> <span class="o">!=</span> <span class="s">"</span><span class="se">\xff</span><span class="s">"</span><span class="p">:</span> <span class="c"># AD2SERIAL specifically apparently sends down \xFF on boot.</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">+=</span> <span class="n">buf</span> | |||||
| <span class="k">if</span> <span class="n">buf</span> <span class="o">==</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s">"</span><span class="se">\r</span><span class="s">"</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> | |||||
| <span class="c"># ignore if we just got \r\n with nothing else in the buffer.</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">got_line</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="k">break</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.001</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="p">(</span><span class="ne">OSError</span><span class="p">,</span> <span class="n">serial</span><span class="o">.</span><span class="n">SerialException</span><span class="p">),</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error reading from AD2SERIAL device: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">got_line</span><span class="p">:</span> | |||||
| <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="s">''</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_read</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">(</span><span class="s">'Timeout while waiting for line terminator.'</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="n">ret</span> | |||||
| </div></div> | |||||
| <div class="viewcode-block" id="SocketDevice"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SocketDevice">[docs]</a><span class="k">class</span> <span class="nc">SocketDevice</span><span class="p">(</span><span class="n">Device</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Device that supports communication with an AD2USB that is exposed via ser2sock or another</span> | |||||
| <span class="sd"> Serial to IP interface.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="p">(</span><span class="s">"localhost"</span><span class="p">,</span> <span class="mi">10000</span><span class="p">)):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Constructor</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">Device</span><span class="o">.</span><span class="n">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <div class="viewcode-block" id="SocketDevice.open"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SocketDevice.open">[docs]</a> <span class="k">def</span> <span class="nf">open</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">baudrate</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">interface</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">index</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">no_reader_thread</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Opens the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">if</span> <span class="n">interface</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_interface</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span> <span class="o">=</span> <span class="n">interface</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socket</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">AF_INET</span><span class="p">,</span> <span class="n">socket</span><span class="o">.</span><span class="n">SOCK_STREAM</span><span class="p">)</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">connect</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="p">))</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_id</span> <span class="o">=</span> <span class="s">'{0}:{1}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">()</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">NoDeviceError</span><span class="p">(</span><span class="s">'Error opening AD2SOCKET device at {0}:{1}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_host</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">_port</span><span class="p">))</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_open</span><span class="p">((</span><span class="s">'N/A'</span><span class="p">,</span> <span class="s">"AD2SOCKET"</span><span class="p">))</span> | |||||
| <span class="k">if</span> <span class="ow">not</span> <span class="n">no_reader_thread</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SocketDevice.close"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SocketDevice.close">[docs]</a> <span class="k">def</span> <span class="nf">close</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Closes the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_running</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">stop</span><span class="p">()</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">shutdown</span><span class="p">(</span><span class="n">socket</span><span class="o">.</span><span class="n">SHUT_RDWR</span><span class="p">)</span> <span class="c"># Make sure that it closes immediately.</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">close</span><span class="p">()</span> | |||||
| <span class="k">except</span><span class="p">:</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_close</span><span class="p">()</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SocketDevice.write"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SocketDevice.write">[docs]</a> <span class="k">def</span> <span class="nf">write</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Writes data to the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="n">data_sent</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">data_sent</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error while sending data.'</span><span class="p">)</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="n">data_sent</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SocketDevice.read"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SocketDevice.read">[docs]</a> <span class="k">def</span> <span class="nf">read</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reads a single character from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error while reading from device: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">return</span> <span class="n">data</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="SocketDevice.read_line"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.devices.SocketDevice.read_line">[docs]</a> <span class="k">def</span> <span class="nf">read_line</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">0.0</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Reads a line from the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">timeout_event</span><span class="p">():</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="n">got_line</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">ret</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">timeout</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Timer</span><span class="p">(</span><span class="n">timeout</span><span class="p">,</span> <span class="n">timeout_event</span><span class="p">)</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="k">while</span> <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span><span class="p">:</span> | |||||
| <span class="n">buf</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_device</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">buf</span> <span class="o">!=</span> <span class="s">''</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">+=</span> <span class="n">buf</span> | |||||
| <span class="k">if</span> <span class="n">buf</span> <span class="o">==</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">)</span> <span class="o">></span> <span class="mi">1</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="s">"</span><span class="se">\r</span><span class="s">"</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[:</span><span class="o">-</span><span class="mi">2</span><span class="p">]</span> | |||||
| <span class="c"># ignore if we just got \r\n with nothing else in the buffer.</span> | |||||
| <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">got_line</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="k">break</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span><span class="p">[:</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.001</span><span class="p">)</span> | |||||
| <span class="k">except</span> <span class="n">socket</span><span class="o">.</span><span class="n">error</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">CommError</span><span class="p">(</span><span class="s">'Error reading from Socket device: {0}'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">err</span><span class="p">)))</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">got_line</span><span class="p">:</span> | |||||
| <span class="n">ret</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_buffer</span> <span class="o">=</span> <span class="s">''</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">on_read</span><span class="p">(</span><span class="n">ret</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">util</span><span class="o">.</span><span class="n">TimeoutError</span><span class="p">(</span><span class="s">'Timeout while waiting for line terminator.'</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="n">ret</span></div></div> | |||||
| </pre></div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="../../search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../index.html" >Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,163 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>pyad2usb.event.event — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="../../../_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: '../../../', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="../../../_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="../../../_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="../../../_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="../../../index.html" /> | |||||
| <link rel="up" title="Module code" href="../../index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../../genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../../index.html" accesskey="U">Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1>Source code for pyad2usb.event.event</h1><div class="highlight"><pre> | |||||
| <span class="c"># event.py (improved)</span> | |||||
| <div class="viewcode-block" id="Event"><a class="viewcode-back" href="../../../pyad2usb.event.html#pyad2usb.event.event.Event">[docs]</a><span class="k">class</span> <span class="nc">Event</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">doc</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">__doc__</span> <span class="o">=</span> <span class="n">doc</span> | |||||
| <span class="k">def</span> <span class="nf">__get__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">objtype</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="k">if</span> <span class="n">obj</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="k">return</span> <span class="bp">self</span> | |||||
| <span class="k">return</span> <span class="n">EventHandler</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">__set__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span> | |||||
| <span class="k">pass</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="EventHandler"><a class="viewcode-back" href="../../../pyad2usb.event.html#pyad2usb.event.event.EventHandler">[docs]</a><span class="k">class</span> <span class="nc">EventHandler</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">event</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">event</span> <span class="o">=</span> <span class="n">event</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">obj</span> <span class="o">=</span> <span class="n">obj</span> | |||||
| <span class="k">def</span> <span class="nf">_getfunctionlist</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> | |||||
| <span class="sd">"""(internal use) """</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="n">eventhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">__eventhandler__</span> | |||||
| <span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span> | |||||
| <span class="n">eventhandler</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">__eventhandler__</span> <span class="o">=</span> <span class="p">{}</span> | |||||
| <span class="k">return</span> <span class="n">eventhandler</span><span class="o">.</span><span class="n">setdefault</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">event</span><span class="p">,</span> <span class="p">[])</span> | |||||
| <div class="viewcode-block" id="EventHandler.add"><a class="viewcode-back" href="../../../pyad2usb.event.html#pyad2usb.event.event.EventHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">):</span> | |||||
| <span class="sd">"""Add new event handler function.</span> | |||||
| <span class="sd"> Event handler function must be defined like func(sender, earg).</span> | |||||
| <span class="sd"> You can add handler also by using '+=' operator.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_getfunctionlist</span><span class="p">()</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">func</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="bp">self</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="EventHandler.remove"><a class="viewcode-back" href="../../../pyad2usb.event.html#pyad2usb.event.event.EventHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">func</span><span class="p">):</span> | |||||
| <span class="sd">"""Remove existing event handler function.</span> | |||||
| <span class="sd"> You can remove handler also by using '-=' operator.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="bp">self</span><span class="o">.</span><span class="n">_getfunctionlist</span><span class="p">()</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">func</span><span class="p">)</span> | |||||
| <span class="k">return</span> <span class="bp">self</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="EventHandler.fire"><a class="viewcode-back" href="../../../pyad2usb.event.html#pyad2usb.event.event.EventHandler.fire">[docs]</a> <span class="k">def</span> <span class="nf">fire</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">earg</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""Fire event and call all handler functions</span> | |||||
| <span class="sd"> You can call EventHandler object itself like e(earg) instead of</span> | |||||
| <span class="sd"> e.fire(earg).</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">for</span> <span class="n">func</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">_getfunctionlist</span><span class="p">():</span> | |||||
| <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">func</span><span class="p">)</span> <span class="o">==</span> <span class="n">EventHandler</span><span class="p">:</span> | |||||
| <span class="n">func</span><span class="o">.</span><span class="n">fire</span><span class="p">(</span><span class="n">earg</span><span class="p">)</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="n">func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">,</span> <span class="n">earg</span><span class="p">)</span> | |||||
| </div> | |||||
| <span class="n">__iadd__</span> <span class="o">=</span> <span class="n">add</span> | |||||
| <span class="n">__isub__</span> <span class="o">=</span> <span class="n">remove</span> | |||||
| <span class="n">__call__</span> <span class="o">=</span> <span class="n">fire</span></div> | |||||
| </pre></div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="../../../search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../../genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../../index.html" >Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,230 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>pyad2usb.util — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="../../_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: '../../', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="../../_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="../../_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="../../_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="../../index.html" /> | |||||
| <link rel="up" title="Module code" href="../index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../index.html" accesskey="U">Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1>Source code for pyad2usb.util</h1><div class="highlight"><pre> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd">Provides utility classes for the AD2USB devices.</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="kn">import</span> <span class="nn">ad2usb</span> | |||||
| <span class="kn">import</span> <span class="nn">time</span> | |||||
| <span class="kn">import</span> <span class="nn">traceback</span> | |||||
| <span class="kn">import</span> <span class="nn">threading</span> | |||||
| <div class="viewcode-block" id="NoDeviceError"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.util.NoDeviceError">[docs]</a><span class="k">class</span> <span class="nc">NoDeviceError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> No devices found.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">pass</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="CommError"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.util.CommError">[docs]</a><span class="k">class</span> <span class="nc">CommError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> There was an error communicating with the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">pass</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="TimeoutError"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.util.TimeoutError">[docs]</a><span class="k">class</span> <span class="nc">TimeoutError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> There was a timeout while trying to communicate with the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">pass</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="InvalidMessageError"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.util.InvalidMessageError">[docs]</a><span class="k">class</span> <span class="nc">InvalidMessageError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> The format of the panel message was invalid.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">pass</span> | |||||
| </div> | |||||
| <div class="viewcode-block" id="Firmware"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.util.Firmware">[docs]</a><span class="k">class</span> <span class="nc">Firmware</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Represents firmware for the AD2USB/AD2SERIAL devices.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="c"># Constants</span> | |||||
| <span class="n">STAGE_START</span> <span class="o">=</span> <span class="mi">0</span> | |||||
| <span class="n">STAGE_WAITING</span> <span class="o">=</span> <span class="mi">1</span> | |||||
| <span class="n">STAGE_BOOT</span> <span class="o">=</span> <span class="mi">2</span> | |||||
| <span class="n">STAGE_LOAD</span> <span class="o">=</span> <span class="mi">3</span> | |||||
| <span class="n">STAGE_UPLOADING</span> <span class="o">=</span> <span class="mi">4</span> | |||||
| <span class="n">STAGE_DONE</span> <span class="o">=</span> <span class="mi">5</span> | |||||
| <span class="nd">@staticmethod</span> | |||||
| <div class="viewcode-block" id="Firmware.upload"><a class="viewcode-back" href="../../pyad2usb.html#pyad2usb.util.Firmware.upload">[docs]</a> <span class="k">def</span> <span class="nf">upload</span><span class="p">(</span><span class="n">dev</span><span class="p">,</span> <span class="n">filename</span><span class="p">,</span> <span class="n">progress_callback</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Uploads firmware to an AD2USB/AD2SERIAL device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">do_upload</span><span class="p">():</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Perform the actual firmware upload to the device.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span> | |||||
| <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">f</span><span class="p">:</span> | |||||
| <span class="n">line</span> <span class="o">=</span> <span class="n">line</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span> | |||||
| <span class="k">if</span> <span class="n">line</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="s">':'</span><span class="p">:</span> | |||||
| <span class="n">dev</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">line</span> <span class="o">+</span> <span class="s">"</span><span class="se">\r</span><span class="s">"</span><span class="p">)</span> | |||||
| <span class="n">res</span> <span class="o">=</span> <span class="n">dev</span><span class="o">.</span><span class="n">read_line</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mf">10.0</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">progress_callback</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="n">progress_callback</span><span class="p">(</span><span class="n">Firmware</span><span class="o">.</span><span class="n">STAGE_UPLOADING</span><span class="p">)</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.05</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">read_until</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">0.0</span><span class="p">):</span> | |||||
| <span class="sd">"""</span> | |||||
| <span class="sd"> Read characters until a specific pattern is found or the timeout is hit.</span> | |||||
| <span class="sd"> """</span> | |||||
| <span class="k">def</span> <span class="nf">timeout_event</span><span class="p">():</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">False</span> | |||||
| <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span> <span class="o">=</span> <span class="bp">True</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="bp">None</span> | |||||
| <span class="k">if</span> <span class="n">timeout</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span> | |||||
| <span class="n">timer</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Timer</span><span class="p">(</span><span class="n">timeout</span><span class="p">,</span> <span class="n">timeout_event</span><span class="p">)</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> | |||||
| <span class="n">buf</span> <span class="o">=</span> <span class="s">''</span> | |||||
| <span class="n">position</span> <span class="o">=</span> <span class="mi">0</span> | |||||
| <span class="k">while</span> <span class="n">timeout_event</span><span class="o">.</span><span class="n">reading</span><span class="p">:</span> | |||||
| <span class="k">try</span><span class="p">:</span> | |||||
| <span class="n">char</span> <span class="o">=</span> <span class="n">dev</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> | |||||
| <span class="k">if</span> <span class="n">char</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">char</span> <span class="o">!=</span> <span class="s">''</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="n">pattern</span><span class="p">[</span><span class="n">position</span><span class="p">]:</span> | |||||
| <span class="n">position</span> <span class="o">=</span> <span class="n">position</span> <span class="o">+</span> <span class="mi">1</span> | |||||
| <span class="k">if</span> <span class="n">position</span> <span class="o">==</span> <span class="nb">len</span><span class="p">(</span><span class="n">pattern</span><span class="p">):</span> | |||||
| <span class="k">break</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="n">position</span> <span class="o">=</span> <span class="mi">0</span> | |||||
| <span class="k">except</span> <span class="ne">Exception</span><span class="p">,</span> <span class="n">err</span><span class="p">:</span> | |||||
| <span class="k">pass</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="p">:</span> | |||||
| <span class="k">if</span> <span class="n">timer</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span> | |||||
| <span class="n">timer</span><span class="o">.</span><span class="n">cancel</span><span class="p">()</span> | |||||
| <span class="k">else</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">TimeoutError</span><span class="p">(</span><span class="s">'Timeout while waiting for line terminator.'</span><span class="p">)</span> | |||||
| <span class="k">def</span> <span class="nf">stage_callback</span><span class="p">(</span><span class="n">stage</span><span class="p">):</span> | |||||
| <span class="k">if</span> <span class="n">progress_callback</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="n">progress_callback</span><span class="p">(</span><span class="n">stage</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">dev</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> | |||||
| <span class="k">raise</span> <span class="n">NoDeviceError</span><span class="p">(</span><span class="s">'No device specified for firmware upload.'</span><span class="p">)</span> | |||||
| <span class="n">stage_callback</span><span class="p">(</span><span class="n">Firmware</span><span class="o">.</span><span class="n">STAGE_START</span><span class="p">)</span> | |||||
| <span class="k">if</span> <span class="n">dev</span><span class="o">.</span><span class="n">is_reader_alive</span><span class="p">():</span> | |||||
| <span class="c"># Close the reader thread and wait for it to die, otherwise</span> | |||||
| <span class="c"># it interferes with our reading.</span> | |||||
| <span class="n">dev</span><span class="o">.</span><span class="n">stop_reader</span><span class="p">()</span> | |||||
| <span class="k">while</span> <span class="n">dev</span><span class="o">.</span><span class="n">_read_thread</span><span class="o">.</span><span class="n">is_alive</span><span class="p">():</span> | |||||
| <span class="n">stage_callback</span><span class="p">(</span><span class="n">Firmware</span><span class="o">.</span><span class="n">STAGE_WAITING</span><span class="p">)</span> | |||||
| <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> | |||||
| <span class="c"># Reboot the device and wait for the boot loader.</span> | |||||
| <span class="n">stage_callback</span><span class="p">(</span><span class="n">Firmware</span><span class="o">.</span><span class="n">STAGE_BOOT</span><span class="p">)</span> | |||||
| <span class="n">dev</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"="</span><span class="p">)</span> | |||||
| <span class="n">read_until</span><span class="p">(</span><span class="s">'!boot'</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">15.0</span><span class="p">)</span> | |||||
| <span class="c"># Get ourselves into the boot loader and wait for indication</span> | |||||
| <span class="c"># that it's ready for the firmware upload.</span> | |||||
| <span class="n">stage_callback</span><span class="p">(</span><span class="n">Firmware</span><span class="o">.</span><span class="n">STAGE_LOAD</span><span class="p">)</span> | |||||
| <span class="n">dev</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s">"="</span><span class="p">)</span> | |||||
| <span class="n">read_until</span><span class="p">(</span><span class="s">'!load'</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mf">15.0</span><span class="p">)</span> | |||||
| <span class="c"># And finally do the upload.</span> | |||||
| <span class="n">do_upload</span><span class="p">()</span> | |||||
| <span class="n">stage_callback</span><span class="p">(</span><span class="n">Firmware</span><span class="o">.</span><span class="n">STAGE_DONE</span><span class="p">)</span></div></div> | |||||
| </pre></div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="../../search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="../../genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="../../py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="../../index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="../index.html" >Module code</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,23 @@ | |||||
| .. pyad2usb documentation master file, created by | |||||
| sphinx-quickstart on Sat Jun 8 14:38:46 2013. | |||||
| You can adapt this file completely to your liking, but it should at least | |||||
| contain the root `toctree` directive. | |||||
| Welcome to pyad2usb's documentation! | |||||
| ==================================== | |||||
| Contents: | |||||
| .. toctree:: | |||||
| :maxdepth: 4 | |||||
| pyad2usb | |||||
| Indices and tables | |||||
| ================== | |||||
| * :ref:`genindex` | |||||
| * :ref:`modindex` | |||||
| * :ref:`search` | |||||
| @@ -0,0 +1,7 @@ | |||||
| pyad2usb | |||||
| ======== | |||||
| .. toctree:: | |||||
| :maxdepth: 4 | |||||
| pyad2usb | |||||
| @@ -0,0 +1,19 @@ | |||||
| event Package | |||||
| ============= | |||||
| :mod:`event` Package | |||||
| -------------------- | |||||
| .. automodule:: pyad2usb.event | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`event` Module | |||||
| ------------------- | |||||
| .. automodule:: pyad2usb.event.event | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| @@ -0,0 +1,42 @@ | |||||
| pyad2usb Package | |||||
| ================ | |||||
| :mod:`pyad2usb` Package | |||||
| ----------------------- | |||||
| .. automodule:: pyad2usb.__init__ | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`ad2usb` Module | |||||
| -------------------- | |||||
| .. automodule:: pyad2usb.ad2usb | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`devices` Module | |||||
| --------------------- | |||||
| .. automodule:: pyad2usb.devices | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`util` Module | |||||
| ------------------ | |||||
| .. automodule:: pyad2usb.util | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| Subpackages | |||||
| ----------- | |||||
| .. toctree:: | |||||
| pyad2usb.event | |||||
| @@ -0,0 +1,540 @@ | |||||
| /* | |||||
| * basic.css | |||||
| * ~~~~~~~~~ | |||||
| * | |||||
| * Sphinx stylesheet -- basic theme. | |||||
| * | |||||
| * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. | |||||
| * :license: BSD, see LICENSE for details. | |||||
| * | |||||
| */ | |||||
| /* -- main layout ----------------------------------------------------------- */ | |||||
| div.clearer { | |||||
| clear: both; | |||||
| } | |||||
| /* -- relbar ---------------------------------------------------------------- */ | |||||
| div.related { | |||||
| width: 100%; | |||||
| font-size: 90%; | |||||
| } | |||||
| div.related h3 { | |||||
| display: none; | |||||
| } | |||||
| div.related ul { | |||||
| margin: 0; | |||||
| padding: 0 0 0 10px; | |||||
| list-style: none; | |||||
| } | |||||
| div.related li { | |||||
| display: inline; | |||||
| } | |||||
| div.related li.right { | |||||
| float: right; | |||||
| margin-right: 5px; | |||||
| } | |||||
| /* -- sidebar --------------------------------------------------------------- */ | |||||
| div.sphinxsidebarwrapper { | |||||
| padding: 10px 5px 0 10px; | |||||
| } | |||||
| div.sphinxsidebar { | |||||
| float: left; | |||||
| width: 230px; | |||||
| margin-left: -100%; | |||||
| font-size: 90%; | |||||
| } | |||||
| div.sphinxsidebar ul { | |||||
| list-style: none; | |||||
| } | |||||
| div.sphinxsidebar ul ul, | |||||
| div.sphinxsidebar ul.want-points { | |||||
| margin-left: 20px; | |||||
| list-style: square; | |||||
| } | |||||
| div.sphinxsidebar ul ul { | |||||
| margin-top: 0; | |||||
| margin-bottom: 0; | |||||
| } | |||||
| div.sphinxsidebar form { | |||||
| margin-top: 10px; | |||||
| } | |||||
| div.sphinxsidebar input { | |||||
| border: 1px solid #98dbcc; | |||||
| font-family: sans-serif; | |||||
| font-size: 1em; | |||||
| } | |||||
| div.sphinxsidebar #searchbox input[type="text"] { | |||||
| width: 170px; | |||||
| } | |||||
| div.sphinxsidebar #searchbox input[type="submit"] { | |||||
| width: 30px; | |||||
| } | |||||
| img { | |||||
| border: 0; | |||||
| } | |||||
| /* -- search page ----------------------------------------------------------- */ | |||||
| ul.search { | |||||
| margin: 10px 0 0 20px; | |||||
| padding: 0; | |||||
| } | |||||
| ul.search li { | |||||
| padding: 5px 0 5px 20px; | |||||
| background-image: url(file.png); | |||||
| background-repeat: no-repeat; | |||||
| background-position: 0 7px; | |||||
| } | |||||
| ul.search li a { | |||||
| font-weight: bold; | |||||
| } | |||||
| ul.search li div.context { | |||||
| color: #888; | |||||
| margin: 2px 0 0 30px; | |||||
| text-align: left; | |||||
| } | |||||
| ul.keywordmatches li.goodmatch a { | |||||
| font-weight: bold; | |||||
| } | |||||
| /* -- index page ------------------------------------------------------------ */ | |||||
| table.contentstable { | |||||
| width: 90%; | |||||
| } | |||||
| table.contentstable p.biglink { | |||||
| line-height: 150%; | |||||
| } | |||||
| a.biglink { | |||||
| font-size: 1.3em; | |||||
| } | |||||
| span.linkdescr { | |||||
| font-style: italic; | |||||
| padding-top: 5px; | |||||
| font-size: 90%; | |||||
| } | |||||
| /* -- general index --------------------------------------------------------- */ | |||||
| table.indextable { | |||||
| width: 100%; | |||||
| } | |||||
| table.indextable td { | |||||
| text-align: left; | |||||
| vertical-align: top; | |||||
| } | |||||
| table.indextable dl, table.indextable dd { | |||||
| margin-top: 0; | |||||
| margin-bottom: 0; | |||||
| } | |||||
| table.indextable tr.pcap { | |||||
| height: 10px; | |||||
| } | |||||
| table.indextable tr.cap { | |||||
| margin-top: 10px; | |||||
| background-color: #f2f2f2; | |||||
| } | |||||
| img.toggler { | |||||
| margin-right: 3px; | |||||
| margin-top: 3px; | |||||
| cursor: pointer; | |||||
| } | |||||
| div.modindex-jumpbox { | |||||
| border-top: 1px solid #ddd; | |||||
| border-bottom: 1px solid #ddd; | |||||
| margin: 1em 0 1em 0; | |||||
| padding: 0.4em; | |||||
| } | |||||
| div.genindex-jumpbox { | |||||
| border-top: 1px solid #ddd; | |||||
| border-bottom: 1px solid #ddd; | |||||
| margin: 1em 0 1em 0; | |||||
| padding: 0.4em; | |||||
| } | |||||
| /* -- general body styles --------------------------------------------------- */ | |||||
| a.headerlink { | |||||
| visibility: hidden; | |||||
| } | |||||
| h1:hover > a.headerlink, | |||||
| h2:hover > a.headerlink, | |||||
| h3:hover > a.headerlink, | |||||
| h4:hover > a.headerlink, | |||||
| h5:hover > a.headerlink, | |||||
| h6:hover > a.headerlink, | |||||
| dt:hover > a.headerlink { | |||||
| visibility: visible; | |||||
| } | |||||
| div.body p.caption { | |||||
| text-align: inherit; | |||||
| } | |||||
| div.body td { | |||||
| text-align: left; | |||||
| } | |||||
| .field-list ul { | |||||
| padding-left: 1em; | |||||
| } | |||||
| .first { | |||||
| margin-top: 0 !important; | |||||
| } | |||||
| p.rubric { | |||||
| margin-top: 30px; | |||||
| font-weight: bold; | |||||
| } | |||||
| img.align-left, .figure.align-left, object.align-left { | |||||
| clear: left; | |||||
| float: left; | |||||
| margin-right: 1em; | |||||
| } | |||||
| img.align-right, .figure.align-right, object.align-right { | |||||
| clear: right; | |||||
| float: right; | |||||
| margin-left: 1em; | |||||
| } | |||||
| img.align-center, .figure.align-center, object.align-center { | |||||
| display: block; | |||||
| margin-left: auto; | |||||
| margin-right: auto; | |||||
| } | |||||
| .align-left { | |||||
| text-align: left; | |||||
| } | |||||
| .align-center { | |||||
| text-align: center; | |||||
| } | |||||
| .align-right { | |||||
| text-align: right; | |||||
| } | |||||
| /* -- sidebars -------------------------------------------------------------- */ | |||||
| div.sidebar { | |||||
| margin: 0 0 0.5em 1em; | |||||
| border: 1px solid #ddb; | |||||
| padding: 7px 7px 0 7px; | |||||
| background-color: #ffe; | |||||
| width: 40%; | |||||
| float: right; | |||||
| } | |||||
| p.sidebar-title { | |||||
| font-weight: bold; | |||||
| } | |||||
| /* -- topics ---------------------------------------------------------------- */ | |||||
| div.topic { | |||||
| border: 1px solid #ccc; | |||||
| padding: 7px 7px 0 7px; | |||||
| margin: 10px 0 10px 0; | |||||
| } | |||||
| p.topic-title { | |||||
| font-size: 1.1em; | |||||
| font-weight: bold; | |||||
| margin-top: 10px; | |||||
| } | |||||
| /* -- admonitions ----------------------------------------------------------- */ | |||||
| div.admonition { | |||||
| margin-top: 10px; | |||||
| margin-bottom: 10px; | |||||
| padding: 7px; | |||||
| } | |||||
| div.admonition dt { | |||||
| font-weight: bold; | |||||
| } | |||||
| div.admonition dl { | |||||
| margin-bottom: 0; | |||||
| } | |||||
| p.admonition-title { | |||||
| margin: 0px 10px 5px 0px; | |||||
| font-weight: bold; | |||||
| } | |||||
| div.body p.centered { | |||||
| text-align: center; | |||||
| margin-top: 25px; | |||||
| } | |||||
| /* -- tables ---------------------------------------------------------------- */ | |||||
| table.docutils { | |||||
| border: 0; | |||||
| border-collapse: collapse; | |||||
| } | |||||
| table.docutils td, table.docutils th { | |||||
| padding: 1px 8px 1px 5px; | |||||
| border-top: 0; | |||||
| border-left: 0; | |||||
| border-right: 0; | |||||
| border-bottom: 1px solid #aaa; | |||||
| } | |||||
| table.field-list td, table.field-list th { | |||||
| border: 0 !important; | |||||
| } | |||||
| table.footnote td, table.footnote th { | |||||
| border: 0 !important; | |||||
| } | |||||
| th { | |||||
| text-align: left; | |||||
| padding-right: 5px; | |||||
| } | |||||
| table.citation { | |||||
| border-left: solid 1px gray; | |||||
| margin-left: 1px; | |||||
| } | |||||
| table.citation td { | |||||
| border-bottom: none; | |||||
| } | |||||
| /* -- other body styles ----------------------------------------------------- */ | |||||
| ol.arabic { | |||||
| list-style: decimal; | |||||
| } | |||||
| ol.loweralpha { | |||||
| list-style: lower-alpha; | |||||
| } | |||||
| ol.upperalpha { | |||||
| list-style: upper-alpha; | |||||
| } | |||||
| ol.lowerroman { | |||||
| list-style: lower-roman; | |||||
| } | |||||
| ol.upperroman { | |||||
| list-style: upper-roman; | |||||
| } | |||||
| dl { | |||||
| margin-bottom: 15px; | |||||
| } | |||||
| dd p { | |||||
| margin-top: 0px; | |||||
| } | |||||
| dd ul, dd table { | |||||
| margin-bottom: 10px; | |||||
| } | |||||
| dd { | |||||
| margin-top: 3px; | |||||
| margin-bottom: 10px; | |||||
| margin-left: 30px; | |||||
| } | |||||
| dt:target, .highlighted { | |||||
| background-color: #fbe54e; | |||||
| } | |||||
| dl.glossary dt { | |||||
| font-weight: bold; | |||||
| font-size: 1.1em; | |||||
| } | |||||
| .field-list ul { | |||||
| margin: 0; | |||||
| padding-left: 1em; | |||||
| } | |||||
| .field-list p { | |||||
| margin: 0; | |||||
| } | |||||
| .refcount { | |||||
| color: #060; | |||||
| } | |||||
| .optional { | |||||
| font-size: 1.3em; | |||||
| } | |||||
| .versionmodified { | |||||
| font-style: italic; | |||||
| } | |||||
| .system-message { | |||||
| background-color: #fda; | |||||
| padding: 5px; | |||||
| border: 3px solid red; | |||||
| } | |||||
| .footnote:target { | |||||
| background-color: #ffa; | |||||
| } | |||||
| .line-block { | |||||
| display: block; | |||||
| margin-top: 1em; | |||||
| margin-bottom: 1em; | |||||
| } | |||||
| .line-block .line-block { | |||||
| margin-top: 0; | |||||
| margin-bottom: 0; | |||||
| margin-left: 1.5em; | |||||
| } | |||||
| .guilabel, .menuselection { | |||||
| font-family: sans-serif; | |||||
| } | |||||
| .accelerator { | |||||
| text-decoration: underline; | |||||
| } | |||||
| .classifier { | |||||
| font-style: oblique; | |||||
| } | |||||
| abbr, acronym { | |||||
| border-bottom: dotted 1px; | |||||
| cursor: help; | |||||
| } | |||||
| /* -- code displays --------------------------------------------------------- */ | |||||
| pre { | |||||
| overflow: auto; | |||||
| overflow-y: hidden; /* fixes display issues on Chrome browsers */ | |||||
| } | |||||
| td.linenos pre { | |||||
| padding: 5px 0px; | |||||
| border: 0; | |||||
| background-color: transparent; | |||||
| color: #aaa; | |||||
| } | |||||
| table.highlighttable { | |||||
| margin-left: 0.5em; | |||||
| } | |||||
| table.highlighttable td { | |||||
| padding: 0 0.5em 0 0.5em; | |||||
| } | |||||
| tt.descname { | |||||
| background-color: transparent; | |||||
| font-weight: bold; | |||||
| font-size: 1.2em; | |||||
| } | |||||
| tt.descclassname { | |||||
| background-color: transparent; | |||||
| } | |||||
| tt.xref, a tt { | |||||
| background-color: transparent; | |||||
| font-weight: bold; | |||||
| } | |||||
| h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { | |||||
| background-color: transparent; | |||||
| } | |||||
| .viewcode-link { | |||||
| float: right; | |||||
| } | |||||
| .viewcode-back { | |||||
| float: right; | |||||
| font-family: sans-serif; | |||||
| } | |||||
| div.viewcode-block:target { | |||||
| margin: -1px -10px; | |||||
| padding: 0 10px; | |||||
| } | |||||
| /* -- math display ---------------------------------------------------------- */ | |||||
| img.math { | |||||
| vertical-align: middle; | |||||
| } | |||||
| div.body div.math p { | |||||
| text-align: center; | |||||
| } | |||||
| span.eqno { | |||||
| float: right; | |||||
| } | |||||
| /* -- printout stylesheet --------------------------------------------------- */ | |||||
| @media print { | |||||
| div.document, | |||||
| div.documentwrapper, | |||||
| div.bodywrapper { | |||||
| margin: 0 !important; | |||||
| width: 100%; | |||||
| } | |||||
| div.sphinxsidebar, | |||||
| div.related, | |||||
| div.footer, | |||||
| #top-link { | |||||
| display: none; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,256 @@ | |||||
| /* | |||||
| * default.css_t | |||||
| * ~~~~~~~~~~~~~ | |||||
| * | |||||
| * Sphinx stylesheet -- default theme. | |||||
| * | |||||
| * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. | |||||
| * :license: BSD, see LICENSE for details. | |||||
| * | |||||
| */ | |||||
| @import url("basic.css"); | |||||
| /* -- page layout ----------------------------------------------------------- */ | |||||
| body { | |||||
| font-family: sans-serif; | |||||
| font-size: 100%; | |||||
| background-color: #11303d; | |||||
| color: #000; | |||||
| margin: 0; | |||||
| padding: 0; | |||||
| } | |||||
| div.document { | |||||
| background-color: #1c4e63; | |||||
| } | |||||
| div.documentwrapper { | |||||
| float: left; | |||||
| width: 100%; | |||||
| } | |||||
| div.bodywrapper { | |||||
| margin: 0 0 0 230px; | |||||
| } | |||||
| div.body { | |||||
| background-color: #ffffff; | |||||
| color: #000000; | |||||
| padding: 0 20px 30px 20px; | |||||
| } | |||||
| div.footer { | |||||
| color: #ffffff; | |||||
| width: 100%; | |||||
| padding: 9px 0 9px 0; | |||||
| text-align: center; | |||||
| font-size: 75%; | |||||
| } | |||||
| div.footer a { | |||||
| color: #ffffff; | |||||
| text-decoration: underline; | |||||
| } | |||||
| div.related { | |||||
| background-color: #133f52; | |||||
| line-height: 30px; | |||||
| color: #ffffff; | |||||
| } | |||||
| div.related a { | |||||
| color: #ffffff; | |||||
| } | |||||
| div.sphinxsidebar { | |||||
| } | |||||
| div.sphinxsidebar h3 { | |||||
| font-family: 'Trebuchet MS', sans-serif; | |||||
| color: #ffffff; | |||||
| font-size: 1.4em; | |||||
| font-weight: normal; | |||||
| margin: 0; | |||||
| padding: 0; | |||||
| } | |||||
| div.sphinxsidebar h3 a { | |||||
| color: #ffffff; | |||||
| } | |||||
| div.sphinxsidebar h4 { | |||||
| font-family: 'Trebuchet MS', sans-serif; | |||||
| color: #ffffff; | |||||
| font-size: 1.3em; | |||||
| font-weight: normal; | |||||
| margin: 5px 0 0 0; | |||||
| padding: 0; | |||||
| } | |||||
| div.sphinxsidebar p { | |||||
| color: #ffffff; | |||||
| } | |||||
| div.sphinxsidebar p.topless { | |||||
| margin: 5px 10px 10px 10px; | |||||
| } | |||||
| div.sphinxsidebar ul { | |||||
| margin: 10px; | |||||
| padding: 0; | |||||
| color: #ffffff; | |||||
| } | |||||
| div.sphinxsidebar a { | |||||
| color: #98dbcc; | |||||
| } | |||||
| div.sphinxsidebar input { | |||||
| border: 1px solid #98dbcc; | |||||
| font-family: sans-serif; | |||||
| font-size: 1em; | |||||
| } | |||||
| /* -- hyperlink styles ------------------------------------------------------ */ | |||||
| a { | |||||
| color: #355f7c; | |||||
| text-decoration: none; | |||||
| } | |||||
| a:visited { | |||||
| color: #355f7c; | |||||
| text-decoration: none; | |||||
| } | |||||
| a:hover { | |||||
| text-decoration: underline; | |||||
| } | |||||
| /* -- body styles ----------------------------------------------------------- */ | |||||
| div.body h1, | |||||
| div.body h2, | |||||
| div.body h3, | |||||
| div.body h4, | |||||
| div.body h5, | |||||
| div.body h6 { | |||||
| font-family: 'Trebuchet MS', sans-serif; | |||||
| background-color: #f2f2f2; | |||||
| font-weight: normal; | |||||
| color: #20435c; | |||||
| border-bottom: 1px solid #ccc; | |||||
| margin: 20px -20px 10px -20px; | |||||
| padding: 3px 0 3px 10px; | |||||
| } | |||||
| div.body h1 { margin-top: 0; font-size: 200%; } | |||||
| div.body h2 { font-size: 160%; } | |||||
| div.body h3 { font-size: 140%; } | |||||
| div.body h4 { font-size: 120%; } | |||||
| div.body h5 { font-size: 110%; } | |||||
| div.body h6 { font-size: 100%; } | |||||
| a.headerlink { | |||||
| color: #c60f0f; | |||||
| font-size: 0.8em; | |||||
| padding: 0 4px 0 4px; | |||||
| text-decoration: none; | |||||
| } | |||||
| a.headerlink:hover { | |||||
| background-color: #c60f0f; | |||||
| color: white; | |||||
| } | |||||
| div.body p, div.body dd, div.body li { | |||||
| text-align: justify; | |||||
| line-height: 130%; | |||||
| } | |||||
| div.admonition p.admonition-title + p { | |||||
| display: inline; | |||||
| } | |||||
| div.admonition p { | |||||
| margin-bottom: 5px; | |||||
| } | |||||
| div.admonition pre { | |||||
| margin-bottom: 5px; | |||||
| } | |||||
| div.admonition ul, div.admonition ol { | |||||
| margin-bottom: 5px; | |||||
| } | |||||
| div.note { | |||||
| background-color: #eee; | |||||
| border: 1px solid #ccc; | |||||
| } | |||||
| div.seealso { | |||||
| background-color: #ffc; | |||||
| border: 1px solid #ff6; | |||||
| } | |||||
| div.topic { | |||||
| background-color: #eee; | |||||
| } | |||||
| div.warning { | |||||
| background-color: #ffe4e4; | |||||
| border: 1px solid #f66; | |||||
| } | |||||
| p.admonition-title { | |||||
| display: inline; | |||||
| } | |||||
| p.admonition-title:after { | |||||
| content: ":"; | |||||
| } | |||||
| pre { | |||||
| padding: 5px; | |||||
| background-color: #eeffcc; | |||||
| color: #333333; | |||||
| line-height: 120%; | |||||
| border: 1px solid #ac9; | |||||
| border-left: none; | |||||
| border-right: none; | |||||
| } | |||||
| tt { | |||||
| background-color: #ecf0f3; | |||||
| padding: 0 1px 0 1px; | |||||
| font-size: 0.95em; | |||||
| } | |||||
| th { | |||||
| background-color: #ede; | |||||
| } | |||||
| .warning tt { | |||||
| background: #efc2c2; | |||||
| } | |||||
| .note tt { | |||||
| background: #d6d6d6; | |||||
| } | |||||
| .viewcode-back { | |||||
| font-family: sans-serif; | |||||
| } | |||||
| div.viewcode-block:target { | |||||
| background-color: #f4debf; | |||||
| border-top: 1px solid #ac9; | |||||
| border-bottom: 1px solid #ac9; | |||||
| } | |||||
| @@ -0,0 +1,235 @@ | |||||
| /* | |||||
| * doctools.js | |||||
| * ~~~~~~~~~~~ | |||||
| * | |||||
| * Sphinx JavaScript utilities for all documentation. | |||||
| * | |||||
| * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. | |||||
| * :license: BSD, see LICENSE for details. | |||||
| * | |||||
| */ | |||||
| /** | |||||
| * select a different prefix for underscore | |||||
| */ | |||||
| $u = _.noConflict(); | |||||
| /** | |||||
| * make the code below compatible with browsers without | |||||
| * an installed firebug like debugger | |||||
| if (!window.console || !console.firebug) { | |||||
| var names = ["log", "debug", "info", "warn", "error", "assert", "dir", | |||||
| "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", | |||||
| "profile", "profileEnd"]; | |||||
| window.console = {}; | |||||
| for (var i = 0; i < names.length; ++i) | |||||
| window.console[names[i]] = function() {}; | |||||
| } | |||||
| */ | |||||
| /** | |||||
| * small helper function to urldecode strings | |||||
| */ | |||||
| jQuery.urldecode = function(x) { | |||||
| return decodeURIComponent(x).replace(/\+/g, ' '); | |||||
| }; | |||||
| /** | |||||
| * small helper function to urlencode strings | |||||
| */ | |||||
| jQuery.urlencode = encodeURIComponent; | |||||
| /** | |||||
| * This function returns the parsed url parameters of the | |||||
| * current request. Multiple values per key are supported, | |||||
| * it will always return arrays of strings for the value parts. | |||||
| */ | |||||
| jQuery.getQueryParameters = function(s) { | |||||
| if (typeof s == 'undefined') | |||||
| s = document.location.search; | |||||
| var parts = s.substr(s.indexOf('?') + 1).split('&'); | |||||
| var result = {}; | |||||
| for (var i = 0; i < parts.length; i++) { | |||||
| var tmp = parts[i].split('=', 2); | |||||
| var key = jQuery.urldecode(tmp[0]); | |||||
| var value = jQuery.urldecode(tmp[1]); | |||||
| if (key in result) | |||||
| result[key].push(value); | |||||
| else | |||||
| result[key] = [value]; | |||||
| } | |||||
| return result; | |||||
| }; | |||||
| /** | |||||
| * highlight a given string on a jquery object by wrapping it in | |||||
| * span elements with the given class name. | |||||
| */ | |||||
| jQuery.fn.highlightText = function(text, className) { | |||||
| function highlight(node) { | |||||
| if (node.nodeType == 3) { | |||||
| var val = node.nodeValue; | |||||
| var pos = val.toLowerCase().indexOf(text); | |||||
| if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { | |||||
| var span = document.createElement("span"); | |||||
| span.className = className; | |||||
| span.appendChild(document.createTextNode(val.substr(pos, text.length))); | |||||
| node.parentNode.insertBefore(span, node.parentNode.insertBefore( | |||||
| document.createTextNode(val.substr(pos + text.length)), | |||||
| node.nextSibling)); | |||||
| node.nodeValue = val.substr(0, pos); | |||||
| } | |||||
| } | |||||
| else if (!jQuery(node).is("button, select, textarea")) { | |||||
| jQuery.each(node.childNodes, function() { | |||||
| highlight(this); | |||||
| }); | |||||
| } | |||||
| } | |||||
| return this.each(function() { | |||||
| highlight(this); | |||||
| }); | |||||
| }; | |||||
| /** | |||||
| * Small JavaScript module for the documentation. | |||||
| */ | |||||
| var Documentation = { | |||||
| init : function() { | |||||
| this.fixFirefoxAnchorBug(); | |||||
| this.highlightSearchWords(); | |||||
| this.initIndexTable(); | |||||
| }, | |||||
| /** | |||||
| * i18n support | |||||
| */ | |||||
| TRANSLATIONS : {}, | |||||
| PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, | |||||
| LOCALE : 'unknown', | |||||
| // gettext and ngettext don't access this so that the functions | |||||
| // can safely bound to a different name (_ = Documentation.gettext) | |||||
| gettext : function(string) { | |||||
| var translated = Documentation.TRANSLATIONS[string]; | |||||
| if (typeof translated == 'undefined') | |||||
| return string; | |||||
| return (typeof translated == 'string') ? translated : translated[0]; | |||||
| }, | |||||
| ngettext : function(singular, plural, n) { | |||||
| var translated = Documentation.TRANSLATIONS[singular]; | |||||
| if (typeof translated == 'undefined') | |||||
| return (n == 1) ? singular : plural; | |||||
| return translated[Documentation.PLURALEXPR(n)]; | |||||
| }, | |||||
| addTranslations : function(catalog) { | |||||
| for (var key in catalog.messages) | |||||
| this.TRANSLATIONS[key] = catalog.messages[key]; | |||||
| this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); | |||||
| this.LOCALE = catalog.locale; | |||||
| }, | |||||
| /** | |||||
| * add context elements like header anchor links | |||||
| */ | |||||
| addContextElements : function() { | |||||
| $('div[id] > :header:first').each(function() { | |||||
| $('<a class="headerlink">\u00B6</a>'). | |||||
| attr('href', '#' + this.id). | |||||
| attr('title', _('Permalink to this headline')). | |||||
| appendTo(this); | |||||
| }); | |||||
| $('dt[id]').each(function() { | |||||
| $('<a class="headerlink">\u00B6</a>'). | |||||
| attr('href', '#' + this.id). | |||||
| attr('title', _('Permalink to this definition')). | |||||
| appendTo(this); | |||||
| }); | |||||
| }, | |||||
| /** | |||||
| * workaround a firefox stupidity | |||||
| */ | |||||
| fixFirefoxAnchorBug : function() { | |||||
| if (document.location.hash && $.browser.mozilla) | |||||
| window.setTimeout(function() { | |||||
| document.location.href += ''; | |||||
| }, 10); | |||||
| }, | |||||
| /** | |||||
| * highlight the search words provided in the url in the text | |||||
| */ | |||||
| highlightSearchWords : function() { | |||||
| var params = $.getQueryParameters(); | |||||
| var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; | |||||
| if (terms.length) { | |||||
| var body = $('div.body'); | |||||
| window.setTimeout(function() { | |||||
| $.each(terms, function() { | |||||
| body.highlightText(this.toLowerCase(), 'highlighted'); | |||||
| }); | |||||
| }, 10); | |||||
| $('<p class="highlight-link"><a href="javascript:Documentation.' + | |||||
| 'hideSearchWords()">' + _('Hide Search Matches') + '</a></p>') | |||||
| .appendTo($('#searchbox')); | |||||
| } | |||||
| }, | |||||
| /** | |||||
| * init the domain index toggle buttons | |||||
| */ | |||||
| initIndexTable : function() { | |||||
| var togglers = $('img.toggler').click(function() { | |||||
| var src = $(this).attr('src'); | |||||
| var idnum = $(this).attr('id').substr(7); | |||||
| $('tr.cg-' + idnum).toggle(); | |||||
| if (src.substr(-9) == 'minus.png') | |||||
| $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); | |||||
| else | |||||
| $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); | |||||
| }).css('display', ''); | |||||
| if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { | |||||
| togglers.click(); | |||||
| } | |||||
| }, | |||||
| /** | |||||
| * helper function to hide the search marks again | |||||
| */ | |||||
| hideSearchWords : function() { | |||||
| $('#searchbox .highlight-link').fadeOut(300); | |||||
| $('span.highlighted').removeClass('highlighted'); | |||||
| }, | |||||
| /** | |||||
| * make the url absolute | |||||
| */ | |||||
| makeURL : function(relativeURL) { | |||||
| return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; | |||||
| }, | |||||
| /** | |||||
| * get the current relative url | |||||
| */ | |||||
| getCurrentURL : function() { | |||||
| var path = document.location.pathname; | |||||
| var parts = path.split(/\//); | |||||
| $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { | |||||
| if (this == '..') | |||||
| parts.pop(); | |||||
| }); | |||||
| var url = parts.join('/'); | |||||
| return path.substring(url.lastIndexOf('/') + 1, path.length - 1); | |||||
| } | |||||
| }; | |||||
| // quick alias for translations | |||||
| _ = Documentation.gettext; | |||||
| $(document).ready(function() { | |||||
| Documentation.init(); | |||||
| }); | |||||
| @@ -0,0 +1,62 @@ | |||||
| .highlight .hll { background-color: #ffffcc } | |||||
| .highlight { background: #eeffcc; } | |||||
| .highlight .c { color: #408090; font-style: italic } /* Comment */ | |||||
| .highlight .err { border: 1px solid #FF0000 } /* Error */ | |||||
| .highlight .k { color: #007020; font-weight: bold } /* Keyword */ | |||||
| .highlight .o { color: #666666 } /* Operator */ | |||||
| .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ | |||||
| .highlight .cp { color: #007020 } /* Comment.Preproc */ | |||||
| .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ | |||||
| .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ | |||||
| .highlight .gd { color: #A00000 } /* Generic.Deleted */ | |||||
| .highlight .ge { font-style: italic } /* Generic.Emph */ | |||||
| .highlight .gr { color: #FF0000 } /* Generic.Error */ | |||||
| .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ | |||||
| .highlight .gi { color: #00A000 } /* Generic.Inserted */ | |||||
| .highlight .go { color: #333333 } /* Generic.Output */ | |||||
| .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ | |||||
| .highlight .gs { font-weight: bold } /* Generic.Strong */ | |||||
| .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ | |||||
| .highlight .gt { color: #0044DD } /* Generic.Traceback */ | |||||
| .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ | |||||
| .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ | |||||
| .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ | |||||
| .highlight .kp { color: #007020 } /* Keyword.Pseudo */ | |||||
| .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ | |||||
| .highlight .kt { color: #902000 } /* Keyword.Type */ | |||||
| .highlight .m { color: #208050 } /* Literal.Number */ | |||||
| .highlight .s { color: #4070a0 } /* Literal.String */ | |||||
| .highlight .na { color: #4070a0 } /* Name.Attribute */ | |||||
| .highlight .nb { color: #007020 } /* Name.Builtin */ | |||||
| .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ | |||||
| .highlight .no { color: #60add5 } /* Name.Constant */ | |||||
| .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ | |||||
| .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ | |||||
| .highlight .ne { color: #007020 } /* Name.Exception */ | |||||
| .highlight .nf { color: #06287e } /* Name.Function */ | |||||
| .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ | |||||
| .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ | |||||
| .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ | |||||
| .highlight .nv { color: #bb60d5 } /* Name.Variable */ | |||||
| .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ | |||||
| .highlight .w { color: #bbbbbb } /* Text.Whitespace */ | |||||
| .highlight .mf { color: #208050 } /* Literal.Number.Float */ | |||||
| .highlight .mh { color: #208050 } /* Literal.Number.Hex */ | |||||
| .highlight .mi { color: #208050 } /* Literal.Number.Integer */ | |||||
| .highlight .mo { color: #208050 } /* Literal.Number.Oct */ | |||||
| .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ | |||||
| .highlight .sc { color: #4070a0 } /* Literal.String.Char */ | |||||
| .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ | |||||
| .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ | |||||
| .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ | |||||
| .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ | |||||
| .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ | |||||
| .highlight .sx { color: #c65d09 } /* Literal.String.Other */ | |||||
| .highlight .sr { color: #235388 } /* Literal.String.Regex */ | |||||
| .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ | |||||
| .highlight .ss { color: #517918 } /* Literal.String.Symbol */ | |||||
| .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ | |||||
| .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ | |||||
| .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ | |||||
| .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ | |||||
| .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ | |||||
| @@ -0,0 +1,622 @@ | |||||
| /* | |||||
| * searchtools.js_t | |||||
| * ~~~~~~~~~~~~~~~~ | |||||
| * | |||||
| * Sphinx JavaScript utilties for the full-text search. | |||||
| * | |||||
| * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. | |||||
| * :license: BSD, see LICENSE for details. | |||||
| * | |||||
| */ | |||||
| /** | |||||
| * Porter Stemmer | |||||
| */ | |||||
| var Stemmer = function() { | |||||
| var step2list = { | |||||
| ational: 'ate', | |||||
| tional: 'tion', | |||||
| enci: 'ence', | |||||
| anci: 'ance', | |||||
| izer: 'ize', | |||||
| bli: 'ble', | |||||
| alli: 'al', | |||||
| entli: 'ent', | |||||
| eli: 'e', | |||||
| ousli: 'ous', | |||||
| ization: 'ize', | |||||
| ation: 'ate', | |||||
| ator: 'ate', | |||||
| alism: 'al', | |||||
| iveness: 'ive', | |||||
| fulness: 'ful', | |||||
| ousness: 'ous', | |||||
| aliti: 'al', | |||||
| iviti: 'ive', | |||||
| biliti: 'ble', | |||||
| logi: 'log' | |||||
| }; | |||||
| var step3list = { | |||||
| icate: 'ic', | |||||
| ative: '', | |||||
| alize: 'al', | |||||
| iciti: 'ic', | |||||
| ical: 'ic', | |||||
| ful: '', | |||||
| ness: '' | |||||
| }; | |||||
| var c = "[^aeiou]"; // consonant | |||||
| var v = "[aeiouy]"; // vowel | |||||
| var C = c + "[^aeiouy]*"; // consonant sequence | |||||
| var V = v + "[aeiou]*"; // vowel sequence | |||||
| var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 | |||||
| var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 | |||||
| var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 | |||||
| var s_v = "^(" + C + ")?" + v; // vowel in stem | |||||
| this.stemWord = function (w) { | |||||
| var stem; | |||||
| var suffix; | |||||
| var firstch; | |||||
| var origword = w; | |||||
| if (w.length < 3) | |||||
| return w; | |||||
| var re; | |||||
| var re2; | |||||
| var re3; | |||||
| var re4; | |||||
| firstch = w.substr(0,1); | |||||
| if (firstch == "y") | |||||
| w = firstch.toUpperCase() + w.substr(1); | |||||
| // Step 1a | |||||
| re = /^(.+?)(ss|i)es$/; | |||||
| re2 = /^(.+?)([^s])s$/; | |||||
| if (re.test(w)) | |||||
| w = w.replace(re,"$1$2"); | |||||
| else if (re2.test(w)) | |||||
| w = w.replace(re2,"$1$2"); | |||||
| // Step 1b | |||||
| re = /^(.+?)eed$/; | |||||
| re2 = /^(.+?)(ed|ing)$/; | |||||
| if (re.test(w)) { | |||||
| var fp = re.exec(w); | |||||
| re = new RegExp(mgr0); | |||||
| if (re.test(fp[1])) { | |||||
| re = /.$/; | |||||
| w = w.replace(re,""); | |||||
| } | |||||
| } | |||||
| else if (re2.test(w)) { | |||||
| var fp = re2.exec(w); | |||||
| stem = fp[1]; | |||||
| re2 = new RegExp(s_v); | |||||
| if (re2.test(stem)) { | |||||
| w = stem; | |||||
| re2 = /(at|bl|iz)$/; | |||||
| re3 = new RegExp("([^aeiouylsz])\\1$"); | |||||
| re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); | |||||
| if (re2.test(w)) | |||||
| w = w + "e"; | |||||
| else if (re3.test(w)) { | |||||
| re = /.$/; | |||||
| w = w.replace(re,""); | |||||
| } | |||||
| else if (re4.test(w)) | |||||
| w = w + "e"; | |||||
| } | |||||
| } | |||||
| // Step 1c | |||||
| re = /^(.+?)y$/; | |||||
| if (re.test(w)) { | |||||
| var fp = re.exec(w); | |||||
| stem = fp[1]; | |||||
| re = new RegExp(s_v); | |||||
| if (re.test(stem)) | |||||
| w = stem + "i"; | |||||
| } | |||||
| // Step 2 | |||||
| re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; | |||||
| if (re.test(w)) { | |||||
| var fp = re.exec(w); | |||||
| stem = fp[1]; | |||||
| suffix = fp[2]; | |||||
| re = new RegExp(mgr0); | |||||
| if (re.test(stem)) | |||||
| w = stem + step2list[suffix]; | |||||
| } | |||||
| // Step 3 | |||||
| re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; | |||||
| if (re.test(w)) { | |||||
| var fp = re.exec(w); | |||||
| stem = fp[1]; | |||||
| suffix = fp[2]; | |||||
| re = new RegExp(mgr0); | |||||
| if (re.test(stem)) | |||||
| w = stem + step3list[suffix]; | |||||
| } | |||||
| // Step 4 | |||||
| re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; | |||||
| re2 = /^(.+?)(s|t)(ion)$/; | |||||
| if (re.test(w)) { | |||||
| var fp = re.exec(w); | |||||
| stem = fp[1]; | |||||
| re = new RegExp(mgr1); | |||||
| if (re.test(stem)) | |||||
| w = stem; | |||||
| } | |||||
| else if (re2.test(w)) { | |||||
| var fp = re2.exec(w); | |||||
| stem = fp[1] + fp[2]; | |||||
| re2 = new RegExp(mgr1); | |||||
| if (re2.test(stem)) | |||||
| w = stem; | |||||
| } | |||||
| // Step 5 | |||||
| re = /^(.+?)e$/; | |||||
| if (re.test(w)) { | |||||
| var fp = re.exec(w); | |||||
| stem = fp[1]; | |||||
| re = new RegExp(mgr1); | |||||
| re2 = new RegExp(meq1); | |||||
| re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); | |||||
| if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) | |||||
| w = stem; | |||||
| } | |||||
| re = /ll$/; | |||||
| re2 = new RegExp(mgr1); | |||||
| if (re.test(w) && re2.test(w)) { | |||||
| re = /.$/; | |||||
| w = w.replace(re,""); | |||||
| } | |||||
| // and turn initial Y back to y | |||||
| if (firstch == "y") | |||||
| w = firstch.toLowerCase() + w.substr(1); | |||||
| return w; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Simple result scoring code. | |||||
| */ | |||||
| var Scorer = { | |||||
| // Implement the following function to further tweak the score for each result | |||||
| // The function takes a result array [filename, title, anchor, descr, score] | |||||
| // and returns the new score. | |||||
| /* | |||||
| score: function(result) { | |||||
| return result[4]; | |||||
| }, | |||||
| */ | |||||
| // query matches the full name of an object | |||||
| objNameMatch: 11, | |||||
| // or matches in the last dotted part of the object name | |||||
| objPartialMatch: 6, | |||||
| // Additive scores depending on the priority of the object | |||||
| objPrio: {0: 15, // used to be importantResults | |||||
| 1: 5, // used to be objectResults | |||||
| 2: -5}, // used to be unimportantResults | |||||
| // Used when the priority is not in the mapping. | |||||
| objPrioDefault: 0, | |||||
| // query found in title | |||||
| title: 15, | |||||
| // query found in terms | |||||
| term: 5 | |||||
| }; | |||||
| /** | |||||
| * Search Module | |||||
| */ | |||||
| var Search = { | |||||
| _index : null, | |||||
| _queued_query : null, | |||||
| _pulse_status : -1, | |||||
| init : function() { | |||||
| var params = $.getQueryParameters(); | |||||
| if (params.q) { | |||||
| var query = params.q[0]; | |||||
| $('input[name="q"]')[0].value = query; | |||||
| this.performSearch(query); | |||||
| } | |||||
| }, | |||||
| loadIndex : function(url) { | |||||
| $.ajax({type: "GET", url: url, data: null, | |||||
| dataType: "script", cache: true, | |||||
| complete: function(jqxhr, textstatus) { | |||||
| if (textstatus != "success") { | |||||
| document.getElementById("searchindexloader").src = url; | |||||
| } | |||||
| }}); | |||||
| }, | |||||
| setIndex : function(index) { | |||||
| var q; | |||||
| this._index = index; | |||||
| if ((q = this._queued_query) !== null) { | |||||
| this._queued_query = null; | |||||
| Search.query(q); | |||||
| } | |||||
| }, | |||||
| hasIndex : function() { | |||||
| return this._index !== null; | |||||
| }, | |||||
| deferQuery : function(query) { | |||||
| this._queued_query = query; | |||||
| }, | |||||
| stopPulse : function() { | |||||
| this._pulse_status = 0; | |||||
| }, | |||||
| startPulse : function() { | |||||
| if (this._pulse_status >= 0) | |||||
| return; | |||||
| function pulse() { | |||||
| var i; | |||||
| Search._pulse_status = (Search._pulse_status + 1) % 4; | |||||
| var dotString = ''; | |||||
| for (i = 0; i < Search._pulse_status; i++) | |||||
| dotString += '.'; | |||||
| Search.dots.text(dotString); | |||||
| if (Search._pulse_status > -1) | |||||
| window.setTimeout(pulse, 500); | |||||
| } | |||||
| pulse(); | |||||
| }, | |||||
| /** | |||||
| * perform a search for something (or wait until index is loaded) | |||||
| */ | |||||
| performSearch : function(query) { | |||||
| // create the required interface elements | |||||
| this.out = $('#search-results'); | |||||
| this.title = $('<h2>' + _('Searching') + '</h2>').appendTo(this.out); | |||||
| this.dots = $('<span></span>').appendTo(this.title); | |||||
| this.status = $('<p style="display: none"></p>').appendTo(this.out); | |||||
| this.output = $('<ul class="search"/>').appendTo(this.out); | |||||
| $('#search-progress').text(_('Preparing search...')); | |||||
| this.startPulse(); | |||||
| // index already loaded, the browser was quick! | |||||
| if (this.hasIndex()) | |||||
| this.query(query); | |||||
| else | |||||
| this.deferQuery(query); | |||||
| }, | |||||
| /** | |||||
| * execute search (requires search index to be loaded) | |||||
| */ | |||||
| query : function(query) { | |||||
| var i; | |||||
| var stopwords = ["a","and","are","as","at","be","but","by","for","if","in","into","is","it","near","no","not","of","on","or","such","that","the","their","then","there","these","they","this","to","was","will","with"]; | |||||
| // stem the searchterms and add them to the correct list | |||||
| var stemmer = new Stemmer(); | |||||
| var searchterms = []; | |||||
| var excluded = []; | |||||
| var hlterms = []; | |||||
| var tmp = query.split(/\s+/); | |||||
| var objectterms = []; | |||||
| for (i = 0; i < tmp.length; i++) { | |||||
| if (tmp[i] !== "") { | |||||
| objectterms.push(tmp[i].toLowerCase()); | |||||
| } | |||||
| if ($u.indexOf(stopwords, tmp[i]) != -1 || tmp[i].match(/^\d+$/) || | |||||
| tmp[i] === "") { | |||||
| // skip this "word" | |||||
| continue; | |||||
| } | |||||
| // stem the word | |||||
| var word = stemmer.stemWord(tmp[i]).toLowerCase(); | |||||
| var toAppend; | |||||
| // select the correct list | |||||
| if (word[0] == '-') { | |||||
| toAppend = excluded; | |||||
| word = word.substr(1); | |||||
| } | |||||
| else { | |||||
| toAppend = searchterms; | |||||
| hlterms.push(tmp[i].toLowerCase()); | |||||
| } | |||||
| // only add if not already in the list | |||||
| if (!$u.contains(toAppend, word)) | |||||
| toAppend.push(word); | |||||
| } | |||||
| var highlightstring = '?highlight=' + $.urlencode(hlterms.join(" ")); | |||||
| // console.debug('SEARCH: searching for:'); | |||||
| // console.info('required: ', searchterms); | |||||
| // console.info('excluded: ', excluded); | |||||
| // prepare search | |||||
| var terms = this._index.terms; | |||||
| var titleterms = this._index.titleterms; | |||||
| // array of [filename, title, anchor, descr, score] | |||||
| var results = []; | |||||
| $('#search-progress').empty(); | |||||
| // lookup as object | |||||
| for (i = 0; i < objectterms.length; i++) { | |||||
| var others = [].concat(objectterms.slice(0, i), | |||||
| objectterms.slice(i+1, objectterms.length)); | |||||
| results = results.concat(this.performObjectSearch(objectterms[i], others)); | |||||
| } | |||||
| // lookup as search terms in fulltext | |||||
| results = results.concat(this.performTermsSearch(searchterms, excluded, terms, Scorer.term)) | |||||
| .concat(this.performTermsSearch(searchterms, excluded, titleterms, Scorer.title)); | |||||
| // let the scorer override scores with a custom scoring function | |||||
| if (Scorer.score) { | |||||
| for (i = 0; i < results.length; i++) | |||||
| results[i][4] = Scorer.score(results[i]); | |||||
| } | |||||
| // now sort the results by score (in opposite order of appearance, since the | |||||
| // display function below uses pop() to retrieve items) and then | |||||
| // alphabetically | |||||
| results.sort(function(a, b) { | |||||
| var left = a[4]; | |||||
| var right = b[4]; | |||||
| if (left > right) { | |||||
| return 1; | |||||
| } else if (left < right) { | |||||
| return -1; | |||||
| } else { | |||||
| // same score: sort alphabetically | |||||
| left = a[1].toLowerCase(); | |||||
| right = b[1].toLowerCase(); | |||||
| return (left > right) ? -1 : ((left < right) ? 1 : 0); | |||||
| } | |||||
| }); | |||||
| // for debugging | |||||
| //Search.lastresults = results.slice(); // a copy | |||||
| //console.info('search results:', Search.lastresults); | |||||
| // print the results | |||||
| var resultCount = results.length; | |||||
| function displayNextItem() { | |||||
| // results left, load the summary and display it | |||||
| if (results.length) { | |||||
| var item = results.pop(); | |||||
| var listItem = $('<li style="display:none"></li>'); | |||||
| if (DOCUMENTATION_OPTIONS.FILE_SUFFIX === '') { | |||||
| // dirhtml builder | |||||
| var dirname = item[0] + '/'; | |||||
| if (dirname.match(/\/index\/$/)) { | |||||
| dirname = dirname.substring(0, dirname.length-6); | |||||
| } else if (dirname == 'index/') { | |||||
| dirname = ''; | |||||
| } | |||||
| listItem.append($('<a/>').attr('href', | |||||
| DOCUMENTATION_OPTIONS.URL_ROOT + dirname + | |||||
| highlightstring + item[2]).html(item[1])); | |||||
| } else { | |||||
| // normal html builders | |||||
| listItem.append($('<a/>').attr('href', | |||||
| item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX + | |||||
| highlightstring + item[2]).html(item[1])); | |||||
| } | |||||
| if (item[3]) { | |||||
| listItem.append($('<span> (' + item[3] + ')</span>')); | |||||
| Search.output.append(listItem); | |||||
| listItem.slideDown(5, function() { | |||||
| displayNextItem(); | |||||
| }); | |||||
| } else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) { | |||||
| $.ajax({url: DOCUMENTATION_OPTIONS.URL_ROOT + '_sources/' + item[0] + '.txt', | |||||
| dataType: "text", | |||||
| complete: function(jqxhr, textstatus) { | |||||
| var data = jqxhr.responseText; | |||||
| if (data !== '') { | |||||
| listItem.append(Search.makeSearchSummary(data, searchterms, hlterms)); | |||||
| } | |||||
| Search.output.append(listItem); | |||||
| listItem.slideDown(5, function() { | |||||
| displayNextItem(); | |||||
| }); | |||||
| }}); | |||||
| } else { | |||||
| // no source available, just display title | |||||
| Search.output.append(listItem); | |||||
| listItem.slideDown(5, function() { | |||||
| displayNextItem(); | |||||
| }); | |||||
| } | |||||
| } | |||||
| // search finished, update title and status message | |||||
| else { | |||||
| Search.stopPulse(); | |||||
| Search.title.text(_('Search Results')); | |||||
| if (!resultCount) | |||||
| Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.')); | |||||
| else | |||||
| Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount)); | |||||
| Search.status.fadeIn(500); | |||||
| } | |||||
| } | |||||
| displayNextItem(); | |||||
| }, | |||||
| /** | |||||
| * search for object names | |||||
| */ | |||||
| performObjectSearch : function(object, otherterms) { | |||||
| var filenames = this._index.filenames; | |||||
| var objects = this._index.objects; | |||||
| var objnames = this._index.objnames; | |||||
| var titles = this._index.titles; | |||||
| var i; | |||||
| var results = []; | |||||
| for (var prefix in objects) { | |||||
| for (var name in objects[prefix]) { | |||||
| var fullname = (prefix ? prefix + '.' : '') + name; | |||||
| if (fullname.toLowerCase().indexOf(object) > -1) { | |||||
| var score = 0; | |||||
| var parts = fullname.split('.'); | |||||
| // check for different match types: exact matches of full name or | |||||
| // "last name" (i.e. last dotted part) | |||||
| if (fullname == object || parts[parts.length - 1] == object) { | |||||
| score += Scorer.objNameMatch; | |||||
| // matches in last name | |||||
| } else if (parts[parts.length - 1].indexOf(object) > -1) { | |||||
| score += Scorer.objPartialMatch; | |||||
| } | |||||
| var match = objects[prefix][name]; | |||||
| var objname = objnames[match[1]][2]; | |||||
| var title = titles[match[0]]; | |||||
| // If more than one term searched for, we require other words to be | |||||
| // found in the name/title/description | |||||
| if (otherterms.length > 0) { | |||||
| var haystack = (prefix + ' ' + name + ' ' + | |||||
| objname + ' ' + title).toLowerCase(); | |||||
| var allfound = true; | |||||
| for (i = 0; i < otherterms.length; i++) { | |||||
| if (haystack.indexOf(otherterms[i]) == -1) { | |||||
| allfound = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| if (!allfound) { | |||||
| continue; | |||||
| } | |||||
| } | |||||
| var descr = objname + _(', in ') + title; | |||||
| var anchor = match[3]; | |||||
| if (anchor === '') | |||||
| anchor = fullname; | |||||
| else if (anchor == '-') | |||||
| anchor = objnames[match[1]][1] + '-' + fullname; | |||||
| // add custom score for some objects according to scorer | |||||
| if (Scorer.objPrio.hasOwnProperty(match[2])) { | |||||
| score += Scorer.objPrio[match[2]]; | |||||
| } else { | |||||
| score += Scorer.objPrioDefault; | |||||
| } | |||||
| results.push([filenames[match[0]], fullname, '#'+anchor, descr, score]); | |||||
| } | |||||
| } | |||||
| } | |||||
| return results; | |||||
| }, | |||||
| /** | |||||
| * search for full-text terms in the index | |||||
| */ | |||||
| performTermsSearch : function(searchterms, excluded, terms, score) { | |||||
| var filenames = this._index.filenames; | |||||
| var titles = this._index.titles; | |||||
| var i, j, file, files; | |||||
| var fileMap = {}; | |||||
| var results = []; | |||||
| // perform the search on the required terms | |||||
| for (i = 0; i < searchterms.length; i++) { | |||||
| var word = searchterms[i]; | |||||
| // no match but word was a required one | |||||
| if (!(files = terms[word])) | |||||
| break; | |||||
| if (files.length === undefined) { | |||||
| files = [files]; | |||||
| } | |||||
| // create the mapping | |||||
| for (j = 0; j < files.length; j++) { | |||||
| file = files[j]; | |||||
| if (file in fileMap) | |||||
| fileMap[file].push(word); | |||||
| else | |||||
| fileMap[file] = [word]; | |||||
| } | |||||
| } | |||||
| // now check if the files don't contain excluded terms | |||||
| for (file in fileMap) { | |||||
| var valid = true; | |||||
| // check if all requirements are matched | |||||
| if (fileMap[file].length != searchterms.length) | |||||
| continue; | |||||
| // ensure that none of the excluded terms is in the search result | |||||
| for (i = 0; i < excluded.length; i++) { | |||||
| if (terms[excluded[i]] == file || | |||||
| $u.contains(terms[excluded[i]] || [], file)) { | |||||
| valid = false; | |||||
| break; | |||||
| } | |||||
| } | |||||
| // if we have still a valid result we can add it to the result list | |||||
| if (valid) { | |||||
| results.push([filenames[file], titles[file], '', null, score]); | |||||
| } | |||||
| } | |||||
| return results; | |||||
| }, | |||||
| /** | |||||
| * helper function to return a node containing the | |||||
| * search summary for a given text. keywords is a list | |||||
| * of stemmed words, hlwords is the list of normal, unstemmed | |||||
| * words. the first one is used to find the occurance, the | |||||
| * latter for highlighting it. | |||||
| */ | |||||
| makeSearchSummary : function(text, keywords, hlwords) { | |||||
| var textLower = text.toLowerCase(); | |||||
| var start = 0; | |||||
| $.each(keywords, function() { | |||||
| var i = textLower.indexOf(this.toLowerCase()); | |||||
| if (i > -1) | |||||
| start = i; | |||||
| }); | |||||
| start = Math.max(start - 120, 0); | |||||
| var excerpt = ((start > 0) ? '...' : '') + | |||||
| $.trim(text.substr(start, 240)) + | |||||
| ((start + 240 - text.length) ? '...' : ''); | |||||
| var rv = $('<div class="context"></div>').text(excerpt); | |||||
| $.each(hlwords, function() { | |||||
| rv = rv.highlightText(this, 'highlighted'); | |||||
| }); | |||||
| return rv; | |||||
| } | |||||
| }; | |||||
| $(document).ready(function() { | |||||
| Search.init(); | |||||
| }); | |||||
| @@ -0,0 +1,159 @@ | |||||
| /* | |||||
| * sidebar.js | |||||
| * ~~~~~~~~~~ | |||||
| * | |||||
| * This script makes the Sphinx sidebar collapsible. | |||||
| * | |||||
| * .sphinxsidebar contains .sphinxsidebarwrapper. This script adds | |||||
| * in .sphixsidebar, after .sphinxsidebarwrapper, the #sidebarbutton | |||||
| * used to collapse and expand the sidebar. | |||||
| * | |||||
| * When the sidebar is collapsed the .sphinxsidebarwrapper is hidden | |||||
| * and the width of the sidebar and the margin-left of the document | |||||
| * are decreased. When the sidebar is expanded the opposite happens. | |||||
| * This script saves a per-browser/per-session cookie used to | |||||
| * remember the position of the sidebar among the pages. | |||||
| * Once the browser is closed the cookie is deleted and the position | |||||
| * reset to the default (expanded). | |||||
| * | |||||
| * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. | |||||
| * :license: BSD, see LICENSE for details. | |||||
| * | |||||
| */ | |||||
| $(function() { | |||||
| // global elements used by the functions. | |||||
| // the 'sidebarbutton' element is defined as global after its | |||||
| // creation, in the add_sidebar_button function | |||||
| var bodywrapper = $('.bodywrapper'); | |||||
| var sidebar = $('.sphinxsidebar'); | |||||
| var sidebarwrapper = $('.sphinxsidebarwrapper'); | |||||
| // for some reason, the document has no sidebar; do not run into errors | |||||
| if (!sidebar.length) return; | |||||
| // original margin-left of the bodywrapper and width of the sidebar | |||||
| // with the sidebar expanded | |||||
| var bw_margin_expanded = bodywrapper.css('margin-left'); | |||||
| var ssb_width_expanded = sidebar.width(); | |||||
| // margin-left of the bodywrapper and width of the sidebar | |||||
| // with the sidebar collapsed | |||||
| var bw_margin_collapsed = '.8em'; | |||||
| var ssb_width_collapsed = '.8em'; | |||||
| // colors used by the current theme | |||||
| var dark_color = $('.related').css('background-color'); | |||||
| var light_color = $('.document').css('background-color'); | |||||
| function sidebar_is_collapsed() { | |||||
| return sidebarwrapper.is(':not(:visible)'); | |||||
| } | |||||
| function toggle_sidebar() { | |||||
| if (sidebar_is_collapsed()) | |||||
| expand_sidebar(); | |||||
| else | |||||
| collapse_sidebar(); | |||||
| } | |||||
| function collapse_sidebar() { | |||||
| sidebarwrapper.hide(); | |||||
| sidebar.css('width', ssb_width_collapsed); | |||||
| bodywrapper.css('margin-left', bw_margin_collapsed); | |||||
| sidebarbutton.css({ | |||||
| 'margin-left': '0', | |||||
| 'height': bodywrapper.height() | |||||
| }); | |||||
| sidebarbutton.find('span').text('»'); | |||||
| sidebarbutton.attr('title', _('Expand sidebar')); | |||||
| document.cookie = 'sidebar=collapsed'; | |||||
| } | |||||
| function expand_sidebar() { | |||||
| bodywrapper.css('margin-left', bw_margin_expanded); | |||||
| sidebar.css('width', ssb_width_expanded); | |||||
| sidebarwrapper.show(); | |||||
| sidebarbutton.css({ | |||||
| 'margin-left': ssb_width_expanded-12, | |||||
| 'height': bodywrapper.height() | |||||
| }); | |||||
| sidebarbutton.find('span').text('«'); | |||||
| sidebarbutton.attr('title', _('Collapse sidebar')); | |||||
| document.cookie = 'sidebar=expanded'; | |||||
| } | |||||
| function add_sidebar_button() { | |||||
| sidebarwrapper.css({ | |||||
| 'float': 'left', | |||||
| 'margin-right': '0', | |||||
| 'width': ssb_width_expanded - 28 | |||||
| }); | |||||
| // create the button | |||||
| sidebar.append( | |||||
| '<div id="sidebarbutton"><span>«</span></div>' | |||||
| ); | |||||
| var sidebarbutton = $('#sidebarbutton'); | |||||
| light_color = sidebarbutton.css('background-color'); | |||||
| // find the height of the viewport to center the '<<' in the page | |||||
| var viewport_height; | |||||
| if (window.innerHeight) | |||||
| viewport_height = window.innerHeight; | |||||
| else | |||||
| viewport_height = $(window).height(); | |||||
| sidebarbutton.find('span').css({ | |||||
| 'display': 'block', | |||||
| 'margin-top': (viewport_height - sidebar.position().top - 20) / 2 | |||||
| }); | |||||
| sidebarbutton.click(toggle_sidebar); | |||||
| sidebarbutton.attr('title', _('Collapse sidebar')); | |||||
| sidebarbutton.css({ | |||||
| 'color': '#FFFFFF', | |||||
| 'border-left': '1px solid ' + dark_color, | |||||
| 'font-size': '1.2em', | |||||
| 'cursor': 'pointer', | |||||
| 'height': bodywrapper.height(), | |||||
| 'padding-top': '1px', | |||||
| 'margin-left': ssb_width_expanded - 12 | |||||
| }); | |||||
| sidebarbutton.hover( | |||||
| function () { | |||||
| $(this).css('background-color', dark_color); | |||||
| }, | |||||
| function () { | |||||
| $(this).css('background-color', light_color); | |||||
| } | |||||
| ); | |||||
| } | |||||
| function set_position_from_cookie() { | |||||
| if (!document.cookie) | |||||
| return; | |||||
| var items = document.cookie.split(';'); | |||||
| for(var k=0; k<items.length; k++) { | |||||
| var key_val = items[k].split('='); | |||||
| var key = key_val[0]; | |||||
| if (key == 'sidebar') { | |||||
| var value = key_val[1]; | |||||
| if ((value == 'collapsed') && (!sidebar_is_collapsed())) | |||||
| collapse_sidebar(); | |||||
| else if ((value == 'expanded') && (sidebar_is_collapsed())) | |||||
| expand_sidebar(); | |||||
| } | |||||
| } | |||||
| } | |||||
| add_sidebar_button(); | |||||
| var sidebarbutton = $('#sidebarbutton'); | |||||
| set_position_from_cookie(); | |||||
| }); | |||||
| @@ -0,0 +1,31 @@ | |||||
| // Underscore.js 1.3.1 | |||||
| // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc. | |||||
| // Underscore is freely distributable under the MIT license. | |||||
| // Portions of Underscore are inspired or borrowed from Prototype, | |||||
| // Oliver Steele's Functional, and John Resig's Micro-Templating. | |||||
| // For all details and documentation: | |||||
| // http://documentcloud.github.com/underscore | |||||
| (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source== | |||||
| c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c, | |||||
| h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each= | |||||
| b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e<f;e++){if(e in a&&c.call(d,a[e],e,a)===n)break}else for(e in a)if(b.has(a,e)&&c.call(d,a[e],e,a)===n)break};b.map=b.collect=function(a,c,b){var e=[];if(a==null)return e;if(x&&a.map===x)return a.map(c,b);j(a,function(a,g,h){e[e.length]=c.call(b,a,g,h)});if(a.length===+a.length)e.length=a.length;return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var f=arguments.length>2;a== | |||||
| null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect= | |||||
| function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e= | |||||
| e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck= | |||||
| function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b<e.computed&&(e={value:a,computed:b})}); | |||||
| return e.value};b.shuffle=function(a){var b=[],d;j(a,function(a,f){f==0?b[0]=a:(d=Math.floor(Math.random()*(f+1)),b[f]=b[d],b[d]=a)});return b};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,g){return{value:a,criteria:c.call(d,a,b,g)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a, | |||||
| c,d){d||(d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){return!a?[]:a.toArray?a.toArray():b.isArray(a)?i.call(a):b.isArguments(a)?i.call(a):b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?i.call(a,0,b):a[0]};b.initial=function(a,b,d){return i.call(a,0,a.length-(b==null||d?1:b))};b.last=function(a,b,d){return b!=null&&!d?i.call(a,Math.max(a.length-b,0)):a[a.length-1]};b.rest= | |||||
| b.tail=function(a,b,d){return i.call(a,b==null||d?1:b)};b.compact=function(a){return b.filter(a,function(a){return!!a})};b.flatten=function(a,c){return b.reduce(a,function(a,e){if(b.isArray(e))return a.concat(c?e:b.flatten(e));a[a.length]=e;return a},[])};b.without=function(a){return b.difference(a,i.call(arguments,1))};b.uniq=b.unique=function(a,c,d){var d=d?b.map(a,d):a,e=[];b.reduce(d,function(d,g,h){if(0==h||(c===true?b.last(d)!=g:!b.include(d,g)))d[d.length]=g,e[e.length]=a[h];return d},[]); | |||||
| return e};b.union=function(){return b.uniq(b.flatten(arguments,true))};b.intersection=b.intersect=function(a){var c=i.call(arguments,1);return b.filter(b.uniq(a),function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c, | |||||
| d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(p&&a.indexOf===p)return a.indexOf(c);for(d=0,e=a.length;d<e;d++)if(d in a&&a[d]===c)return d;return-1};b.lastIndexOf=function(a,b){if(a==null)return-1;if(D&&a.lastIndexOf===D)return a.lastIndexOf(b);for(var d=a.length;d--;)if(d in a&&a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);for(var d=arguments[2]||1,e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g}; | |||||
| var F=function(){};b.bind=function(a,c){var d,e;if(a.bind===s&&s)return s.apply(a,i.call(arguments,1));if(!b.isFunction(a))throw new TypeError;e=i.call(arguments,2);return d=function(){if(!(this instanceof d))return a.apply(c,e.concat(i.call(arguments)));F.prototype=a.prototype;var b=new F,g=a.apply(b,e.concat(i.call(arguments)));return Object(g)===g?g:b}};b.bindAll=function(a){var c=i.call(arguments,1);c.length==0&&(c=b.functions(a));j(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a, | |||||
| c){var d={};c||(c=b.identity);return function(){var e=c.apply(this,arguments);return b.has(d,e)?d[e]:d[e]=a.apply(this,arguments)}};b.delay=function(a,b){var d=i.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(i.call(arguments,1)))};b.throttle=function(a,c){var d,e,f,g,h,i=b.debounce(function(){h=g=false},c);return function(){d=this;e=arguments;var b;f||(f=setTimeout(function(){f=null;h&&a.apply(d,e);i()},c));g?h=true: | |||||
| a.apply(d,e);i();g=true}};b.debounce=function(a,b){var d;return function(){var e=this,f=arguments;clearTimeout(d);d=setTimeout(function(){d=null;a.apply(e,f)},b)}};b.once=function(a){var b=false,d;return function(){if(b)return d;b=true;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(i.call(arguments,0));return b.apply(this,d)}};b.compose=function(){var a=arguments;return function(){for(var b=arguments,d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}}; | |||||
| b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments, | |||||
| 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)}; | |||||
| b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"}; | |||||
| b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.escape=function(a){return(""+a).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a), | |||||
| function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+ | |||||
| u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]= | |||||
| function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain= | |||||
| true;return this};m.prototype.value=function(){return this._wrapped}}).call(this); | |||||
| @@ -0,0 +1,808 @@ | |||||
| /* | |||||
| * websupport.js | |||||
| * ~~~~~~~~~~~~~ | |||||
| * | |||||
| * sphinx.websupport utilties for all documentation. | |||||
| * | |||||
| * :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. | |||||
| * :license: BSD, see LICENSE for details. | |||||
| * | |||||
| */ | |||||
| (function($) { | |||||
| $.fn.autogrow = function() { | |||||
| return this.each(function() { | |||||
| var textarea = this; | |||||
| $.fn.autogrow.resize(textarea); | |||||
| $(textarea) | |||||
| .focus(function() { | |||||
| textarea.interval = setInterval(function() { | |||||
| $.fn.autogrow.resize(textarea); | |||||
| }, 500); | |||||
| }) | |||||
| .blur(function() { | |||||
| clearInterval(textarea.interval); | |||||
| }); | |||||
| }); | |||||
| }; | |||||
| $.fn.autogrow.resize = function(textarea) { | |||||
| var lineHeight = parseInt($(textarea).css('line-height'), 10); | |||||
| var lines = textarea.value.split('\n'); | |||||
| var columns = textarea.cols; | |||||
| var lineCount = 0; | |||||
| $.each(lines, function() { | |||||
| lineCount += Math.ceil(this.length / columns) || 1; | |||||
| }); | |||||
| var height = lineHeight * (lineCount + 1); | |||||
| $(textarea).css('height', height); | |||||
| }; | |||||
| })(jQuery); | |||||
| (function($) { | |||||
| var comp, by; | |||||
| function init() { | |||||
| initEvents(); | |||||
| initComparator(); | |||||
| } | |||||
| function initEvents() { | |||||
| $('a.comment-close').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| hide($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.vote').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| handleVote($(this)); | |||||
| }); | |||||
| $('a.reply').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| openReply($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.close-reply').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| closeReply($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.sort-option').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| handleReSort($(this)); | |||||
| }); | |||||
| $('a.show-proposal').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| showProposal($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.hide-proposal').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| hideProposal($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.show-propose-change').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| showProposeChange($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.hide-propose-change').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| hideProposeChange($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.accept-comment').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| acceptComment($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.delete-comment').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| deleteComment($(this).attr('id').substring(2)); | |||||
| }); | |||||
| $('a.comment-markup').live("click", function(event) { | |||||
| event.preventDefault(); | |||||
| toggleCommentMarkupBox($(this).attr('id').substring(2)); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Set comp, which is a comparator function used for sorting and | |||||
| * inserting comments into the list. | |||||
| */ | |||||
| function setComparator() { | |||||
| // If the first three letters are "asc", sort in ascending order | |||||
| // and remove the prefix. | |||||
| if (by.substring(0,3) == 'asc') { | |||||
| var i = by.substring(3); | |||||
| comp = function(a, b) { return a[i] - b[i]; }; | |||||
| } else { | |||||
| // Otherwise sort in descending order. | |||||
| comp = function(a, b) { return b[by] - a[by]; }; | |||||
| } | |||||
| // Reset link styles and format the selected sort option. | |||||
| $('a.sel').attr('href', '#').removeClass('sel'); | |||||
| $('a.by' + by).removeAttr('href').addClass('sel'); | |||||
| } | |||||
| /** | |||||
| * Create a comp function. If the user has preferences stored in | |||||
| * the sortBy cookie, use those, otherwise use the default. | |||||
| */ | |||||
| function initComparator() { | |||||
| by = 'rating'; // Default to sort by rating. | |||||
| // If the sortBy cookie is set, use that instead. | |||||
| if (document.cookie.length > 0) { | |||||
| var start = document.cookie.indexOf('sortBy='); | |||||
| if (start != -1) { | |||||
| start = start + 7; | |||||
| var end = document.cookie.indexOf(";", start); | |||||
| if (end == -1) { | |||||
| end = document.cookie.length; | |||||
| by = unescape(document.cookie.substring(start, end)); | |||||
| } | |||||
| } | |||||
| } | |||||
| setComparator(); | |||||
| } | |||||
| /** | |||||
| * Show a comment div. | |||||
| */ | |||||
| function show(id) { | |||||
| $('#ao' + id).hide(); | |||||
| $('#ah' + id).show(); | |||||
| var context = $.extend({id: id}, opts); | |||||
| var popup = $(renderTemplate(popupTemplate, context)).hide(); | |||||
| popup.find('textarea[name="proposal"]').hide(); | |||||
| popup.find('a.by' + by).addClass('sel'); | |||||
| var form = popup.find('#cf' + id); | |||||
| form.submit(function(event) { | |||||
| event.preventDefault(); | |||||
| addComment(form); | |||||
| }); | |||||
| $('#s' + id).after(popup); | |||||
| popup.slideDown('fast', function() { | |||||
| getComments(id); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Hide a comment div. | |||||
| */ | |||||
| function hide(id) { | |||||
| $('#ah' + id).hide(); | |||||
| $('#ao' + id).show(); | |||||
| var div = $('#sc' + id); | |||||
| div.slideUp('fast', function() { | |||||
| div.remove(); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Perform an ajax request to get comments for a node | |||||
| * and insert the comments into the comments tree. | |||||
| */ | |||||
| function getComments(id) { | |||||
| $.ajax({ | |||||
| type: 'GET', | |||||
| url: opts.getCommentsURL, | |||||
| data: {node: id}, | |||||
| success: function(data, textStatus, request) { | |||||
| var ul = $('#cl' + id); | |||||
| var speed = 100; | |||||
| $('#cf' + id) | |||||
| .find('textarea[name="proposal"]') | |||||
| .data('source', data.source); | |||||
| if (data.comments.length === 0) { | |||||
| ul.html('<li>No comments yet.</li>'); | |||||
| ul.data('empty', true); | |||||
| } else { | |||||
| // If there are comments, sort them and put them in the list. | |||||
| var comments = sortComments(data.comments); | |||||
| speed = data.comments.length * 100; | |||||
| appendComments(comments, ul); | |||||
| ul.data('empty', false); | |||||
| } | |||||
| $('#cn' + id).slideUp(speed + 200); | |||||
| ul.slideDown(speed); | |||||
| }, | |||||
| error: function(request, textStatus, error) { | |||||
| showError('Oops, there was a problem retrieving the comments.'); | |||||
| }, | |||||
| dataType: 'json' | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Add a comment via ajax and insert the comment into the comment tree. | |||||
| */ | |||||
| function addComment(form) { | |||||
| var node_id = form.find('input[name="node"]').val(); | |||||
| var parent_id = form.find('input[name="parent"]').val(); | |||||
| var text = form.find('textarea[name="comment"]').val(); | |||||
| var proposal = form.find('textarea[name="proposal"]').val(); | |||||
| if (text == '') { | |||||
| showError('Please enter a comment.'); | |||||
| return; | |||||
| } | |||||
| // Disable the form that is being submitted. | |||||
| form.find('textarea,input').attr('disabled', 'disabled'); | |||||
| // Send the comment to the server. | |||||
| $.ajax({ | |||||
| type: "POST", | |||||
| url: opts.addCommentURL, | |||||
| dataType: 'json', | |||||
| data: { | |||||
| node: node_id, | |||||
| parent: parent_id, | |||||
| text: text, | |||||
| proposal: proposal | |||||
| }, | |||||
| success: function(data, textStatus, error) { | |||||
| // Reset the form. | |||||
| if (node_id) { | |||||
| hideProposeChange(node_id); | |||||
| } | |||||
| form.find('textarea') | |||||
| .val('') | |||||
| .add(form.find('input')) | |||||
| .removeAttr('disabled'); | |||||
| var ul = $('#cl' + (node_id || parent_id)); | |||||
| if (ul.data('empty')) { | |||||
| $(ul).empty(); | |||||
| ul.data('empty', false); | |||||
| } | |||||
| insertComment(data.comment); | |||||
| var ao = $('#ao' + node_id); | |||||
| ao.find('img').attr({'src': opts.commentBrightImage}); | |||||
| if (node_id) { | |||||
| // if this was a "root" comment, remove the commenting box | |||||
| // (the user can get it back by reopening the comment popup) | |||||
| $('#ca' + node_id).slideUp(); | |||||
| } | |||||
| }, | |||||
| error: function(request, textStatus, error) { | |||||
| form.find('textarea,input').removeAttr('disabled'); | |||||
| showError('Oops, there was a problem adding the comment.'); | |||||
| } | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Recursively append comments to the main comment list and children | |||||
| * lists, creating the comment tree. | |||||
| */ | |||||
| function appendComments(comments, ul) { | |||||
| $.each(comments, function() { | |||||
| var div = createCommentDiv(this); | |||||
| ul.append($(document.createElement('li')).html(div)); | |||||
| appendComments(this.children, div.find('ul.comment-children')); | |||||
| // To avoid stagnating data, don't store the comments children in data. | |||||
| this.children = null; | |||||
| div.data('comment', this); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * After adding a new comment, it must be inserted in the correct | |||||
| * location in the comment tree. | |||||
| */ | |||||
| function insertComment(comment) { | |||||
| var div = createCommentDiv(comment); | |||||
| // To avoid stagnating data, don't store the comments children in data. | |||||
| comment.children = null; | |||||
| div.data('comment', comment); | |||||
| var ul = $('#cl' + (comment.node || comment.parent)); | |||||
| var siblings = getChildren(ul); | |||||
| var li = $(document.createElement('li')); | |||||
| li.hide(); | |||||
| // Determine where in the parents children list to insert this comment. | |||||
| for(i=0; i < siblings.length; i++) { | |||||
| if (comp(comment, siblings[i]) <= 0) { | |||||
| $('#cd' + siblings[i].id) | |||||
| .parent() | |||||
| .before(li.html(div)); | |||||
| li.slideDown('fast'); | |||||
| return; | |||||
| } | |||||
| } | |||||
| // If we get here, this comment rates lower than all the others, | |||||
| // or it is the only comment in the list. | |||||
| ul.append(li.html(div)); | |||||
| li.slideDown('fast'); | |||||
| } | |||||
| function acceptComment(id) { | |||||
| $.ajax({ | |||||
| type: 'POST', | |||||
| url: opts.acceptCommentURL, | |||||
| data: {id: id}, | |||||
| success: function(data, textStatus, request) { | |||||
| $('#cm' + id).fadeOut('fast'); | |||||
| $('#cd' + id).removeClass('moderate'); | |||||
| }, | |||||
| error: function(request, textStatus, error) { | |||||
| showError('Oops, there was a problem accepting the comment.'); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function deleteComment(id) { | |||||
| $.ajax({ | |||||
| type: 'POST', | |||||
| url: opts.deleteCommentURL, | |||||
| data: {id: id}, | |||||
| success: function(data, textStatus, request) { | |||||
| var div = $('#cd' + id); | |||||
| if (data == 'delete') { | |||||
| // Moderator mode: remove the comment and all children immediately | |||||
| div.slideUp('fast', function() { | |||||
| div.remove(); | |||||
| }); | |||||
| return; | |||||
| } | |||||
| // User mode: only mark the comment as deleted | |||||
| div | |||||
| .find('span.user-id:first') | |||||
| .text('[deleted]').end() | |||||
| .find('div.comment-text:first') | |||||
| .text('[deleted]').end() | |||||
| .find('#cm' + id + ', #dc' + id + ', #ac' + id + ', #rc' + id + | |||||
| ', #sp' + id + ', #hp' + id + ', #cr' + id + ', #rl' + id) | |||||
| .remove(); | |||||
| var comment = div.data('comment'); | |||||
| comment.username = '[deleted]'; | |||||
| comment.text = '[deleted]'; | |||||
| div.data('comment', comment); | |||||
| }, | |||||
| error: function(request, textStatus, error) { | |||||
| showError('Oops, there was a problem deleting the comment.'); | |||||
| } | |||||
| }); | |||||
| } | |||||
| function showProposal(id) { | |||||
| $('#sp' + id).hide(); | |||||
| $('#hp' + id).show(); | |||||
| $('#pr' + id).slideDown('fast'); | |||||
| } | |||||
| function hideProposal(id) { | |||||
| $('#hp' + id).hide(); | |||||
| $('#sp' + id).show(); | |||||
| $('#pr' + id).slideUp('fast'); | |||||
| } | |||||
| function showProposeChange(id) { | |||||
| $('#pc' + id).hide(); | |||||
| $('#hc' + id).show(); | |||||
| var textarea = $('#pt' + id); | |||||
| textarea.val(textarea.data('source')); | |||||
| $.fn.autogrow.resize(textarea[0]); | |||||
| textarea.slideDown('fast'); | |||||
| } | |||||
| function hideProposeChange(id) { | |||||
| $('#hc' + id).hide(); | |||||
| $('#pc' + id).show(); | |||||
| var textarea = $('#pt' + id); | |||||
| textarea.val('').removeAttr('disabled'); | |||||
| textarea.slideUp('fast'); | |||||
| } | |||||
| function toggleCommentMarkupBox(id) { | |||||
| $('#mb' + id).toggle(); | |||||
| } | |||||
| /** Handle when the user clicks on a sort by link. */ | |||||
| function handleReSort(link) { | |||||
| var classes = link.attr('class').split(/\s+/); | |||||
| for (var i=0; i<classes.length; i++) { | |||||
| if (classes[i] != 'sort-option') { | |||||
| by = classes[i].substring(2); | |||||
| } | |||||
| } | |||||
| setComparator(); | |||||
| // Save/update the sortBy cookie. | |||||
| var expiration = new Date(); | |||||
| expiration.setDate(expiration.getDate() + 365); | |||||
| document.cookie= 'sortBy=' + escape(by) + | |||||
| ';expires=' + expiration.toUTCString(); | |||||
| $('ul.comment-ul').each(function(index, ul) { | |||||
| var comments = getChildren($(ul), true); | |||||
| comments = sortComments(comments); | |||||
| appendComments(comments, $(ul).empty()); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Function to process a vote when a user clicks an arrow. | |||||
| */ | |||||
| function handleVote(link) { | |||||
| if (!opts.voting) { | |||||
| showError("You'll need to login to vote."); | |||||
| return; | |||||
| } | |||||
| var id = link.attr('id'); | |||||
| if (!id) { | |||||
| // Didn't click on one of the voting arrows. | |||||
| return; | |||||
| } | |||||
| // If it is an unvote, the new vote value is 0, | |||||
| // Otherwise it's 1 for an upvote, or -1 for a downvote. | |||||
| var value = 0; | |||||
| if (id.charAt(1) != 'u') { | |||||
| value = id.charAt(0) == 'u' ? 1 : -1; | |||||
| } | |||||
| // The data to be sent to the server. | |||||
| var d = { | |||||
| comment_id: id.substring(2), | |||||
| value: value | |||||
| }; | |||||
| // Swap the vote and unvote links. | |||||
| link.hide(); | |||||
| $('#' + id.charAt(0) + (id.charAt(1) == 'u' ? 'v' : 'u') + d.comment_id) | |||||
| .show(); | |||||
| // The div the comment is displayed in. | |||||
| var div = $('div#cd' + d.comment_id); | |||||
| var data = div.data('comment'); | |||||
| // If this is not an unvote, and the other vote arrow has | |||||
| // already been pressed, unpress it. | |||||
| if ((d.value !== 0) && (data.vote === d.value * -1)) { | |||||
| $('#' + (d.value == 1 ? 'd' : 'u') + 'u' + d.comment_id).hide(); | |||||
| $('#' + (d.value == 1 ? 'd' : 'u') + 'v' + d.comment_id).show(); | |||||
| } | |||||
| // Update the comments rating in the local data. | |||||
| data.rating += (data.vote === 0) ? d.value : (d.value - data.vote); | |||||
| data.vote = d.value; | |||||
| div.data('comment', data); | |||||
| // Change the rating text. | |||||
| div.find('.rating:first') | |||||
| .text(data.rating + ' point' + (data.rating == 1 ? '' : 's')); | |||||
| // Send the vote information to the server. | |||||
| $.ajax({ | |||||
| type: "POST", | |||||
| url: opts.processVoteURL, | |||||
| data: d, | |||||
| error: function(request, textStatus, error) { | |||||
| showError('Oops, there was a problem casting that vote.'); | |||||
| } | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Open a reply form used to reply to an existing comment. | |||||
| */ | |||||
| function openReply(id) { | |||||
| // Swap out the reply link for the hide link | |||||
| $('#rl' + id).hide(); | |||||
| $('#cr' + id).show(); | |||||
| // Add the reply li to the children ul. | |||||
| var div = $(renderTemplate(replyTemplate, {id: id})).hide(); | |||||
| $('#cl' + id) | |||||
| .prepend(div) | |||||
| // Setup the submit handler for the reply form. | |||||
| .find('#rf' + id) | |||||
| .submit(function(event) { | |||||
| event.preventDefault(); | |||||
| addComment($('#rf' + id)); | |||||
| closeReply(id); | |||||
| }) | |||||
| .find('input[type=button]') | |||||
| .click(function() { | |||||
| closeReply(id); | |||||
| }); | |||||
| div.slideDown('fast', function() { | |||||
| $('#rf' + id).find('textarea').focus(); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * Close the reply form opened with openReply. | |||||
| */ | |||||
| function closeReply(id) { | |||||
| // Remove the reply div from the DOM. | |||||
| $('#rd' + id).slideUp('fast', function() { | |||||
| $(this).remove(); | |||||
| }); | |||||
| // Swap out the hide link for the reply link | |||||
| $('#cr' + id).hide(); | |||||
| $('#rl' + id).show(); | |||||
| } | |||||
| /** | |||||
| * Recursively sort a tree of comments using the comp comparator. | |||||
| */ | |||||
| function sortComments(comments) { | |||||
| comments.sort(comp); | |||||
| $.each(comments, function() { | |||||
| this.children = sortComments(this.children); | |||||
| }); | |||||
| return comments; | |||||
| } | |||||
| /** | |||||
| * Get the children comments from a ul. If recursive is true, | |||||
| * recursively include childrens' children. | |||||
| */ | |||||
| function getChildren(ul, recursive) { | |||||
| var children = []; | |||||
| ul.children().children("[id^='cd']") | |||||
| .each(function() { | |||||
| var comment = $(this).data('comment'); | |||||
| if (recursive) | |||||
| comment.children = getChildren($(this).find('#cl' + comment.id), true); | |||||
| children.push(comment); | |||||
| }); | |||||
| return children; | |||||
| } | |||||
| /** Create a div to display a comment in. */ | |||||
| function createCommentDiv(comment) { | |||||
| if (!comment.displayed && !opts.moderator) { | |||||
| return $('<div class="moderate">Thank you! Your comment will show up ' | |||||
| + 'once it is has been approved by a moderator.</div>'); | |||||
| } | |||||
| // Prettify the comment rating. | |||||
| comment.pretty_rating = comment.rating + ' point' + | |||||
| (comment.rating == 1 ? '' : 's'); | |||||
| // Make a class (for displaying not yet moderated comments differently) | |||||
| comment.css_class = comment.displayed ? '' : ' moderate'; | |||||
| // Create a div for this comment. | |||||
| var context = $.extend({}, opts, comment); | |||||
| var div = $(renderTemplate(commentTemplate, context)); | |||||
| // If the user has voted on this comment, highlight the correct arrow. | |||||
| if (comment.vote) { | |||||
| var direction = (comment.vote == 1) ? 'u' : 'd'; | |||||
| div.find('#' + direction + 'v' + comment.id).hide(); | |||||
| div.find('#' + direction + 'u' + comment.id).show(); | |||||
| } | |||||
| if (opts.moderator || comment.text != '[deleted]') { | |||||
| div.find('a.reply').show(); | |||||
| if (comment.proposal_diff) | |||||
| div.find('#sp' + comment.id).show(); | |||||
| if (opts.moderator && !comment.displayed) | |||||
| div.find('#cm' + comment.id).show(); | |||||
| if (opts.moderator || (opts.username == comment.username)) | |||||
| div.find('#dc' + comment.id).show(); | |||||
| } | |||||
| return div; | |||||
| } | |||||
| /** | |||||
| * A simple template renderer. Placeholders such as <%id%> are replaced | |||||
| * by context['id'] with items being escaped. Placeholders such as <#id#> | |||||
| * are not escaped. | |||||
| */ | |||||
| function renderTemplate(template, context) { | |||||
| var esc = $(document.createElement('div')); | |||||
| function handle(ph, escape) { | |||||
| var cur = context; | |||||
| $.each(ph.split('.'), function() { | |||||
| cur = cur[this]; | |||||
| }); | |||||
| return escape ? esc.text(cur || "").html() : cur; | |||||
| } | |||||
| return template.replace(/<([%#])([\w\.]*)\1>/g, function() { | |||||
| return handle(arguments[2], arguments[1] == '%' ? true : false); | |||||
| }); | |||||
| } | |||||
| /** Flash an error message briefly. */ | |||||
| function showError(message) { | |||||
| $(document.createElement('div')).attr({'class': 'popup-error'}) | |||||
| .append($(document.createElement('div')) | |||||
| .attr({'class': 'error-message'}).text(message)) | |||||
| .appendTo('body') | |||||
| .fadeIn("slow") | |||||
| .delay(2000) | |||||
| .fadeOut("slow"); | |||||
| } | |||||
| /** Add a link the user uses to open the comments popup. */ | |||||
| $.fn.comment = function() { | |||||
| return this.each(function() { | |||||
| var id = $(this).attr('id').substring(1); | |||||
| var count = COMMENT_METADATA[id]; | |||||
| var title = count + ' comment' + (count == 1 ? '' : 's'); | |||||
| var image = count > 0 ? opts.commentBrightImage : opts.commentImage; | |||||
| var addcls = count == 0 ? ' nocomment' : ''; | |||||
| $(this) | |||||
| .append( | |||||
| $(document.createElement('a')).attr({ | |||||
| href: '#', | |||||
| 'class': 'sphinx-comment-open' + addcls, | |||||
| id: 'ao' + id | |||||
| }) | |||||
| .append($(document.createElement('img')).attr({ | |||||
| src: image, | |||||
| alt: 'comment', | |||||
| title: title | |||||
| })) | |||||
| .click(function(event) { | |||||
| event.preventDefault(); | |||||
| show($(this).attr('id').substring(2)); | |||||
| }) | |||||
| ) | |||||
| .append( | |||||
| $(document.createElement('a')).attr({ | |||||
| href: '#', | |||||
| 'class': 'sphinx-comment-close hidden', | |||||
| id: 'ah' + id | |||||
| }) | |||||
| .append($(document.createElement('img')).attr({ | |||||
| src: opts.closeCommentImage, | |||||
| alt: 'close', | |||||
| title: 'close' | |||||
| })) | |||||
| .click(function(event) { | |||||
| event.preventDefault(); | |||||
| hide($(this).attr('id').substring(2)); | |||||
| }) | |||||
| ); | |||||
| }); | |||||
| }; | |||||
| var opts = { | |||||
| processVoteURL: '/_process_vote', | |||||
| addCommentURL: '/_add_comment', | |||||
| getCommentsURL: '/_get_comments', | |||||
| acceptCommentURL: '/_accept_comment', | |||||
| deleteCommentURL: '/_delete_comment', | |||||
| commentImage: '/static/_static/comment.png', | |||||
| closeCommentImage: '/static/_static/comment-close.png', | |||||
| loadingImage: '/static/_static/ajax-loader.gif', | |||||
| commentBrightImage: '/static/_static/comment-bright.png', | |||||
| upArrow: '/static/_static/up.png', | |||||
| downArrow: '/static/_static/down.png', | |||||
| upArrowPressed: '/static/_static/up-pressed.png', | |||||
| downArrowPressed: '/static/_static/down-pressed.png', | |||||
| voting: false, | |||||
| moderator: false | |||||
| }; | |||||
| if (typeof COMMENT_OPTIONS != "undefined") { | |||||
| opts = jQuery.extend(opts, COMMENT_OPTIONS); | |||||
| } | |||||
| var popupTemplate = '\ | |||||
| <div class="sphinx-comments" id="sc<%id%>">\ | |||||
| <p class="sort-options">\ | |||||
| Sort by:\ | |||||
| <a href="#" class="sort-option byrating">best rated</a>\ | |||||
| <a href="#" class="sort-option byascage">newest</a>\ | |||||
| <a href="#" class="sort-option byage">oldest</a>\ | |||||
| </p>\ | |||||
| <div class="comment-header">Comments</div>\ | |||||
| <div class="comment-loading" id="cn<%id%>">\ | |||||
| loading comments... <img src="<%loadingImage%>" alt="" /></div>\ | |||||
| <ul id="cl<%id%>" class="comment-ul"></ul>\ | |||||
| <div id="ca<%id%>">\ | |||||
| <p class="add-a-comment">Add a comment\ | |||||
| (<a href="#" class="comment-markup" id="ab<%id%>">markup</a>):</p>\ | |||||
| <div class="comment-markup-box" id="mb<%id%>">\ | |||||
| reStructured text markup: <i>*emph*</i>, <b>**strong**</b>, \ | |||||
| <tt>``code``</tt>, \ | |||||
| code blocks: <tt>::</tt> and an indented block after blank line</div>\ | |||||
| <form method="post" id="cf<%id%>" class="comment-form" action="">\ | |||||
| <textarea name="comment" cols="80"></textarea>\ | |||||
| <p class="propose-button">\ | |||||
| <a href="#" id="pc<%id%>" class="show-propose-change">\ | |||||
| Propose a change ▹\ | |||||
| </a>\ | |||||
| <a href="#" id="hc<%id%>" class="hide-propose-change">\ | |||||
| Propose a change ▿\ | |||||
| </a>\ | |||||
| </p>\ | |||||
| <textarea name="proposal" id="pt<%id%>" cols="80"\ | |||||
| spellcheck="false"></textarea>\ | |||||
| <input type="submit" value="Add comment" />\ | |||||
| <input type="hidden" name="node" value="<%id%>" />\ | |||||
| <input type="hidden" name="parent" value="" />\ | |||||
| </form>\ | |||||
| </div>\ | |||||
| </div>'; | |||||
| var commentTemplate = '\ | |||||
| <div id="cd<%id%>" class="sphinx-comment<%css_class%>">\ | |||||
| <div class="vote">\ | |||||
| <div class="arrow">\ | |||||
| <a href="#" id="uv<%id%>" class="vote" title="vote up">\ | |||||
| <img src="<%upArrow%>" />\ | |||||
| </a>\ | |||||
| <a href="#" id="uu<%id%>" class="un vote" title="vote up">\ | |||||
| <img src="<%upArrowPressed%>" />\ | |||||
| </a>\ | |||||
| </div>\ | |||||
| <div class="arrow">\ | |||||
| <a href="#" id="dv<%id%>" class="vote" title="vote down">\ | |||||
| <img src="<%downArrow%>" id="da<%id%>" />\ | |||||
| </a>\ | |||||
| <a href="#" id="du<%id%>" class="un vote" title="vote down">\ | |||||
| <img src="<%downArrowPressed%>" />\ | |||||
| </a>\ | |||||
| </div>\ | |||||
| </div>\ | |||||
| <div class="comment-content">\ | |||||
| <p class="tagline comment">\ | |||||
| <span class="user-id"><%username%></span>\ | |||||
| <span class="rating"><%pretty_rating%></span>\ | |||||
| <span class="delta"><%time.delta%></span>\ | |||||
| </p>\ | |||||
| <div class="comment-text comment"><#text#></div>\ | |||||
| <p class="comment-opts comment">\ | |||||
| <a href="#" class="reply hidden" id="rl<%id%>">reply ▹</a>\ | |||||
| <a href="#" class="close-reply" id="cr<%id%>">reply ▿</a>\ | |||||
| <a href="#" id="sp<%id%>" class="show-proposal">proposal ▹</a>\ | |||||
| <a href="#" id="hp<%id%>" class="hide-proposal">proposal ▿</a>\ | |||||
| <a href="#" id="dc<%id%>" class="delete-comment hidden">delete</a>\ | |||||
| <span id="cm<%id%>" class="moderation hidden">\ | |||||
| <a href="#" id="ac<%id%>" class="accept-comment">accept</a>\ | |||||
| </span>\ | |||||
| </p>\ | |||||
| <pre class="proposal" id="pr<%id%>">\ | |||||
| <#proposal_diff#>\ | |||||
| </pre>\ | |||||
| <ul class="comment-children" id="cl<%id%>"></ul>\ | |||||
| </div>\ | |||||
| <div class="clearleft"></div>\ | |||||
| </div>\ | |||||
| </div>'; | |||||
| var replyTemplate = '\ | |||||
| <li>\ | |||||
| <div class="reply-div" id="rd<%id%>">\ | |||||
| <form id="rf<%id%>">\ | |||||
| <textarea name="comment" cols="80"></textarea>\ | |||||
| <input type="submit" value="Add reply" />\ | |||||
| <input type="button" value="Cancel" />\ | |||||
| <input type="hidden" name="parent" value="<%id%>" />\ | |||||
| <input type="hidden" name="node" value="" />\ | |||||
| </form>\ | |||||
| </div>\ | |||||
| </li>'; | |||||
| $(document).ready(function() { | |||||
| init(); | |||||
| }); | |||||
| })(jQuery); | |||||
| $(document).ready(function() { | |||||
| // add comment anchors for all paragraphs that are commentable | |||||
| $('.sphinx-has-comment').comment(); | |||||
| // highlight search words in search results | |||||
| $("div.context").each(function() { | |||||
| var params = $.getQueryParameters(); | |||||
| var terms = (params.q) ? params.q[0].split(/\s+/) : []; | |||||
| var result = $(this); | |||||
| $.each(terms, function() { | |||||
| result.highlightText(this.toLowerCase(), 'highlighted'); | |||||
| }); | |||||
| }); | |||||
| // directly open comment window if requested | |||||
| var anchor = document.location.hash; | |||||
| if (anchor.substring(0, 9) == '#comment-') { | |||||
| $('#ao' + anchor.substring(9)).click(); | |||||
| document.location.hash = '#s' + anchor.substring(9); | |||||
| } | |||||
| }); | |||||
| @@ -0,0 +1,683 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>Index — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="#" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1 id="index">Index</h1> | |||||
| <div class="genindex-jumpbox"> | |||||
| <a href="#A"><strong>A</strong></a> | |||||
| | <a href="#B"><strong>B</strong></a> | |||||
| | <a href="#C"><strong>C</strong></a> | |||||
| | <a href="#D"><strong>D</strong></a> | |||||
| | <a href="#E"><strong>E</strong></a> | |||||
| | <a href="#F"><strong>F</strong></a> | |||||
| | <a href="#G"><strong>G</strong></a> | |||||
| | <a href="#I"><strong>I</strong></a> | |||||
| | <a href="#L"><strong>L</strong></a> | |||||
| | <a href="#M"><strong>M</strong></a> | |||||
| | <a href="#N"><strong>N</strong></a> | |||||
| | <a href="#O"><strong>O</strong></a> | |||||
| | <a href="#P"><strong>P</strong></a> | |||||
| | <a href="#R"><strong>R</strong></a> | |||||
| | <a href="#S"><strong>S</strong></a> | |||||
| | <a href="#T"><strong>T</strong></a> | |||||
| | <a href="#U"><strong>U</strong></a> | |||||
| | <a href="#W"><strong>W</strong></a> | |||||
| | <a href="#Z"><strong>Z</strong></a> | |||||
| </div> | |||||
| <h2 id="A">A</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB">AD2USB (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.event.html#pyad2usb.event.event.EventHandler.add">add() (pyad2usb.event.event.EventHandler method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="B">B</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.BAUDRATE">BAUDRATE (pyad2usb.devices.SerialDevice attribute)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.BAUDRATE">(pyad2usb.devices.USBDevice attribute)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="C">C</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.close">close() (pyad2usb.ad2usb.AD2USB method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.close">(pyad2usb.ad2usb.Overseer method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.close">(pyad2usb.devices.SerialDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SocketDevice.close">(pyad2usb.devices.SocketDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.close">(pyad2usb.devices.USBDevice method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.CommError">CommError</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.create">create() (pyad2usb.ad2usb.Overseer class method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="D">D</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device">Device (class in pyad2usb.devices)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.ReadThread">Device.ReadThread (class in pyad2usb.devices)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.devices">devices() (pyad2usb.ad2usb.Overseer class method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="E">E</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.event.html#pyad2usb.event.event.Event">Event (class in pyad2usb.event.event)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.event.html#pyad2usb.event.event.EventHandler">EventHandler (class in pyad2usb.event.event)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.ExpanderMessage">ExpanderMessage (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="F">F</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.F1">F1 (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.F2">F2 (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.F3">F3 (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.F4">F4 (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.find_all">find_all() (pyad2usb.ad2usb.Overseer class method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.find_all">(pyad2usb.devices.SerialDevice static method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.find_all">(pyad2usb.devices.USBDevice static method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.event.html#pyad2usb.event.event.EventHandler.fire">fire() (pyad2usb.event.event.EventHandler method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware">Firmware (class in pyad2usb.util)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.FTDI_PRODUCT_ID">FTDI_PRODUCT_ID (pyad2usb.devices.USBDevice attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.FTDI_VENDOR_ID">FTDI_VENDOR_ID (pyad2usb.devices.USBDevice attribute)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="G">G</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.get_config">get_config() (pyad2usb.ad2usb.AD2USB method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.get_device">get_device() (pyad2usb.ad2usb.Overseer method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="I">I</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.id">id (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.id">(pyad2usb.devices.Device attribute)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.InvalidMessageError">InvalidMessageError</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.is_reader_alive">is_reader_alive() (pyad2usb.devices.Device method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="L">L</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.LRRMessage">LRRMessage (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="M">M</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Message">Message (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="N">N</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.NoDeviceError">NoDeviceError</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="O">O</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_alarm">on_alarm (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.on_attached">on_attached (pyad2usb.ad2usb.Overseer attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_boot">on_boot (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_bypass">on_bypass (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_close">on_close (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.on_close">(pyad2usb.devices.Device attribute)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_config_received">on_config_received (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.on_detached">on_detached (pyad2usb.ad2usb.Overseer attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_message">on_message (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_open">on_open (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.on_open">(pyad2usb.devices.Device attribute)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_power_changed">on_power_changed (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_read">on_read (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.on_read">(pyad2usb.devices.Device attribute)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_status_changed">on_status_changed (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.on_write">on_write (pyad2usb.ad2usb.AD2USB attribute)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.on_write">(pyad2usb.devices.Device attribute)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.open">open() (pyad2usb.ad2usb.AD2USB method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.open">(pyad2usb.devices.SerialDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SocketDevice.open">(pyad2usb.devices.SocketDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.open">(pyad2usb.devices.USBDevice method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer">Overseer (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.DetectThread">Overseer.DetectThread (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="P">P</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#module-pyad2usb.__init__">pyad2usb.__init__ (module)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#module-pyad2usb.ad2usb">pyad2usb.ad2usb (module)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#module-pyad2usb.devices">pyad2usb.devices (module)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.event.html#module-pyad2usb.event">pyad2usb.event (module)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.event.html#module-pyad2usb.event.event">pyad2usb.event.event (module)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#module-pyad2usb.util">pyad2usb.util (module)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="R">R</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.read">read() (pyad2usb.devices.SerialDevice method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SocketDevice.read">(pyad2usb.devices.SocketDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.read">(pyad2usb.devices.USBDevice method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.read_line">read_line() (pyad2usb.devices.SerialDevice method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SocketDevice.read_line">(pyad2usb.devices.SocketDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.read_line">(pyad2usb.devices.USBDevice method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.ReadThread.READ_TIMEOUT">READ_TIMEOUT (pyad2usb.devices.Device.ReadThread attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.reboot">reboot() (pyad2usb.ad2usb.AD2USB method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.ExpanderMessage.RELAY">RELAY (pyad2usb.ad2usb.ExpanderMessage attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.event.html#pyad2usb.event.event.EventHandler.remove">remove() (pyad2usb.event.event.EventHandler method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.RFMessage">RFMessage (class in pyad2usb.ad2usb)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.DetectThread.run">run() (pyad2usb.ad2usb.Overseer.DetectThread method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.ReadThread.run">(pyad2usb.devices.Device.ReadThread method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="S">S</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice">SerialDevice (class in pyad2usb.devices)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.AD2USB.set_config">set_config() (pyad2usb.ad2usb.AD2USB method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SocketDevice">SocketDevice (class in pyad2usb.devices)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.STAGE_BOOT">STAGE_BOOT (pyad2usb.util.Firmware attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.STAGE_DONE">STAGE_DONE (pyad2usb.util.Firmware attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.STAGE_LOAD">STAGE_LOAD (pyad2usb.util.Firmware attribute)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.STAGE_START">STAGE_START (pyad2usb.util.Firmware attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.STAGE_UPLOADING">STAGE_UPLOADING (pyad2usb.util.Firmware attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.STAGE_WAITING">STAGE_WAITING (pyad2usb.util.Firmware attribute)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.start">start() (pyad2usb.ad2usb.Overseer method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.stop">stop() (pyad2usb.ad2usb.Overseer method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.Overseer.DetectThread.stop">(pyad2usb.ad2usb.Overseer.DetectThread method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.ReadThread.stop">(pyad2usb.devices.Device.ReadThread method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.Device.stop_reader">stop_reader() (pyad2usb.devices.Device method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="T">T</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.TimeoutError">TimeoutError</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="U">U</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.util.Firmware.upload">upload() (pyad2usb.util.Firmware static method)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice">USBDevice (class in pyad2usb.devices)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="W">W</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SerialDevice.write">write() (pyad2usb.devices.SerialDevice method)</a> | |||||
| </dt> | |||||
| <dd><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.SocketDevice.write">(pyad2usb.devices.SocketDevice method)</a> | |||||
| </dt> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.devices.USBDevice.write">(pyad2usb.devices.USBDevice method)</a> | |||||
| </dt> | |||||
| </dl></dd> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| <h2 id="Z">Z</h2> | |||||
| <table style="width: 100%" class="indextable genindextable"><tr> | |||||
| <td style="width: 33%" valign="top"><dl> | |||||
| <dt><a href="pyad2usb.html#pyad2usb.ad2usb.ExpanderMessage.ZONE">ZONE (pyad2usb.ad2usb.ExpanderMessage attribute)</a> | |||||
| </dt> | |||||
| </dl></td> | |||||
| </tr></table> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="#" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,142 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>Welcome to pyad2usb’s documentation! — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="#" /> | |||||
| <link rel="next" title="pyad2usb Package" href="pyad2usb.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="pyad2usb.html" title="pyad2usb Package" | |||||
| accesskey="N">next</a> |</li> | |||||
| <li><a href="#">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <div class="section" id="welcome-to-pyad2usb-s-documentation"> | |||||
| <h1>Welcome to pyad2usb’s documentation!<a class="headerlink" href="#welcome-to-pyad2usb-s-documentation" title="Permalink to this headline">¶</a></h1> | |||||
| <p>Contents:</p> | |||||
| <div class="toctree-wrapper compound"> | |||||
| <ul> | |||||
| <li class="toctree-l1"><a class="reference internal" href="pyad2usb.html">pyad2usb Package</a><ul> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#id1"><tt class="docutils literal"><span class="pre">pyad2usb</span></tt> Package</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#module-pyad2usb.ad2usb"><tt class="docutils literal"><span class="pre">ad2usb</span></tt> Module</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#module-pyad2usb.devices"><tt class="docutils literal"><span class="pre">devices</span></tt> Module</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#module-pyad2usb.util"><tt class="docutils literal"><span class="pre">util</span></tt> Module</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#subpackages">Subpackages</a><ul> | |||||
| <li class="toctree-l3"><a class="reference internal" href="pyad2usb.event.html">event Package</a><ul> | |||||
| <li class="toctree-l4"><a class="reference internal" href="pyad2usb.event.html#id1"><tt class="docutils literal"><span class="pre">event</span></tt> Package</a></li> | |||||
| <li class="toctree-l4"><a class="reference internal" href="pyad2usb.event.html#module-pyad2usb.event.event"><tt class="docutils literal"><span class="pre">event</span></tt> Module</a></li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| <div class="section" id="indices-and-tables"> | |||||
| <h1>Indices and tables<a class="headerlink" href="#indices-and-tables" title="Permalink to this headline">¶</a></h1> | |||||
| <ul class="simple"> | |||||
| <li><a class="reference internal" href="genindex.html"><em>Index</em></a></li> | |||||
| <li><a class="reference internal" href="py-modindex.html"><em>Module Index</em></a></li> | |||||
| <li><a class="reference internal" href="search.html"><em>Search Page</em></a></li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <h3><a href="#">Table Of Contents</a></h3> | |||||
| <ul> | |||||
| <li><a class="reference internal" href="#">Welcome to pyad2usb’s documentation!</a><ul> | |||||
| </ul> | |||||
| </li> | |||||
| <li><a class="reference internal" href="#indices-and-tables">Indices and tables</a></li> | |||||
| </ul> | |||||
| <h4>Next topic</h4> | |||||
| <p class="topless"><a href="pyad2usb.html" | |||||
| title="next chapter">pyad2usb Package</a></p> | |||||
| <h3>This Page</h3> | |||||
| <ul class="this-page-menu"> | |||||
| <li><a href="_sources/index.txt" | |||||
| rel="nofollow">Show Source</a></li> | |||||
| </ul> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="pyad2usb.html" title="pyad2usb Package" | |||||
| >next</a> |</li> | |||||
| <li><a href="#">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,115 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>pyad2usb — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <div class="section" id="pyad2usb"> | |||||
| <h1>pyad2usb<a class="headerlink" href="#pyad2usb" title="Permalink to this headline">¶</a></h1> | |||||
| <div class="toctree-wrapper compound"> | |||||
| <ul> | |||||
| <li class="toctree-l1"><a class="reference internal" href="pyad2usb.html">pyad2usb Package</a><ul> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#id1"><tt class="docutils literal"><span class="pre">pyad2usb</span></tt> Package</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#module-pyad2usb.ad2usb"><tt class="docutils literal"><span class="pre">ad2usb</span></tt> Module</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#module-pyad2usb.devices"><tt class="docutils literal"><span class="pre">devices</span></tt> Module</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#module-pyad2usb.util"><tt class="docutils literal"><span class="pre">util</span></tt> Module</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.html#subpackages">Subpackages</a><ul> | |||||
| <li class="toctree-l3"><a class="reference internal" href="pyad2usb.event.html">event Package</a><ul> | |||||
| <li class="toctree-l4"><a class="reference internal" href="pyad2usb.event.html#id1"><tt class="docutils literal"><span class="pre">event</span></tt> Package</a></li> | |||||
| <li class="toctree-l4"><a class="reference internal" href="pyad2usb.event.html#module-pyad2usb.event.event"><tt class="docutils literal"><span class="pre">event</span></tt> Module</a></li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <h3>This Page</h3> | |||||
| <ul class="this-page-menu"> | |||||
| <li><a href="_sources/modules.txt" | |||||
| rel="nofollow">Show Source</a></li> | |||||
| </ul> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,139 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>Python Module Index — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="#" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1>Python Module Index</h1> | |||||
| <div class="modindex-jumpbox"> | |||||
| <a href="#cap-p"><strong>p</strong></a> | |||||
| </div> | |||||
| <table class="indextable modindextable" cellspacing="0" cellpadding="2"> | |||||
| <tr class="pcap"><td></td><td> </td><td></td></tr> | |||||
| <tr class="cap" id="cap-p"><td></td><td> | |||||
| <strong>p</strong></td><td></td></tr> | |||||
| <tr> | |||||
| <td><img src="_static/minus.png" class="toggler" | |||||
| id="toggle-1" style="display: none" alt="-" /></td> | |||||
| <td> | |||||
| <tt class="xref">pyad2usb</tt></td><td> | |||||
| <em></em></td></tr> | |||||
| <tr class="cg-1"> | |||||
| <td></td> | |||||
| <td> | |||||
| <a href="pyad2usb.html#module-pyad2usb.__init__"><tt class="xref">pyad2usb.__init__</tt></a></td><td> | |||||
| <em></em></td></tr> | |||||
| <tr class="cg-1"> | |||||
| <td></td> | |||||
| <td> | |||||
| <a href="pyad2usb.html#module-pyad2usb.ad2usb"><tt class="xref">pyad2usb.ad2usb</tt></a></td><td> | |||||
| <em></em></td></tr> | |||||
| <tr class="cg-1"> | |||||
| <td></td> | |||||
| <td> | |||||
| <a href="pyad2usb.html#module-pyad2usb.devices"><tt class="xref">pyad2usb.devices</tt></a></td><td> | |||||
| <em></em></td></tr> | |||||
| <tr class="cg-1"> | |||||
| <td></td> | |||||
| <td> | |||||
| <a href="pyad2usb.event.html#module-pyad2usb.event"><tt class="xref">pyad2usb.event</tt></a></td><td> | |||||
| <em></em></td></tr> | |||||
| <tr class="cg-1"> | |||||
| <td></td> | |||||
| <td> | |||||
| <a href="pyad2usb.event.html#module-pyad2usb.event.event"><tt class="xref">pyad2usb.event.event</tt></a></td><td> | |||||
| <em></em></td></tr> | |||||
| <tr class="cg-1"> | |||||
| <td></td> | |||||
| <td> | |||||
| <a href="pyad2usb.html#module-pyad2usb.util"><tt class="xref">pyad2usb.util</tt></a></td><td> | |||||
| <em></em></td></tr> | |||||
| </table> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="#" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,159 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>event Package — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="index.html" /> | |||||
| <link rel="up" title="pyad2usb Package" href="pyad2usb.html" /> | |||||
| <link rel="prev" title="pyad2usb Package" href="pyad2usb.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="pyad2usb.html" title="pyad2usb Package" | |||||
| accesskey="P">previous</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="pyad2usb.html" accesskey="U">pyad2usb Package</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <div class="section" id="event-package"> | |||||
| <h1>event Package<a class="headerlink" href="#event-package" title="Permalink to this headline">¶</a></h1> | |||||
| <div class="section" id="id1"> | |||||
| <h2><tt class="xref py py-mod docutils literal"><span class="pre">event</span></tt> Package<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2> | |||||
| <span class="target" id="module-pyad2usb.event"></span></div> | |||||
| <div class="section" id="module-pyad2usb.event.event"> | |||||
| <span id="event-module"></span><h2><tt class="xref py py-mod docutils literal"><span class="pre">event</span></tt> Module<a class="headerlink" href="#module-pyad2usb.event.event" title="Permalink to this headline">¶</a></h2> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.event.event.Event"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.event.event.</tt><tt class="descname">Event</tt><big>(</big><em>doc=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/event/event.html#Event"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.event.event.Event" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.event.event.EventHandler"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.event.event.</tt><tt class="descname">EventHandler</tt><big>(</big><em>event</em>, <em>obj</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/event/event.html#EventHandler"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.event.event.EventHandler" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.event.event.EventHandler.add"> | |||||
| <tt class="descname">add</tt><big>(</big><em>func</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/event/event.html#EventHandler.add"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.event.event.EventHandler.add" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Add new event handler function.</p> | |||||
| <p>Event handler function must be defined like func(sender, earg). | |||||
| You can add handler also by using ‘+=’ operator.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.event.event.EventHandler.fire"> | |||||
| <tt class="descname">fire</tt><big>(</big><em>earg=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/event/event.html#EventHandler.fire"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.event.event.EventHandler.fire" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Fire event and call all handler functions</p> | |||||
| <p>You can call EventHandler object itself like e(earg) instead of | |||||
| e.fire(earg).</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.event.event.EventHandler.remove"> | |||||
| <tt class="descname">remove</tt><big>(</big><em>func</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/event/event.html#EventHandler.remove"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.event.event.EventHandler.remove" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Remove existing event handler function.</p> | |||||
| <p>You can remove handler also by using ‘-=’ operator.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <h3><a href="index.html">Table Of Contents</a></h3> | |||||
| <ul> | |||||
| <li><a class="reference internal" href="#">event Package</a><ul> | |||||
| <li><a class="reference internal" href="#id1"><tt class="docutils literal"><span class="pre">event</span></tt> Package</a></li> | |||||
| <li><a class="reference internal" href="#module-pyad2usb.event.event"><tt class="docutils literal"><span class="pre">event</span></tt> Module</a></li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| <h4>Previous topic</h4> | |||||
| <p class="topless"><a href="pyad2usb.html" | |||||
| title="previous chapter">pyad2usb Package</a></p> | |||||
| <h3>This Page</h3> | |||||
| <ul class="this-page-menu"> | |||||
| <li><a href="_sources/pyad2usb.event.txt" | |||||
| rel="nofollow">Show Source</a></li> | |||||
| </ul> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="pyad2usb.html" title="pyad2usb Package" | |||||
| >previous</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| <li><a href="pyad2usb.html" >pyad2usb Package</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,691 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>pyad2usb Package — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="index.html" /> | |||||
| <link rel="next" title="event Package" href="pyad2usb.event.html" /> | |||||
| <link rel="prev" title="Welcome to pyad2usb’s documentation!" href="index.html" /> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="pyad2usb.event.html" title="event Package" | |||||
| accesskey="N">next</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="index.html" title="Welcome to pyad2usb’s documentation!" | |||||
| accesskey="P">previous</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <div class="section" id="pyad2usb-package"> | |||||
| <h1>pyad2usb Package<a class="headerlink" href="#pyad2usb-package" title="Permalink to this headline">¶</a></h1> | |||||
| <div class="section" id="id1"> | |||||
| <h2><tt class="xref py py-mod docutils literal"><span class="pre">pyad2usb</span></tt> Package<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2> | |||||
| <span class="target" id="module-pyad2usb.__init__"></span><p>The PyAD2USB module.</p> | |||||
| </div> | |||||
| <div class="section" id="module-pyad2usb.ad2usb"> | |||||
| <span id="ad2usb-module"></span><h2><tt class="xref py py-mod docutils literal"><span class="pre">ad2usb</span></tt> Module<a class="headerlink" href="#module-pyad2usb.ad2usb" title="Permalink to this headline">¶</a></h2> | |||||
| <p>Provides the full AD2USB class and factory.</p> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.ad2usb.</tt><tt class="descname">AD2USB</tt><big>(</big><em>device</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>High-level wrapper around AD2USB/AD2SERIAL devices.</p> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.F1"> | |||||
| <tt class="descname">F1</tt><em class="property"> = u'\x01\x01\x01'</em><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.F1" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.F2"> | |||||
| <tt class="descname">F2</tt><em class="property"> = u'\x02\x02\x02'</em><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.F2" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.F3"> | |||||
| <tt class="descname">F3</tt><em class="property"> = u'\x03\x03\x03'</em><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.F3" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.F4"> | |||||
| <tt class="descname">F4</tt><em class="property"> = u'\x04\x04\x04'</em><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.F4" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.close"> | |||||
| <tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Closes the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.get_config"> | |||||
| <tt class="descname">get_config</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB.get_config"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.get_config" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Retrieves the configuration from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.id"> | |||||
| <tt class="descname">id</tt><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB.id"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.id" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_alarm"> | |||||
| <tt class="descname">on_alarm</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_alarm" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the alarm is triggered.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_boot"> | |||||
| <tt class="descname">on_boot</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_boot" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the device finishes bootings.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_bypass"> | |||||
| <tt class="descname">on_bypass</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_bypass" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when a zone is bypassed.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_close"> | |||||
| <tt class="descname">on_close</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the device has been closed.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_config_received"> | |||||
| <tt class="descname">on_config_received</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_config_received" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the device receives its configuration.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_message"> | |||||
| <tt class="descname">on_message</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_message" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when a message has been received from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_open"> | |||||
| <tt class="descname">on_open</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_open" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the device has been opened.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_power_changed"> | |||||
| <tt class="descname">on_power_changed</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_power_changed" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when panel power switches between AC and DC.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_read"> | |||||
| <tt class="descname">on_read</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_read" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when a line has been read from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_status_changed"> | |||||
| <tt class="descname">on_status_changed</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_status_changed" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the panel status changes.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.on_write"> | |||||
| <tt class="descname">on_write</tt><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.on_write" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when data has been written to the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.open"> | |||||
| <tt class="descname">open</tt><big>(</big><em>baudrate=None</em>, <em>interface=None</em>, <em>index=None</em>, <em>no_reader_thread=False</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB.open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.open" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Opens the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.reboot"> | |||||
| <tt class="descname">reboot</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB.reboot"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.reboot" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reboots the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.AD2USB.set_config"> | |||||
| <tt class="descname">set_config</tt><big>(</big><em>settings</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#AD2USB.set_config"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.AD2USB.set_config" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Sets configuration entries on the device.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.ExpanderMessage"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.ad2usb.</tt><tt class="descname">ExpanderMessage</tt><big>(</big><em>data=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#ExpanderMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.ExpanderMessage" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Represents a message from a zone or relay expansion module.</p> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.ExpanderMessage.RELAY"> | |||||
| <tt class="descname">RELAY</tt><em class="property"> = 1</em><a class="headerlink" href="#pyad2usb.ad2usb.ExpanderMessage.RELAY" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.ExpanderMessage.ZONE"> | |||||
| <tt class="descname">ZONE</tt><em class="property"> = 0</em><a class="headerlink" href="#pyad2usb.ad2usb.ExpanderMessage.ZONE" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.LRRMessage"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.ad2usb.</tt><tt class="descname">LRRMessage</tt><big>(</big><em>data=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#LRRMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.LRRMessage" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Represent a message from a Long Range Radio.</p> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.Message"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.ad2usb.</tt><tt class="descname">Message</tt><big>(</big><em>data=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Message"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Message" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Represents a message from the alarm panel.</p> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.ad2usb.</tt><tt class="descname">Overseer</tt><big>(</big><em>attached_event=None</em>, <em>detached_event=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Factory for creation of AD2USB devices as well as provide4s attach/detach events.”</p> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.DetectThread"> | |||||
| <em class="property">class </em><tt class="descname">DetectThread</tt><big>(</big><em>overseer</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.DetectThread"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.DetectThread" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">threading.Thread</span></tt></p> | |||||
| <p>Thread that handles detection of added/removed devices.</p> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.DetectThread.run"> | |||||
| <tt class="descname">run</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.DetectThread.run"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.DetectThread.run" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>The actual detection process.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.DetectThread.stop"> | |||||
| <tt class="descname">stop</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.DetectThread.stop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.DetectThread.stop" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Stops the thread.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.close"> | |||||
| <tt class="descclassname">Overseer.</tt><tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Clean up and shut down.</p> | |||||
| </dd></dl> | |||||
| <dl class="classmethod"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.create"> | |||||
| <em class="property">classmethod </em><tt class="descclassname">Overseer.</tt><tt class="descname">create</tt><big>(</big><em>device=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.create"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.create" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Factory method that returns the requested AD2USB device, or the first device.</p> | |||||
| </dd></dl> | |||||
| <dl class="classmethod"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.devices"> | |||||
| <em class="property">classmethod </em><tt class="descclassname">Overseer.</tt><tt class="descname">devices</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.devices"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.devices" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Returns a cached list of AD2USB devices located on the system.</p> | |||||
| </dd></dl> | |||||
| <dl class="classmethod"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.find_all"> | |||||
| <em class="property">classmethod </em><tt class="descclassname">Overseer.</tt><tt class="descname">find_all</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.find_all"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.find_all" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Returns all AD2USB devices located on the system.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.get_device"> | |||||
| <tt class="descclassname">Overseer.</tt><tt class="descname">get_device</tt><big>(</big><em>device=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.get_device"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.get_device" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Factory method that returns the requested AD2USB device, or the first device.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.on_attached"> | |||||
| <tt class="descclassname">Overseer.</tt><tt class="descname">on_attached</tt><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.on_attached" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when an AD2USB device has been detected.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.on_detached"> | |||||
| <tt class="descclassname">Overseer.</tt><tt class="descname">on_detached</tt><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.on_detached" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when an AD2USB device has been removed.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.start"> | |||||
| <tt class="descclassname">Overseer.</tt><tt class="descname">start</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.start"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.start" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Starts the detection thread, if not already running.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.ad2usb.Overseer.stop"> | |||||
| <tt class="descclassname">Overseer.</tt><tt class="descname">stop</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#Overseer.stop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.Overseer.stop" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Stops the detection thread.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.ad2usb.RFMessage"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.ad2usb.</tt><tt class="descname">RFMessage</tt><big>(</big><em>data=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/ad2usb.html#RFMessage"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.ad2usb.RFMessage" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Represents a message from an RF receiver.</p> | |||||
| </dd></dl> | |||||
| </div> | |||||
| <div class="section" id="module-pyad2usb.devices"> | |||||
| <span id="devices-module"></span><h2><tt class="xref py py-mod docutils literal"><span class="pre">devices</span></tt> Module<a class="headerlink" href="#module-pyad2usb.devices" title="Permalink to this headline">¶</a></h2> | |||||
| <p>Contains different types of devices belonging to the AD2USB family.</p> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.devices.Device"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.devices.</tt><tt class="descname">Device</tt><a class="reference internal" href="_modules/pyad2usb/devices.html#Device"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Generic parent device to all AD2USB products.</p> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.devices.Device.ReadThread"> | |||||
| <em class="property">class </em><tt class="descname">ReadThread</tt><big>(</big><em>device</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#Device.ReadThread"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device.ReadThread" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">threading.Thread</span></tt></p> | |||||
| <p>Reader thread which processes messages from the device.</p> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.Device.ReadThread.READ_TIMEOUT"> | |||||
| <tt class="descname">READ_TIMEOUT</tt><em class="property"> = 10</em><a class="headerlink" href="#pyad2usb.devices.Device.ReadThread.READ_TIMEOUT" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.Device.ReadThread.run"> | |||||
| <tt class="descname">run</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#Device.ReadThread.run"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device.ReadThread.run" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>The actual read process.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.Device.ReadThread.stop"> | |||||
| <tt class="descname">stop</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#Device.ReadThread.stop"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device.ReadThread.stop" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Stops the running thread.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.Device.id"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">id</tt><a class="reference internal" href="_modules/pyad2usb/devices.html#Device.id"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device.id" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.Device.is_reader_alive"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">is_reader_alive</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#Device.is_reader_alive"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device.is_reader_alive" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Indicates whether or not the reader thread is alive.</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.Device.on_close"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">on_close</tt><a class="headerlink" href="#pyad2usb.devices.Device.on_close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the device has been closed</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.Device.on_open"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">on_open</tt><a class="headerlink" href="#pyad2usb.devices.Device.on_open" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when the device has been opened</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.Device.on_read"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">on_read</tt><a class="headerlink" href="#pyad2usb.devices.Device.on_read" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when a line has been read from the device</p> | |||||
| </dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.Device.on_write"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">on_write</tt><a class="headerlink" href="#pyad2usb.devices.Device.on_write" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Called when data has been written to the device</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.Device.stop_reader"> | |||||
| <tt class="descclassname">Device.</tt><tt class="descname">stop_reader</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#Device.stop_reader"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.Device.stop_reader" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Stops the reader thread.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.devices.SerialDevice"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.devices.</tt><tt class="descname">SerialDevice</tt><big>(</big><em>interface=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <a class="reference internal" href="#pyad2usb.devices.Device" title="pyad2usb.devices.Device"><tt class="xref py py-class docutils literal"><span class="pre">pyad2usb.devices.Device</span></tt></a></p> | |||||
| <p>AD2USB or AD2SERIAL device exposed with the pyserial interface.</p> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.BAUDRATE"> | |||||
| <tt class="descname">BAUDRATE</tt><em class="property"> = 19200</em><a class="headerlink" href="#pyad2usb.devices.SerialDevice.BAUDRATE" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.close"> | |||||
| <tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice.close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Closes the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="staticmethod"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.find_all"> | |||||
| <em class="property">static </em><tt class="descname">find_all</tt><big>(</big><em>pattern=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice.find_all"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice.find_all" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Returns all serial ports present.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.open"> | |||||
| <tt class="descname">open</tt><big>(</big><em>baudrate=19200</em>, <em>interface=None</em>, <em>index=None</em>, <em>no_reader_thread=False</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice.open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice.open" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Opens the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.read"> | |||||
| <tt class="descname">read</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice.read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice.read" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reads a single character from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.read_line"> | |||||
| <tt class="descname">read_line</tt><big>(</big><em>timeout=0.0</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice.read_line"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice.read_line" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reads a line from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SerialDevice.write"> | |||||
| <tt class="descname">write</tt><big>(</big><em>data</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SerialDevice.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SerialDevice.write" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Writes data to the device.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.devices.SocketDevice"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.devices.</tt><tt class="descname">SocketDevice</tt><big>(</big><em>interface=('localhost'</em>, <em>10000)</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SocketDevice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SocketDevice" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <a class="reference internal" href="#pyad2usb.devices.Device" title="pyad2usb.devices.Device"><tt class="xref py py-class docutils literal"><span class="pre">pyad2usb.devices.Device</span></tt></a></p> | |||||
| <p>Device that supports communication with an AD2USB that is exposed via ser2sock or another | |||||
| Serial to IP interface.</p> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SocketDevice.close"> | |||||
| <tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SocketDevice.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SocketDevice.close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Closes the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SocketDevice.open"> | |||||
| <tt class="descname">open</tt><big>(</big><em>baudrate=None</em>, <em>interface=None</em>, <em>index=0</em>, <em>no_reader_thread=False</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SocketDevice.open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SocketDevice.open" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Opens the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SocketDevice.read"> | |||||
| <tt class="descname">read</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SocketDevice.read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SocketDevice.read" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reads a single character from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SocketDevice.read_line"> | |||||
| <tt class="descname">read_line</tt><big>(</big><em>timeout=0.0</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SocketDevice.read_line"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SocketDevice.read_line" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reads a line from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.SocketDevice.write"> | |||||
| <tt class="descname">write</tt><big>(</big><em>data</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#SocketDevice.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.SocketDevice.write" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Writes data to the device.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.devices.USBDevice"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.devices.</tt><tt class="descname">USBDevice</tt><big>(</big><em>vid=1027</em>, <em>pid=24577</em>, <em>serial=None</em>, <em>description=None</em>, <em>interface=0</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <a class="reference internal" href="#pyad2usb.devices.Device" title="pyad2usb.devices.Device"><tt class="xref py py-class docutils literal"><span class="pre">pyad2usb.devices.Device</span></tt></a></p> | |||||
| <p>AD2USB device exposed with PyFTDI’s interface.</p> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.USBDevice.BAUDRATE"> | |||||
| <tt class="descname">BAUDRATE</tt><em class="property"> = 115200</em><a class="headerlink" href="#pyad2usb.devices.USBDevice.BAUDRATE" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.USBDevice.FTDI_PRODUCT_ID"> | |||||
| <tt class="descname">FTDI_PRODUCT_ID</tt><em class="property"> = 24577</em><a class="headerlink" href="#pyad2usb.devices.USBDevice.FTDI_PRODUCT_ID" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.devices.USBDevice.FTDI_VENDOR_ID"> | |||||
| <tt class="descname">FTDI_VENDOR_ID</tt><em class="property"> = 1027</em><a class="headerlink" href="#pyad2usb.devices.USBDevice.FTDI_VENDOR_ID" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.USBDevice.close"> | |||||
| <tt class="descname">close</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice.close"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice.close" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Closes the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="staticmethod"> | |||||
| <dt id="pyad2usb.devices.USBDevice.find_all"> | |||||
| <em class="property">static </em><tt class="descname">find_all</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice.find_all"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice.find_all" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Returns all FTDI devices matching our vendor and product IDs.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.USBDevice.open"> | |||||
| <tt class="descname">open</tt><big>(</big><em>baudrate=115200</em>, <em>interface=None</em>, <em>index=0</em>, <em>no_reader_thread=False</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice.open"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice.open" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Opens the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.USBDevice.read"> | |||||
| <tt class="descname">read</tt><big>(</big><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice.read"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice.read" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reads a single character from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.USBDevice.read_line"> | |||||
| <tt class="descname">read_line</tt><big>(</big><em>timeout=0.0</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice.read_line"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice.read_line" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Reads a line from the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="method"> | |||||
| <dt id="pyad2usb.devices.USBDevice.write"> | |||||
| <tt class="descname">write</tt><big>(</big><em>data</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/devices.html#USBDevice.write"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.devices.USBDevice.write" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Writes data to the device.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| </div> | |||||
| <div class="section" id="module-pyad2usb.util"> | |||||
| <span id="util-module"></span><h2><tt class="xref py py-mod docutils literal"><span class="pre">util</span></tt> Module<a class="headerlink" href="#module-pyad2usb.util" title="Permalink to this headline">¶</a></h2> | |||||
| <p>Provides utility classes for the AD2USB devices.</p> | |||||
| <dl class="exception"> | |||||
| <dt id="pyad2usb.util.CommError"> | |||||
| <em class="property">exception </em><tt class="descclassname">pyad2usb.util.</tt><tt class="descname">CommError</tt><a class="reference internal" href="_modules/pyad2usb/util.html#CommError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.util.CommError" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">exceptions.Exception</span></tt></p> | |||||
| <p>There was an error communicating with the device.</p> | |||||
| </dd></dl> | |||||
| <dl class="class"> | |||||
| <dt id="pyad2usb.util.Firmware"> | |||||
| <em class="property">class </em><tt class="descclassname">pyad2usb.util.</tt><tt class="descname">Firmware</tt><a class="reference internal" href="_modules/pyad2usb/util.html#Firmware"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.util.Firmware" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">object</span></tt></p> | |||||
| <p>Represents firmware for the AD2USB/AD2SERIAL devices.</p> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.util.Firmware.STAGE_BOOT"> | |||||
| <tt class="descname">STAGE_BOOT</tt><em class="property"> = 2</em><a class="headerlink" href="#pyad2usb.util.Firmware.STAGE_BOOT" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.util.Firmware.STAGE_DONE"> | |||||
| <tt class="descname">STAGE_DONE</tt><em class="property"> = 5</em><a class="headerlink" href="#pyad2usb.util.Firmware.STAGE_DONE" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.util.Firmware.STAGE_LOAD"> | |||||
| <tt class="descname">STAGE_LOAD</tt><em class="property"> = 3</em><a class="headerlink" href="#pyad2usb.util.Firmware.STAGE_LOAD" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.util.Firmware.STAGE_START"> | |||||
| <tt class="descname">STAGE_START</tt><em class="property"> = 0</em><a class="headerlink" href="#pyad2usb.util.Firmware.STAGE_START" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.util.Firmware.STAGE_UPLOADING"> | |||||
| <tt class="descname">STAGE_UPLOADING</tt><em class="property"> = 4</em><a class="headerlink" href="#pyad2usb.util.Firmware.STAGE_UPLOADING" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="attribute"> | |||||
| <dt id="pyad2usb.util.Firmware.STAGE_WAITING"> | |||||
| <tt class="descname">STAGE_WAITING</tt><em class="property"> = 1</em><a class="headerlink" href="#pyad2usb.util.Firmware.STAGE_WAITING" title="Permalink to this definition">¶</a></dt> | |||||
| <dd></dd></dl> | |||||
| <dl class="staticmethod"> | |||||
| <dt id="pyad2usb.util.Firmware.upload"> | |||||
| <em class="property">static </em><tt class="descname">upload</tt><big>(</big><em>dev</em>, <em>filename</em>, <em>progress_callback=None</em><big>)</big><a class="reference internal" href="_modules/pyad2usb/util.html#Firmware.upload"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.util.Firmware.upload" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Uploads firmware to an AD2USB/AD2SERIAL device.</p> | |||||
| </dd></dl> | |||||
| </dd></dl> | |||||
| <dl class="exception"> | |||||
| <dt id="pyad2usb.util.InvalidMessageError"> | |||||
| <em class="property">exception </em><tt class="descclassname">pyad2usb.util.</tt><tt class="descname">InvalidMessageError</tt><a class="reference internal" href="_modules/pyad2usb/util.html#InvalidMessageError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.util.InvalidMessageError" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">exceptions.Exception</span></tt></p> | |||||
| <p>The format of the panel message was invalid.</p> | |||||
| </dd></dl> | |||||
| <dl class="exception"> | |||||
| <dt id="pyad2usb.util.NoDeviceError"> | |||||
| <em class="property">exception </em><tt class="descclassname">pyad2usb.util.</tt><tt class="descname">NoDeviceError</tt><a class="reference internal" href="_modules/pyad2usb/util.html#NoDeviceError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.util.NoDeviceError" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">exceptions.Exception</span></tt></p> | |||||
| <p>No devices found.</p> | |||||
| </dd></dl> | |||||
| <dl class="exception"> | |||||
| <dt id="pyad2usb.util.TimeoutError"> | |||||
| <em class="property">exception </em><tt class="descclassname">pyad2usb.util.</tt><tt class="descname">TimeoutError</tt><a class="reference internal" href="_modules/pyad2usb/util.html#TimeoutError"><span class="viewcode-link">[source]</span></a><a class="headerlink" href="#pyad2usb.util.TimeoutError" title="Permalink to this definition">¶</a></dt> | |||||
| <dd><p>Bases: <tt class="xref py py-class docutils literal"><span class="pre">exceptions.Exception</span></tt></p> | |||||
| <p>There was a timeout while trying to communicate with the device.</p> | |||||
| </dd></dl> | |||||
| </div> | |||||
| <div class="section" id="subpackages"> | |||||
| <h2>Subpackages<a class="headerlink" href="#subpackages" title="Permalink to this headline">¶</a></h2> | |||||
| <div class="toctree-wrapper compound"> | |||||
| <ul> | |||||
| <li class="toctree-l1"><a class="reference internal" href="pyad2usb.event.html">event Package</a><ul> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.event.html#id1"><tt class="docutils literal"><span class="pre">event</span></tt> Package</a></li> | |||||
| <li class="toctree-l2"><a class="reference internal" href="pyad2usb.event.html#module-pyad2usb.event.event"><tt class="docutils literal"><span class="pre">event</span></tt> Module</a></li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| <h3><a href="index.html">Table Of Contents</a></h3> | |||||
| <ul> | |||||
| <li><a class="reference internal" href="#">pyad2usb Package</a><ul> | |||||
| <li><a class="reference internal" href="#id1"><tt class="docutils literal"><span class="pre">pyad2usb</span></tt> Package</a></li> | |||||
| <li><a class="reference internal" href="#module-pyad2usb.ad2usb"><tt class="docutils literal"><span class="pre">ad2usb</span></tt> Module</a></li> | |||||
| <li><a class="reference internal" href="#module-pyad2usb.devices"><tt class="docutils literal"><span class="pre">devices</span></tt> Module</a></li> | |||||
| <li><a class="reference internal" href="#module-pyad2usb.util"><tt class="docutils literal"><span class="pre">util</span></tt> Module</a></li> | |||||
| <li><a class="reference internal" href="#subpackages">Subpackages</a><ul> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| </li> | |||||
| </ul> | |||||
| <h4>Previous topic</h4> | |||||
| <p class="topless"><a href="index.html" | |||||
| title="previous chapter">Welcome to pyad2usb’s documentation!</a></p> | |||||
| <h4>Next topic</h4> | |||||
| <p class="topless"><a href="pyad2usb.event.html" | |||||
| title="next chapter">event Package</a></p> | |||||
| <h3>This Page</h3> | |||||
| <ul class="this-page-menu"> | |||||
| <li><a href="_sources/pyad2usb.txt" | |||||
| rel="nofollow">Show Source</a></li> | |||||
| </ul> | |||||
| <div id="searchbox" style="display: none"> | |||||
| <h3>Quick search</h3> | |||||
| <form class="search" action="search.html" method="get"> | |||||
| <input type="text" name="q" /> | |||||
| <input type="submit" value="Go" /> | |||||
| <input type="hidden" name="check_keywords" value="yes" /> | |||||
| <input type="hidden" name="area" value="default" /> | |||||
| </form> | |||||
| <p class="searchtip" style="font-size: 90%"> | |||||
| Enter search terms or a module, class or function name. | |||||
| </p> | |||||
| </div> | |||||
| <script type="text/javascript">$('#searchbox').show(0);</script> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="pyad2usb.event.html" title="event Package" | |||||
| >next</a> |</li> | |||||
| <li class="right" > | |||||
| <a href="index.html" title="Welcome to pyad2usb’s documentation!" | |||||
| >previous</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,105 @@ | |||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" | |||||
| "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |||||
| <html xmlns="http://www.w3.org/1999/xhtml"> | |||||
| <head> | |||||
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||||
| <title>Search — pyad2usb documentation</title> | |||||
| <link rel="stylesheet" href="_static/default.css" type="text/css" /> | |||||
| <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> | |||||
| <script type="text/javascript"> | |||||
| var DOCUMENTATION_OPTIONS = { | |||||
| URL_ROOT: './', | |||||
| VERSION: '', | |||||
| COLLAPSE_INDEX: false, | |||||
| FILE_SUFFIX: '.html', | |||||
| HAS_SOURCE: true | |||||
| }; | |||||
| </script> | |||||
| <script type="text/javascript" src="_static/jquery.js"></script> | |||||
| <script type="text/javascript" src="_static/underscore.js"></script> | |||||
| <script type="text/javascript" src="_static/doctools.js"></script> | |||||
| <script type="text/javascript" src="_static/searchtools.js"></script> | |||||
| <link rel="top" title="pyad2usb documentation" href="index.html" /> | |||||
| <script type="text/javascript"> | |||||
| jQuery(function() { Search.loadIndex("searchindex.js"); }); | |||||
| </script> | |||||
| <script type="text/javascript" id="searchindexloader"></script> | |||||
| </head> | |||||
| <body> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| accesskey="I">index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="document"> | |||||
| <div class="documentwrapper"> | |||||
| <div class="bodywrapper"> | |||||
| <div class="body"> | |||||
| <h1 id="search-documentation">Search</h1> | |||||
| <div id="fallback" class="admonition warning"> | |||||
| <script type="text/javascript">$('#fallback').hide();</script> | |||||
| <p> | |||||
| Please activate JavaScript to enable the search | |||||
| functionality. | |||||
| </p> | |||||
| </div> | |||||
| <p> | |||||
| From here you can search these documents. Enter your search | |||||
| words into the box below and click "search". Note that the search | |||||
| function will automatically search for all of the words. Pages | |||||
| containing fewer words won't appear in the result list. | |||||
| </p> | |||||
| <form action="" method="get"> | |||||
| <input type="text" name="q" value="" /> | |||||
| <input type="submit" value="search" /> | |||||
| <span id="search-progress" style="padding-left: 10px"></span> | |||||
| </form> | |||||
| <div id="search-results"> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="sphinxsidebar"> | |||||
| <div class="sphinxsidebarwrapper"> | |||||
| </div> | |||||
| </div> | |||||
| <div class="clearer"></div> | |||||
| </div> | |||||
| <div class="related"> | |||||
| <h3>Navigation</h3> | |||||
| <ul> | |||||
| <li class="right" style="margin-right: 10px"> | |||||
| <a href="genindex.html" title="General Index" | |||||
| >index</a></li> | |||||
| <li class="right" > | |||||
| <a href="py-modindex.html" title="Python Module Index" | |||||
| >modules</a> |</li> | |||||
| <li><a href="index.html">pyad2usb documentation</a> »</li> | |||||
| </ul> | |||||
| </div> | |||||
| <div class="footer"> | |||||
| © Copyright 2013, Author. | |||||
| Created using <a href="http://sphinx-doc.org/">Sphinx</a> 1.2b1. | |||||
| </div> | |||||
| </body> | |||||
| </html> | |||||
| @@ -0,0 +1,306 @@ | |||||
| # -*- coding: utf-8 -*- | |||||
| # | |||||
| # pyad2usb documentation build configuration file, created by | |||||
| # sphinx-quickstart on Sat Jun 8 14:38:46 2013. | |||||
| # | |||||
| # This file is execfile()d with the current directory set to its containing dir. | |||||
| # | |||||
| # Note that not all possible configuration values are present in this | |||||
| # autogenerated file. | |||||
| # | |||||
| # All configuration values have a default; values that are commented out | |||||
| # serve to show the default. | |||||
| import sys, os | |||||
| # If extensions (or modules to document with autodoc) are in another directory, | |||||
| # add these directories to sys.path here. If the directory is relative to the | |||||
| # documentation root, use os.path.abspath to make it absolute, like shown here. | |||||
| sys.path.insert(0, os.path.abspath('..')) | |||||
| # -- General configuration ----------------------------------------------------- | |||||
| # If your documentation needs a minimal Sphinx version, state it here. | |||||
| #needs_sphinx = '1.0' | |||||
| # Add any Sphinx extension module names here, as strings. They can be extensions | |||||
| # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. | |||||
| extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode'] | |||||
| # Add any paths that contain templates here, relative to this directory. | |||||
| templates_path = ['_templates'] | |||||
| # The suffix of source filenames. | |||||
| source_suffix = '.rst' | |||||
| # The encoding of source files. | |||||
| #source_encoding = 'utf-8-sig' | |||||
| # The master toctree document. | |||||
| master_doc = 'index' | |||||
| # General information about the project. | |||||
| project = u'pyad2usb' | |||||
| copyright = u'2013, Author' | |||||
| # The version info for the project you're documenting, acts as replacement for | |||||
| # |version| and |release|, also used in various other places throughout the | |||||
| # built documents. | |||||
| # | |||||
| # The short X.Y version. | |||||
| version = '' | |||||
| # The full version, including alpha/beta/rc tags. | |||||
| release = '' | |||||
| # The language for content autogenerated by Sphinx. Refer to documentation | |||||
| # for a list of supported languages. | |||||
| #language = None | |||||
| # There are two options for replacing |today|: either, you set today to some | |||||
| # non-false value, then it is used: | |||||
| #today = '' | |||||
| # Else, today_fmt is used as the format for a strftime call. | |||||
| #today_fmt = '%B %d, %Y' | |||||
| # List of patterns, relative to source directory, that match files and | |||||
| # directories to ignore when looking for source files. | |||||
| exclude_patterns = ['_build'] | |||||
| # The reST default role (used for this markup: `text`) to use for all documents. | |||||
| #default_role = None | |||||
| # If true, '()' will be appended to :func: etc. cross-reference text. | |||||
| #add_function_parentheses = True | |||||
| # If true, the current module name will be prepended to all description | |||||
| # unit titles (such as .. function::). | |||||
| #add_module_names = True | |||||
| # If true, sectionauthor and moduleauthor directives will be shown in the | |||||
| # output. They are ignored by default. | |||||
| #show_authors = False | |||||
| # The name of the Pygments (syntax highlighting) style to use. | |||||
| pygments_style = 'sphinx' | |||||
| # A list of ignored prefixes for module index sorting. | |||||
| #modindex_common_prefix = [] | |||||
| # If true, keep warnings as "system message" paragraphs in the built documents. | |||||
| #keep_warnings = False | |||||
| # -- Options for HTML output --------------------------------------------------- | |||||
| # The theme to use for HTML and HTML Help pages. See the documentation for | |||||
| # a list of builtin themes. | |||||
| html_theme = 'default' | |||||
| # Theme options are theme-specific and customize the look and feel of a theme | |||||
| # further. For a list of options available for each theme, see the | |||||
| # documentation. | |||||
| #html_theme_options = {} | |||||
| # Add any paths that contain custom themes here, relative to this directory. | |||||
| #html_theme_path = [] | |||||
| # The name for this set of Sphinx documents. If None, it defaults to | |||||
| # "<project> v<release> documentation". | |||||
| #html_title = None | |||||
| # A shorter title for the navigation bar. Default is the same as html_title. | |||||
| #html_short_title = None | |||||
| # The name of an image file (relative to this directory) to place at the top | |||||
| # of the sidebar. | |||||
| #html_logo = None | |||||
| # The name of an image file (within the static path) to use as favicon of the | |||||
| # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 | |||||
| # pixels large. | |||||
| #html_favicon = None | |||||
| # Add any paths that contain custom static files (such as style sheets) here, | |||||
| # relative to this directory. They are copied after the builtin static files, | |||||
| # so a file named "default.css" will overwrite the builtin "default.css". | |||||
| html_static_path = ['_static'] | |||||
| # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, | |||||
| # using the given strftime format. | |||||
| #html_last_updated_fmt = '%b %d, %Y' | |||||
| # If true, SmartyPants will be used to convert quotes and dashes to | |||||
| # typographically correct entities. | |||||
| #html_use_smartypants = True | |||||
| # Custom sidebar templates, maps document names to template names. | |||||
| #html_sidebars = {} | |||||
| # Additional templates that should be rendered to pages, maps page names to | |||||
| # template names. | |||||
| #html_additional_pages = {} | |||||
| # If false, no module index is generated. | |||||
| #html_domain_indices = True | |||||
| # If false, no index is generated. | |||||
| #html_use_index = True | |||||
| # If true, the index is split into individual pages for each letter. | |||||
| #html_split_index = False | |||||
| # If true, links to the reST sources are added to the pages. | |||||
| #html_show_sourcelink = True | |||||
| # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. | |||||
| #html_show_sphinx = True | |||||
| # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. | |||||
| #html_show_copyright = True | |||||
| # If true, an OpenSearch description file will be output, and all pages will | |||||
| # contain a <link> tag referring to it. The value of this option must be the | |||||
| # base URL from which the finished HTML is served. | |||||
| #html_use_opensearch = '' | |||||
| # This is the file name suffix for HTML files (e.g. ".xhtml"). | |||||
| #html_file_suffix = None | |||||
| # Output file base name for HTML help builder. | |||||
| htmlhelp_basename = 'pyad2usbdoc' | |||||
| # -- Options for LaTeX output -------------------------------------------------- | |||||
| latex_elements = { | |||||
| # The paper size ('letterpaper' or 'a4paper'). | |||||
| #'papersize': 'letterpaper', | |||||
| # The font size ('10pt', '11pt' or '12pt'). | |||||
| #'pointsize': '10pt', | |||||
| # Additional stuff for the LaTeX preamble. | |||||
| #'preamble': '', | |||||
| } | |||||
| # Grouping the document tree into LaTeX files. List of tuples | |||||
| # (source start file, target name, title, author, documentclass [howto/manual]). | |||||
| latex_documents = [ | |||||
| ('index', 'pyad2usb.tex', u'pyad2usb Documentation', | |||||
| u'Author', 'manual'), | |||||
| ] | |||||
| # The name of an image file (relative to this directory) to place at the top of | |||||
| # the title page. | |||||
| #latex_logo = None | |||||
| # For "manual" documents, if this is true, then toplevel headings are parts, | |||||
| # not chapters. | |||||
| #latex_use_parts = False | |||||
| # If true, show page references after internal links. | |||||
| #latex_show_pagerefs = False | |||||
| # If true, show URL addresses after external links. | |||||
| #latex_show_urls = False | |||||
| # Documents to append as an appendix to all manuals. | |||||
| #latex_appendices = [] | |||||
| # If false, no module index is generated. | |||||
| #latex_domain_indices = True | |||||
| # -- Options for manual page output -------------------------------------------- | |||||
| # One entry per manual page. List of tuples | |||||
| # (source start file, name, description, authors, manual section). | |||||
| man_pages = [ | |||||
| ('index', 'pyad2usb', u'pyad2usb Documentation', | |||||
| [u'Author'], 1) | |||||
| ] | |||||
| # If true, show URL addresses after external links. | |||||
| #man_show_urls = False | |||||
| # -- Options for Texinfo output ------------------------------------------------ | |||||
| # Grouping the document tree into Texinfo files. List of tuples | |||||
| # (source start file, target name, title, author, | |||||
| # dir menu entry, description, category) | |||||
| texinfo_documents = [ | |||||
| ('index', 'pyad2usb', u'pyad2usb Documentation', | |||||
| u'Author', 'pyad2usb', 'One line description of project.', | |||||
| 'Miscellaneous'), | |||||
| ] | |||||
| # Documents to append as an appendix to all manuals. | |||||
| #texinfo_appendices = [] | |||||
| # If false, no module index is generated. | |||||
| #texinfo_domain_indices = True | |||||
| # How to display URL addresses: 'footnote', 'no', or 'inline'. | |||||
| #texinfo_show_urls = 'footnote' | |||||
| # If true, do not generate a @detailmenu in the "Top" node's menu. | |||||
| #texinfo_no_detailmenu = False | |||||
| # -- Options for Epub output --------------------------------------------------- | |||||
| # Bibliographic Dublin Core info. | |||||
| epub_title = u'pyad2usb' | |||||
| epub_author = u'Author' | |||||
| epub_publisher = u'Author' | |||||
| epub_copyright = u'2013, Author' | |||||
| # The language of the text. It defaults to the language option | |||||
| # or en if the language is not set. | |||||
| #epub_language = '' | |||||
| # The scheme of the identifier. Typical schemes are ISBN or URL. | |||||
| #epub_scheme = '' | |||||
| # The unique identifier of the text. This can be a ISBN number | |||||
| # or the project homepage. | |||||
| #epub_identifier = '' | |||||
| # A unique identification for the text. | |||||
| #epub_uid = '' | |||||
| # A tuple containing the cover image and cover page html template filenames. | |||||
| #epub_cover = () | |||||
| # A sequence of (type, uri, title) tuples for the guide element of content.opf. | |||||
| #epub_guide = () | |||||
| # HTML files that should be inserted before the pages created by sphinx. | |||||
| # The format is a list of tuples containing the path and title. | |||||
| #epub_pre_files = [] | |||||
| # HTML files shat should be inserted after the pages created by sphinx. | |||||
| # The format is a list of tuples containing the path and title. | |||||
| #epub_post_files = [] | |||||
| # A list of files that should not be packed into the epub file. | |||||
| #epub_exclude_files = [] | |||||
| # The depth of the table of contents in toc.ncx. | |||||
| #epub_tocdepth = 3 | |||||
| # Allow duplicate toc entries. | |||||
| #epub_tocdup = True | |||||
| # Fix unsupported image types using the PIL. | |||||
| #epub_fix_images = False | |||||
| # Scale large images. | |||||
| #epub_max_image_width = 0 | |||||
| # If 'no', URL addresses will not be shown. | |||||
| #epub_show_urls = 'inline' | |||||
| # If false, no index is generated. | |||||
| #epub_use_index = True | |||||
| @@ -0,0 +1,23 @@ | |||||
| .. pyad2usb documentation master file, created by | |||||
| sphinx-quickstart on Sat Jun 8 14:38:46 2013. | |||||
| You can adapt this file completely to your liking, but it should at least | |||||
| contain the root `toctree` directive. | |||||
| Welcome to pyad2usb's documentation! | |||||
| ==================================== | |||||
| Contents: | |||||
| .. toctree:: | |||||
| :maxdepth: 4 | |||||
| pyad2usb | |||||
| Indices and tables | |||||
| ================== | |||||
| * :ref:`genindex` | |||||
| * :ref:`modindex` | |||||
| * :ref:`search` | |||||
| @@ -0,0 +1,242 @@ | |||||
| @ECHO OFF | |||||
| REM Command file for Sphinx documentation | |||||
| if "%SPHINXBUILD%" == "" ( | |||||
| set SPHINXBUILD=sphinx-build | |||||
| ) | |||||
| set BUILDDIR=_build | |||||
| set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . | |||||
| set I18NSPHINXOPTS=%SPHINXOPTS% . | |||||
| if NOT "%PAPER%" == "" ( | |||||
| set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% | |||||
| set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% | |||||
| ) | |||||
| if "%1" == "" goto help | |||||
| if "%1" == "help" ( | |||||
| :help | |||||
| echo.Please use `make ^<target^>` where ^<target^> is one of | |||||
| echo. html to make standalone HTML files | |||||
| echo. dirhtml to make HTML files named index.html in directories | |||||
| echo. singlehtml to make a single large HTML file | |||||
| echo. pickle to make pickle files | |||||
| echo. json to make JSON files | |||||
| echo. htmlhelp to make HTML files and a HTML help project | |||||
| echo. qthelp to make HTML files and a qthelp project | |||||
| echo. devhelp to make HTML files and a Devhelp project | |||||
| echo. epub to make an epub | |||||
| echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter | |||||
| echo. text to make text files | |||||
| echo. man to make manual pages | |||||
| echo. texinfo to make Texinfo files | |||||
| echo. gettext to make PO message catalogs | |||||
| echo. changes to make an overview over all changed/added/deprecated items | |||||
| echo. xml to make Docutils-native XML files | |||||
| echo. pseudoxml to make pseudoxml-XML files for display purposes | |||||
| echo. linkcheck to check all external links for integrity | |||||
| echo. doctest to run all doctests embedded in the documentation if enabled | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "clean" ( | |||||
| for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i | |||||
| del /q /s %BUILDDIR%\* | |||||
| goto end | |||||
| ) | |||||
| %SPHINXBUILD% 2> nul | |||||
| if errorlevel 9009 ( | |||||
| echo. | |||||
| echo.The 'sphinx-build' command was not found. Make sure you have Sphinx | |||||
| echo.installed, then set the SPHINXBUILD environment variable to point | |||||
| echo.to the full path of the 'sphinx-build' executable. Alternatively you | |||||
| echo.may add the Sphinx directory to PATH. | |||||
| echo. | |||||
| echo.If you don't have Sphinx installed, grab it from | |||||
| echo.http://sphinx-doc.org/ | |||||
| exit /b 1 | |||||
| ) | |||||
| if "%1" == "html" ( | |||||
| %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The HTML pages are in %BUILDDIR%/html. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "dirhtml" ( | |||||
| %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "singlehtml" ( | |||||
| %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "pickle" ( | |||||
| %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished; now you can process the pickle files. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "json" ( | |||||
| %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished; now you can process the JSON files. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "htmlhelp" ( | |||||
| %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished; now you can run HTML Help Workshop with the ^ | |||||
| .hhp project file in %BUILDDIR%/htmlhelp. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "qthelp" ( | |||||
| %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished; now you can run "qcollectiongenerator" with the ^ | |||||
| .qhcp project file in %BUILDDIR%/qthelp, like this: | |||||
| echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pyad2usb.qhcp | |||||
| echo.To view the help file: | |||||
| echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyad2usb.ghc | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "devhelp" ( | |||||
| %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "epub" ( | |||||
| %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The epub file is in %BUILDDIR%/epub. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "latex" ( | |||||
| %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "latexpdf" ( | |||||
| %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | |||||
| cd %BUILDDIR%/latex | |||||
| make all-pdf | |||||
| cd %BUILDDIR%/.. | |||||
| echo. | |||||
| echo.Build finished; the PDF files are in %BUILDDIR%/latex. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "latexpdfja" ( | |||||
| %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex | |||||
| cd %BUILDDIR%/latex | |||||
| make all-pdf-ja | |||||
| cd %BUILDDIR%/.. | |||||
| echo. | |||||
| echo.Build finished; the PDF files are in %BUILDDIR%/latex. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "text" ( | |||||
| %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The text files are in %BUILDDIR%/text. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "man" ( | |||||
| %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The manual pages are in %BUILDDIR%/man. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "texinfo" ( | |||||
| %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "gettext" ( | |||||
| %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The message catalogs are in %BUILDDIR%/locale. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "changes" ( | |||||
| %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.The overview file is in %BUILDDIR%/changes. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "linkcheck" ( | |||||
| %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Link check complete; look for any errors in the above output ^ | |||||
| or in %BUILDDIR%/linkcheck/output.txt. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "doctest" ( | |||||
| %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Testing of doctests in the sources finished, look at the ^ | |||||
| results in %BUILDDIR%/doctest/output.txt. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "xml" ( | |||||
| %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The XML files are in %BUILDDIR%/xml. | |||||
| goto end | |||||
| ) | |||||
| if "%1" == "pseudoxml" ( | |||||
| %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml | |||||
| if errorlevel 1 exit /b 1 | |||||
| echo. | |||||
| echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. | |||||
| goto end | |||||
| ) | |||||
| :end | |||||
| @@ -0,0 +1,7 @@ | |||||
| pyad2usb | |||||
| ======== | |||||
| .. toctree:: | |||||
| :maxdepth: 4 | |||||
| pyad2usb | |||||
| @@ -0,0 +1,19 @@ | |||||
| event Package | |||||
| ============= | |||||
| :mod:`event` Package | |||||
| -------------------- | |||||
| .. automodule:: pyad2usb.event | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`event` Module | |||||
| ------------------- | |||||
| .. automodule:: pyad2usb.event.event | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| @@ -0,0 +1,42 @@ | |||||
| pyad2usb Package | |||||
| ================ | |||||
| :mod:`pyad2usb` Package | |||||
| ----------------------- | |||||
| .. automodule:: pyad2usb.__init__ | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`ad2usb` Module | |||||
| -------------------- | |||||
| .. automodule:: pyad2usb.ad2usb | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`devices` Module | |||||
| --------------------- | |||||
| .. automodule:: pyad2usb.devices | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| :mod:`util` Module | |||||
| ------------------ | |||||
| .. automodule:: pyad2usb.util | |||||
| :members: | |||||
| :undoc-members: | |||||
| :show-inheritance: | |||||
| Subpackages | |||||
| ----------- | |||||
| .. toctree:: | |||||
| pyad2usb.event | |||||
| @@ -0,0 +1 @@ | |||||
| Subproject commit b1a341240b29750d6448ac452c611c09c238e5d6 | |||||
| @@ -2,4 +2,4 @@ | |||||
| The PyAD2USB module. | The PyAD2USB module. | ||||
| """ | """ | ||||
| __all__ = ['Overseer', 'AD2USB', 'USBDevice', 'SerialDevice', 'Firmware'] | |||||
| __all__ = ['ad2usb', 'devices', 'util'] | |||||
| @@ -5,9 +5,13 @@ Provides the full AD2USB class and factory. | |||||
| import time | import time | ||||
| import threading | import threading | ||||
| import re | import re | ||||
| import logging | |||||
| from collections import OrderedDict | |||||
| from .event import event | from .event import event | ||||
| from . import devices | from . import devices | ||||
| from . import util | from . import util | ||||
| from . import messages | |||||
| from . import zonetracking | |||||
| class Overseer(object): | class Overseer(object): | ||||
| """ | """ | ||||
| @@ -70,12 +74,6 @@ class Overseer(object): | |||||
| self.start() | self.start() | ||||
| def __del__(self): | |||||
| """ | |||||
| Destructor | |||||
| """ | |||||
| pass | |||||
| def close(self): | def close(self): | ||||
| """ | """ | ||||
| Clean up and shut down. | Clean up and shut down. | ||||
| @@ -101,7 +99,6 @@ class Overseer(object): | |||||
| """ | """ | ||||
| return Overseer.create(device) | return Overseer.create(device) | ||||
| class DetectThread(threading.Thread): | class DetectThread(threading.Thread): | ||||
| """ | """ | ||||
| Thread that handles detection of added/removed devices. | Thread that handles detection of added/removed devices. | ||||
| @@ -143,6 +140,7 @@ class Overseer(object): | |||||
| for d in removed_devices: | for d in removed_devices: | ||||
| self._overseer.on_detached(d) | self._overseer.on_detached(d) | ||||
| except util.CommError, err: | except util.CommError, err: | ||||
| pass | pass | ||||
| @@ -155,38 +153,59 @@ class AD2USB(object): | |||||
| """ | """ | ||||
| # High-level Events | # High-level Events | ||||
| on_open = event.Event('Called when the device has been opened.') | |||||
| on_close = event.Event('Called when the device has been closed.') | |||||
| on_status_changed = event.Event('Called when the panel status changes.') | |||||
| on_arm = event.Event('Called when the panel is armed.') | |||||
| on_disarm = event.Event('Called when the panel is disarmed.') | |||||
| on_power_changed = event.Event('Called when panel power switches between AC and DC.') | on_power_changed = event.Event('Called when panel power switches between AC and DC.') | ||||
| on_alarm = event.Event('Called when the alarm is triggered.') | on_alarm = event.Event('Called when the alarm is triggered.') | ||||
| on_fire = event.Event('Called when a fire is detected.') | |||||
| on_bypass = event.Event('Called when a zone is bypassed.') | on_bypass = event.Event('Called when a zone is bypassed.') | ||||
| on_boot = event.Event('Called when the device finishes bootings.') | |||||
| on_config_received = event.Event('Called when the device receives its configuration.') | |||||
| on_zone_fault = event.Event('Called when the device detects a zone fault.') | |||||
| on_zone_restore = event.Event('Called when the device detects that a fault is restored.') | |||||
| # Mid-level Events | # Mid-level Events | ||||
| on_message = event.Event('Called when a message has been received from the device.') | on_message = event.Event('Called when a message has been received from the device.') | ||||
| # Low-level Events | # Low-level Events | ||||
| on_open = event.Event('Called when the device has been opened.') | |||||
| on_close = event.Event('Called when the device has been closed.') | |||||
| on_read = event.Event('Called when a line has been read from the device.') | on_read = event.Event('Called when a line has been read from the device.') | ||||
| on_write = event.Event('Called when data has been written to the device.') | on_write = event.Event('Called when data has been written to the device.') | ||||
| # Constants | |||||
| F1 = unichr(1) + unichr(1) + unichr(1) | |||||
| F2 = unichr(2) + unichr(2) + unichr(2) | |||||
| F3 = unichr(3) + unichr(3) + unichr(3) | |||||
| F4 = unichr(4) + unichr(4) + unichr(4) | |||||
| def __init__(self, device): | def __init__(self, device): | ||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| self._device = device | |||||
| self._zonetracker = zonetracking.Zonetracker() | |||||
| self._power_status = None | self._power_status = None | ||||
| self._alarm_status = None | self._alarm_status = None | ||||
| self._bypass_status = None | self._bypass_status = None | ||||
| self._device = device | |||||
| self._armed_status = None | |||||
| self._fire_status = None | |||||
| self._address_mask = 0xFF80 # TEMP | |||||
| self.address = 18 | |||||
| self.configbits = 0xFF00 | |||||
| self.address_mask = 0x00000000 | |||||
| self.emulate_zone = [False for x in range(5)] | |||||
| self.emulate_relay = [False for x in range(4)] | |||||
| self.emulate_lrr = False | |||||
| self.deduplicate = False | |||||
| def __del__(self): | |||||
| @property | |||||
| def id(self): | |||||
| """ | """ | ||||
| Destructor | |||||
| The ID of the AD2USB device. | |||||
| """ | """ | ||||
| pass | |||||
| return self._device.id | |||||
| def open(self, baudrate=None, interface=None, index=None, no_reader_thread=False): | def open(self, baudrate=None, interface=None, index=None, no_reader_thread=False): | ||||
| """ | """ | ||||
| @@ -200,594 +219,227 @@ class AD2USB(object): | |||||
| Closes the device. | Closes the device. | ||||
| """ | """ | ||||
| self._device.close() | self._device.close() | ||||
| del self._device | |||||
| self._device = None | self._device = None | ||||
| @property | |||||
| def id(self): | |||||
| return self._device.id | |||||
| def _wire_events(self): | |||||
| """ | |||||
| Wires up the internal device events. | |||||
| """ | |||||
| self._device.on_open += self._on_open | |||||
| self._device.on_close += self._on_close | |||||
| self._device.on_read += self._on_read | |||||
| self._device.on_write += self._on_write | |||||
| def _handle_message(self, data): | |||||
| """ | |||||
| Parses messages from the panel. | |||||
| """ | |||||
| msg = None | |||||
| if data[0] != '!': | |||||
| msg = Message(data) | |||||
| if self._address_mask & msg.mask > 0: | |||||
| self._update_internal_states(msg) | |||||
| else: # specialty messages | |||||
| header = data[0:4] | |||||
| if header == '!EXP' or header == '!REL': | |||||
| msg = ExpanderMessage(data) | |||||
| elif header == '!RFX': | |||||
| msg = RFMessage(data) | |||||
| return msg | |||||
| def _update_internal_states(self, message): | |||||
| if message.ac_power != self._power_status: | |||||
| self._power_status, old_status = message.ac_power, self._power_status | |||||
| if old_status is not None: | |||||
| self.on_power_changed(self._power_status) | |||||
| if message.alarm_sounding != self._alarm_status: | |||||
| self._alarm_status, old_status = message.alarm_sounding, self._alarm_status | |||||
| if old_status is not None: | |||||
| self.on_alarm(self._alarm_status) | |||||
| if message.zone_bypassed != self._bypass_status: | |||||
| self._bypass_status, old_status = message.zone_bypassed, self._bypass_status | |||||
| if old_status is not None: | |||||
| self.on_bypass(self._bypass_status) | |||||
| def _on_open(self, sender, args): | |||||
| """ | |||||
| Internal handler for opening the device. | |||||
| """ | |||||
| self.on_open(args) | |||||
| def _on_close(self, sender, args): | |||||
| """ | |||||
| Internal handler for closing the device. | |||||
| """ | |||||
| self.on_close(args) | |||||
| def _on_read(self, sender, args): | |||||
| """ | |||||
| Internal handler for reading from the device. | |||||
| """ | |||||
| self.on_read(args) | |||||
| msg = self._handle_message(args) | |||||
| if msg: | |||||
| self.on_message(msg) | |||||
| def _on_write(self, sender, args): | |||||
| """ | |||||
| Internal handler for writing to the device. | |||||
| """ | |||||
| self.on_write(args) | |||||
| class Message(object): | |||||
| """ | |||||
| Represents a message from the alarm panel. | |||||
| """ | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self._ready = False | |||||
| self._armed_away = False | |||||
| self._armed_home = False | |||||
| self._backlight_on = False | |||||
| self._programming_mode = False | |||||
| self._beeps = -1 | |||||
| self._zone_bypassed = False | |||||
| self._ac_power = False | |||||
| self._chime_on = False | |||||
| self._alarm_event_occurred = False | |||||
| self._alarm_sounding = False | |||||
| self._numeric_code = "" | |||||
| self._text = "" | |||||
| self._cursor_location = -1 | |||||
| self._data = "" | |||||
| self._mask = "" | |||||
| self._bitfield = "" | |||||
| self._panel_data = "" | |||||
| self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)') | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| def _parse_message(self, data): | |||||
| """ | |||||
| Parse the message from the device. | |||||
| """ | |||||
| m = self._regex.match(data) | |||||
| if m is None: | |||||
| raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) | |||||
| self._bitfield, self._numeric_code, self._panel_data, alpha = m.group(1, 2, 3, 4) | |||||
| self._mask = int(self._panel_data[3:3+8], 16) | |||||
| self._data = data | |||||
| self._ready = not self._bitfield[1:2] == "0" | |||||
| self._armed_away = not self._bitfield[2:3] == "0" | |||||
| self._armed_home = not self._bitfield[3:4] == "0" | |||||
| self._backlight_on = not self._bitfield[4:5] == "0" | |||||
| self._programming_mode = not self._bitfield[5:6] == "0" | |||||
| self._beeps = int(self._bitfield[6:7], 16) | |||||
| self._zone_bypassed = not self._bitfield[7:8] == "0" | |||||
| self._ac_power = not self._bitfield[8:9] == "0" | |||||
| self._chime_on = not self._bitfield[9:10] == "0" | |||||
| self._alarm_event_occurred = not self._bitfield[10:11] == "0" | |||||
| self._alarm_sounding = not self._bitfield[11:12] == "0" | |||||
| self._text = alpha.strip('"') | |||||
| if int(self._panel_data[19:21], 16) & 0x01 > 0: | |||||
| self._cursor_location = int(self._bitfield[21:23], 16) # Alpha character index that the cursor is on. | |||||
| def __str__(self): | |||||
| """ | |||||
| String conversion operator. | |||||
| """ | |||||
| return 'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'.format(hex(self.mask), 1 if self.ready else 0, 1 if self.armed_away else 0, 1 if self.armed_home else 0, self.numeric_code, self.text) | |||||
| @property | |||||
| def ready(self): | |||||
| """ | |||||
| Indicates whether or not the panel is ready. | |||||
| """ | |||||
| return self._ready | |||||
| @ready.setter | |||||
| def ready(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is ready. | |||||
| """ | |||||
| self._ready = value | |||||
| @property | |||||
| def armed_away(self): | |||||
| """ | |||||
| Indicates whether or not the panel is armed in away mode. | |||||
| """ | |||||
| return self._armed_away | |||||
| @armed_away.setter | |||||
| def armed_away(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is armed in away mode. | |||||
| """ | |||||
| self._armed_away = value | |||||
| @property | |||||
| def armed_home(self): | |||||
| """ | |||||
| Indicates whether or not the panel is armed in home/stay mode. | |||||
| """ | |||||
| return self._armed_home | |||||
| @armed_home.setter | |||||
| def armed_home(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is armed in home/stay mode. | |||||
| """ | |||||
| self._armed_home = value | |||||
| @property | |||||
| def backlight_on(self): | |||||
| """ | |||||
| Indicates whether or not the panel backlight is on. | |||||
| """ | |||||
| return self._backlight_on | |||||
| @backlight_on.setter | |||||
| def backlight_on(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel backlight is on. | |||||
| """ | |||||
| self._backlight_on = value | |||||
| @property | |||||
| def programming_mode(self): | |||||
| """ | |||||
| Indicates whether or not the panel is in programming mode. | |||||
| """ | |||||
| return self._programming_mode | |||||
| @programming_mode.setter | |||||
| def programming_mode(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is in programming mode. | |||||
| """ | |||||
| self._programming_mode = value | |||||
| @property | |||||
| def beeps(self): | |||||
| """ | |||||
| Returns the number of beeps associated with this message. | |||||
| """ | |||||
| return self._beeps | |||||
| @beeps.setter | |||||
| def beeps(self, value): | |||||
| """ | |||||
| Sets the number of beeps associated with this message. | |||||
| """ | |||||
| self._beeps = value | |||||
| @property | |||||
| def zone_bypassed(self): | |||||
| def get_config(self): | |||||
| """ | """ | ||||
| Indicates whether or not zones have been bypassed. | |||||
| Retrieves the configuration from the device. | |||||
| """ | """ | ||||
| return self._zone_bypassed | |||||
| self._device.write("C\r") | |||||
| @zone_bypassed.setter | |||||
| def zone_bypassed(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not zones have been bypassed. | |||||
| """ | |||||
| self._zone_bypassed = value | |||||
| @property | |||||
| def ac_power(self): | |||||
| def save_config(self): | |||||
| """ | """ | ||||
| Indicates whether or not the system is on AC power. | |||||
| Sets configuration entries on the device. | |||||
| """ | """ | ||||
| return self._ac_power | |||||
| config_string = '' | |||||
| @ac_power.setter | |||||
| def ac_power(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the system is on AC power. | |||||
| """ | |||||
| self._ac_power = value | |||||
| @property | |||||
| def chime_on(self): | |||||
| """ | |||||
| Indicates whether or not panel chimes are enabled. | |||||
| """ | |||||
| return self._chime_on | |||||
| @chime_on.setter | |||||
| def chime_on(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel chimes are enabled. | |||||
| """ | |||||
| self._chime_on = value | |||||
| @property | |||||
| def alarm_event_occurred(self): | |||||
| """ | |||||
| Indicates whether or not an alarm event has occurred. | |||||
| """ | |||||
| return self._alarm_event_occurred | |||||
| # HACK: Both of these methods are ugly.. but I can't think of an elegant way of doing it. | |||||
| @alarm_event_occurred.setter | |||||
| def alarm_event_occurred(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not an alarm event has occurred. | |||||
| """ | |||||
| self._alarm_event_occurred = value | |||||
| #config_string += 'ADDRESS={0}&'.format(self.address) | |||||
| #config_string += 'CONFIGBITS={0:x}&'.format(self.configbits) | |||||
| #config_string += 'MASK={0:x}&'.format(self.address_mask) | |||||
| #config_string += 'EXP={0}&'.format(''.join(['Y' if z else 'N' for z in self.emulate_zone])) | |||||
| #config_string += 'REL={0}&'.format(''.join(['Y' if r else 'N' for r in self.emulate_relay])) | |||||
| #config_string += 'LRR={0}&'.format('Y' if self.emulate_lrr else 'N') | |||||
| #config_string += 'DEDUPLICATE={0}'.format('Y' if self.deduplicate else 'N') | |||||
| @property | |||||
| def alarm_sounding(self): | |||||
| """ | |||||
| Indicates whether or not an alarm is currently sounding. | |||||
| """ | |||||
| return self._alarm_sounding | |||||
| config_entries = [] | |||||
| config_entries.append(('ADDRESS', '{0}'.format(self.address))) | |||||
| config_entries.append(('CONFIGBITS', '{0:x}'.format(self.configbits))) | |||||
| config_entries.append(('MASK', '{0:x}'.format(self.address_mask))) | |||||
| config_entries.append(('EXP', ''.join(['Y' if z else 'N' for z in self.emulate_zone]))) | |||||
| config_entries.append(('REL', ''.join(['Y' if r else 'N' for r in self.emulate_relay]))) | |||||
| config_entries.append(('LRR', 'Y' if self.emulate_lrr else 'N')) | |||||
| config_entries.append(('DEDUPLICATE', 'Y' if self.deduplicate else 'N')) | |||||
| @alarm_sounding.setter | |||||
| def alarm_sounding(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not an alarm is currently sounding. | |||||
| """ | |||||
| self._alarm_sounding = value | |||||
| config_string = '&'.join(['='.join(t) for t in config_entries]) | |||||
| @property | |||||
| def numeric_code(self): | |||||
| """ | |||||
| Numeric indicator of associated with message. For example: If zone #3 is faulted, this value is 003. | |||||
| """ | |||||
| return self._numeric_code | |||||
| self._device.write("C{0}\r".format(config_string)) | |||||
| @numeric_code.setter | |||||
| def numeric_code(self, value): | |||||
| def reboot(self): | |||||
| """ | """ | ||||
| Sets the numeric indicator associated with this message. | |||||
| Reboots the device. | |||||
| """ | """ | ||||
| self._numeric_code = value | |||||
| self._device.write('=') | |||||
| @property | |||||
| def text(self): | |||||
| def fault_zone(self, zone, simulate_wire_problem=False): | |||||
| """ | """ | ||||
| Alphanumeric text associated with this message. | |||||
| Faults a zone if we are emulating a zone expander. | |||||
| """ | """ | ||||
| return self._text | |||||
| # Allow ourselves to also be passed an address/channel combination | |||||
| # for zone expanders. | |||||
| # | |||||
| # Format (expander index, channel) | |||||
| if isinstance(zone, tuple): | |||||
| zone = self._zonetracker._expander_to_zone(*zone) | |||||
| @text.setter | |||||
| def text(self, value): | |||||
| """ | |||||
| Sets the alphanumeric text associated with this message. | |||||
| """ | |||||
| self._text = value | |||||
| status = 2 if simulate_wire_problem else 1 | |||||
| @property | |||||
| def cursor_location(self): | |||||
| """ | |||||
| Indicates which text position has the cursor underneath it. | |||||
| """ | |||||
| return self._cursor_location | |||||
| self._device.write("L{0:02}{1}\r".format(zone, status)) | |||||
| @cursor_location.setter | |||||
| def cursor_location(self, value): | |||||
| def clear_zone(self, zone): | |||||
| """ | """ | ||||
| Sets the value indicating which text position has the cursor underneath it. | |||||
| Clears a zone if we are emulating a zone expander. | |||||
| """ | """ | ||||
| self._cursor_location = value | |||||
| self._device.write("L{0:02}0\r".format(zone)) | |||||
| @property | |||||
| def data(self): | |||||
| """ | |||||
| Raw representation of the message from the panel. | |||||
| """ | |||||
| return self._data | |||||
| @data.setter | |||||
| def data(self, value): | |||||
| """ | |||||
| Sets the raw representation of the message from the panel. | |||||
| """ | |||||
| self._data = value | |||||
| @property | |||||
| def mask(self): | |||||
| """ | |||||
| The panel mask for which this message is intended. | |||||
| """ | |||||
| return self._mask | |||||
| @mask.setter | |||||
| def mask(self, value): | |||||
| """ | |||||
| Sets the panel mask for which this message is intended. | |||||
| """ | |||||
| self._mask = value | |||||
| @property | |||||
| def bitfield(self): | |||||
| def _wire_events(self): | |||||
| """ | """ | ||||
| The bit field associated with this message. | |||||
| Wires up the internal device events. | |||||
| """ | """ | ||||
| return self._bitfield | |||||
| self._device.on_open += self._on_open | |||||
| self._device.on_close += self._on_close | |||||
| self._device.on_read += self._on_read | |||||
| self._device.on_write += self._on_write | |||||
| self._zonetracker.on_fault += self._on_zone_fault | |||||
| self._zonetracker.on_restore += self._on_zone_restore | |||||
| @bitfield.setter | |||||
| def bitfield(self, value): | |||||
| def _handle_message(self, data): | |||||
| """ | """ | ||||
| Sets the bit field associated with this message. | |||||
| Parses messages from the panel. | |||||
| """ | """ | ||||
| self._bitfield = value | |||||
| if data is None: | |||||
| return None | |||||
| @property | |||||
| def panel_data(self): | |||||
| """ | |||||
| The binary field associated with this message. | |||||
| """ | |||||
| return self._panel_data | |||||
| msg = None | |||||
| @panel_data.setter | |||||
| def panel_data(self, value): | |||||
| """ | |||||
| Sets the binary field associated with this message. | |||||
| """ | |||||
| self._panel_data = value | |||||
| if data[0] != '!': | |||||
| msg = messages.Message(data) | |||||
| class ExpanderMessage(object): | |||||
| """ | |||||
| Represents a message from a zone or relay expansion module. | |||||
| """ | |||||
| ZONE = 0 | |||||
| RELAY = 1 | |||||
| if self.address_mask & msg.mask > 0: | |||||
| self._update_internal_states(msg) | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self._type = None | |||||
| self._address = None | |||||
| self._channel = None | |||||
| self._value = None | |||||
| self._raw = None | |||||
| else: # specialty messages | |||||
| header = data[0:4] | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| if header == '!EXP' or header == '!REL': | |||||
| msg = messages.ExpanderMessage(data) | |||||
| self._update_internal_states(msg) | |||||
| elif header == '!RFX': | |||||
| msg = messages.RFMessage(data) | |||||
| elif header == '!LRR': | |||||
| msg = messages.LRRMessage(data) | |||||
| elif data.startswith('!Ready'): | |||||
| self.on_boot() | |||||
| elif data.startswith('!CONFIG'): | |||||
| self._handle_config(data) | |||||
| def __str__(self): | |||||
| """ | |||||
| String conversion operator. | |||||
| """ | |||||
| expander_type = 'UNKWN' | |||||
| if self.type == ExpanderMessage.ZONE: | |||||
| expander_type = 'ZONE' | |||||
| elif self.type == ExpanderMessage.RELAY: | |||||
| expander_type = 'RELAY' | |||||
| return msg | |||||
| return 'exp > [{0: <5}] {1}/{2} -- {3}'.format(expander_type, self.address, self.channel, self.value) | |||||
| def _handle_config(self, data): | |||||
| """ | |||||
| Handles received configuration data. | |||||
| """ | |||||
| _, config_string = data.split('>') | |||||
| for setting in config_string.split('&'): | |||||
| k, v = setting.split('=') | |||||
| if k == 'ADDRESS': | |||||
| self.address = int(v) | |||||
| elif k == 'CONFIGBITS': | |||||
| self.configbits = int(v, 16) | |||||
| elif k == 'MASK': | |||||
| self.address_mask = int(v, 16) | |||||
| elif k == 'EXP': | |||||
| for z in range(5): | |||||
| self.emulate_zone[z] = True if v[z] == 'Y' else False | |||||
| elif k == 'REL': | |||||
| for r in range(4): | |||||
| self.emulate_relay[r] = True if v[r] == 'Y' else False | |||||
| elif k == 'LRR': | |||||
| self.emulate_lrr = True if v == 'Y' else False | |||||
| elif k == 'DEDUPLICATE': | |||||
| self.deduplicate = True if v == 'Y' else False | |||||
| self.on_config_received() | |||||
| def _parse_message(self, data): | |||||
| def _update_internal_states(self, message): | |||||
| """ | """ | ||||
| Parse the raw message from the device. | |||||
| Updates internal device states. | |||||
| """ | """ | ||||
| header, values = data.split(':') | |||||
| address, channel, value = values.split(',') | |||||
| if isinstance(message, messages.Message): | |||||
| if message.ac_power != self._power_status: | |||||
| self._power_status, old_status = message.ac_power, self._power_status | |||||
| self.raw = data | |||||
| self.address = address | |||||
| self.channel = channel | |||||
| self.value = value | |||||
| if old_status is not None: | |||||
| self.on_power_changed(self._power_status) | |||||
| if header == '!EXP': | |||||
| self.type = ExpanderMessage.ZONE | |||||
| elif header == '!REL': | |||||
| self.type = ExpanderMessage.RELAY | |||||
| if message.alarm_sounding != self._alarm_status: | |||||
| self._alarm_status, old_status = message.alarm_sounding, self._alarm_status | |||||
| @property | |||||
| def address(self): | |||||
| """ | |||||
| The relay address from which the message originated. | |||||
| """ | |||||
| return self._address | |||||
| if old_status is not None: | |||||
| self.on_alarm(self._alarm_status) | |||||
| @address.setter | |||||
| def address(self, value): | |||||
| """ | |||||
| Sets the relay address from which the message originated. | |||||
| """ | |||||
| self._address = value | |||||
| if message.zone_bypassed != self._bypass_status: | |||||
| self._bypass_status, old_status = message.zone_bypassed, self._bypass_status | |||||
| @property | |||||
| def channel(self): | |||||
| """ | |||||
| The zone expander channel from which the message originated. | |||||
| """ | |||||
| return self._channel | |||||
| @channel.setter | |||||
| def channel(self, value): | |||||
| """ | |||||
| Sets the zone expander channel from which the message originated. | |||||
| """ | |||||
| self._channel = value | |||||
| @property | |||||
| def value(self): | |||||
| """ | |||||
| The value associated with the message. | |||||
| """ | |||||
| return self._value | |||||
| if old_status is not None: | |||||
| self.on_bypass(self._bypass_status) | |||||
| @value.setter | |||||
| def value(self, value): | |||||
| """ | |||||
| Sets the value associated with the message. | |||||
| """ | |||||
| self._value = value | |||||
| if (message.armed_away | message.armed_home) != self._armed_status: | |||||
| self._armed_status, old_status = message.armed_away | message.armed_home, self._armed_status | |||||
| @property | |||||
| def raw(self): | |||||
| """ | |||||
| The raw message from the expander device. | |||||
| """ | |||||
| return self._raw | |||||
| if old_status is not None: | |||||
| if self._armed_status: | |||||
| self.on_arm() | |||||
| else: | |||||
| self.on_disarm() | |||||
| @raw.setter | |||||
| def raw(self, value): | |||||
| """ | |||||
| Sets the raw message from the expander device. | |||||
| """ | |||||
| self._value = value | |||||
| if message.fire_alarm != self._fire_status: | |||||
| self._fire_status, old_status = message.fire_alarm, self._fire_status | |||||
| @property | |||||
| def type(self): | |||||
| """ | |||||
| The type of expander associated with this message. | |||||
| """ | |||||
| return self._type | |||||
| if old_status is not None: | |||||
| self.on_fire(self._fire_status) | |||||
| @type.setter | |||||
| def type(self, value): | |||||
| """ | |||||
| Sets the type of expander associated with this message. | |||||
| """ | |||||
| self._type = value | |||||
| self._update_zone_tracker(message) | |||||
| class RFMessage(object): | |||||
| """ | |||||
| Represents a message from an RF receiver. | |||||
| """ | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self._raw = None | |||||
| self._serial_number = None | |||||
| self._value = None | |||||
| def _update_zone_tracker(self, message): | |||||
| # Retrieve a list of faults. | |||||
| # NOTE: This only happens on first boot or after exiting programming mode. | |||||
| if isinstance(message, messages.Message): | |||||
| if not message.ready and "Hit * for faults" in message.text: | |||||
| self._device.write('*') | |||||
| return | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| self._zonetracker.update(message) | |||||
| def __str__(self): | |||||
| def _on_open(self, sender, args): | |||||
| """ | """ | ||||
| String conversion operator. | |||||
| Internal handler for opening the device. | |||||
| """ | """ | ||||
| return 'rf > {0}: {1}'.format(self.serial_number, self.value) | |||||
| self.on_open(args) | |||||
| def _parse_message(self, data): | |||||
| def _on_close(self, sender, args): | |||||
| """ | """ | ||||
| Parses the raw message from the device. | |||||
| Internal handler for closing the device. | |||||
| """ | """ | ||||
| self.raw = data | |||||
| _, values = data.split(':') | |||||
| self.serial_number, self.value = values.split(',') | |||||
| self.on_close(args) | |||||
| @property | |||||
| def serial_number(self): | |||||
| def _on_read(self, sender, args): | |||||
| """ | """ | ||||
| The serial number for the RF receiver. | |||||
| Internal handler for reading from the device. | |||||
| """ | """ | ||||
| return self._serial_number | |||||
| @serial_number.setter | |||||
| def serial_number(self, value): | |||||
| self._serial_number = value | |||||
| self.on_read(args) | |||||
| @property | |||||
| def value(self): | |||||
| """ | |||||
| The value of the RF message. | |||||
| """ | |||||
| return self._value | |||||
| msg = self._handle_message(args) | |||||
| if msg: | |||||
| self.on_message(msg) | |||||
| @value.setter | |||||
| def value(self, value): | |||||
| def _on_write(self, sender, args): | |||||
| """ | """ | ||||
| Sets the value of the RF message. | |||||
| Internal handler for writing to the device. | |||||
| """ | """ | ||||
| self._value = value | |||||
| self.on_write(args) | |||||
| @property | |||||
| def raw(self): | |||||
| def _on_zone_fault(self, sender, args): | |||||
| """ | """ | ||||
| The raw message from the RF receiver. | |||||
| Internal handler for zone faults. | |||||
| """ | """ | ||||
| return self._raw | |||||
| self.on_zone_fault(args) | |||||
| @raw.setter | |||||
| def raw(self, value): | |||||
| def _on_zone_restore(self, sender, args): | |||||
| """ | """ | ||||
| Sets the raw message from the RF receiver. | |||||
| Internal handler for zone restoration. | |||||
| """ | """ | ||||
| self._raw = value | |||||
| self.on_zone_restore(args) | |||||
| @@ -9,7 +9,6 @@ import threading | |||||
| import serial | import serial | ||||
| import serial.tools.list_ports | import serial.tools.list_ports | ||||
| import socket | import socket | ||||
| import traceback | |||||
| from pyftdi.pyftdi.ftdi import * | from pyftdi.pyftdi.ftdi import * | ||||
| from pyftdi.pyftdi.usbtools import * | from pyftdi.pyftdi.usbtools import * | ||||
| from . import util | from . import util | ||||
| @@ -27,16 +26,49 @@ class Device(object): | |||||
| on_write = event.Event('Called when data has been written to the device') | on_write = event.Event('Called when data has been written to the device') | ||||
| def __init__(self): | def __init__(self): | ||||
| pass | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self._id = '' | |||||
| self._buffer = '' | |||||
| self._interface = None | |||||
| self._device = None | |||||
| self._running = False | |||||
| self._read_thread = Device.ReadThread(self) | |||||
| @property | |||||
| def id(self): | |||||
| """ | |||||
| Retrieve the device ID. | |||||
| """ | |||||
| return self._id | |||||
| @id.setter | |||||
| def id(self, value): | |||||
| """ | |||||
| Sets the device ID. | |||||
| """ | |||||
| self._id = value | |||||
| def is_reader_alive(self): | |||||
| """ | |||||
| Indicates whether or not the reader thread is alive. | |||||
| """ | |||||
| return self._read_thread.is_alive() | |||||
| def __del__(self): | |||||
| pass | |||||
| def stop_reader(self): | |||||
| """ | |||||
| Stops the reader thread. | |||||
| """ | |||||
| self._read_thread.stop() | |||||
| class ReadThread(threading.Thread): | class ReadThread(threading.Thread): | ||||
| """ | """ | ||||
| Reader thread which processes messages from the device. | Reader thread which processes messages from the device. | ||||
| """ | """ | ||||
| READ_TIMEOUT = 10 | |||||
| def __init__(self, device): | def __init__(self, device): | ||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| @@ -59,9 +91,8 @@ class Device(object): | |||||
| while self._running: | while self._running: | ||||
| try: | try: | ||||
| self._device.read_line(timeout=10) | |||||
| except util.CommError, err: | |||||
| traceback.print_exc(err) # TEMP | |||||
| self._device.read_line(timeout=self.READ_TIMEOUT) | |||||
| except util.TimeoutError, err: | except util.TimeoutError, err: | ||||
| pass | pass | ||||
| @@ -82,11 +113,11 @@ class USBDevice(Device): | |||||
| """ | """ | ||||
| Returns all FTDI devices matching our vendor and product IDs. | Returns all FTDI devices matching our vendor and product IDs. | ||||
| """ | """ | ||||
| devices = [] | devices = [] | ||||
| try: | try: | ||||
| devices = Ftdi.find_all([(USBDevice.FTDI_VENDOR_ID, USBDevice.FTDI_PRODUCT_ID)], nocache=True) | devices = Ftdi.find_all([(USBDevice.FTDI_VENDOR_ID, USBDevice.FTDI_PRODUCT_ID)], nocache=True) | ||||
| except (usb.core.USBError, FtdiError), err: | except (usb.core.USBError, FtdiError), err: | ||||
| raise util.CommError('Error enumerating AD2USB devices: {0}'.format(str(err))) | raise util.CommError('Error enumerating AD2USB devices: {0}'.format(str(err))) | ||||
| @@ -96,20 +127,14 @@ class USBDevice(Device): | |||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| Device.__init__(self) | Device.__init__(self) | ||||
| self._device = Ftdi() | |||||
| self._interface = interface | |||||
| self._vendor_id = vid | self._vendor_id = vid | ||||
| self._product_id = pid | self._product_id = pid | ||||
| self._serial_number = serial | self._serial_number = serial | ||||
| self._description = description | self._description = description | ||||
| self._buffer = '' | |||||
| self._device = Ftdi() | |||||
| self._running = False | |||||
| self._interface = interface | |||||
| self._id = '' | |||||
| self._read_thread = Device.ReadThread(self) | |||||
| def open(self, baudrate=BAUDRATE, interface=None, index=0, no_reader_thread=False): | def open(self, baudrate=BAUDRATE, interface=None, index=0, no_reader_thread=False): | ||||
| """ | """ | ||||
| @@ -140,10 +165,10 @@ class USBDevice(Device): | |||||
| self._device.set_baudrate(baudrate) | self._device.set_baudrate(baudrate) | ||||
| self._id = 'USB {0}:{1}'.format(self._device.usb_dev.bus, self._device.usb_dev.address) | self._id = 'USB {0}:{1}'.format(self._device.usb_dev.bus, self._device.usb_dev.address) | ||||
| except (usb.core.USBError, FtdiError), err: | except (usb.core.USBError, FtdiError), err: | ||||
| self.on_close() | |||||
| raise util.NoDeviceError('Error opening device: {0}'.format(str(err))) | |||||
| raise util.CommError('Error opening AD2USB device: {0}'.format(str(err))) | |||||
| else: | else: | ||||
| self._running = True | self._running = True | ||||
| if not no_reader_thread: | if not no_reader_thread: | ||||
| @@ -163,27 +188,12 @@ class USBDevice(Device): | |||||
| # HACK: Probably should fork pyftdi and make this call in .close(). | # HACK: Probably should fork pyftdi and make this call in .close(). | ||||
| self._device.usb_dev.attach_kernel_driver(self._interface) | self._device.usb_dev.attach_kernel_driver(self._interface) | ||||
| except (FtdiError, usb.core.USBError): | |||||
| except: | |||||
| pass | pass | ||||
| self.on_close() | self.on_close() | ||||
| @property | |||||
| def id(self): | |||||
| return self._id | |||||
| def is_reader_alive(self): | |||||
| """ | |||||
| Indicates whether or not the reader thread is alive. | |||||
| """ | |||||
| return self._read_thread.is_alive() | |||||
| def stop_reader(self): | |||||
| """ | |||||
| Stops the reader thread. | |||||
| """ | |||||
| self._read_thread.stop() | |||||
| def write(self, data): | def write(self, data): | ||||
| """ | """ | ||||
| Writes data to the device. | Writes data to the device. | ||||
| @@ -193,13 +203,21 @@ class USBDevice(Device): | |||||
| self.on_write(data) | self.on_write(data) | ||||
| except FtdiError, err: | except FtdiError, err: | ||||
| raise util.CommError('Error writing to AD2USB device.') | |||||
| raise util.CommError('Error writing to device: {0}'.format(str(err))) | |||||
| def read(self): | def read(self): | ||||
| """ | """ | ||||
| Reads a single character from the device. | Reads a single character from the device. | ||||
| """ | """ | ||||
| return self._device.read_data(1) | |||||
| ret = None | |||||
| try: | |||||
| ret = self._device.read_data(1) | |||||
| except (usb.core.USBError, FtdiError), err: | |||||
| raise util.CommError('Error reading from device: {0}'.format(str(err))) | |||||
| return ret | |||||
| def read_line(self, timeout=0.0, purge_buffer=False): | def read_line(self, timeout=0.0, purge_buffer=False): | ||||
| """ | """ | ||||
| @@ -244,7 +262,8 @@ class USBDevice(Device): | |||||
| except (usb.core.USBError, FtdiError), err: | except (usb.core.USBError, FtdiError), err: | ||||
| timer.cancel() | timer.cancel() | ||||
| raise util.CommError('Error reading from AD2USB device: {0}'.format(str(err))) | |||||
| raise util.CommError('Error reading from device: {0}'.format(str(err))) | |||||
| else: | else: | ||||
| if got_line: | if got_line: | ||||
| ret = self._buffer | ret = self._buffer | ||||
| @@ -281,8 +300,9 @@ class SerialDevice(Device): | |||||
| devices = serial.tools.list_ports.grep(pattern) | devices = serial.tools.list_ports.grep(pattern) | ||||
| else: | else: | ||||
| devices = serial.tools.list_ports.comports() | devices = serial.tools.list_ports.comports() | ||||
| except Exception, err: | |||||
| raise util.CommError('Error enumerating AD2SERIAL devices: {0}'.format(str(err))) | |||||
| except SerialException, err: | |||||
| raise util.CommError('Error enumerating serial devices: {0}'.format(str(err))) | |||||
| return devices | return devices | ||||
| @@ -292,18 +312,9 @@ class SerialDevice(Device): | |||||
| """ | """ | ||||
| Device.__init__(self) | Device.__init__(self) | ||||
| self._device = serial.Serial(timeout=0, writeTimeout=0) # Timeout = non-blocking to match pyftdi. | |||||
| self._read_thread = Device.ReadThread(self) | |||||
| self._buffer = '' | |||||
| self._running = False | |||||
| self._interface = interface | self._interface = interface | ||||
| self._id = interface | self._id = interface | ||||
| def __del__(self): | |||||
| """ | |||||
| Destructor | |||||
| """ | |||||
| pass | |||||
| self._device = serial.Serial(timeout=0, writeTimeout=0) # Timeout = non-blocking to match pyftdi. | |||||
| def open(self, baudrate=BAUDRATE, interface=None, index=None, no_reader_thread=False): | def open(self, baudrate=BAUDRATE, interface=None, index=None, no_reader_thread=False): | ||||
| """ | """ | ||||
| @@ -314,7 +325,7 @@ class SerialDevice(Device): | |||||
| baudrate = SerialDevice.BAUDRATE | baudrate = SerialDevice.BAUDRATE | ||||
| if self._interface is None and interface is None: | if self._interface is None and interface is None: | ||||
| raise util.NoDeviceError('No AD2SERIAL device interface specified.') | |||||
| raise util.NoDeviceError('No device interface specified.') | |||||
| if interface is not None: | if interface is not None: | ||||
| self._interface = interface | self._interface = interface | ||||
| @@ -330,15 +341,13 @@ class SerialDevice(Device): | |||||
| # | # | ||||
| # Moving it to this point seems to resolve | # Moving it to this point seems to resolve | ||||
| # all issues with it. | # all issues with it. | ||||
| self._id = '{0}'.format(self._interface) | |||||
| except (serial.SerialException, ValueError), err: | except (serial.SerialException, ValueError), err: | ||||
| self.on_close() | |||||
| raise util.NoDeviceError('Error opening device on port {0}.'.format(interface)) | |||||
| raise util.NoDeviceError('Error opening AD2SERIAL device on port {0}.'.format(interface)) | |||||
| else: | else: | ||||
| self._running = True | self._running = True | ||||
| self.on_open((None, "AD2SERIAL")) # TODO: Fixme. | |||||
| self.on_open(('N/A', "AD2SERIAL")) | |||||
| if not no_reader_thread: | if not no_reader_thread: | ||||
| self._read_thread.start() | self._read_thread.start() | ||||
| @@ -352,37 +361,25 @@ class SerialDevice(Device): | |||||
| self._read_thread.stop() | self._read_thread.stop() | ||||
| self._device.close() | self._device.close() | ||||
| except Exception, err: | |||||
| except: | |||||
| pass | pass | ||||
| self.on_close() | self.on_close() | ||||
| @property | |||||
| def id(self): | |||||
| return self._id | |||||
| def is_reader_alive(self): | |||||
| """ | |||||
| Indicates whether or not the reader thread is alive. | |||||
| """ | |||||
| return self._read_thread.is_alive() | |||||
| def stop_reader(self): | |||||
| """ | |||||
| Stops the reader thread. | |||||
| """ | |||||
| self._read_thread.stop() | |||||
| def write(self, data): | def write(self, data): | ||||
| """ | """ | ||||
| Writes data to the device. | Writes data to the device. | ||||
| """ | """ | ||||
| try: | try: | ||||
| self._device.write(data) | self._device.write(data) | ||||
| except serial.SerialTimeoutException, err: | except serial.SerialTimeoutException, err: | ||||
| pass | pass | ||||
| except serial.SerialException, err: | except serial.SerialException, err: | ||||
| raise util.CommError('Error writing to serial device.') | |||||
| raise util.CommError('Error writing to device.') | |||||
| else: | else: | ||||
| self.on_write(data) | self.on_write(data) | ||||
| @@ -390,15 +387,20 @@ class SerialDevice(Device): | |||||
| """ | """ | ||||
| Reads a single character from the device. | Reads a single character from the device. | ||||
| """ | """ | ||||
| return self._device.read(1) | |||||
| ret = None | |||||
| try: | |||||
| ret = self._device.read(1) | |||||
| except serial.SerialException, err: | |||||
| raise util.CommError('Error reading from device: {0}'.format(str(err))) | |||||
| return ret | |||||
| def read_line(self, timeout=0.0, purge_buffer=False): | def read_line(self, timeout=0.0, purge_buffer=False): | ||||
| """ | """ | ||||
| Reads a line from the device. | Reads a line from the device. | ||||
| """ | """ | ||||
| if purge_buffer: | |||||
| self._buffer = '' | |||||
| def timeout_event(): | def timeout_event(): | ||||
| timeout_event.reading = False | timeout_event.reading = False | ||||
| @@ -434,7 +436,7 @@ class SerialDevice(Device): | |||||
| except (OSError, serial.SerialException), err: | except (OSError, serial.SerialException), err: | ||||
| timer.cancel() | timer.cancel() | ||||
| raise util.CommError('Error reading from AD2SERIAL device: {0}'.format(str(err))) | |||||
| raise util.CommError('Error reading from device: {0}'.format(str(err))) | |||||
| else: | else: | ||||
| if got_line: | if got_line: | ||||
| @@ -457,45 +459,36 @@ class SocketDevice(Device): | |||||
| Serial to IP interface. | Serial to IP interface. | ||||
| """ | """ | ||||
| def __init__(self, interface=None): | |||||
| def __init__(self, interface=("localhost", 10000)): | |||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| self._host = "localhost" | |||||
| self._port = 10000 | |||||
| self._device = None | |||||
| self._buffer = '' | |||||
| self._running = False | |||||
| self._id = '' | |||||
| self._read_thread = Device.ReadThread(self) | |||||
| Device.__init__(self) | |||||
| def __del__(self): | |||||
| """ | |||||
| Destructor | |||||
| """ | |||||
| pass | |||||
| self._interface = interface | |||||
| self._host, self._port = interface | |||||
| def open(self, baudrate=None, interface=None, index=0, no_reader_thread=False): | def open(self, baudrate=None, interface=None, index=0, no_reader_thread=False): | ||||
| """ | """ | ||||
| Opens the device. | Opens the device. | ||||
| """ | """ | ||||
| if interface is not None: | if interface is not None: | ||||
| self._interface = interface | |||||
| self._host, self._port = interface | self._host, self._port = interface | ||||
| try: | try: | ||||
| self._device = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | self._device = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||
| self._device.connect((self._host, self._port)) | self._device.connect((self._host, self._port)) | ||||
| self._id = '{0}:{1}'.format(self._host, self._port) | self._id = '{0}:{1}'.format(self._host, self._port) | ||||
| except socket.error, err: | except socket.error, err: | ||||
| self.on_close() | |||||
| raise util.NoDeviceError('Error opening device at {0}:{1}'.format(self._host, self._port)) | |||||
| traceback.print_exc(err) # TEMP | |||||
| else: | else: | ||||
| self._running = True | self._running = True | ||||
| self.on_open((None, "AD2SOCKET")) # TEMP: Change me. | |||||
| self.on_open(('N/A', "AD2SOCKET")) | |||||
| if not no_reader_thread: | if not no_reader_thread: | ||||
| self._read_thread.start() | self._read_thread.start() | ||||
| @@ -510,51 +503,43 @@ class SocketDevice(Device): | |||||
| self._read_thread.stop() | self._read_thread.stop() | ||||
| self._device.shutdown(socket.SHUT_RDWR) # Make sure that it closes immediately. | self._device.shutdown(socket.SHUT_RDWR) # Make sure that it closes immediately. | ||||
| self._device.close() | self._device.close() | ||||
| except: | except: | ||||
| pass | pass | ||||
| self.on_close() | self.on_close() | ||||
| @property | |||||
| def id(self): | |||||
| return self._id | |||||
| def is_reader_alive(self): | |||||
| """ | |||||
| Indicates whether or not the reader thread is alive. | |||||
| """ | |||||
| return self._read_thread.is_alive() | |||||
| def stop_reader(self): | |||||
| """ | |||||
| Stops the reader thread. | |||||
| """ | |||||
| self._read_thread.stop() | |||||
| def write(self, data): | def write(self, data): | ||||
| """ | """ | ||||
| Writes data to the device. | Writes data to the device. | ||||
| """ | """ | ||||
| data_sent = self._device.send(data) | |||||
| data_sent = None | |||||
| try: | |||||
| data_sent = self._device.send(data) | |||||
| if data_sent == 0: | |||||
| raise util.CommError('Error writing to device.') | |||||
| if data_sent == 0: | |||||
| raise util.CommError('Error while sending data.') | |||||
| else: | |||||
| self.on_write(data) | self.on_write(data) | ||||
| except socket.error, err: | |||||
| raise util.CommError('Error writing to device: {0}'.format(str(err))) | |||||
| return data_sent | return data_sent | ||||
| def read(self): | def read(self): | ||||
| """ | """ | ||||
| Reads a single character from the device. | Reads a single character from the device. | ||||
| """ | """ | ||||
| data = None | |||||
| try: | try: | ||||
| data = self._device.recv(1) | data = self._device.recv(1) | ||||
| except socket.error, err: | except socket.error, err: | ||||
| raise util.CommError('Error while reading from device: {0}'.format(str(err))) | raise util.CommError('Error while reading from device: {0}'.format(str(err))) | ||||
| # ??? - Should we trigger an on_read here as well? | |||||
| return data | return data | ||||
| def read_line(self, timeout=0.0, purge_buffer=False): | def read_line(self, timeout=0.0, purge_buffer=False): | ||||
| @@ -600,7 +585,8 @@ class SocketDevice(Device): | |||||
| except socket.error, err: | except socket.error, err: | ||||
| timer.cancel() | timer.cancel() | ||||
| raise util.CommError('Error reading from Socket device: {0}'.format(str(err))) | |||||
| raise util.CommError('Error reading from device: {0}'.format(str(err))) | |||||
| else: | else: | ||||
| if got_line: | if got_line: | ||||
| ret = self._buffer | ret = self._buffer | ||||
| @@ -0,0 +1,197 @@ | |||||
| """ | |||||
| Message representations received from the panel through the AD2USB. | |||||
| """ | |||||
| import re | |||||
| class Message(object): | |||||
| """ | |||||
| Represents a message from the alarm panel. | |||||
| """ | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self.ready = False | |||||
| self.armed_away = False | |||||
| self.armed_home = False | |||||
| self.backlight_on = False | |||||
| self.programming_mode = False | |||||
| self.beeps = -1 | |||||
| self.zone_bypassed = False | |||||
| self.ac_power = False | |||||
| self.chime_on = False | |||||
| self.alarm_event_occurred = False | |||||
| self.alarm_sounding = False | |||||
| self.battery_low = False | |||||
| self.entry_delay_off = False | |||||
| self.fire_alarm = False | |||||
| self.check_zone = False | |||||
| self.perimeter_only = False | |||||
| self.numeric_code = "" | |||||
| self.text = "" | |||||
| self.cursor_location = -1 | |||||
| self.data = "" | |||||
| self.mask = "" | |||||
| self.bitfield = "" | |||||
| self.panel_data = "" | |||||
| self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)') | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| def _parse_message(self, data): | |||||
| """ | |||||
| Parse the message from the device. | |||||
| """ | |||||
| m = self._regex.match(data) | |||||
| if m is None: | |||||
| raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) | |||||
| self.bitfield, self.numeric_code, self.panel_data, alpha = m.group(1, 2, 3, 4) | |||||
| self.mask = int(self.panel_data[3:3+8], 16) | |||||
| self.data = data | |||||
| self.ready = not self.bitfield[1:2] == "0" | |||||
| self.armed_away = not self.bitfield[2:3] == "0" | |||||
| self.armed_home = not self.bitfield[3:4] == "0" | |||||
| self.backlight_on = not self.bitfield[4:5] == "0" | |||||
| self.programming_mode = not self.bitfield[5:6] == "0" | |||||
| self.beeps = int(self.bitfield[6:7], 16) | |||||
| self.zone_bypassed = not self.bitfield[7:8] == "0" | |||||
| self.ac_power = not self.bitfield[8:9] == "0" | |||||
| self.chime_on = not self.bitfield[9:10] == "0" | |||||
| self.alarm_event_occurred = not self.bitfield[10:11] == "0" | |||||
| self.alarm_sounding = not self.bitfield[11:12] == "0" | |||||
| self.battery_low = not self.bitfield[12:13] == "0" | |||||
| self.entry_delay_off = not self.bitfield[13:14] == "0" | |||||
| self.fire_alarm = not self.bitfield[14:15] == "0" | |||||
| self.check_zone = not self.bitfield[15:16] == "0" | |||||
| self.perimeter_only = not self.bitfield[16:17] == "0" | |||||
| # bits 17-20 unused. | |||||
| self.text = alpha.strip('"') | |||||
| if int(self.panel_data[19:21], 16) & 0x01 > 0: | |||||
| self.cursor_location = int(self.bitfield[21:23], 16) # Alpha character index that the cursor is on. | |||||
| def __str__(self): | |||||
| """ | |||||
| String conversion operator. | |||||
| """ | |||||
| return 'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'.format(hex(self.mask), 1 if self.ready else 0, 1 if self.armed_away else 0, 1 if self.armed_home else 0, self.numeric_code, self.text) | |||||
| class ExpanderMessage(object): | |||||
| """ | |||||
| Represents a message from a zone or relay expansion module. | |||||
| """ | |||||
| ZONE = 0 | |||||
| RELAY = 1 | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self.type = None | |||||
| self.address = None | |||||
| self.channel = None | |||||
| self.value = None | |||||
| self.raw = None | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| def __str__(self): | |||||
| """ | |||||
| String conversion operator. | |||||
| """ | |||||
| expander_type = 'UNKWN' | |||||
| if self.type == ExpanderMessage.ZONE: | |||||
| expander_type = 'ZONE' | |||||
| elif self.type == ExpanderMessage.RELAY: | |||||
| expander_type = 'RELAY' | |||||
| return 'exp > [{0: <5}] {1}/{2} -- {3}'.format(expander_type, self.address, self.channel, self.value) | |||||
| def _parse_message(self, data): | |||||
| """ | |||||
| Parse the raw message from the device. | |||||
| """ | |||||
| header, values = data.split(':') | |||||
| address, channel, value = values.split(',') | |||||
| self.raw = data | |||||
| self.address = address | |||||
| self.channel = channel | |||||
| self.value = value | |||||
| if header == '!EXP': | |||||
| self.type = ExpanderMessage.ZONE | |||||
| elif header == '!REL': | |||||
| self.type = ExpanderMessage.RELAY | |||||
| class RFMessage(object): | |||||
| """ | |||||
| Represents a message from an RF receiver. | |||||
| """ | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self.raw = None | |||||
| self.serial_number = None | |||||
| self.value = None | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| def __str__(self): | |||||
| """ | |||||
| String conversion operator. | |||||
| """ | |||||
| return 'rf > {0}: {1}'.format(self.serial_number, self.value) | |||||
| def _parse_message(self, data): | |||||
| """ | |||||
| Parses the raw message from the device. | |||||
| """ | |||||
| self.raw = data | |||||
| _, values = data.split(':') | |||||
| self.serial_number, self.value = values.split(',') | |||||
| class LRRMessage(object): | |||||
| """ | |||||
| Represent a message from a Long Range Radio. | |||||
| """ | |||||
| def __init__(self, data=None): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self.raw = None | |||||
| self._event_data = None | |||||
| self._partition = None | |||||
| self._event_type = None | |||||
| if data is not None: | |||||
| self._parse_message(data) | |||||
| def __str__(self): | |||||
| """ | |||||
| String conversion operator. | |||||
| """ | |||||
| return 'lrr > {0} @ {1} -- {2}'.format() | |||||
| def _parse_message(self, data): | |||||
| """ | |||||
| Parses the raw message from the device. | |||||
| """ | |||||
| self.raw = data | |||||
| _, values = data.split(':') | |||||
| self._event_data, self._partition, self._event_type = values.split(',') | |||||
| @@ -44,18 +44,6 @@ class Firmware(object): | |||||
| STAGE_UPLOADING = 4 | STAGE_UPLOADING = 4 | ||||
| STAGE_DONE = 5 | STAGE_DONE = 5 | ||||
| def __init__(self): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| pass | |||||
| def __del__(self): | |||||
| """ | |||||
| Destructor | |||||
| """ | |||||
| pass | |||||
| @staticmethod | @staticmethod | ||||
| def upload(dev, filename, progress_callback=None): | def upload(dev, filename, progress_callback=None): | ||||
| """ | """ | ||||
| @@ -0,0 +1,209 @@ | |||||
| """ | |||||
| Provides zone tracking functionality for the AD2USB device family. | |||||
| """ | |||||
| import time | |||||
| from .event import event | |||||
| from . import messages | |||||
| class Zone(object): | |||||
| """ | |||||
| Representation of a panel zone. | |||||
| """ | |||||
| CLEAR = 0 | |||||
| FAULT = 1 | |||||
| CHECK = 2 # Wire fault | |||||
| STATUS = { CLEAR: 'CLEAR', FAULT: 'FAULT', CHECK: 'CHECK' } | |||||
| def __init__(self, zone=0, name='', status=CLEAR): | |||||
| self.zone = zone | |||||
| self.name = name | |||||
| self.status = status | |||||
| self.timestamp = time.time() | |||||
| def __str__(self): | |||||
| return 'Zone {0} {1}'.format(self.zone, self.name) | |||||
| def __repr__(self): | |||||
| return 'Zone({0}, {1}, ts {2})'.format(self.zone, Zone.STATUS[self.status], self.timestamp) | |||||
| class Zonetracker(object): | |||||
| """ | |||||
| Handles tracking of zone and their statuses. | |||||
| """ | |||||
| on_fault = event.Event('Called when the device detects a zone fault.') | |||||
| on_restore = event.Event('Called when the device detects that a fault is restored.') | |||||
| EXPIRE = 30 | |||||
| def __init__(self): | |||||
| """ | |||||
| Constructor | |||||
| """ | |||||
| self._zones = {} | |||||
| self._zones_faulted = [] | |||||
| self._last_zone_fault = 0 | |||||
| def update(self, message): | |||||
| """ | |||||
| Update zone statuses based on the current message. | |||||
| """ | |||||
| zone = -1 | |||||
| if isinstance(message, messages.ExpanderMessage): | |||||
| zone = self._expander_to_zone(int(message.address), int(message.channel)) | |||||
| status = Zone.CLEAR | |||||
| if int(message.value) == 1: | |||||
| status = Zone.FAULT | |||||
| elif int(message.value) == 2: | |||||
| status = Zone.CHECK | |||||
| try: | |||||
| self._update_zone(zone, status=status) | |||||
| except IndexError: | |||||
| self._add_zone(zone, status=status) | |||||
| else: | |||||
| # Panel is ready, restore all zones. | |||||
| if message.ready: | |||||
| for idx, z in enumerate(self._zones_faulted): | |||||
| self._update_zone(z, Zone.CLEAR) | |||||
| self._last_zone_fault = 0 | |||||
| # Process fault | |||||
| elif "FAULT" in message.text or message.check_zone: | |||||
| # Apparently this representation can be both base 10 | |||||
| # or base 16, depending on where the message came | |||||
| # from. | |||||
| try: | |||||
| zone = int(message.numeric_code) | |||||
| except ValueError: | |||||
| zone = int(message.numeric_code, 16) | |||||
| # Add new zones and clear expired ones. | |||||
| if zone in self._zones_faulted: | |||||
| self._update_zone(zone) | |||||
| self._clear_zones(zone) | |||||
| else: | |||||
| status = Zone.FAULT | |||||
| if message.check_zone: | |||||
| status = Zone.CHECK | |||||
| self._add_zone(zone, status=status) | |||||
| self._zones_faulted.append(zone) | |||||
| self._zones_faulted.sort() | |||||
| # Save our spot for the next message. | |||||
| self._last_zone_fault = zone | |||||
| self._clear_expired_zones() | |||||
| def _clear_zones(self, zone): | |||||
| """ | |||||
| Clear all expired zones from our status list. | |||||
| """ | |||||
| cleared_zones = [] | |||||
| found_last = found_new = at_end = False | |||||
| # First pass: Find our start spot. | |||||
| it = iter(self._zones_faulted) | |||||
| try: | |||||
| while not found_last: | |||||
| z = it.next() | |||||
| if z == self._last_zone_fault: | |||||
| found_last = True | |||||
| break | |||||
| except StopIteration: | |||||
| at_end = True | |||||
| # Continue until we find our end point and add zones in | |||||
| # between to our clear list. | |||||
| try: | |||||
| while not at_end and not found_new: | |||||
| z = it.next() | |||||
| if z == zone: | |||||
| found_new = True | |||||
| break | |||||
| else: | |||||
| cleared_zones += [z] | |||||
| except StopIteration: | |||||
| pass | |||||
| # Second pass: roll through the list again if we didn't find | |||||
| # our end point and remove everything until we do. | |||||
| if not found_new: | |||||
| it = iter(self._zones_faulted) | |||||
| try: | |||||
| while not found_new: | |||||
| z = it.next() | |||||
| if z == zone: | |||||
| found_new = True | |||||
| break | |||||
| else: | |||||
| cleared_zones += [z] | |||||
| except StopIteration: | |||||
| pass | |||||
| # Actually remove the zones and trigger the restores. | |||||
| for idx, z in enumerate(cleared_zones): | |||||
| self._update_zone(z, Zone.CLEAR) | |||||
| def _clear_expired_zones(self): | |||||
| zones = [] | |||||
| for z in self._zones.keys(): | |||||
| zones += [z] | |||||
| for z in zones: | |||||
| if self._zones[z].status != Zone.CLEAR and self._zone_expired(z): | |||||
| self._update_zone(z, Zone.CLEAR) | |||||
| def _add_zone(self, zone, name='', status=Zone.CLEAR): | |||||
| """ | |||||
| Adds a zone to the internal zone list. | |||||
| """ | |||||
| if not zone in self._zones: | |||||
| self._zones[zone] = Zone(zone=zone, name=name, status=status) | |||||
| if status != Zone.CLEAR: | |||||
| self.on_fault(zone) | |||||
| def _update_zone(self, zone, status=None): | |||||
| """ | |||||
| Updates a zones status. | |||||
| """ | |||||
| if not zone in self._zones: | |||||
| raise IndexError('Zone does not exist and cannot be updated: %d', zone) | |||||
| if status is not None: | |||||
| self._zones[zone].status = status | |||||
| self._zones[zone].timestamp = time.time() | |||||
| if status == Zone.CLEAR: | |||||
| if zone in self._zones_faulted: | |||||
| self._zones_faulted.remove(zone) | |||||
| self.on_restore(zone) | |||||
| def _zone_expired(self, zone): | |||||
| if time.time() > self._zones[zone].timestamp + Zonetracker.EXPIRE: | |||||
| return True | |||||
| return False | |||||
| def _expander_to_zone(self, address, channel): | |||||
| idx = address - 7 # Expanders start at address 7. | |||||
| return address + channel + (idx * 7) + 1 | |||||
| @@ -1 +1 @@ | |||||
| ../../pyftdi/pyftdi/ | |||||
| libs/pyftdi/pyftdi/ | |||||
| @@ -5,6 +5,7 @@ import time | |||||
| import signal | import signal | ||||
| import traceback | import traceback | ||||
| import sys | import sys | ||||
| import logging | |||||
| running = True | running = True | ||||
| @@ -43,6 +44,12 @@ def handle_bypass(sender, args): | |||||
| def handle_message(sender, args): | def handle_message(sender, args): | ||||
| print args | print args | ||||
| def handle_arm(sender, args): | |||||
| print 'armed', args | |||||
| def handle_disarm(sender, args): | |||||
| print 'disarmed', args | |||||
| def handle_firmware(stage): | def handle_firmware(stage): | ||||
| if stage == pyad2usb.ad2usb.util.Firmware.STAGE_START: | if stage == pyad2usb.ad2usb.util.Firmware.STAGE_START: | ||||
| handle_firmware.wait_tick = 0 | handle_firmware.wait_tick = 0 | ||||
| @@ -71,6 +78,18 @@ def handle_firmware(stage): | |||||
| elif stage == pyad2usb.ad2usb.util.Firmware.STAGE_DONE: | elif stage == pyad2usb.ad2usb.util.Firmware.STAGE_DONE: | ||||
| print "\r\nDone!" | print "\r\nDone!" | ||||
| def handle_boot(sender, args): | |||||
| print 'boot', args | |||||
| def handle_config(sender, args): | |||||
| print 'config', args | |||||
| def handle_fault(sender, args): | |||||
| print 'zone fault', args | |||||
| def handle_restore(sender, args): | |||||
| print 'zone restored', args | |||||
| def upload_usb(): | def upload_usb(): | ||||
| dev = pyad2usb.ad2usb.devices.USBDevice() | dev = pyad2usb.ad2usb.devices.USBDevice() | ||||
| @@ -200,7 +219,7 @@ def test_factory_watcher(): | |||||
| overseer.close() | overseer.close() | ||||
| def test_socket(): | def test_socket(): | ||||
| dev = pyad2usb.ad2usb.devices.SocketDevice(interface=("localhost", 10000)) | |||||
| dev = pyad2usb.ad2usb.devices.SocketDevice(interface=("singularity.corp.nutech.com", 10000)) | |||||
| a2u = pyad2usb.ad2usb.AD2USB(dev) | a2u = pyad2usb.ad2usb.AD2USB(dev) | ||||
| a2u.on_open += handle_open | a2u.on_open += handle_open | ||||
| @@ -212,10 +231,39 @@ def test_socket(): | |||||
| a2u.on_power_changed += handle_power_changed | a2u.on_power_changed += handle_power_changed | ||||
| a2u.on_alarm += handle_alarm_bell | a2u.on_alarm += handle_alarm_bell | ||||
| a2u.on_bypass += handle_bypass | a2u.on_bypass += handle_bypass | ||||
| a2u.on_boot += handle_boot | |||||
| a2u.on_config_received += handle_config | |||||
| a2u.on_arm += handle_arm | |||||
| a2u.on_disarm += handle_disarm | |||||
| a2u.on_zone_fault += handle_fault | |||||
| a2u.on_zone_restore += handle_restore | |||||
| a2u.open() | a2u.open() | ||||
| #a2u.save_config() | |||||
| #a2u.reboot() | |||||
| a2u.get_config() | |||||
| #a2u.address = 18 | |||||
| #a2u.configbits = 0xff00 | |||||
| #a2u.address_mask = 0xFFFFFFFF | |||||
| #a2u.emulate_zone[0] = False | |||||
| #a2u.emulate_relay[0] = False | |||||
| #a2u.emulate_lrr = False | |||||
| #a2u.deduplicate = False | |||||
| #time.sleep(3) | |||||
| #a2u.emulate_zone[1] = True | |||||
| #a2u.save_config() | |||||
| time.sleep(1) | |||||
| a2u.fault_zone(17, True) | |||||
| time.sleep(15) | |||||
| a2u.clear_zone(17) | |||||
| #time.sleep(1) | |||||
| #a2u.fault_zone((2, 2), True) | |||||
| print dev._id | |||||
| while running: | while running: | ||||
| time.sleep(0.1) | time.sleep(0.1) | ||||
| @@ -279,10 +327,11 @@ def test_double_panel_write(): | |||||
| dev2.close() | dev2.close() | ||||
| try: | try: | ||||
| logging.basicConfig(level=logging.DEBUG) | |||||
| signal.signal(signal.SIGINT, signal_handler) | signal.signal(signal.SIGINT, signal_handler) | ||||
| #test_serial() | #test_serial() | ||||
| upload_serial() | |||||
| #upload_serial() | |||||
| #test_usb() | #test_usb() | ||||
| #test_usb_serial() | #test_usb_serial() | ||||
| @@ -291,7 +340,7 @@ try: | |||||
| #upload_usb() | #upload_usb() | ||||
| #upload_usb_serial() | #upload_usb_serial() | ||||
| #test_socket() | |||||
| test_socket() | |||||
| #upload_socket() | #upload_socket() | ||||
| #test_no_read_thread() | #test_no_read_thread() | ||||