Full Code of iancmcc/ouimeaux for AI

develop bc3c299dd275 cached
86 files
521.5 KB
141.7k tokens
734 symbols
1 requests
Download .txt
Showing preview only (549K chars total). Download the full file or copy to clipboard to get everything.
Repository: iancmcc/ouimeaux
Branch: develop
Commit: bc3c299dd275
Files: 86
Total size: 521.5 KB

Directory structure:
gitextract_v9i5cwgu/

├── .gitignore
├── .travis.yml
├── AUTHORS.rst
├── CONTRIBUTING.rst
├── HISTORY.rst
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── client.py
├── docs/
│   ├── Makefile
│   ├── api.rst
│   ├── authors.rst
│   ├── conf.py
│   ├── configuration.rst
│   ├── contributing.rst
│   ├── history.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── make.bat
│   ├── modules.rst
│   ├── ouimeaux.device.api.rst
│   ├── ouimeaux.device.api.xsd.rst
│   ├── ouimeaux.device.rst
│   ├── ouimeaux.examples.rst
│   ├── ouimeaux.pysignals.rst
│   ├── ouimeaux.rst
│   ├── ouimeaux.server.rst
│   ├── ouimeaux.xsd.rst
│   ├── readme.rst
│   ├── server.rst
│   └── wemo.rst
├── ouimeaux/
│   ├── __init__.py
│   ├── cli.py
│   ├── config.py
│   ├── device/
│   │   ├── __init__.py
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── service.py
│   │   │   └── xsd/
│   │   │       ├── __init__.py
│   │   │       ├── device.py
│   │   │       ├── device.xsd
│   │   │       ├── service.py
│   │   │       └── service.xsd
│   │   ├── bridge.py
│   │   ├── insight.py
│   │   ├── lightswitch.py
│   │   ├── maker.py
│   │   ├── motion.py
│   │   └── switch.py
│   ├── discovery.py
│   ├── environment.py
│   ├── examples/
│   │   ├── Randomize.py
│   │   ├── __init__.py
│   │   └── watch.py
│   ├── pysignals/
│   │   ├── LICENSE.txt
│   │   ├── __init__.py
│   │   ├── dispatcher.py
│   │   ├── inspect.py
│   │   ├── license.python.txt
│   │   └── weakref_backports.py
│   ├── server/
│   │   ├── __init__.py
│   │   ├── settings.py
│   │   ├── static/
│   │   │   ├── css/
│   │   │   │   ├── bootstrap-responsive.css
│   │   │   │   ├── bootstrap-theme.css
│   │   │   │   ├── bootstrap.css
│   │   │   │   └── main.css
│   │   │   ├── js/
│   │   │   │   ├── app.js
│   │   │   │   ├── bootstrap.js
│   │   │   │   ├── controllers.js
│   │   │   │   ├── directives.js
│   │   │   │   ├── filters.js
│   │   │   │   ├── services.js
│   │   │   │   └── socket.js
│   │   │   └── partials/
│   │   │       ├── about.html
│   │   │       └── landing.html
│   │   └── templates/
│   │       ├── 404.html
│   │       └── index.html
│   ├── signals.py
│   ├── subscribe.py
│   └── utils.py
├── requirements.txt
├── setup.cfg
├── setup.py
├── tests/
│   ├── __init__.py
│   └── test_ouimeaux.py
└── tox.ini

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
*.py[cod]

# C extensions
*.so

# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
lib
lib64

# Installer logs
pip-log.txt

# Unit test / coverage reports
.coverage
.tox
nosetests.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Complexity
output/*.html
output/*/index.html

# Sphinx
docs/_build

.DS_Store
*~
*.xcodeproj

================================================
FILE: .travis.yml
================================================
# Config file for automatic testing at travis-ci.org

language: python

python:
  - "2.7"
  - "3.5"
  - "3.6"

# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
install: pip install -r requirements.txt

# command to run tests, e.g. python setup.py test
script: python setup.py test


================================================
FILE: AUTHORS.rst
================================================
=======
Credits
=======

Development Lead
----------------

* Ian McCracken <ian.mccracken@gmail.com>

Contributors
------------

* `Aron Parsons <https://github.com/aronparsons>`_
* `Brian Peiris <https://github.com/brianpeiris>`_
* `nschrenk <https://github.com/nschrenk>`_
* `Gabriel M. Schuyler <https://github.com/fnaard>`_
* `Markus Stenberg <https://github.com/fingon>`_
* `aktur <https://github.com/aktur>`_
* `Justin Eldridge <https://github.com/eldridgejm>`_
* `logjames <https://github.com/logjames>`_
* `jgstew <https://github.com/jgstew>`_
* `Bob Gardner <https://github.com/rgardner>`_
* `FRITZ|FRITZ <https://github.com/fritz-fritz>`_

================================================
FILE: CONTRIBUTING.rst
================================================
============
Contributing
============

Contributions are welcome, and they are greatly appreciated! Every
little bit helps, and credit will always be given. 

You can contribute in many ways:

Types of Contributions
----------------------

Report Bugs
~~~~~~~~~~~

Report bugs at https://github.com/iancmcc/ouimeaux/issues.

If you are reporting a bug, please include:

* Your operating system name and version.
* Any details about your local setup that might be helpful in troubleshooting.
* Detailed steps to reproduce the bug.

Fix Bugs
~~~~~~~~

Look through the GitHub issues for bugs. Anything tagged with "bug"
is open to whoever wants to implement it.

Implement Features
~~~~~~~~~~~~~~~~~~

Look through the GitHub issues for features. Anything tagged with "feature"
is open to whoever wants to implement it.

Write Documentation
~~~~~~~~~~~~~~~~~~~

ouimeaux could always use more documentation, whether as part of the 
official ouimeaux docs, in docstrings, or even on the web in blog posts,
articles, and such.

Submit Feedback
~~~~~~~~~~~~~~~

The best way to send feedback is to file an issue at https://github.com/iancmcc/ouimeaux/issues.

If you are proposing a feature:

* Explain in detail how it would work.
* Keep the scope as narrow as possible, to make it easier to implement.
* Remember that this is a volunteer-driven project, and that contributions
  are welcome :)

Get Started!
------------

Ready to contribute? Here's how to set up `ouimeaux` for local development.

1. Fork the `ouimeaux` repo on GitHub.
2. Clone your fork locally::

    $ git clone git@github.com:your_name_here/ouimeaux.git

3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development::

    $ mkvirtualenv ouimeaux
    $ cd ouimeaux/
    $ python setup.py develop

4. Create a branch for local development::

    $ git checkout -b name-of-your-bugfix-or-feature
   
   Now you can make your changes locally.

5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox::

    $ flake8 ouimeaux tests
    $ python setup.py test
    $ tox

   To get flake8 and tox, just pip install them into your virtualenv. 

6. Commit your changes and push your branch to GitHub::

    $ git add .
    $ git commit -m "Your detailed description of your changes."
    $ git push origin name-of-your-bugfix-or-feature

7. Submit a pull request through the GitHub website.

Pull Request Guidelines
-----------------------

Before you submit a pull request, check that it meets these guidelines:

1. The pull request should include tests.
2. If the pull request adds functionality, the docs should be updated. Put
   your new functionality into a function with a docstring, and add the
   feature to the list in README.md.
3. The pull request should work for Python 2.6, 2.7, and 3.3, and for PyPy. Check 
   https://travis-ci.org/iancmcc/ouimeaux/pull_requests
   and make sure that the tests pass for all supported Python versions.

Tips
----

To run a subset of tests::

	$ python -m unittest tests.test_ouimeaux


================================================
FILE: HISTORY.rst
================================================
.. :changelog:

History
-------

Release 0.8.0 (July 30, 2016)
+++++++++++++++++++++++++++++
- Randomize subscription ports to enable simultaneous ouimeaux scripts (thanks @bennytheshap)
- Fix for WeMo LED Light support (thanks @sstangle73)
- #32: Removed address cache, broke server out into optional feature
- Fix for Maker state reporting (thanks @pavoni)
- Filter by SSDP location, fixing case where multiple devices respond from the same IP (thanks @szakharchenko)
- Fix Maker event handlers, which were being passed as bridges (thanks @maxlazarov)
- Work around gevent-socketio bug by explicitly casting header value as string
- Fix for inconsistent Light state (thanks @canduuk)
- StateChange signals are now a separate class and do not fire if value is unchanged (thanks @esecules)
- Python 3 support (thanks to @drock371)

Release 0.7.9 (March 17, 2015)
++++++++++++++++++++++++++++++
- Command line support for WeMo LED Light (thanks @fritz-fritz)
- Command line support for WeMo Maker (thanks @logjames)
- Support for 2.0.0 firmware (thanks @fritz-fritz)
- Bug fixes

Release 0.7.3 (August 10, 2014)
++++++++++++++++++++++++++++++++
- Fixed #18: Error when run as root
- Fixed #26: Evict devices from cache when unreachable
- Fixed #29: GetPower stopped working for Insight devices
- Fixed #31: Add blink method on switches, include in REST API
- Fixed #33, #37: Handle invalid devices without dying
- Fixed #35: Require requests >= 2.3.0
- Fixed #40: Retry requests in the event of failure
- Fixed #47: Don't choke on invalid newlines in XML returned by switches
             (thanks to @fingon)

Release 0.7.2 (January 28, 2014)
++++++++++++++++++++++++++++++++
- Fix a bug with using query parameters on /api/device

Release 0.7 (January 27, 2014)
++++++++++++++++++++++++++++++
- Added REST API
- Added Web app

Release 0.6 (January 25, 2014)
++++++++++++++++++++++++++++++++
- Added signals framework
- Fixed #16, #19, #22: Defensively resubscribe to events when device responds with an error
- Fixed #15: Signals framework includes relevant device when sending signal
- Refactored structure, added Sphinx docs

Release 0.5.3 (January 25, 2014)
++++++++++++++++++++++++++++++++
- Fixed #20: Allow timeout in environment.wait()
- Fixed #21: Add Insight support

Release 0.5.2 (November 23, 2013)
+++++++++++++++++++++++++++++++++
- Fixed #14: Indicate Connection:close header to avoid logging when WeMo sends
  invalid HTTP response.

Release 0.5.1 (November 9, 2013)
++++++++++++++++++++++++++++++++
- Fixed #10: Updated subscriber listener to use more reliable method of
  retrieving non-loopback IP address; updated docs to fix typo in listener
  registration example (thanks to @benhoyle, @francxk)
- Fixed #11: Remove instancemethod objects before attempting to pickle devices
  in the cache (thanks @piperde, @JonPenner, @tomtomau, @masilu77)

Release 0.5 (October 14, 2013)
+++++++++++++++++++++++++++++++
- Added fuzzy matching of device name when searching/toggling from command line
- Added ``status`` mode to print status for all devices
- Added ``switch status`` mode to print status for specific device
- Added flags for all command-line options
- Fixed #9: Removed unused fcntl import that precluded Windows usage (thanks to
  @deepseven)

Release 0.4.3 (August 31, 2013)
+++++++++++++++++++++++++++++++
- Used new method of obtaining local IP for discovery that is less likely to
  return loopback
- Exit with failure and instructions for solution if loopback IP is used
- Updated installation docs to include python-dev and pip instructions (patch
  by @fnaard)
- Fixed README inclusion bug that occasionally broke installation via pip.
- Added ``--debug`` option to enable debug logging to stdout

Release 0.4 (August 17, 2013)
+++++++++++++++++++++++++++++
- Fixed #7: Added support for light switch devices (patch by nschrenk).
- Fixed #6: Added "wemo clear" command to clear the device cache.

Release 0.3 (May 25, 2013)
++++++++++++++++++++++++++
- Fixed #4: Added ability to specify ip:port for discovery server binding. Removed
  documentation describing need to disable SSDP service on Windows.
- Fixed #5: Added device cache for faster results.
- Added configuration file.
- Added ability to configure aliases for devices to avoid quoting strings on
  the command line.
- Added 'toggle' command to command line switch control.

Release 0.2 (April 21, 2013)
++++++++++++++++++++++++++++++
- Fixed #1: Added ability to subscribe to motion and switch state change events.
- Added Windows installation details to README (patch by @brianpeiris)
- Cleaned up UDP server lifecycle so rediscovery doesn't try to start it back up.

Release 0.1 (February 2, 2013)
++++++++++++++++++++++++++++++
- Initial release.

* First release on PyPI.

================================================
FILE: LICENSE
================================================
Copyright (c) 2014, Ian McCracken
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

* Neither the name of ouimeaux nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

================================================
FILE: MANIFEST.in
================================================
include AUTHORS.rst
include CONTRIBUTING.rst
include HISTORY.rst
include LICENSE
include README.md
include requirements.txt
graft ouimeaux


================================================
FILE: Makefile
================================================
.PHONY: clean-pyc clean-build docs

help:
	@echo "clean-build - remove build artifacts"
	@echo "clean-pyc - remove Python file artifacts"
	@echo "lint - check style with flake8"
	@echo "test - run tests quickly with the default Python"
	@echo "testall - run tests on every Python version with tox"
	@echo "coverage - check code coverage quickly with the default Python"
	@echo "docs - generate Sphinx HTML documentation, including API docs"
	@echo "release - package and upload a release"
	@echo "sdist - package"

clean: clean-build clean-pyc

clean-build:
	rm -fr build/
	rm -fr dist/
	rm -fr *.egg-info

clean-pyc:
	find . -name '*.pyc' -exec rm -f {} +
	find . -name '*.pyo' -exec rm -f {} +
	find . -name '*~' -exec rm -f {} +

lint:
	flake8 ouimeaux tests

test:
	python setup.py test

test-all:
	tox

coverage:
	coverage run --source ouimeaux setup.py test
	coverage report -m
	coverage html
	open htmlcov/index.html

docs:
	rm -f docs/ouimeaux.rst
	rm -f docs/modules.rst
	sphinx-apidoc -o docs/ ouimeaux
	$(MAKE) -C docs clean
	$(MAKE) -C docs html
	open docs/_build/html/index.html

release: clean
	python setup.py sdist upload

sdist: clean
	python setup.py sdist
	ls -l dist

================================================
FILE: README.md
================================================
# ouimeaux

⚠️ ⚠️ ⚠️

The ouimeaux project is no longer actively maintained. Please contact @iancmcc
if you would like to be added to a list of maintained forks.

⚠️ ⚠️ ⚠️

Open source control for Belkin WeMo devices

* Free software: BSD license
* Documentation: http://ouimeaux.rtfd.org.

## Features

* Supports WeMo Switch, Light Switch, Insight Switch and Motion
* Command-line tool to discover and control devices in your environment
* REST API to obtain information and perform actions on devices
* Simple responsive Web app provides device control on mobile
* Python API to interact with device at a low level

## About this fork

The original repository can be found here: https://github.com/iancmcc/ouimeaux

It doesn't appear to be maintained and it doesn't work with modern Python
packages.

It has been forked here so that I can include my modifications to
`requirements.txt` as well as document how to use it.

## Installation

```
$ sudo pip install virtualenv
$ mkdir ouimeaux-env
$ virtualenv ouimeaux-env
$ source ouimeaux-env/bin/activate
$ cd ouimeaux-env
$ pip install git+https://github.com/iancmcc/ouimeaux.git
```

At this point you should be able to use `wemo` and `wemo server` so long as
you've activated your environment with `source ouimeaux-env/bin/activate`.

**Note:** Ensure that the `pip` and `virtualenv` command you use belongs to a
Python 2 installation. On some systems, there are multiple versions of Python
installed. See below for an example from my Fedora system.

```
$ /bin/ls -1 "$(dirname $(which python))/virtualenv"{,-2} "$(dirname $(which python))/p"{ython,ip}[23]
/usr/bin/pip2
/usr/bin/pip3
/usr/bin/python2
/usr/bin/python3
/usr/bin/virtualenv
/usr/bin/virtualenv-2

$ pip --version
pip 9.0.1 from /usr/lib/python3.5/site-packages (python 3.5)

$ pip2 --version
pip 9.0.1 from /usr/lib/python2.7/site-packages (python 2.7)
```

## HTTP client version

The `client.py` script provided by [BlackLight](https://github.com/BlackLight)
allows the user to send simple commands to a device without the cumbersome
(and [currently broken](https://github.com/iancmcc/ouimeaux/issues/193)) `Discoverer`
object.

Requirements: install requests:

```
pip install requests
```

You can run client.py in two modes:

### Scan mode

Will scan for available WeMo Switch devices on the network. Example:

```
python client.py --scan --subnet 192.168.1.0/24
```

### Action mode

Will run an action on a specified device. Example:

```
python client.py --device 192.168.1.19 --on
```

With no `--on|--off|--toggle` action specified the script will return a JSON
with the device info:

```json
{
  "device": "192.168.1.19",
  "name": "Lightbulbs",
  "state": false
}
```

Run `python client.py --help` for more info about the available options.

## Troubleshooting

#### Using a VPN 
The `wemo` command won't be able to communicate with your devices if you're connected to a VPN. It may be redirecting UDP traffic somewhere else. Disconnect from the VPN and the tool should work.

Open an issue and I'll try to help.

#### Docker

You need to be on the same network as your device. To do this ensure you are using `host` network, see [https://docs.docker.com/network/host/](https://docs.docker.com/network/host/) for more info. 

================================================
FILE: client.py
================================================
#!/usr/bin/env python
# :author: Fabio "BlackLight" Manganiello <info@fabiomanganiello.com>
#
# Requirements:
#     - `requests` package (`pip install requests`)
#     - [Advised] static IP allocation for your WeMo devices

import argparse
import enum
import ipaddress
import json
import multiprocessing
import re
import requests
import socket
import sys
import textwrap

from typing import Type
from xml.dom.minidom import parseString


default_port = 49153


class SwitchAction(enum.Enum):
    GET_STATE = 'GetBinaryState'
    SET_STATE = 'SetBinaryState'
    GET_NAME = 'GetFriendlyName'


class Worker(multiprocessing.Process):
    _END_OF_STREAM = None

    def __init__(self, request_queue: multiprocessing.Queue, response_queue=multiprocessing.Queue):
        super().__init__()
        self.request_queue = request_queue
        self.response_queue = response_queue

    def send_stop(self):
        self.request_queue.put(self._END_OF_STREAM)

    def process_response(self, resp):
        self.response_queue.put(resp)


class Workers:
    def __init__(self, n_workers: int, worker_type: Type[Worker], *args, **kwargs):
        self.request_queue = multiprocessing.Queue()
        self.response_queue = multiprocessing.Queue()
        self._workers = [worker_type(self.request_queue, self.response_queue,
            *args, **kwargs) for _ in range(n_workers)]

    def start(self):
        for wrk in self._workers:
            wrk.start()

    def put(self, msg):
        self.request_queue.put(msg)

    def wait(self) -> list:
        while self._workers:
            for i, wrk in enumerate(self._workers):
                if not self._workers[i].is_alive():
                    self._workers.pop(i)
                    break

        ret = []
        while not self.response_queue.empty():
            ret.append(self.response_queue.get())
        return ret

    def send_stop(self):
        for wrk in self._workers:
            wrk.send_stop()


class ScanWorker(Worker):
    def __init__(self, request_queue: multiprocessing.Queue, response_queue: multiprocessing.Queue,
            scan_timeout: float, connect_timeout: float, port: int = default_port):
        super().__init__(request_queue, response_queue)
        self.scan_timeout = scan_timeout
        self.connect_timeout = connect_timeout
        self.port = port

    def run(self):
        while True:
            addr = self.request_queue.get()
            if addr == self._END_OF_STREAM:
                break

            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(self.scan_timeout)
                sock.connect((addr, self.port))
                sock.close()
                dev = get_device(addr, timeout=self.connect_timeout)
                print('Found WeMo device: {}'.format(dev))
                self.process_response(dev)
            except OSError:
                pass


def _exec(device: str, action: SwitchAction, value=None, port: int = default_port, timeout: float = None):
    state_name = action.value[3:]

    response = requests.post(
        'http://{}:{}/upnp/control/basicevent1'.format(device, port),
        headers={
            'User-Agent': '',
            'Accept': '',
            'Content-Type': 'text/xml; charset="utf-8"',
            'SOAPACTION': '\"urn:Belkin:service:basicevent:1#{}\"'.format(action.value),
        },
        data=re.sub('\s+', ' ', textwrap.dedent(
            '''
            <?xml version="1.0" encoding="utf-8"?>
            <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"
                    s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                <s:Body>
                    <u:{action} xmlns:u="urn:Belkin:service:basicevent:1">
                        <{state}>{value}</{state}>
                    </u:{action}
                ></s:Body>
            </s:Envelope>
            '''.format(action=action.value, state=state_name,
                       value=value if value is not None else ''))))

    dom = parseString(response.text)
    return dom.getElementsByTagName(state_name).item(0).firstChild.data


def on(device: str, *args, **kwargs):
    return _exec(device, SwitchAction.SET_STATE, 1)


def off(device: str, *args, **kwargs):
    return _exec(device, SwitchAction.SET_STATE, 0, *args, **kwargs)


def get_state(device: str, *args, **kwargs):
    return bool(int(_exec(device, SwitchAction.GET_STATE, *args, **kwargs)))


def get_name(device: str, *args, **kwargs):
    return _exec(device, SwitchAction.GET_NAME, *args, **kwargs)


def get_device(device: str, *args, **kwargs):
    return {
        'device': device,
        'name': get_name(device, *args, **kwargs),
        'state': get_state(device, *args, **kwargs),
    }


def main():
    global default_port

    parser = argparse.ArgumentParser()
    parser.add_argument('--scan', '-s', dest='scan', required=False, default=False, action='store_true',
                        help="Run Switchbot in scan mode - scan devices to control")

    parser.add_argument('--subnet', '-n', dest='subnet', required=False, default=None,
                        help="Set the network subnet for --scan mode (e.g. 192.168.1.0/24)")

    parser.add_argument('--port', '-p', dest='port', required=False, type=int, default=default_port,
                        help="TCP port used by the WeMo device(s)")

    parser.add_argument('--scan-timeout', dest='scan_timeout', type=float, required=False, default=2.0,
                        help="Device scan timeout (default: 2 seconds)")

    parser.add_argument('--connect-timeout', dest='connect_timeout', type=float, required=False, default=30.0,
                        help="Device connection timeout (default: 30 seconds)")

    parser.add_argument('--device', '-d', dest='device', required=False, default=None,
                        help="IP address of a device to control")

    parser.add_argument('--on', dest='on', required=False, default=False, action='store_true',
                        help="Turn the device on")

    parser.add_argument('--off', dest='off', required=False, default=False, action='store_true',
                        help="Turn the device off")

    parser.add_argument('--toggle', dest='toggle', required=False, default=False, action='store_true',
                        help="Toggle the device")

    opts, args = parser.parse_known_args(sys.argv[1:])

    if (opts.scan and opts.device) or not (opts.scan or opts.device):
        raise AttributeError('Please specify either --scan or --device')

    if opts.scan:
        if not opts.subnet:
            raise AttributeError('No --subnet specified for --scan mode')

        workers = Workers(10, ScanWorker, scan_timeout=opts.scan_timeout,
                connect_timeout=opts.connect_timeout, port=opts.port)

        workers.start()

        for addr in ipaddress.IPv4Network(opts.subnet):
            workers.put(addr.exploded)

        workers.send_stop()
        devices = workers.wait()
        print('\nFound {} WeMo devices'.format(len(devices)))
        print(json.dumps(devices, indent=2))
        return

    _on = opts.on
    _off = opts.off

    if opts.toggle:
        if get_state(opts.device):
            _off = True
        else:
            _on = True

    if _on:
        on(opts.device, timeout=opts.connect_timeout)
    elif _off:
        off(opts.device, timeout=opts.connect_timeout)
    else:
        print(json.dumps(
            get_device(opts.device, timeout=opts.connect_timeout),
            indent=2))


if __name__ == '__main__':
    main()


# vim:sw=4:ts=4:et:


================================================
FILE: docs/Makefile
================================================
# 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/complexity.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/complexity.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/complexity"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/complexity"
	@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."

================================================
FILE: docs/api.rst
================================================
===========
Python API
===========

Environment
-----------
The main interface is presented by an ``Environment``, which optionally accepts
functions called when a Switch or Motion device is identified::

    >>> from ouimeaux.environment import Environment
    >>>
    >>> def on_switch(switch):
    ...     print "Switch found!", switch.name
    ...
    >>> def on_motion(motion):
    ...     print "Motion found!", motion.name
    ...
    >>> env = Environment(on_switch, on_motion)

Start up the server to listen for responses to the discovery broadcast::

    >>> env.start()

Discovery of all WeMo devices in an environment is then straightforward; simply
pass the length of time (in seconds) you want discovery to run::

    >>> env.discover(seconds=3)
    Switch found! Living Room

During that time, the ``Environment`` will continually broadcast search requests
and parse responses. At any point, you can see the names of discovered devices::

    >>> env.list_switches()
    ['Living Room', 'TV Room', 'Front Closet']
    >>> env.list_motions()
    ['Front Hallway']

Devices can be retrieved by using ``get_switch`` and ``get_motion`` methods::

    >>> switch = env.get_switch('TV Room')
    >>> switch
    <WeMo Switch "TV Room">

Devices
-------
All devices have an ``explain()`` method, which will print out a list of all
available services, as well as the actions and arguments to those actions
on each service::

    >>> switch.explain()

    basicevent
    ----------
      SetSmartDevInfo(SmartDevURL)
      SetServerEnvironment(ServerEnvironmentType, TurnServerEnvironment, ServerEnvironment)
      GetDeviceId()
      GetRuleOverrideStatus(RuleOverrideStatus)
      GetIconURL(URL)
      SetBinaryState(BinaryState)
    ...

Services and actions are available via simple attribute access. Calling actions
returns a dictionary of return values::

    >>> switch.basicevent.SetBinaryState(BinaryState=0)
    {'BinaryState': 0}

Events
------
.. warning:: This events framework is deprecated and will be removed prior to the 1.0 release. Please use the signals framework.

By default, ouimeaux subscribes to property change events on discovered
devices (this can be disabled by passing ``with_subscribers=False`` to the
``Environment`` constructor). You can register callbacks that will be called
when switches and motions change state (on/off, or motion detected)::

    >>> def on_motion(value):
    ...     print "Motion detected!"
    ...
    >>> env.get_motion('Front Hallway').register_listener(on_motion)
    >>> env.wait(timeout=60)

Note the use of ``Environment.wait()`` to give control to the event loop for
events to be detected. A timeout in seconds may optionally be specified;
default is no timeout.

Signals
-------
A simple signals framework (using pysignals_) is included to replace the
rudimentary events in earlier releases. These are found in the
`ouimeaux.signals` module. Signal handlers may be registered using the
``receiver`` decorator and must have the signature ``sender, **kwargs``::

    @receiver(devicefound)
    def handler(sender, **kwargs):
        print "Found device", sender


Where ``sender`` is the relevant object (in most cases, the device). Signals
may also have handlers registered using ``signal.connect(handler)``::

    def handler(sender, **kwargs):
        pass

    statechange.connect(sender)

Available signals:

    ``discovered``
        Fires when a device responds to the broadcast request. Includes:
         - ``sender``: The UPnP broadcast component
         - ``address``: The address of the responding device
         - ``headers``: The response headers

    ``devicefound``
        Sent when a device is found and registered into the environment. Includes:
         - ``sender``: The device found

    ``subscription``
        Sent when a device sends an event as the result of a subscription. Includes:
         - ``sender``: The device that sent the event
         - ``type``: The type of the event send (e.g., ``BinaryState``)
         - ``value``: The value associated with the event

    ``statechange``
        Sent when a device indicates it has detected a state change. Includes:
         - ``sender``: The device that changed state
         - ``state``: The resulting state (0 or 1)


See the pysignals_ documentation for further information.

Example: Registering a handler for when a Light Switch switches on or off::

    from ouimeaux.signals import statechange, receiver

    env = Environment(); env.start()
    env.discover(5)

    switch = env.get_switch('Porch Light')

    @receiver(statechange, sender=switch)
    def switch_toggle(device, **kwargs):
        print device, kwargs['state']

    env.wait()  # Pass control to the event loop

See the examples_ for a more detailed implementation.

.. _pysignals: https://github.com/theojulienne/PySignals

Switches
--------
Switches have three shortcut methods defined: ``get_state``, ``on`` and
``off``. Switches also have a ``blink`` method, which accepts a number of
seconds. This will toggle the device, wait the number of seconds, then toggle
it again. Remember to call ``env.wait()`` to give control to the event loop.

Motions
-------
Motions have one shortcut method defined: ``get_state``.

Insight
-------
In addition to the normal Switch methods, Insight switches have several metrics
exposed::

    insight.today_kwh
    insight.current_power
    insight.today_on_time
    insight.on_for
    insight.today_standby_time

Device Cache
------------
By default, device results are cached on the filesystem for quicker
initialization. This can be disabled by passing ``with_cache=False`` to the
``Environment`` constructor. On a related note, if you want to use the cache
exclusively, you can pass ``with_discovery=False`` to the ``Environment``
constructor to disable M-SEARCH requests.

You can clear the device cache either by deleting the file ``~/.wemo/cache`` 
or by using the ``wemo clear`` command.

Examples
--------
Detailed examples_ are included in the source demonstrating common use cases.
Suggestions (or implementations) for more are always welcome.

.. _examples: https://github.com/iancmcc/ouimeaux/tree/develop/ouimeaux/examples


================================================
FILE: docs/authors.rst
================================================
.. include:: ../AUTHORS.rst

================================================
FILE: docs/conf.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# complexity documentation build configuration file, created by
# sphinx-quickstart on Tue Jul  9 22:26:36 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('.'))

# Get the project root dir, which is the parent dir of this
cwd = os.getcwd()
project_root = os.path.dirname(cwd)

# Insert the project root dir as the first element in the PYTHONPATH.
# This lets us ensure that the source package is imported, and that its
# version is used.
sys.path.insert(0, project_root)

import ouimeaux

# -- 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'ouimeaux'
copyright = u'2014, Ian McCracken'

# 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 = ouimeaux.__version__
# The full version, including alpha/beta/rc tags.
release = ouimeaux.__version__

# 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 = 'ouimeauxdoc'


# -- 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', 'ouimeaux.tex', u'ouimeaux Documentation',
   u'Ian McCracken', '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', 'ouimeaux', u'ouimeaux Documentation',
     [u'Ian McCracken'], 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', 'ouimeaux', u'ouimeaux Documentation',
   u'Ian McCracken', 'ouimeaux', '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

================================================
FILE: docs/configuration.rst
================================================
=============
Configuration
=============

A configuration file in YAML format will be created at ``~/.wemo/config.yml``::

    # ip:port to bind to when receiving responses from discovery.
    # The default is first DNS resolution of local host, port 54321
    #
    # bind: 10.1.2.3:9090

    # Whether to use a device cache (stored at ~/.wemo/cache)
    #
    # cache: false

    aliases:
    # Shortcuts to longer device names. Uncommenting the following
    # line will allow you to execute 'wemo switch lr on' instead of
    # 'wemo switch "Living Room Lights" on'
    #
    #    lr: Living Room Lights

    # Web app bind address
    #
    # listen: 0.0.0.0:5000

    # Require basic authentication (username:password) for the web app
    #
    # auth: admin:password


================================================
FILE: docs/contributing.rst
================================================
.. include:: ../CONTRIBUTING.rst

================================================
FILE: docs/history.rst
================================================
.. include:: ../HISTORY.rst

================================================
FILE: docs/index.rst
================================================
.. complexity documentation master file, created by
   sphinx-quickstart on Tue Jul  9 22:26:36 2013.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Ouimeaux: Open Source WeMo Control
==================================

Contents:

.. toctree::
   :maxdepth: 2

   readme
   installation
   wemo
   server
   configuration
   api
   contributing
   authors
   history

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`


================================================
FILE: docs/installation.rst
================================================
============
Installation
============

Basic
-----
At the command line::

    $ easy_install ouimeaux

Or, if you have virtualenvwrapper installed::

    $ mkvirtualenv ouimeaux
    $ pip install ouimeaux

If you want to enable ``wemo server`` functionality, specify the ``server``
feature to install the necessary dependencies::

    $ pip install ouimeaux[server]

Linux
-----
ouimeaux requires Python header files to build some dependencies, and is
installed normally using pip or easy_install.

Debian/Ubuntu::

    sudo apt-get install python-setuptools python-dev

RHEL/CentOS/Fedora::

    sudo yum -y install python-setuptools python-devel

If you wish to build from a local copy of the source, you can of course always
execute::

    python setup.py install


Windows
-------
ouimeaux requires gevent version 1.0rc2 or higher. If you don't have the 
ability to compile gevent and greenlet (a sub-dependency) locally, you can 
find and download the binary installers for these packages here:

- gevent: https://github.com/SiteSupport/gevent/downloads
- greenlet: https://pypi.python.org/pypi/greenlet


================================================
FILE: docs/make.bat
================================================
@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\complexity.qhcp
	echo.To view the help file:
	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\complexity.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

================================================
FILE: docs/modules.rst
================================================
ouimeaux
========

.. toctree::
   :maxdepth: 4

   ouimeaux


================================================
FILE: docs/ouimeaux.device.api.rst
================================================
ouimeaux.device.api package
===========================

Subpackages
-----------

.. toctree::

    ouimeaux.device.api.xsd

Submodules
----------

ouimeaux.device.api.service module
----------------------------------

.. automodule:: ouimeaux.device.api.service
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.device.api
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.device.api.xsd.rst
================================================
ouimeaux.device.api.xsd package
===============================

Submodules
----------

ouimeaux.device.api.xsd.device module
-------------------------------------

.. automodule:: ouimeaux.device.api.xsd.device
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.device.api.xsd.service module
--------------------------------------

.. automodule:: ouimeaux.device.api.xsd.service
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.device.api.xsd
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.device.rst
================================================
ouimeaux.device package
=======================

Subpackages
-----------

.. toctree::

    ouimeaux.device.api

Submodules
----------

ouimeaux.device.insight module
------------------------------

.. automodule:: ouimeaux.device.insight
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.device.lightswitch module
----------------------------------

.. automodule:: ouimeaux.device.lightswitch
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.device.motion module
-----------------------------

.. automodule:: ouimeaux.device.motion
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.device.switch module
-----------------------------

.. automodule:: ouimeaux.device.switch
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.device
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.examples.rst
================================================
ouimeaux.examples package
=========================

Submodules
----------

ouimeaux.examples.watch module
------------------------------

.. automodule:: ouimeaux.examples.watch
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.examples
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.pysignals.rst
================================================
ouimeaux.pysignals package
==========================

Submodules
----------

ouimeaux.pysignals.dispatcher module
------------------------------------

.. automodule:: ouimeaux.pysignals.dispatcher
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.pysignals.inspect module
---------------------------------

.. automodule:: ouimeaux.pysignals.inspect
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.pysignals.weakref_backports module
-------------------------------------------

.. automodule:: ouimeaux.pysignals.weakref_backports
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.pysignals
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.rst
================================================
ouimeaux package
================

Subpackages
-----------

.. toctree::

    ouimeaux.device
    ouimeaux.examples
    ouimeaux.pysignals
    ouimeaux.server

Submodules
----------

ouimeaux.cli module
-------------------

.. automodule:: ouimeaux.cli
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.config module
----------------------

.. automodule:: ouimeaux.config
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.discovery module
-------------------------

.. automodule:: ouimeaux.discovery
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.environment module
---------------------------

.. automodule:: ouimeaux.environment
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.signals module
-----------------------

.. automodule:: ouimeaux.signals
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.subscribe module
-------------------------

.. automodule:: ouimeaux.subscribe
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.utils module
---------------------

.. automodule:: ouimeaux.utils
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.server.rst
================================================
ouimeaux.server package
=======================

Submodules
----------

ouimeaux.server.settings module
-------------------------------

.. automodule:: ouimeaux.server.settings
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.server
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/ouimeaux.xsd.rst
================================================
ouimeaux.xsd package
====================

Submodules
----------

ouimeaux.xsd.device module
--------------------------

.. automodule:: ouimeaux.xsd.device
    :members:
    :undoc-members:
    :show-inheritance:

ouimeaux.xsd.service module
---------------------------

.. automodule:: ouimeaux.xsd.service
    :members:
    :undoc-members:
    :show-inheritance:


Module contents
---------------

.. automodule:: ouimeaux.xsd
    :members:
    :undoc-members:
    :show-inheritance:


================================================
FILE: docs/readme.rst
================================================
.. include:: ../README.md


================================================
FILE: docs/server.rst
================================================
=======
Server
=======

``wemo server`` starts a process serving up both a Web app providing basic
device control and a REST API allowing integration with any number of services.

The necessary dependencies to run the server are not installed unless the
``server`` feature is specified at installation::

    $ pip install ouimeaux[server]

Configuration
-------------
The IP and port to which the server will bind are specified by the ``listen``
parameter in the configuration file. Default: ``0.0.0.0:5000``.  
Optionally, basic authentication can be enabled for the web server by 
setting the ``auth`` parameter in the configuration file.

Web App
--------
The Web app very simply presents buttons allowing control of devices and
indicating current state. Motions appear as disabled buttons but will turn
green when activated.

.. image:: webapp.png

REST API
---------
A vaguely RESTful API is provided to control devices. Arguments, where
specified, may be passed either as query arguments or as JSON::
    
    curl -X POST http://localhost:5000/api/environment -d '{"seconds":10}'

is as valid as::

    curl -X POST http://localhost:5000/api/environment?seconds=10

.. table::

   =====================         =========================================
   Resource                      Description
   =====================         =========================================
   GET /api/environment          Returns a JSON description of all devices 
                                 in the environment
   POST /api/environment         Initiates a discovery of the environment.
                                 Optional ``seconds`` argument (default: 5)
                                 determines length of discovery.
   GET /api/device/NAME          Returns a JSON description of the device 
                                 named NAME. NAME will be fuzzy-matched 
                                 against device names, as on the command
                                 line (e.g., "closet" will match "Hall 
                                 Closet"). 
   POST /api/device/NAME         Toggle switch state, specified by optional
                                 ``state`` argument (default: "toggle"). Valid
                                 values are "on", "off" or "toggle".
   =====================         =========================================


================================================
FILE: docs/wemo.rst
================================================
================
``wemo`` Command
================

The ``wemo`` script will discover devices in your environment and turn
switches on and off. To list devices::

    $ wemo list

Default is to search for 5 seconds; you can pass ``--timeout`` to change that.

You can also print the status of every device found in your environment (the
``-v`` option is available to print on/off instead of 0/1)::

    $ wemo status

To turn a switch on and off, you first have to know the name. Then::

    $ wemo switch "TV Room" on
    $ wemo switch "TV Room" off

You can also toggle the device::

    $ wemo switch "TV Room" toggle

Or check its current status (the ``-v`` option will print the word on/off
instead of 0/1)::

    $ wemo -v switch "TV Room" status
    on

WeMo LED Bulbs are supported on the command line as well. Control them like
switches with ``wemo light``::

    $ wemo light lamp on

Or set them to a dimness level from 1 to 255::

    $ wemo light lamp on 45

The ``wemo`` script will do fuzzy matching of the name you pass in (this can be
disabled with the ``-e`` option)::

    $ wemo switch tvrm on

Aliases configured in the file will be accessible on the command line as well::

    aliases:
        tv: TV Room Lights

    $ wemo switch tv on

Note: If an alias is used on the command line, fuzzy matching will not be
attempted.

The ``wemo`` script will obey configured settings; they can also be overridden
on the command line:

``-b``, ``--bind IP:PORT``
    Bind to this host and port when listening for responses

``-d``, ``--debug``
    Enable debug logging to stdout

``-e``, ``--exact-match``
    Disable fuzzy matching

``-v``, ``--human-readable``
    Print statuses as human-readable words

``-t``, ``--timeout``
    Time in seconds to allow for discovery


================================================
FILE: ouimeaux/__init__.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-

__author__ = 'Ian McCracken'
__email__ = 'ian.mccracken@gmail.com'
__version__ = '0.8.2'


================================================
FILE: ouimeaux/cli.py
================================================
import sys
import logging
import argparse

from .discovery import UPnPLoopbackException
from .environment import Environment
from .config import WemoConfiguration
from .utils import matcher

reqlog = logging.getLogger("requests.packages.urllib3.connectionpool")
reqlog.disabled = True

NOOP = lambda *x: None


def _state(device, readable=False):
    state = device.get_state(force_update=True)
    if readable:
        return "on" if state else "off"
    else:
        return state


def scan(args, on_switch=NOOP, on_motion=NOOP, on_bridge=NOOP, on_maker=NOOP):
    try:
        env = Environment(on_switch, on_motion, on_bridge, on_maker,
                          with_subscribers=False, bind=args.bind)
        env.start()
        env.discover(args.timeout)
    except KeyboardInterrupt:
        sys.exit(0)
    except UPnPLoopbackException:
        print("""
Loopback interface is being used! You will probably not receive any responses
from devices.  Use ifconfig to find your IP address, then either pass the
--bind argument or edit ~/.wemo/config.yml to specify the IP to which devices
should call back during discovery.""".strip())
        sys.exit(1)


def switch(args):
    if args.state.lower() in ("on", "1", "true"):
        state = "on"
    elif args.state.lower() in ("off", "0", "false"):
        state = "off"
    elif args.state.lower() == "toggle":
        state = "toggle"
    elif args.state.lower() == "status":
        state = "status"
    else:
        print("""No valid action specified.
Usage: wemo switch NAME (on|off|toggle|status)""")
        sys.exit(1)

    matches = make_matcher(args.device)

    def on_switch(switch):
        if matches(switch.name):
            if state == "toggle":
                found_state = switch.get_state(force_update=True)
                switch.set_state(not found_state)
            elif state == "status":
                print(_state(switch, args.human_readable))
            else:
                getattr(switch, state)()
            if args.device.lower() != 'all':
                sys.exit(0)

    scan(args, on_switch)
    if args.device != 'all':
        # If we got here, we didn't find anything
        print("No device found with that name.")
        sys.exit(1)


def light(args):
    if args.state.lower() in ("on", "1", "true"):
        state = "on"
    elif args.state.lower() in ("off", "0", "false"):
        state = "off"
    elif args.state.lower() == "toggle":
        state = "toggle"
    elif args.state.lower() == "status":
        state = "status"
    else:
        print("""No valid action specified.
Usage: wemo light NAME (on|off|toggle|status)""")
        sys.exit(1)

    matches = make_matcher(args.name)

    def on_switch(switch):
        pass

    def on_motion(motion):
        pass

    def on_bridge(bridge):
        bridge.bridge_get_lights()
        bridge.bridge_get_groups()
        for light in bridge.Lights:
            if matches(light):
                if args.state == "toggle":
                    found_state = bridge.light_get_state(bridge.Lights[light]).get('state')
                    bridge.light_set_state(bridge.Lights[light], state=not found_state)
                elif args.state == "status":
                    print(bridge.light_get_state(bridge.Lights[light]))
                else:
                    if args.state == "on":
                        if args.dim is not None:
                            if args.dim <= 255 and args.dim >= 0:
                                dim = args.dim
                                state = None
                            else:
                                print("""Invalid dim specified.
Dim must be between 0 and 255""")
                                sys.exit(1)
                        else:
                            dim = None
                            state = 1
                    else:
                        dim = None
                        state = 0
                    bridge.light_set_state(bridge.Lights[light], state=state, dim=dim)
                if args.name != 'all':
                    sys.exit(0)
        for group in bridge.Groups:
            if matches(group):
                if args.state == "toggle":
                    found_state = bridge.group_get_state(bridge.Groups[group]).get('state')
                    bridge.group_set_state(bridge.Groups[group], state=not found_state)
                elif args.state == "status":
                    print(bridge.group_get_state(bridge.Groups[group]))
                else:
                    if args.dim == None and args.state == "on":
                        dim = bridge.group_get_state(bridge.Groups[group]).get('dim')
                        state = 1
                    elif args.state == "off":
                        dim = None
                        state = 0
                    elif args.dim <= 255 and args.dim >= 0:
                        dim = args.dim
                        state = 1
                    else:
                        print("""Invalid dim specified.
Dim must be between 0 and 255""")
                        sys.exit(1)
                    bridge.group_set_state(bridge.Groups[group], state=state, dim=dim)
                sys.exit(0)

    scan(args, on_switch, on_motion, on_bridge)
    if args.name != 'all':
        # If we got here, we didn't find anything
        print("No device or group found with that name.")
        sys.exit(1)


def make_matcher(device_name):
    alias = WemoConfiguration().aliases.get(device_name)
    if device_name.lower() in ('all', 'any'):
        matches = lambda x: True
    elif alias:
        matches = lambda x: x == alias
    elif device_name:
        matches = matcher(device_name)
    else:
        matches = NOOP
    return matches


def maker(args):
    if args.state.lower() in ("on", "1", "true"):
        state = "on"
    elif args.state.lower() in ("off", "0", "false"):
        state = "off"
    elif args.state.lower() == "toggle":
        state = "toggle"
    elif args.state.lower() == "sensor":
        state = "sensor"
    elif args.state.lower() == "switch":
        state = "switch"
    else:
        print("""No valid action specified.
Usage: wemo maker NAME (on|off|toggle|sensor|switch)""")
        sys.exit(1)

    matches = make_matcher(args.device)

    def on_switch(maker):
        return

    def on_motion(maker):
        return

    def on_bridge(maker):
        return

    def on_maker(maker):
        if matches(maker.name):
            if state == "toggle":
                found_state = maker.get_state(force_update=True)
                maker.set_state(not found_state)
            elif state == "sensor":
                if maker.has_sensor:
                    if args.human_readable:
                        if maker.sensor_state:
                            sensorstate = 'Sensor not triggered'
                        else:
                            sensorstate = 'Sensor triggered'
                        print(sensorstate)
                    else:
                        print(maker.sensor_state)
                else:
                    print("Sensor not present")
            elif state == "switch":
                if maker.switch_mode:
                    print("Momentary Switch")
                else:
                    print(_state(maker, args.human_readable))
            else:
                getattr(maker, state)()
            if args.device != 'all':
                sys.exit(0)

    scan(args, on_switch, on_motion, on_bridge, on_maker)
    if args.device != 'all':
        # If we got here, we didn't find anything
        print("No device found with that name.")
        sys.exit(1)


def list_(args):
    def on_switch(switch):
        print("Switch:", switch.name)

    def on_motion(motion):
        print("Motion:", motion.name)

    def on_maker(maker):
        print("Maker:", maker.name)

    def on_bridge(bridge):
        print("Bridge:", bridge.name)
        bridge.bridge_get_lights()
        bridge.bridge_get_groups()
        for group in bridge.Groups:
            print("Group:", group)
        for light in bridge.Lights:
            print("Light:", light)

    scan(args, on_switch, on_motion, on_bridge, on_maker)


def status(args):
    def on_switch(switch):
        print("Switch:", switch.name, '\t', _state(switch, args.human_readable))

    def on_motion(motion):
        print("Motion:", motion.name, '\t', _state(motion, args.human_readable))

    def on_maker(maker):
        if maker.switch_mode:
            print("Maker:", maker.name, '\t', "Momentary State:", _state(maker, args.human_readable))
        else:
            print("Maker:", maker.name, '\t', "Persistent State:", _state(maker, args.human_readable))
        if maker.has_sensor:
            if args.human_readable:
                if maker.sensor_state:
                    sensorstate = 'Sensor not triggered'
                else:
                    sensorstate = 'Sensor triggered'
                print('\t\t\t', "Sensor:", sensorstate)
            else:
                print('\t\t\t', "Sensor:", maker.sensor_state)
        else:
            print('\t\t\t' "Sensor not present")

    def on_bridge(bridge):
        print("Bridge:", bridge.name, '\t', _state(bridge, args.human_readable))
        bridge.bridge_get_lights()
        for light in bridge.Lights:
            print("Light:", light, '\t', bridge.light_get_state(bridge.Lights[light]))
        for group in bridge.Groups:
            print("Group:", group, '\t', bridge.group_get_state(bridge.Groups[group]))

    scan(args, on_switch, on_motion, on_bridge, on_maker)


def server(args):
    try:
        from socketio.server import SocketIOServer
        from ouimeaux.server import app, initialize
    except ImportError:
        print("ouimeaux server dependencies are not installed. Please run, e.g., 'pip install ouimeaux[server]'")
        sys.exit(1)
    initialize(bind=getattr(args, 'bind', None), auth=(WemoConfiguration().auth or None))
    level = logging.INFO
    if getattr(args, 'debug', False):
        level = logging.DEBUG
    logging.basicConfig(level=level)
    try:
        # TODO: Move this to configuration
        listen = WemoConfiguration().listen or '0.0.0.0:5000'
        try:
            host, port = listen.split(':')
        except Exception:
            print("Invalid bind address configuration:", listen)
            sys.exit(1)
        SocketIOServer((host, int(port)), app,
                       policy_server=False,
                       namespace="socket.io").serve_forever()
    except (KeyboardInterrupt, SystemExit):
        sys.exit(0)


def wemo():
    import ouimeaux.utils
    ouimeaux.utils._RETRIES = 0

    parser = argparse.ArgumentParser()

    parser.add_argument("-b", "--bind", default=None,
                        help="ip:port to which to bind the response server."
                             " Default is localhost:54321")
    parser.add_argument("-d", "--debug", action="store_true", default=False,
                        help="Enable debug logging")
    parser.add_argument("-e", "--exact-match", action="store_true",
                        default=False,
                        help="Disable fuzzy matching for device names")
    parser.add_argument("-v", "--human-readable", dest="human_readable",
                        action="store_true", default=False,
                        help="Print statuses as human-readable words")
    parser.add_argument("-t", "--timeout", type=int, default=5,
                        help="Time in seconds to allow for discovery")
    subparsers = parser.add_subparsers()

    statusparser = subparsers.add_parser("status",
                                         help="Print status of WeMo devices")
    statusparser.set_defaults(func=status)

    stateparser = subparsers.add_parser("switch",
                                        help="Turn a WeMo Switch on or off")
    stateparser.add_argument("device", help="Name or alias of the device")
    stateparser.add_argument("state", help="'on' or 'off'")
    stateparser.set_defaults(func=switch)

    makerparser = subparsers.add_parser("maker",
                                        help="Get sensor or switch state of a Maker or Turn on or off")
    makerparser.add_argument("device", help="Name or alias of the device")
    makerparser.add_argument("state", help="'on' or 'off' or 'toggle' or 'sensor' or 'switch'")
    makerparser.set_defaults(func=maker)

    stateparser = subparsers.add_parser("light",
                                        help="Turn a WeMo LED light on or off")
    stateparser.add_argument("name", help="Name or alias of the device or group")
    stateparser.add_argument("state", help="'on' or 'off'")
    stateparser.add_argument("dim", nargs='?', type=int,
                             help="Dim value 0 to 255")
    stateparser.set_defaults(func=light)

    listparser = subparsers.add_parser("list",
                                       help="List all devices found in the environment")
    listparser.set_defaults(func=list_)

    serverparser = subparsers.add_parser("server",
                                         help="Run the API server and web app")
    serverparser.set_defaults(func=server)

    args = parser.parse_args()

    if getattr(args, 'debug', False):
        logging.basicConfig(level=logging.DEBUG)

    if hasattr(args, 'func'):
        args.func(args)
    else:
        parser.print_help(sys.stderr)


================================================
FILE: ouimeaux/config.py
================================================
import os
import yaml


def in_home(*path):
    try:
        from win32com.shell import shellcon, shell
    except ImportError:
        home = os.path.expanduser("~")
    else:
        home = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)
    return os.path.join(home, *path)


def ensure_directory(directory):
    if not os.path.exists(directory):
        os.makedirs(directory)
    return directory


class WemoConfiguration(object):
    def __init__(self, filename=None):
        if filename is None:
            ensure_directory(in_home('.wemo'))
            filename = in_home('.wemo', 'config.yml')
        if not os.path.isfile(filename):
            with open(filename, 'w') as f:
                f.write("""
aliases:
# Shortcuts to longer device names. Uncommenting the following
# line will allow you to execute 'wemo switch lr on' instead of
# 'wemo switch "Living Room Lights" on'
#
#    lr: Living Room Lights

# ip:port to bind to when receiving responses from discovery.
# The default is first DNS resolution of local host, port 54321
#
# bind: 10.1.2.3:9090

# Web app bind address
#
# listen: 0.0.0.0:5000

# Require basic authentication (username:password) for the web app
#
# auth: admin:password
""")
        with open(filename, 'r') as cfg:
            self._parsed = yaml.load(cfg, Loader=yaml.FullLoader)

    @property
    def aliases(self):
        return self._parsed.get('aliases') or {}

    @property
    def bind(self):
        return self._parsed.get('bind', None)

    @property
    def listen(self):
        return self._parsed.get('listen', None)

    @property
    def auth(self):
        return self._parsed.get('auth', None)


================================================
FILE: ouimeaux/device/__init__.py
================================================
import logging
from six.moves.urllib.parse import urlsplit

from .api.service import Service
from .api.xsd import device as deviceParser
from ..utils import requests_get


log = logging.getLogger(__name__)


class DeviceUnreachable(Exception): pass
class UnknownService(Exception): pass


class Device(object):
    def __init__(self, url):
        self._state = None
        base_url = url.rsplit('/', 1)[0]
        self.host = urlsplit(url).hostname
        #self.port = urlsplit(url).port
        xml = requests_get(url)
        self._config = deviceParser.parseString(xml.content).device
        sl = self._config.serviceList
        self.services = {}
        for svc in sl.service:
            svcname = svc.get_serviceType().split(':')[-2]
            service = Service(svc, base_url)
            service.eventSubURL = base_url + svc.get_eventSubURL()
            self.services[svcname] = service
            setattr(self, svcname, service)

    def _update_state(self, value):
        self._state = int(value)

    def get_state(self, force_update=False):
        """
        Returns 0 if off and 1 if on.
        """
        if force_update or self._state is None:
            return int(self.basicevent.GetBinaryState()['BinaryState'])
        return self._state

    def __getstate__(self):
        odict = self.__dict__.copy() # copy the dict since we change it
        if 'register_listener' in odict:
            del odict['register_listener']
        return odict

    def get_service(self, name):
        try:
            return self.services[name]
        except KeyError:
            raise UnknownService(name)

    def list_services(self):
        return self.services.keys()

    def ping(self):
        try:
            self.get_state()
        except Exception:
            raise DeviceUnreachable(self)

    def explain(self):
        for name, svc in self.services.items():
            print(name)
            print('-' * len(name))
            for aname, action in svc.actions.items():
                print("  %s(%s)" % (aname, ', '.join(action.args)))
            print()

    @property
    def model(self):
        return self._config.get_modelDescription()

    @property
    def name(self):
        return self._config.get_friendlyName()

    @property
    def serialnumber(self):
        return self._config.get_serialNumber()


def test():
    device = Device("http://10.42.1.102:49152/setup.xml")
    print(device.get_service('basicevent').SetBinaryState(BinaryState=1))


if __name__ == "__main__":
    test()



================================================
FILE: ouimeaux/device/api/__init__.py
================================================


================================================
FILE: ouimeaux/device/api/service.py
================================================
import logging
from xml.etree import ElementTree as et

from ...utils import requests_get, requests_post
from .xsd import service as serviceParser


log = logging.getLogger(__name__)

REQUEST_TEMPLATE = """
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
 <s:Body>
  <u:{action} xmlns:u="{service}">
   {args}
  </u:{action}>
 </s:Body>
</s:Envelope>
"""


class Action(object):
    def __init__(self, service, action_config):
        self._action_config = action_config
        self.name = action_config.get_name()
        self.serviceType = service.serviceType
        self.controlURL = service.controlURL
        self.args = {}
        self.headers = {
            'Content-Type': 'text/xml',
            'SOAPACTION': '"%s#%s"' % (self.serviceType, self.name)
        }
        arglist = action_config.get_argumentList()
        if arglist is not None:
            for arg in arglist.get_argument():
                name = arg.get_name()
                if name:
                    # TODO: Get type instead of setting 0
                    self.args[arg.get_name()] = 0

    def __call__(self, **kwargs):
        arglist = '\n'.join('<{0}>{1}</{0}>'.format(arg, value)
                            for arg, value in kwargs.items())
        body = REQUEST_TEMPLATE.format(
            action=self.name,
            service=self.serviceType,
            args=arglist
        )
        response = requests_post(self.controlURL, body.strip(), headers=self.headers)
        d = {}
        for r in list(list(list(et.fromstring(response.content))[0])[0]):
            d[r.tag] = r.text
        return d

    def __repr__(self):
        return "<Action %s(%s)>" % (self.name, ", ".join(self.args))


class Service(object):
    """
    Represents an instance of a service on a device.
    """

    def __init__(self, service, base_url):
        self._base_url = base_url.rstrip('/')
        self._config = service
        url = '%s/%s' % (base_url, service.get_SCPDURL().strip('/'))
        xml = requests_get(url)
        self.actions = {}
        self._svc_config = serviceParser.parseString(xml.content).actionList
        for action in self._svc_config.get_action():
            act = Action(self, action)
            name = action.get_name()
            self.actions[name] = act
            setattr(self, name, act)

    @property
    def hostname(self):
        return self._base_url.split('/')[-1]

    @property
    def controlURL(self):
        return '%s/%s' % (self._base_url,
                          self._config.get_controlURL().strip('/'))

    @property
    def serviceType(self):
        return self._config.get_serviceType()


================================================
FILE: ouimeaux/device/api/xsd/__init__.py
================================================


================================================
FILE: ouimeaux/device/api/xsd/device.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# Generated Thu Jan 31 15:50:44 2013 by generateDS.py version 2.8b.
#

import sys
import getopt
import re as re_
import base64
from datetime import datetime, tzinfo, timedelta

etree_ = None
Verbose_import_ = False
(   XMLParser_import_none, XMLParser_import_lxml,
    XMLParser_import_elementtree
    ) = range(3)
XMLParser_import_library = None
try:
    # lxml
    from lxml import etree as etree_
    XMLParser_import_library = XMLParser_import_lxml
    if Verbose_import_:
        print("running with lxml.etree")
except ImportError:
    try:
        # cElementTree from Python 2.5+
        import xml.etree.cElementTree as etree_
        XMLParser_import_library = XMLParser_import_elementtree
        if Verbose_import_:
            print("running with cElementTree on Python 2.5+")
    except ImportError:
        try:
            # ElementTree from Python 2.5+
            import xml.etree.ElementTree as etree_
            XMLParser_import_library = XMLParser_import_elementtree
            if Verbose_import_:
                print("running with ElementTree on Python 2.5+")
        except ImportError:
            try:
                # normal cElementTree install
                import cElementTree as etree_
                XMLParser_import_library = XMLParser_import_elementtree
                if Verbose_import_:
                    print("running with cElementTree")
            except ImportError:
                try:
                    # normal ElementTree install
                    import elementtree.ElementTree as etree_
                    XMLParser_import_library = XMLParser_import_elementtree
                    if Verbose_import_:
                        print("running with ElementTree")
                except ImportError:
                    raise ImportError(
                        "Failed to import ElementTree from any known place")

def parsexml_(*args, **kwargs):
    if (XMLParser_import_library == XMLParser_import_lxml and
        'parser' not in kwargs):
        # Use the lxml ElementTree compatible parser so that, e.g.,
        #   we ignore comments.
        kwargs['parser'] = etree_.ETCompatXMLParser()
    doc = etree_.parse(*args, **kwargs)
    return doc

#
# User methods
#
# Calls to the methods in these classes are generated by generateDS.py.
# You can replace these methods by re-implementing the following class
#   in a module named generatedssuper.py.

try:
    from generatedssuper import GeneratedsSuper
except ImportError as exp:

    class GeneratedsSuper(object):
        tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$')
        class _FixedOffsetTZ(tzinfo):
            def __init__(self, offset, name):
                self.__offset = timedelta(minutes = offset)
                self.__name = name
            def utcoffset(self, dt):
                return self.__offset
            def tzname(self, dt):
                return self.__name
            def dst(self, dt):
                return None
        def gds_format_string(self, input_data, input_name=''):
            return input_data
        def gds_validate_string(self, input_data, node, input_name=''):
            return input_data
        def gds_format_base64(self, input_data, input_name=''):
            return base64.b64encode(input_data)
        def gds_validate_base64(self, input_data, node, input_name=''):
            return input_data
        def gds_format_integer(self, input_data, input_name=''):
            return '%d' % input_data
        def gds_validate_integer(self, input_data, node, input_name=''):
            return input_data
        def gds_format_integer_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_integer_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                try:
                    fvalue = float(value)
                except (TypeError, ValueError) as exp:
                    raise_parse_error(node, 'Requires sequence of integers')
            return input_data
        def gds_format_float(self, input_data, input_name=''):
            return '%f' % input_data
        def gds_validate_float(self, input_data, node, input_name=''):
            return input_data
        def gds_format_float_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_float_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                try:
                    fvalue = float(value)
                except (TypeError, ValueError) as exp:
                    raise_parse_error(node, 'Requires sequence of floats')
            return input_data
        def gds_format_double(self, input_data, input_name=''):
            return '%e' % input_data
        def gds_validate_double(self, input_data, node, input_name=''):
            return input_data
        def gds_format_double_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_double_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                try:
                    fvalue = float(value)
                except (TypeError, ValueError) as exp:
                    raise_parse_error(node, 'Requires sequence of doubles')
            return input_data
        def gds_format_boolean(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_boolean(self, input_data, node, input_name=''):
            return input_data
        def gds_format_boolean_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_boolean_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                if value not in ('true', '1', 'false', '0', ):
                    raise_parse_error(node,
                        'Requires sequence of booleans '
                        '("true", "1", "false", "0")')
            return input_data
        def gds_validate_datetime(self, input_data, node, input_name=''):
            return input_data
        def gds_format_datetime(self, input_data, input_name=''):
            if input_data.microsecond == 0:
                _svalue = input_data.strftime('%Y-%m-%dT%H:%M:%S')
            else:
                _svalue = input_data.strftime('%Y-%m-%dT%H:%M:%S.%f')
            if input_data.tzinfo is not None:
                tzoff = input_data.tzinfo.utcoffset(input_data)
                if tzoff is not None:
                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
                    if total_seconds == 0:
                        _svalue += 'Z'
                    else:
                        if total_seconds < 0:
                            _svalue += '-'
                            total_seconds *= -1
                        else:
                            _svalue += '+'
                        hours = total_seconds // 3600
                        minutes = (total_seconds - (hours * 3600)) // 60
                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
            return _svalue
        def gds_parse_datetime(self, input_data, node, input_name=''):
            tz = None
            if input_data[-1] == 'Z':
                tz = GeneratedsSuper._FixedOffsetTZ(0, 'GMT')
                input_data = input_data[:-1]
            else:
                results = GeneratedsSuper.tzoff_pattern.search(input_data)
                if results is not None:
                    tzoff_parts = results.group(2).split(':')
                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
                    if results.group(1) == '-':
                        tzoff *= -1
                    tz = GeneratedsSuper._FixedOffsetTZ(
                        tzoff, results.group(0))
                    input_data = input_data[:-6]
            if len(input_data.split('.')) > 1:
                dt = datetime.strptime(
                        input_data, '%Y-%m-%dT%H:%M:%S.%f')
            else:
                dt = datetime.strptime(
                        input_data, '%Y-%m-%dT%H:%M:%S')
            return dt.replace(tzinfo = tz)

        def gds_validate_date(self, input_data, node, input_name=''):
            return input_data
        def gds_format_date(self, input_data, input_name=''):
            _svalue = input_data.strftime('%Y-%m-%d')
            if input_data.tzinfo is not None:
                tzoff = input_data.tzinfo.utcoffset(input_data)
                if tzoff is not None:
                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
                    if total_seconds == 0:
                        _svalue += 'Z'
                    else:
                        if total_seconds < 0:
                            _svalue += '-'
                            total_seconds *= -1
                        else:
                            _svalue += '+'
                        hours = total_seconds // 3600
                        minutes = (total_seconds - (hours * 3600)) // 60
                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
            return _svalue
        def gds_parse_date(self, input_data, node, input_name=''):
            tz = None
            if input_data[-1] == 'Z':
                tz = GeneratedsSuper._FixedOffsetTZ(0, 'GMT')
                input_data = input_data[:-1]
            else:
                results = GeneratedsSuper.tzoff_pattern.search(input_data)
                if results is not None:
                    tzoff_parts = results.group(2).split(':')
                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
                    if results.group(1) == '-':
                        tzoff *= -1
                    tz = GeneratedsSuper._FixedOffsetTZ(
                        tzoff, results.group(0))
                    input_data = input_data[:-6]
            return datetime.strptime(input_data,
                '%Y-%m-%d').replace(tzinfo = tz)
        def gds_str_lower(self, instring):
            return instring.lower()
        def get_path_(self, node):
            path_list = []
            self.get_path_list_(node, path_list)
            path_list.reverse()
            path = '/'.join(path_list)
            return path
        Tag_strip_pattern_ = re_.compile(r'\{.*\}')
        def get_path_list_(self, node, path_list):
            if node is None:
                return
            tag = GeneratedsSuper.Tag_strip_pattern_.sub('', node.tag)
            if tag:
                path_list.append(tag)
            self.get_path_list_(node.getparent(), path_list)
        def get_class_obj_(self, node, default_class=None):
            class_obj1 = default_class
            if 'xsi' in node.nsmap:
                classname = node.get('{%s}type' % node.nsmap['xsi'])
                if classname is not None:
                    names = classname.split(':')
                    if len(names) == 2:
                        classname = names[1]
                    class_obj2 = globals().get(classname)
                    if class_obj2 is not None:
                        class_obj1 = class_obj2
            return class_obj1
        def gds_build_any(self, node, type_name=None):
            return None


#
# If you have installed IPython you can uncomment and use the following.
# IPython is available from http://ipython.scipy.org/.
#

## from IPython.Shell import IPShellEmbed
## args = ''
## ipshell = IPShellEmbed(args,
##     banner = 'Dropping into IPython',
##     exit_msg = 'Leaving Interpreter, back to program.')

# Then use the following line where and when you want to drop into the
# IPython shell:
#    ipshell('<some message> -- Entering ipshell.\nHit Ctrl-D to exit')

#
# Globals
#

ExternalEncoding = 'ascii'
Tag_pattern_ = re_.compile(r'({.*})?(.*)')
String_cleanup_pat_ = re_.compile(r"[\n\r\s]+")
Namespace_extract_pat_ = re_.compile(r'{(.*)}(.*)')

#
# Support/utility functions.
#

def showIndent(outfile, level, pretty_print=True):
    if pretty_print:
        for idx in range(level):
            outfile.write('    ')

def quote_xml(inStr):
    if not inStr:
        return ''
    s1 = (isinstance(inStr, basestring) and inStr or
          '%s' % inStr)
    s1 = s1.replace('&', '&amp;')
    s1 = s1.replace('<', '&lt;')
    s1 = s1.replace('>', '&gt;')
    return s1

def quote_attrib(inStr):
    s1 = (isinstance(inStr, basestring) and inStr or
          '%s' % inStr)
    s1 = s1.replace('&', '&amp;')
    s1 = s1.replace('<', '&lt;')
    s1 = s1.replace('>', '&gt;')
    if '"' in s1:
        if "'" in s1:
            s1 = '"%s"' % s1.replace('"', "&quot;")
        else:
            s1 = "'%s'" % s1
    else:
        s1 = '"%s"' % s1
    return s1

def quote_python(inStr):
    s1 = inStr
    if s1.find("'") == -1:
        if s1.find('\n') == -1:
            return "'%s'" % s1
        else:
            return "'''%s'''" % s1
    else:
        if s1.find('"') != -1:
            s1 = s1.replace('"', '\\"')
        if s1.find('\n') == -1:
            return '"%s"' % s1
        else:
            return '"""%s"""' % s1

def get_all_text_(node):
    if node.text is not None:
        text = node.text
    else:
        text = ''
    for child in node:
        if child.tail is not None:
            text += child.tail
    return text

def find_attr_value_(attr_name, node):
    attrs = node.attrib
    attr_parts = attr_name.split(':')
    value = None
    if len(attr_parts) == 1:
        value = attrs.get(attr_name)
    elif len(attr_parts) == 2:
        prefix, name = attr_parts
        namespace = node.nsmap.get(prefix)
        if namespace is not None:
            value = attrs.get('{%s}%s' % (namespace, name, ))
    return value


class GDSParseError(Exception):
    pass

def raise_parse_error(node, msg):
    if XMLParser_import_library == XMLParser_import_lxml:
        msg = '%s (element %s/line %d)' % (
            msg, node.tag, node.sourceline, )
    else:
        msg = '%s (element %s)' % (msg, node.tag, )
    raise GDSParseError(msg)


class MixedContainer:
    # Constants for category:
    CategoryNone = 0
    CategoryText = 1
    CategorySimple = 2
    CategoryComplex = 3
    # Constants for content_type:
    TypeNone = 0
    TypeText = 1
    TypeString = 2
    TypeInteger = 3
    TypeFloat = 4
    TypeDecimal = 5
    TypeDouble = 6
    TypeBoolean = 7
    TypeBase64 = 8
    def __init__(self, category, content_type, name, value):
        self.category = category
        self.content_type = content_type
        self.name = name
        self.value = value
    def getCategory(self):
        return self.category
    def getContenttype(self, content_type):
        return self.content_type
    def getValue(self):
        return self.value
    def getName(self):
        return self.name
    def export(self, outfile, level, name, namespace, pretty_print=True):
        if self.category == MixedContainer.CategoryText:
            # Prevent exporting empty content as empty lines.
            if self.value.strip():
                outfile.write(self.value)
        elif self.category == MixedContainer.CategorySimple:
            self.exportSimple(outfile, level, name)
        else:    # category == MixedContainer.CategoryComplex
            self.value.export(outfile, level, namespace, name, pretty_print)
    def exportSimple(self, outfile, level, name):
        if self.content_type == MixedContainer.TypeString:
            outfile.write('<%s>%s</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeInteger or \
                self.content_type == MixedContainer.TypeBoolean:
            outfile.write('<%s>%d</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeFloat or \
                self.content_type == MixedContainer.TypeDecimal:
            outfile.write('<%s>%f</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeDouble:
            outfile.write('<%s>%g</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeBase64:
            outfile.write('<%s>%s</%s>' %
                (self.name, base64.b64encode(self.value), self.name))
    def exportLiteral(self, outfile, level, name):
        if self.category == MixedContainer.CategoryText:
            showIndent(outfile, level)
            outfile.write('model_.MixedContainer(%d, %d, "%s", "%s"),\n'
                % (self.category, self.content_type, self.name, self.value))
        elif self.category == MixedContainer.CategorySimple:
            showIndent(outfile, level)
            outfile.write('model_.MixedContainer(%d, %d, "%s", "%s"),\n'
                % (self.category, self.content_type, self.name, self.value))
        else:    # category == MixedContainer.CategoryComplex
            showIndent(outfile, level)
            outfile.write('model_.MixedContainer(%d, %d, "%s",\n' % \
                (self.category, self.content_type, self.name,))
            self.value.exportLiteral(outfile, level + 1)
            showIndent(outfile, level)
            outfile.write(')\n')


class MemberSpec_(object):
    def __init__(self, name='', data_type='', container=0):
        self.name = name
        self.data_type = data_type
        self.container = container
    def set_name(self, name): self.name = name
    def get_name(self): return self.name
    def set_data_type(self, data_type): self.data_type = data_type
    def get_data_type_chain(self): return self.data_type
    def get_data_type(self):
        if isinstance(self.data_type, list):
            if len(self.data_type) > 0:
                return self.data_type[-1]
            else:
                return 'xs:string'
        else:
            return self.data_type
    def set_container(self, container): self.container = container
    def get_container(self): return self.container

def _cast(typ, value):
    if typ is None or value is None:
        return value
    return typ(value)

#
# Data representation classes.
#

class root(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, specVersion=None, URLBase=None, device=None):
        self.specVersion = specVersion
        self.URLBase = URLBase
        self.device = device
        self.anyAttributes_ = {}
    def factory(*args_, **kwargs_):
        if root.subclass:
            return root.subclass(*args_, **kwargs_)
        else:
            return root(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_specVersion(self): return self.specVersion
    def set_specVersion(self, specVersion): self.specVersion = specVersion
    def get_URLBase(self): return self.URLBase
    def set_URLBase(self, URLBase): self.URLBase = URLBase
    def get_device(self): return self.device
    def set_device(self, device): self.device = device
    def get_anyAttributes_(self): return self.anyAttributes_
    def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_
    def export(self, outfile, level, namespace_='tns:', name_='root', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='root')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='root'):
        unique_counter = 0
        for name, value in self.anyAttributes_.items():
            xsinamespaceprefix = 'xsi'
            xsinamespace1 = 'http://www.w3.org/2001/XMLSchema-instance'
            xsinamespace2 = '{%s}' % (xsinamespace1, )
            if name.startswith(xsinamespace2):
                name1 = name[len(xsinamespace2):]
                name2 = '%s:%s' % (xsinamespaceprefix, name1, )
                if name2 not in already_processed:
                    already_processed.append(name2)
                    outfile.write(' %s=%s' % (name2, quote_attrib(value), ))
            else:
                mo = re_.match(Namespace_extract_pat_, name)
                if mo is not None:
                    namespace, name = mo.group(1, 2)
                    if name not in already_processed:
                        already_processed.append(name)
                        if namespace == 'http://www.w3.org/XML/1998/namespace':
                            outfile.write(' %s=%s' % (
                                name, quote_attrib(value), ))
                        else:
                            unique_counter += 1
                            outfile.write(' xmlns:yyy%d="%s"' % (
                                unique_counter, namespace, ))
                            outfile.write(' yyy%d:%s=%s' % (
                                unique_counter, name, quote_attrib(value), ))
                else:
                    if name not in already_processed:
                        already_processed.append(name)
                        outfile.write(' %s=%s' % (
                            name, quote_attrib(value), ))
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='root', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.specVersion is not None:
            self.specVersion.export(outfile, level, namespace_, name_='specVersion', pretty_print=pretty_print)
        if self.URLBase is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sURLBase>%s</%sURLBase>%s' % (namespace_, self.gds_format_string(quote_xml(self.URLBase).encode(ExternalEncoding), input_name='URLBase'), namespace_, eol_))
        if self.device is not None:
            self.device.export(outfile, level, namespace_, name_='device', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.specVersion is not None or
            self.URLBase is not None or
            self.device is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='root'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        for name, value in self.anyAttributes_.items():
            showIndent(outfile, level)
            outfile.write('%s = "%s",\n' % (name, value,))
    def exportLiteralChildren(self, outfile, level, name_):
        if self.specVersion is not None:
            showIndent(outfile, level)
            outfile.write('specVersion=model_.SpecVersionType(\n')
            self.specVersion.exportLiteral(outfile, level, name_='specVersion')
            showIndent(outfile, level)
            outfile.write('),\n')
        if self.URLBase is not None:
            showIndent(outfile, level)
            outfile.write('URLBase=%s,\n' % quote_python(self.URLBase).encode(ExternalEncoding))
        if self.device is not None:
            showIndent(outfile, level)
            outfile.write('device=model_.DeviceType(\n')
            self.device.exportLiteral(outfile, level, name_='device')
            showIndent(outfile, level)
            outfile.write('),\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        self.anyAttributes_ = {}
        for name, value in attrs.items():
            if name not in already_processed:
                self.anyAttributes_[name] = value
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'specVersion':
            obj_ = SpecVersionType.factory()
            obj_.build(child_)
            self.set_specVersion(obj_)
        elif nodeName_ == 'URLBase':
            URLBase_ = child_.text
            URLBase_ = self.gds_validate_string(URLBase_, node, 'URLBase')
            self.URLBase = URLBase_
        elif nodeName_ == 'device':
            obj_ = DeviceType.factory()
            obj_.build(child_)
            self.set_device(obj_)
# end class root


class SpecVersionType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, major=None, minor=None):
        self.major = major
        self.minor = minor
    def factory(*args_, **kwargs_):
        if SpecVersionType.subclass:
            return SpecVersionType.subclass(*args_, **kwargs_)
        else:
            return SpecVersionType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_major(self): return self.major
    def set_major(self, major): self.major = major
    def get_minor(self): return self.minor
    def set_minor(self, minor): self.minor = minor
    def export(self, outfile, level, namespace_='tns:', name_='SpecVersionType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='SpecVersionType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='SpecVersionType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='SpecVersionType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.major is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smajor>%s</%smajor>%s' % (namespace_, self.gds_format_integer(self.major, input_name='major'), namespace_, eol_))
        if self.minor is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sminor>%s</%sminor>%s' % (namespace_, self.gds_format_integer(self.minor, input_name='minor'), namespace_, eol_))
    def hasContent_(self):
        if (
            self.major is not None or
            self.minor is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='SpecVersionType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.major is not None:
            showIndent(outfile, level)
            outfile.write('major=%d,\n' % self.major)
        if self.minor is not None:
            showIndent(outfile, level)
            outfile.write('minor=%d,\n' % self.minor)
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'major':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'major')
            self.major = ival_
        elif nodeName_ == 'minor':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'minor')
            self.minor = ival_
# end class SpecVersionType


class DeviceType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, deviceType=None, friendlyName=None, manufacturer=None, manufacturerURL=None, modelDescription=None, modelName=None, modelNumber=None, modelURL=None, serialNumber=None, UDN=None, UPC=None, iconList=None, serviceList=None, deviceList=None, presentationURL=None, anytypeobjs_=None):
        self.deviceType = deviceType
        self.friendlyName = friendlyName
        self.manufacturer = manufacturer
        self.manufacturerURL = manufacturerURL
        self.modelDescription = modelDescription
        self.modelName = modelName
        self.modelNumber = modelNumber
        self.modelURL = modelURL
        self.serialNumber = serialNumber
        self.UDN = UDN
        self.UPC = UPC
        self.iconList = iconList
        self.serviceList = serviceList
        self.deviceList = deviceList
        self.presentationURL = presentationURL
        if anytypeobjs_ is None:
            self.anytypeobjs_ = []
        else:
            self.anytypeobjs_ = anytypeobjs_
    def factory(*args_, **kwargs_):
        if DeviceType.subclass:
            return DeviceType.subclass(*args_, **kwargs_)
        else:
            return DeviceType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_deviceType(self): return self.deviceType
    def set_deviceType(self, deviceType): self.deviceType = deviceType
    def get_friendlyName(self): return self.friendlyName
    def set_friendlyName(self, friendlyName): self.friendlyName = friendlyName
    def get_manufacturer(self): return self.manufacturer
    def set_manufacturer(self, manufacturer): self.manufacturer = manufacturer
    def get_manufacturerURL(self): return self.manufacturerURL
    def set_manufacturerURL(self, manufacturerURL): self.manufacturerURL = manufacturerURL
    def get_modelDescription(self): return self.modelDescription
    def set_modelDescription(self, modelDescription): self.modelDescription = modelDescription
    def get_modelName(self): return self.modelName
    def set_modelName(self, modelName): self.modelName = modelName
    def get_modelNumber(self): return self.modelNumber
    def set_modelNumber(self, modelNumber): self.modelNumber = modelNumber
    def get_modelURL(self): return self.modelURL
    def set_modelURL(self, modelURL): self.modelURL = modelURL
    def get_serialNumber(self): return self.serialNumber
    def set_serialNumber(self, serialNumber): self.serialNumber = serialNumber
    def get_UDN(self): return self.UDN
    def set_UDN(self, UDN): self.UDN = UDN
    def get_UPC(self): return self.UPC
    def set_UPC(self, UPC): self.UPC = UPC
    def get_iconList(self): return self.iconList
    def set_iconList(self, iconList): self.iconList = iconList
    def get_serviceList(self): return self.serviceList
    def set_serviceList(self, serviceList): self.serviceList = serviceList
    def get_deviceList(self): return self.deviceList
    def set_deviceList(self, deviceList): self.deviceList = deviceList
    def get_presentationURL(self): return self.presentationURL
    def set_presentationURL(self, presentationURL): self.presentationURL = presentationURL
    def get_anytypeobjs_(self): return self.anytypeobjs_
    def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeobjs_
    def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value)
    def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index] = value
    def export(self, outfile, level, namespace_='tns:', name_='DeviceType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='DeviceType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='DeviceType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='DeviceType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.deviceType is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sdeviceType>%s</%sdeviceType>%s' % (namespace_, self.gds_format_string(quote_xml(self.deviceType).encode(ExternalEncoding), input_name='deviceType'), namespace_, eol_))
        if self.friendlyName is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sfriendlyName>%s</%sfriendlyName>%s' % (namespace_, self.gds_format_string(quote_xml(self.friendlyName).encode(ExternalEncoding), input_name='friendlyName'), namespace_, eol_))
        if self.manufacturer is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smanufacturer>%s</%smanufacturer>%s' % (namespace_, self.gds_format_string(quote_xml(self.manufacturer).encode(ExternalEncoding), input_name='manufacturer'), namespace_, eol_))
        if self.manufacturerURL is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smanufacturerURL>%s</%smanufacturerURL>%s' % (namespace_, self.gds_format_string(quote_xml(self.manufacturerURL).encode(ExternalEncoding), input_name='manufacturerURL'), namespace_, eol_))
        if self.modelDescription is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smodelDescription>%s</%smodelDescription>%s' % (namespace_, self.gds_format_string(quote_xml(self.modelDescription).encode(ExternalEncoding), input_name='modelDescription'), namespace_, eol_))
        if self.modelName is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smodelName>%s</%smodelName>%s' % (namespace_, self.gds_format_string(quote_xml(self.modelName).encode(ExternalEncoding), input_name='modelName'), namespace_, eol_))
        if self.modelNumber is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smodelNumber>%s</%smodelNumber>%s' % (namespace_, self.gds_format_string(quote_xml(self.modelNumber).encode(ExternalEncoding), input_name='modelNumber'), namespace_, eol_))
        if self.modelURL is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smodelURL>%s</%smodelURL>%s' % (namespace_, self.gds_format_string(quote_xml(self.modelURL).encode(ExternalEncoding), input_name='modelURL'), namespace_, eol_))
        if self.serialNumber is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sserialNumber>%s</%sserialNumber>%s' % (namespace_, self.gds_format_string(quote_xml(self.serialNumber).encode(ExternalEncoding), input_name='serialNumber'), namespace_, eol_))
        if self.UDN is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sUDN>%s</%sUDN>%s' % (namespace_, self.gds_format_string(quote_xml(self.UDN).encode(ExternalEncoding), input_name='UDN'), namespace_, eol_))
        if self.UPC is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sUPC>%s</%sUPC>%s' % (namespace_, self.gds_format_string(quote_xml(self.UPC).encode(ExternalEncoding), input_name='UPC'), namespace_, eol_))
        if self.iconList is not None:
            self.iconList.export(outfile, level, namespace_, name_='iconList', pretty_print=pretty_print)
        if self.serviceList is not None:
            self.serviceList.export(outfile, level, namespace_, name_='serviceList', pretty_print=pretty_print)
        if self.deviceList is not None:
            self.deviceList.export(outfile, level, namespace_, name_='deviceList', pretty_print=pretty_print)
        if self.presentationURL is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%spresentationURL>%s</%spresentationURL>%s' % (namespace_, self.gds_format_string(quote_xml(self.presentationURL).encode(ExternalEncoding), input_name='presentationURL'), namespace_, eol_))
        for obj_ in self.anytypeobjs_:
            obj_.export(outfile, level, namespace_, pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.deviceType is not None or
            self.friendlyName is not None or
            self.manufacturer is not None or
            self.manufacturerURL is not None or
            self.modelDescription is not None or
            self.modelName is not None or
            self.modelNumber is not None or
            self.modelURL is not None or
            self.serialNumber is not None or
            self.UDN is not None or
            self.UPC is not None or
            self.iconList is not None or
            self.serviceList is not None or
            self.deviceList is not None or
            self.presentationURL is not None or
            self.anytypeobjs_
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='DeviceType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.deviceType is not None:
            showIndent(outfile, level)
            outfile.write('deviceType=%s,\n' % quote_python(self.deviceType).encode(ExternalEncoding))
        if self.friendlyName is not None:
            showIndent(outfile, level)
            outfile.write('friendlyName=%s,\n' % quote_python(self.friendlyName).encode(ExternalEncoding))
        if self.manufacturer is not None:
            showIndent(outfile, level)
            outfile.write('manufacturer=%s,\n' % quote_python(self.manufacturer).encode(ExternalEncoding))
        if self.manufacturerURL is not None:
            showIndent(outfile, level)
            outfile.write('manufacturerURL=%s,\n' % quote_python(self.manufacturerURL).encode(ExternalEncoding))
        if self.modelDescription is not None:
            showIndent(outfile, level)
            outfile.write('modelDescription=%s,\n' % quote_python(self.modelDescription).encode(ExternalEncoding))
        if self.modelName is not None:
            showIndent(outfile, level)
            outfile.write('modelName=%s,\n' % quote_python(self.modelName).encode(ExternalEncoding))
        if self.modelNumber is not None:
            showIndent(outfile, level)
            outfile.write('modelNumber=%s,\n' % quote_python(self.modelNumber).encode(ExternalEncoding))
        if self.modelURL is not None:
            showIndent(outfile, level)
            outfile.write('modelURL=%s,\n' % quote_python(self.modelURL).encode(ExternalEncoding))
        if self.serialNumber is not None:
            showIndent(outfile, level)
            outfile.write('serialNumber=%s,\n' % quote_python(self.serialNumber).encode(ExternalEncoding))
        if self.UDN is not None:
            showIndent(outfile, level)
            outfile.write('UDN=%s,\n' % quote_python(self.UDN).encode(ExternalEncoding))
        if self.UPC is not None:
            showIndent(outfile, level)
            outfile.write('UPC=%s,\n' % quote_python(self.UPC).encode(ExternalEncoding))
        if self.iconList is not None:
            showIndent(outfile, level)
            outfile.write('iconList=model_.IconListType(\n')
            self.iconList.exportLiteral(outfile, level, name_='iconList')
            showIndent(outfile, level)
            outfile.write('),\n')
        if self.serviceList is not None:
            showIndent(outfile, level)
            outfile.write('serviceList=model_.ServiceListType(\n')
            self.serviceList.exportLiteral(outfile, level, name_='serviceList')
            showIndent(outfile, level)
            outfile.write('),\n')
        if self.deviceList is not None:
            showIndent(outfile, level)
            outfile.write('deviceList=model_.DeviceListType(\n')
            self.deviceList.exportLiteral(outfile, level, name_='deviceList')
            showIndent(outfile, level)
            outfile.write('),\n')
        if self.presentationURL is not None:
            showIndent(outfile, level)
            outfile.write('presentationURL=%s,\n' % quote_python(self.presentationURL).encode(ExternalEncoding))
        showIndent(outfile, level)
        outfile.write('anytypeobjs_=[\n')
        level += 1
        for anytypeobjs_ in self.anytypeobjs_:
            anytypeobjs_.exportLiteral(outfile, level)
        level -= 1
        showIndent(outfile, level)
        outfile.write('],\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'deviceType':
            deviceType_ = child_.text
            deviceType_ = self.gds_validate_string(deviceType_, node, 'deviceType')
            self.deviceType = deviceType_
        elif nodeName_ == 'friendlyName':
            friendlyName_ = child_.text
            friendlyName_ = self.gds_validate_string(friendlyName_, node, 'friendlyName')
            self.friendlyName = friendlyName_
        elif nodeName_ == 'manufacturer':
            manufacturer_ = child_.text
            manufacturer_ = self.gds_validate_string(manufacturer_, node, 'manufacturer')
            self.manufacturer = manufacturer_
        elif nodeName_ == 'manufacturerURL':
            manufacturerURL_ = child_.text
            manufacturerURL_ = self.gds_validate_string(manufacturerURL_, node, 'manufacturerURL')
            self.manufacturerURL = manufacturerURL_
        elif nodeName_ == 'modelDescription':
            modelDescription_ = child_.text
            modelDescription_ = self.gds_validate_string(modelDescription_, node, 'modelDescription')
            self.modelDescription = modelDescription_
        elif nodeName_ == 'modelName':
            modelName_ = child_.text
            modelName_ = self.gds_validate_string(modelName_, node, 'modelName')
            self.modelName = modelName_
        elif nodeName_ == 'modelNumber':
            modelNumber_ = child_.text
            modelNumber_ = self.gds_validate_string(modelNumber_, node, 'modelNumber')
            self.modelNumber = modelNumber_
        elif nodeName_ == 'modelURL':
            modelURL_ = child_.text
            modelURL_ = self.gds_validate_string(modelURL_, node, 'modelURL')
            self.modelURL = modelURL_
        elif nodeName_ == 'serialNumber':
            serialNumber_ = child_.text
            serialNumber_ = self.gds_validate_string(serialNumber_, node, 'serialNumber')
            self.serialNumber = serialNumber_
        elif nodeName_ == 'UDN':
            UDN_ = child_.text
            UDN_ = self.gds_validate_string(UDN_, node, 'UDN')
            self.UDN = UDN_
        elif nodeName_ == 'UPC':
            UPC_ = child_.text
            UPC_ = self.gds_validate_string(UPC_, node, 'UPC')
            self.UPC = UPC_
        elif nodeName_ == 'iconList':
            obj_ = IconListType.factory()
            obj_.build(child_)
            self.set_iconList(obj_)
        elif nodeName_ == 'serviceList':
            obj_ = ServiceListType.factory()
            obj_.build(child_)
            self.set_serviceList(obj_)
        elif nodeName_ == 'deviceList':
            obj_ = DeviceListType.factory()
            obj_.build(child_)
            self.set_deviceList(obj_)
        elif nodeName_ == 'presentationURL':
            presentationURL_ = child_.text
            presentationURL_ = self.gds_validate_string(presentationURL_, node, 'presentationURL')
            self.presentationURL = presentationURL_
        else:
            obj_ = self.gds_build_any(child_, 'DeviceType')
            if obj_ is not None:
                self.add_anytypeobjs_(obj_)
# end class DeviceType


class IconListType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, icon=None):
        if icon is None:
            self.icon = []
        else:
            self.icon = icon
    def factory(*args_, **kwargs_):
        if IconListType.subclass:
            return IconListType.subclass(*args_, **kwargs_)
        else:
            return IconListType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_icon(self): return self.icon
    def set_icon(self, icon): self.icon = icon
    def add_icon(self, value): self.icon.append(value)
    def insert_icon(self, index, value): self.icon[index] = value
    def export(self, outfile, level, namespace_='tns:', name_='IconListType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='IconListType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='IconListType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='IconListType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        for icon_ in self.icon:
            icon_.export(outfile, level, namespace_, name_='icon', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.icon
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='IconListType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        showIndent(outfile, level)
        outfile.write('icon=[\n')
        level += 1
        for icon_ in self.icon:
            showIndent(outfile, level)
            outfile.write('model_.iconType(\n')
            icon_.exportLiteral(outfile, level, name_='iconType')
            showIndent(outfile, level)
            outfile.write('),\n')
        level -= 1
        showIndent(outfile, level)
        outfile.write('],\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'icon':
            obj_ = iconType.factory()
            obj_.build(child_)
            self.icon.append(obj_)
# end class IconListType


class ServiceListType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, service=None):
        if service is None:
            self.service = []
        else:
            self.service = service
    def factory(*args_, **kwargs_):
        if ServiceListType.subclass:
            return ServiceListType.subclass(*args_, **kwargs_)
        else:
            return ServiceListType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_service(self): return self.service
    def set_service(self, service): self.service = service
    def add_service(self, value): self.service.append(value)
    def insert_service(self, index, value): self.service[index] = value
    def export(self, outfile, level, namespace_='tns:', name_='ServiceListType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='ServiceListType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='ServiceListType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='ServiceListType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        for service_ in self.service:
            service_.export(outfile, level, namespace_, name_='service', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.service
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='ServiceListType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        showIndent(outfile, level)
        outfile.write('service=[\n')
        level += 1
        for service_ in self.service:
            showIndent(outfile, level)
            outfile.write('model_.serviceType(\n')
            service_.exportLiteral(outfile, level, name_='serviceType')
            showIndent(outfile, level)
            outfile.write('),\n')
        level -= 1
        showIndent(outfile, level)
        outfile.write('],\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'service':
            obj_ = serviceType.factory()
            obj_.build(child_)
            self.service.append(obj_)
# end class ServiceListType


class DeviceListType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, device=None):
        if device is None:
            self.device = []
        else:
            self.device = device
    def factory(*args_, **kwargs_):
        if DeviceListType.subclass:
            return DeviceListType.subclass(*args_, **kwargs_)
        else:
            return DeviceListType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_device(self): return self.device
    def set_device(self, device): self.device = device
    def add_device(self, value): self.device.append(value)
    def insert_device(self, index, value): self.device[index] = value
    def export(self, outfile, level, namespace_='tns:', name_='DeviceListType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='DeviceListType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='DeviceListType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='DeviceListType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        for device_ in self.device:
            device_.export(outfile, level, namespace_, name_='device', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.device
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='DeviceListType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        showIndent(outfile, level)
        outfile.write('device=[\n')
        level += 1
        for device_ in self.device:
            showIndent(outfile, level)
            outfile.write('model_.DeviceType(\n')
            device_.exportLiteral(outfile, level, name_='DeviceType')
            showIndent(outfile, level)
            outfile.write('),\n')
        level -= 1
        showIndent(outfile, level)
        outfile.write('],\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'device':
            obj_ = DeviceType.factory()
            obj_.build(child_)
            self.device.append(obj_)
# end class DeviceListType


class iconType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, mimetype=None, width=None, height=None, depth=None, url=None):
        self.mimetype = mimetype
        self.width = width
        self.height = height
        self.depth = depth
        self.url = url
    def factory(*args_, **kwargs_):
        if iconType.subclass:
            return iconType.subclass(*args_, **kwargs_)
        else:
            return iconType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_mimetype(self): return self.mimetype
    def set_mimetype(self, mimetype): self.mimetype = mimetype
    def get_width(self): return self.width
    def set_width(self, width): self.width = width
    def get_height(self): return self.height
    def set_height(self, height): self.height = height
    def get_depth(self): return self.depth
    def set_depth(self, depth): self.depth = depth
    def get_url(self): return self.url
    def set_url(self, url): self.url = url
    def export(self, outfile, level, namespace_='tns:', name_='iconType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='iconType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='iconType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='iconType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.mimetype is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smimetype>%s</%smimetype>%s' % (namespace_, self.gds_format_string(quote_xml(self.mimetype).encode(ExternalEncoding), input_name='mimetype'), namespace_, eol_))
        if self.width is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%swidth>%s</%swidth>%s' % (namespace_, self.gds_format_integer(self.width, input_name='width'), namespace_, eol_))
        if self.height is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sheight>%s</%sheight>%s' % (namespace_, self.gds_format_integer(self.height, input_name='height'), namespace_, eol_))
        if self.depth is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sdepth>%s</%sdepth>%s' % (namespace_, self.gds_format_integer(self.depth, input_name='depth'), namespace_, eol_))
        if self.url is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%surl>%s</%surl>%s' % (namespace_, self.gds_format_string(quote_xml(self.url).encode(ExternalEncoding), input_name='url'), namespace_, eol_))
    def hasContent_(self):
        if (
            self.mimetype is not None or
            self.width is not None or
            self.height is not None or
            self.depth is not None or
            self.url is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='iconType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.mimetype is not None:
            showIndent(outfile, level)
            outfile.write('mimetype=%s,\n' % quote_python(self.mimetype).encode(ExternalEncoding))
        if self.width is not None:
            showIndent(outfile, level)
            outfile.write('width=%d,\n' % self.width)
        if self.height is not None:
            showIndent(outfile, level)
            outfile.write('height=%d,\n' % self.height)
        if self.depth is not None:
            showIndent(outfile, level)
            outfile.write('depth=%d,\n' % self.depth)
        if self.url is not None:
            showIndent(outfile, level)
            outfile.write('url=%s,\n' % quote_python(self.url).encode(ExternalEncoding))
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'mimetype':
            mimetype_ = child_.text
            mimetype_ = self.gds_validate_string(mimetype_, node, 'mimetype')
            self.mimetype = mimetype_
        elif nodeName_ == 'width':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'width')
            self.width = ival_
        elif nodeName_ == 'height':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'height')
            self.height = ival_
        elif nodeName_ == 'depth':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'depth')
            self.depth = ival_
        elif nodeName_ == 'url':
            url_ = child_.text
            url_ = self.gds_validate_string(url_, node, 'url')
            self.url = url_
# end class iconType


class serviceType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, serviceType=None, serviceId=None, SCPDURL=None, controlURL=None, eventSubURL=None):
        self.serviceType = serviceType
        self.serviceId = serviceId
        self.SCPDURL = SCPDURL
        self.controlURL = controlURL
        self.eventSubURL = eventSubURL
    def factory(*args_, **kwargs_):
        if serviceType.subclass:
            return serviceType.subclass(*args_, **kwargs_)
        else:
            return serviceType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_serviceType(self): return self.serviceType
    def set_serviceType(self, serviceType): self.serviceType = serviceType
    def get_serviceId(self): return self.serviceId
    def set_serviceId(self, serviceId): self.serviceId = serviceId
    def get_SCPDURL(self): return self.SCPDURL
    def set_SCPDURL(self, SCPDURL): self.SCPDURL = SCPDURL
    def get_controlURL(self): return self.controlURL
    def set_controlURL(self, controlURL): self.controlURL = controlURL
    def get_eventSubURL(self): return self.eventSubURL
    def set_eventSubURL(self, eventSubURL): self.eventSubURL = eventSubURL
    def export(self, outfile, level, namespace_='tns:', name_='serviceType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='serviceType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='tns:', name_='serviceType'):
        pass
    def exportChildren(self, outfile, level, namespace_='tns:', name_='serviceType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.serviceType is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sserviceType>%s</%sserviceType>%s' % (namespace_, self.gds_format_string(quote_xml(self.serviceType).encode(ExternalEncoding), input_name='serviceType'), namespace_, eol_))
        if self.serviceId is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sserviceId>%s</%sserviceId>%s' % (namespace_, self.gds_format_string(quote_xml(self.serviceId).encode(ExternalEncoding), input_name='serviceId'), namespace_, eol_))
        if self.SCPDURL is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sSCPDURL>%s</%sSCPDURL>%s' % (namespace_, self.gds_format_string(quote_xml(self.SCPDURL).encode(ExternalEncoding), input_name='SCPDURL'), namespace_, eol_))
        if self.controlURL is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%scontrolURL>%s</%scontrolURL>%s' % (namespace_, self.gds_format_string(quote_xml(self.controlURL).encode(ExternalEncoding), input_name='controlURL'), namespace_, eol_))
        if self.eventSubURL is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%seventSubURL>%s</%seventSubURL>%s' % (namespace_, self.gds_format_string(quote_xml(self.eventSubURL).encode(ExternalEncoding), input_name='eventSubURL'), namespace_, eol_))
    def hasContent_(self):
        if (
            self.serviceType is not None or
            self.serviceId is not None or
            self.SCPDURL is not None or
            self.controlURL is not None or
            self.eventSubURL is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='serviceType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.serviceType is not None:
            showIndent(outfile, level)
            outfile.write('serviceType=%s,\n' % quote_python(self.serviceType).encode(ExternalEncoding))
        if self.serviceId is not None:
            showIndent(outfile, level)
            outfile.write('serviceId=%s,\n' % quote_python(self.serviceId).encode(ExternalEncoding))
        if self.SCPDURL is not None:
            showIndent(outfile, level)
            outfile.write('SCPDURL=%s,\n' % quote_python(self.SCPDURL).encode(ExternalEncoding))
        if self.controlURL is not None:
            showIndent(outfile, level)
            outfile.write('controlURL=%s,\n' % quote_python(self.controlURL).encode(ExternalEncoding))
        if self.eventSubURL is not None:
            showIndent(outfile, level)
            outfile.write('eventSubURL=%s,\n' % quote_python(self.eventSubURL).encode(ExternalEncoding))
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'serviceType':
            serviceType_ = child_.text
            serviceType_ = self.gds_validate_string(serviceType_, node, 'serviceType')
            self.serviceType = serviceType_
        elif nodeName_ == 'serviceId':
            serviceId_ = child_.text
            serviceId_ = self.gds_validate_string(serviceId_, node, 'serviceId')
            self.serviceId = serviceId_
        elif nodeName_ == 'SCPDURL':
            SCPDURL_ = child_.text
            SCPDURL_ = self.gds_validate_string(SCPDURL_, node, 'SCPDURL')
            self.SCPDURL = SCPDURL_
        elif nodeName_ == 'controlURL':
            controlURL_ = child_.text
            controlURL_ = self.gds_validate_string(controlURL_, node, 'controlURL')
            self.controlURL = controlURL_
        elif nodeName_ == 'eventSubURL':
            eventSubURL_ = child_.text
            eventSubURL_ = self.gds_validate_string(eventSubURL_, node, 'eventSubURL')
            self.eventSubURL = eventSubURL_
# end class serviceType


GDSClassesMapping = {
    'serviceList': ServiceListType,
    'service': serviceType,
    'iconList': IconListType,
    'deviceList': DeviceListType,
    'device': DeviceType,
    'specVersion': SpecVersionType,
    'icon': iconType,
}


USAGE_TEXT = """
Usage: python <Parser>.py [ -s ] <in_xml_file>
"""

def usage():
    print(USAGE_TEXT)
    sys.exit(1)


def get_root_tag(node):
    tag = Tag_pattern_.match(node.tag).groups()[-1]
    rootClass = GDSClassesMapping.get(tag)
    if rootClass is None:
        rootClass = globals().get(tag)
    return tag, rootClass


def parse(inFileName):
    doc = parsexml_(inFileName)
    rootNode = doc.getroot()
    rootTag, rootClass = get_root_tag(rootNode)
    if rootClass is None:
        rootTag = 'root'
        rootClass = root
    rootObj = rootClass.factory()
    rootObj.build(rootNode)
    # Enable Python to collect the space used by the DOM.
    doc = None
    return rootObj


def parseString(inString):
    from io import BytesIO
    doc = parsexml_(BytesIO(inString))
    rootNode = doc.getroot()
    rootTag, rootClass = get_root_tag(rootNode)
    if rootClass is None:
        rootTag = 'root'
        rootClass = root
    rootObj = rootClass.factory()
    rootObj.build(rootNode)
    # Enable Python to collect the space used by the DOM.
    doc = None
    return rootObj


def parseLiteral(inFileName):
    doc = parsexml_(inFileName)
    rootNode = doc.getroot()
    rootTag, rootClass = get_root_tag(rootNode)
    if rootClass is None:
        rootTag = 'root'
        rootClass = root
    rootObj = rootClass.factory()
    rootObj.build(rootNode)
    # Enable Python to collect the space used by the DOM.
    doc = None
    sys.stdout.write('#from device import *\n\n')
    sys.stdout.write('from datetime import datetime as datetime_\n\n')
    sys.stdout.write('import device as model_\n\n')
    sys.stdout.write('rootObj = model_.rootTag(\n')
    rootObj.exportLiteral(sys.stdout, 0, name_=rootTag)
    sys.stdout.write(')\n')
    return rootObj


def main():
    args = sys.argv[1:]
    if len(args) == 1:
        parse(args[0])
    else:
        usage()


if __name__ == '__main__':
    #import pdb; pdb.set_trace()
    main()


__all__ = [
    "DeviceListType",
    "DeviceType",
    "IconListType",
    "ServiceListType",
    "SpecVersionType",
    "iconType",
    "root",
    "serviceType"
    ]


================================================
FILE: ouimeaux/device/api/xsd/device.xsd
================================================
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
  targetNamespace="urn:schemas-upnp-org:device-1-0"
  xmlns:tns="urn:schemas-upnp-org:device-1-0"
  xmlns="urn:schemas-upnp-org:device-1-0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  attributeFormDefault="qualified" elementFormDefault="qualified">
 
  <xs:annotation>
    <xs:documentation>
      XML Schema for UPnP device descriptions in real XSD format
      (not like the XDR one from Microsoft)
      Created by Michael Weinrich 2007
    </xs:documentation>
  </xs:annotation>

  <xs:element name="root">
    <xs:complexType>
      <xs:all>
        <xs:element name="specVersion" type="SpecVersionType" minOccurs="1" maxOccurs="1" />
        <xs:element name="URLBase" type="xs:string" minOccurs="0" maxOccurs="1" />
        <xs:element name="device" type="DeviceType" minOccurs="1" maxOccurs="1" />
      </xs:all>
      <xs:anyAttribute/>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="SpecVersionType">
    <xs:all>
      <xs:element name="major" type="xs:int" minOccurs="1" />
      <xs:element name="minor" type="xs:int" minOccurs="1"/>
    </xs:all>
  </xs:complexType>

  <xs:complexType name="DeviceType">
    <xs:sequence>
      <xs:element name="deviceType" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="friendlyName" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="manufacturer" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="manufacturerURL" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="modelDescription" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="modelName" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="modelNumber" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="modelURL" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="serialNumber" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="UDN" type="xs:string" minOccurs="1" maxOccurs="1" />
      <xs:element name="UPC" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:element name="iconList" type="IconListType" minOccurs="0" maxOccurs="1" />
      <xs:element name="serviceList" type="ServiceListType" minOccurs="0" maxOccurs="1" />
      <xs:element name="deviceList" type="DeviceListType" minOccurs="0" maxOccurs="1" />
      <xs:element name="presentationURL" type="xs:string" minOccurs="0" maxOccurs="1" />
      <xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
 
  <xs:complexType name="IconListType">
    <xs:sequence>
      <xs:element name="icon" minOccurs="1" maxOccurs="unbounded">
        <xs:complexType>
          <xs:all>
            <xs:element name="mimetype" type="xs:string" minOccurs="1" maxOccurs="1" />
            <xs:element name="width" type="xs:int" minOccurs="1" maxOccurs="1" />
            <xs:element name="height" type="xs:int" minOccurs="1" maxOccurs="1" />
            <xs:element name="depth" type="xs:int" minOccurs="1" maxOccurs="1" />
            <xs:element name="url" type="xs:string" minOccurs="1" maxOccurs="1" />
          </xs:all>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="ServiceListType">
    <xs:sequence>
      <xs:element name="service" minOccurs="1" maxOccurs="unbounded">
        <xs:complexType>
          <xs:all>
            <xs:element name="serviceType" type="xs:string" minOccurs="1" maxOccurs="1" />
            <xs:element name="serviceId" type="xs:string" minOccurs="1" maxOccurs="1" />
            <xs:element name="SCPDURL" type="xs:string" minOccurs="1" maxOccurs="1" />
            <xs:element name="controlURL" type="xs:string" minOccurs="1" maxOccurs="1" />
            <xs:element name="eventSubURL" type="xs:string" minOccurs="1" maxOccurs="1" />
          </xs:all>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="DeviceListType">
    <xs:sequence>
      <xs:element name="device" type="DeviceType" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>
 	 
</xs:schema>

================================================
FILE: ouimeaux/device/api/xsd/service.py
================================================
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# Generated Thu Jan 31 15:52:45 2013 by generateDS.py version 2.8b.
#

import sys
import getopt
import re as re_
import base64
from datetime import datetime, tzinfo, timedelta

etree_ = None
Verbose_import_ = False
(   XMLParser_import_none, XMLParser_import_lxml,
    XMLParser_import_elementtree
    ) = range(3)
XMLParser_import_library = None
try:
    # lxml
    from lxml import etree as etree_
    XMLParser_import_library = XMLParser_import_lxml
    if Verbose_import_:
        print("running with lxml.etree")
except ImportError:
    try:
        # cElementTree from Python 2.5+
        import xml.etree.cElementTree as etree_
        XMLParser_import_library = XMLParser_import_elementtree
        if Verbose_import_:
            print("running with cElementTree on Python 2.5+")
    except ImportError:
        try:
            # ElementTree from Python 2.5+
            import xml.etree.ElementTree as etree_
            XMLParser_import_library = XMLParser_import_elementtree
            if Verbose_import_:
                print("running with ElementTree on Python 2.5+")
        except ImportError:
            try:
                # normal cElementTree install
                import cElementTree as etree_
                XMLParser_import_library = XMLParser_import_elementtree
                if Verbose_import_:
                    print("running with cElementTree")
            except ImportError:
                try:
                    # normal ElementTree install
                    import elementtree.ElementTree as etree_
                    XMLParser_import_library = XMLParser_import_elementtree
                    if Verbose_import_:
                        print("running with ElementTree")
                except ImportError:
                    raise ImportError(
                        "Failed to import ElementTree from any known place")

def parsexml_(*args, **kwargs):
    if (XMLParser_import_library == XMLParser_import_lxml and
        'parser' not in kwargs):
        # Use the lxml ElementTree compatible parser so that, e.g.,
        #   we ignore comments.
        kwargs['parser'] = etree_.ETCompatXMLParser()
    doc = etree_.parse(*args, **kwargs)
    return doc

#
# User methods
#
# Calls to the methods in these classes are generated by generateDS.py.
# You can replace these methods by re-implementing the following class
#   in a module named generatedssuper.py.

try:
    from generatedssuper import GeneratedsSuper
except ImportError as exp:

    class GeneratedsSuper(object):
        tzoff_pattern = re_.compile(r'(\+|-)((0\d|1[0-3]):[0-5]\d|14:00)$')
        class _FixedOffsetTZ(tzinfo):
            def __init__(self, offset, name):
                self.__offset = timedelta(minutes = offset)
                self.__name = name
            def utcoffset(self, dt):
                return self.__offset
            def tzname(self, dt):
                return self.__name
            def dst(self, dt):
                return None
        def gds_format_string(self, input_data, input_name=''):
            return input_data
        def gds_validate_string(self, input_data, node, input_name=''):
            return input_data
        def gds_format_base64(self, input_data, input_name=''):
            return base64.b64encode(input_data)
        def gds_validate_base64(self, input_data, node, input_name=''):
            return input_data
        def gds_format_integer(self, input_data, input_name=''):
            return '%d' % input_data
        def gds_validate_integer(self, input_data, node, input_name=''):
            return input_data
        def gds_format_integer_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_integer_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                try:
                    fvalue = float(value)
                except (TypeError, ValueError):
                    raise_parse_error(node, 'Requires sequence of integers')
            return input_data
        def gds_format_float(self, input_data, input_name=''):
            return '%f' % input_data
        def gds_validate_float(self, input_data, node, input_name=''):
            return input_data
        def gds_format_float_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_float_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                try:
                    fvalue = float(value)
                except (TypeError, ValueError):
                    raise_parse_error(node, 'Requires sequence of floats')
            return input_data
        def gds_format_double(self, input_data, input_name=''):
            return '%e' % input_data
        def gds_validate_double(self, input_data, node, input_name=''):
            return input_data
        def gds_format_double_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_double_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                try:
                    fvalue = float(value)
                except (TypeError, ValueError):
                    raise_parse_error(node, 'Requires sequence of doubles')
            return input_data
        def gds_format_boolean(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_boolean(self, input_data, node, input_name=''):
            return input_data
        def gds_format_boolean_list(self, input_data, input_name=''):
            return '%s' % input_data
        def gds_validate_boolean_list(self, input_data, node, input_name=''):
            values = input_data.split()
            for value in values:
                if value not in ('true', '1', 'false', '0', ):
                    raise_parse_error(node,
                        'Requires sequence of booleans '
                        '("true", "1", "false", "0")')
            return input_data
        def gds_validate_datetime(self, input_data, node, input_name=''):
            return input_data
        def gds_format_datetime(self, input_data, input_name=''):
            if input_data.microsecond == 0:
                _svalue = input_data.strftime('%Y-%m-%dT%H:%M:%S')
            else:
                _svalue = input_data.strftime('%Y-%m-%dT%H:%M:%S.%f')
            if input_data.tzinfo is not None:
                tzoff = input_data.tzinfo.utcoffset(input_data)
                if tzoff is not None:
                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
                    if total_seconds == 0:
                        _svalue += 'Z'
                    else:
                        if total_seconds < 0:
                            _svalue += '-'
                            total_seconds *= -1
                        else:
                            _svalue += '+'
                        hours = total_seconds // 3600
                        minutes = (total_seconds - (hours * 3600)) // 60
                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
            return _svalue
        def gds_parse_datetime(self, input_data, node, input_name=''):
            tz = None
            if input_data[-1] == 'Z':
                tz = GeneratedsSuper._FixedOffsetTZ(0, 'GMT')
                input_data = input_data[:-1]
            else:
                results = GeneratedsSuper.tzoff_pattern.search(input_data)
                if results is not None:
                    tzoff_parts = results.group(2).split(':')
                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
                    if results.group(1) == '-':
                        tzoff *= -1
                    tz = GeneratedsSuper._FixedOffsetTZ(
                        tzoff, results.group(0))
                    input_data = input_data[:-6]
            if len(input_data.split('.')) > 1:
                dt = datetime.strptime(
                        input_data, '%Y-%m-%dT%H:%M:%S.%f')
            else:
                dt = datetime.strptime(
                        input_data, '%Y-%m-%dT%H:%M:%S')
            return dt.replace(tzinfo = tz)

        def gds_validate_date(self, input_data, node, input_name=''):
            return input_data
        def gds_format_date(self, input_data, input_name=''):
            _svalue = input_data.strftime('%Y-%m-%d')
            if input_data.tzinfo is not None:
                tzoff = input_data.tzinfo.utcoffset(input_data)
                if tzoff is not None:
                    total_seconds = tzoff.seconds + (86400 * tzoff.days)
                    if total_seconds == 0:
                        _svalue += 'Z'
                    else:
                        if total_seconds < 0:
                            _svalue += '-'
                            total_seconds *= -1
                        else:
                            _svalue += '+'
                        hours = total_seconds // 3600
                        minutes = (total_seconds - (hours * 3600)) // 60
                        _svalue += '{0:02d}:{1:02d}'.format(hours, minutes)
            return _svalue
        def gds_parse_date(self, input_data, node, input_name=''):
            tz = None
            if input_data[-1] == 'Z':
                tz = GeneratedsSuper._FixedOffsetTZ(0, 'GMT')
                input_data = input_data[:-1]
            else:
                results = GeneratedsSuper.tzoff_pattern.search(input_data)
                if results is not None:
                    tzoff_parts = results.group(2).split(':')
                    tzoff = int(tzoff_parts[0]) * 60 + int(tzoff_parts[1])
                    if results.group(1) == '-':
                        tzoff *= -1
                    tz = GeneratedsSuper._FixedOffsetTZ(
                        tzoff, results.group(0))
                    input_data = input_data[:-6]
            return datetime.strptime(input_data,
                '%Y-%m-%d').replace(tzinfo = tz)
        def gds_str_lower(self, instring):
            return instring.lower()
        def get_path_(self, node):
            path_list = []
            self.get_path_list_(node, path_list)
            path_list.reverse()
            path = '/'.join(path_list)
            return path
        Tag_strip_pattern_ = re_.compile(r'\{.*\}')
        def get_path_list_(self, node, path_list):
            if node is None:
                return
            tag = GeneratedsSuper.Tag_strip_pattern_.sub('', node.tag)
            if tag:
                path_list.append(tag)
            self.get_path_list_(node.getparent(), path_list)
        def get_class_obj_(self, node, default_class=None):
            class_obj1 = default_class
            if 'xsi' in node.nsmap:
                classname = node.get('{%s}type' % node.nsmap['xsi'])
                if classname is not None:
                    names = classname.split(':')
                    if len(names) == 2:
                        classname = names[1]
                    class_obj2 = globals().get(classname)
                    if class_obj2 is not None:
                        class_obj1 = class_obj2
            return class_obj1
        def gds_build_any(self, node, type_name=None):
            return None


#
# If you have installed IPython you can uncomment and use the following.
# IPython is available from http://ipython.scipy.org/.
#

## from IPython.Shell import IPShellEmbed
## args = ''
## ipshell = IPShellEmbed(args,
##     banner = 'Dropping into IPython',
##     exit_msg = 'Leaving Interpreter, back to program.')

# Then use the following line where and when you want to drop into the
# IPython shell:
#    ipshell('<some message> -- Entering ipshell.\nHit Ctrl-D to exit')

#
# Globals
#

ExternalEncoding = 'ascii'
Tag_pattern_ = re_.compile(r'({.*})?(.*)')
String_cleanup_pat_ = re_.compile(r"[\n\r\s]+")
Namespace_extract_pat_ = re_.compile(r'{(.*)}(.*)')

#
# Support/utility functions.
#

def showIndent(outfile, level, pretty_print=True):
    if pretty_print:
        for idx in range(level):
            outfile.write('    ')

def quote_xml(inStr):
    if not inStr:
        return ''
    s1 = (isinstance(inStr, basestring) and inStr or
          '%s' % inStr)
    s1 = s1.replace('&', '&amp;')
    s1 = s1.replace('<', '&lt;')
    s1 = s1.replace('>', '&gt;')
    return s1

def quote_attrib(inStr):
    s1 = (isinstance(inStr, basestring) and inStr or
          '%s' % inStr)
    s1 = s1.replace('&', '&amp;')
    s1 = s1.replace('<', '&lt;')
    s1 = s1.replace('>', '&gt;')
    if '"' in s1:
        if "'" in s1:
            s1 = '"%s"' % s1.replace('"', "&quot;")
        else:
            s1 = "'%s'" % s1
    else:
        s1 = '"%s"' % s1
    return s1

def quote_python(inStr):
    s1 = inStr
    if s1.find("'") == -1:
        if s1.find('\n') == -1:
            return "'%s'" % s1
        else:
            return "'''%s'''" % s1
    else:
        if s1.find('"') != -1:
            s1 = s1.replace('"', '\\"')
        if s1.find('\n') == -1:
            return '"%s"' % s1
        else:
            return '"""%s"""' % s1

def get_all_text_(node):
    if node.text is not None:
        text = node.text
    else:
        text = ''
    for child in node:
        if child.tail is not None:
            text += child.tail
    return text

def find_attr_value_(attr_name, node):
    attrs = node.attrib
    attr_parts = attr_name.split(':')
    value = None
    if len(attr_parts) == 1:
        value = attrs.get(attr_name)
    elif len(attr_parts) == 2:
        prefix, name = attr_parts
        namespace = node.nsmap.get(prefix)
        if namespace is not None:
            value = attrs.get('{%s}%s' % (namespace, name, ))
    return value


class GDSParseError(Exception):
    pass

def raise_parse_error(node, msg):
    if XMLParser_import_library == XMLParser_import_lxml:
        msg = '%s (element %s/line %d)' % (
            msg, node.tag, node.sourceline, )
    else:
        msg = '%s (element %s)' % (msg, node.tag, )
    raise GDSParseError(msg)


class MixedContainer:
    # Constants for category:
    CategoryNone = 0
    CategoryText = 1
    CategorySimple = 2
    CategoryComplex = 3
    # Constants for content_type:
    TypeNone = 0
    TypeText = 1
    TypeString = 2
    TypeInteger = 3
    TypeFloat = 4
    TypeDecimal = 5
    TypeDouble = 6
    TypeBoolean = 7
    TypeBase64 = 8
    def __init__(self, category, content_type, name, value):
        self.category = category
        self.content_type = content_type
        self.name = name
        self.value = value
    def getCategory(self):
        return self.category
    def getContenttype(self, content_type):
        return self.content_type
    def getValue(self):
        return self.value
    def getName(self):
        return self.name
    def export(self, outfile, level, name, namespace, pretty_print=True):
        if self.category == MixedContainer.CategoryText:
            # Prevent exporting empty content as empty lines.
            if self.value.strip():
                outfile.write(self.value)
        elif self.category == MixedContainer.CategorySimple:
            self.exportSimple(outfile, level, name)
        else:    # category == MixedContainer.CategoryComplex
            self.value.export(outfile, level, namespace, name, pretty_print)
    def exportSimple(self, outfile, level, name):
        if self.content_type == MixedContainer.TypeString:
            outfile.write('<%s>%s</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeInteger or \
                self.content_type == MixedContainer.TypeBoolean:
            outfile.write('<%s>%d</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeFloat or \
                self.content_type == MixedContainer.TypeDecimal:
            outfile.write('<%s>%f</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeDouble:
            outfile.write('<%s>%g</%s>' %
                (self.name, self.value, self.name))
        elif self.content_type == MixedContainer.TypeBase64:
            outfile.write('<%s>%s</%s>' %
                (self.name, base64.b64encode(self.value), self.name))
    def exportLiteral(self, outfile, level, name):
        if self.category == MixedContainer.CategoryText:
            showIndent(outfile, level)
            outfile.write('model_.MixedContainer(%d, %d, "%s", "%s"),\n'
                % (self.category, self.content_type, self.name, self.value))
        elif self.category == MixedContainer.CategorySimple:
            showIndent(outfile, level)
            outfile.write('model_.MixedContainer(%d, %d, "%s", "%s"),\n'
                % (self.category, self.content_type, self.name, self.value))
        else:    # category == MixedContainer.CategoryComplex
            showIndent(outfile, level)
            outfile.write('model_.MixedContainer(%d, %d, "%s",\n' % \
                (self.category, self.content_type, self.name,))
            self.value.exportLiteral(outfile, level + 1)
            showIndent(outfile, level)
            outfile.write(')\n')


class MemberSpec_(object):
    def __init__(self, name='', data_type='', container=0):
        self.name = name
        self.data_type = data_type
        self.container = container
    def set_name(self, name): self.name = name
    def get_name(self): return self.name
    def set_data_type(self, data_type): self.data_type = data_type
    def get_data_type_chain(self): return self.data_type
    def get_data_type(self):
        if isinstance(self.data_type, list):
            if len(self.data_type) > 0:
                return self.data_type[-1]
            else:
                return 'xs:string'
        else:
            return self.data_type
    def set_container(self, container): self.container = container
    def get_container(self): return self.container

def _cast(typ, value):
    if typ is None or value is None:
        return value
    return typ(value)

#
# Data representation classes.
#

class scpd(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, specVersion=None, actionList=None, serviceStateTable=None):
        self.specVersion = specVersion
        self.actionList = actionList
        self.serviceStateTable = serviceStateTable
    def factory(*args_, **kwargs_):
        if scpd.subclass:
            return scpd.subclass(*args_, **kwargs_)
        else:
            return scpd(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_specVersion(self): return self.specVersion
    def set_specVersion(self, specVersion): self.specVersion = specVersion
    def get_actionList(self): return self.actionList
    def set_actionList(self, actionList): self.actionList = actionList
    def get_serviceStateTable(self): return self.serviceStateTable
    def set_serviceStateTable(self, serviceStateTable): self.serviceStateTable = serviceStateTable
    def export(self, outfile, level, namespace_='', name_='scpd', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='scpd')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='scpd'):
        pass
    def exportChildren(self, outfile, level, namespace_='', name_='scpd', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.specVersion is not None:
            self.specVersion.export(outfile, level, namespace_, name_='specVersion', pretty_print=pretty_print)
        if self.actionList is not None:
            self.actionList.export(outfile, level, namespace_, name_='actionList', pretty_print=pretty_print)
        if self.serviceStateTable is not None:
            self.serviceStateTable.export(outfile, level, namespace_, name_='serviceStateTable', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.specVersion is not None or
            self.actionList is not None or
            self.serviceStateTable is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='scpd'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.specVersion is not None:
            showIndent(outfile, level)
            outfile.write('specVersion=model_.SpecVersionType(\n')
            self.specVersion.exportLiteral(outfile, level, name_='specVersion')
            showIndent(outfile, level)
            outfile.write('),\n')
        if self.actionList is not None:
            showIndent(outfile, level)
            outfile.write('actionList=model_.ActionListType(\n')
            self.actionList.exportLiteral(outfile, level, name_='actionList')
            showIndent(outfile, level)
            outfile.write('),\n')
        if self.serviceStateTable is not None:
            showIndent(outfile, level)
            outfile.write('serviceStateTable=model_.ServiceStateTableType(\n')
            self.serviceStateTable.exportLiteral(outfile, level, name_='serviceStateTable')
            showIndent(outfile, level)
            outfile.write('),\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'specVersion':
            obj_ = SpecVersionType.factory()
            obj_.build(child_)
            self.set_specVersion(obj_)
        elif nodeName_ == 'actionList':
            obj_ = ActionListType.factory()
            obj_.build(child_)
            self.set_actionList(obj_)
        elif nodeName_ == 'serviceStateTable':
            obj_ = ServiceStateTableType.factory()
            obj_.build(child_)
            self.set_serviceStateTable(obj_)
# end class scpd


class SpecVersionType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, major=None, minor=None):
        self.major = major
        self.minor = minor
    def factory(*args_, **kwargs_):
        if SpecVersionType.subclass:
            return SpecVersionType.subclass(*args_, **kwargs_)
        else:
            return SpecVersionType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_major(self): return self.major
    def set_major(self, major): self.major = major
    def get_minor(self): return self.minor
    def set_minor(self, minor): self.minor = minor
    def export(self, outfile, level, namespace_='', name_='SpecVersionType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='SpecVersionType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='SpecVersionType'):
        pass
    def exportChildren(self, outfile, level, namespace_='', name_='SpecVersionType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.major is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%smajor>%s</%smajor>%s' % (namespace_, self.gds_format_integer(self.major, input_name='major'), namespace_, eol_))
        if self.minor is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sminor>%s</%sminor>%s' % (namespace_, self.gds_format_integer(self.minor, input_name='minor'), namespace_, eol_))
    def hasContent_(self):
        if (
            self.major is not None or
            self.minor is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='SpecVersionType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.major is not None:
            showIndent(outfile, level)
            outfile.write('major=%d,\n' % self.major)
        if self.minor is not None:
            showIndent(outfile, level)
            outfile.write('minor=%d,\n' % self.minor)
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'major':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'major')
            self.major = ival_
        elif nodeName_ == 'minor':
            sval_ = child_.text
            try:
                ival_ = int(sval_)
            except (TypeError, ValueError) as exp:
                raise_parse_error(child_, 'requires integer: %s' % exp)
            ival_ = self.gds_validate_integer(ival_, node, 'minor')
            self.minor = ival_
# end class SpecVersionType


class ActionListType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, action=None):
        if action is None:
            self.action = []
        else:
            self.action = action
    def factory(*args_, **kwargs_):
        if ActionListType.subclass:
            return ActionListType.subclass(*args_, **kwargs_)
        else:
            return ActionListType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_action(self): return self.action
    def set_action(self, action): self.action = action
    def add_action(self, value): self.action.append(value)
    def insert_action(self, index, value): self.action[index] = value
    def export(self, outfile, level, namespace_='', name_='ActionListType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='ActionListType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='ActionListType'):
        pass
    def exportChildren(self, outfile, level, namespace_='', name_='ActionListType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        for action_ in self.action:
            action_.export(outfile, level, namespace_, name_='action', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.action
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='ActionListType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        showIndent(outfile, level)
        outfile.write('action=[\n')
        level += 1
        for action_ in self.action:
            showIndent(outfile, level)
            outfile.write('model_.ActionType(\n')
            action_.exportLiteral(outfile, level, name_='ActionType')
            showIndent(outfile, level)
            outfile.write('),\n')
        level -= 1
        showIndent(outfile, level)
        outfile.write('],\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, already_processed):
        pass
    def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
        if nodeName_ == 'action':
            obj_ = ActionType.factory()
            obj_.build(child_)
            self.action.append(obj_)
# end class ActionListType


class ActionType(GeneratedsSuper):
    subclass = None
    superclass = None
    def __init__(self, name=None, argumentList=None):
        self.name = name
        self.argumentList = argumentList
    def factory(*args_, **kwargs_):
        if ActionType.subclass:
            return ActionType.subclass(*args_, **kwargs_)
        else:
            return ActionType(*args_, **kwargs_)
    factory = staticmethod(factory)
    def get_name(self): return self.name
    def set_name(self, name): self.name = name
    def get_argumentList(self): return self.argumentList
    def set_argumentList(self, argumentList): self.argumentList = argumentList
    def export(self, outfile, level, namespace_='', name_='ActionType', namespacedef_='', pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        showIndent(outfile, level, pretty_print)
        outfile.write('<%s%s%s' % (namespace_, name_, namespacedef_ and ' ' + namespacedef_ or '', ))
        already_processed = []
        self.exportAttributes(outfile, level, already_processed, namespace_, name_='ActionType')
        if self.hasContent_():
            outfile.write('>%s' % (eol_, ))
            self.exportChildren(outfile, level + 1, namespace_, name_, pretty_print=pretty_print)
            showIndent(outfile, level, pretty_print)
            outfile.write('</%s%s>%s' % (namespace_, name_, eol_))
        else:
            outfile.write('/>%s' % (eol_, ))
    def exportAttributes(self, outfile, level, already_processed, namespace_='', name_='ActionType'):
        pass
    def exportChildren(self, outfile, level, namespace_='', name_='ActionType', fromsubclass_=False, pretty_print=True):
        if pretty_print:
            eol_ = '\n'
        else:
            eol_ = ''
        if self.name is not None:
            showIndent(outfile, level, pretty_print)
            outfile.write('<%sname>%s</%sname>%s' % (namespace_, self.gds_format_string(quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_, eol_))
        if self.argumentList is not None:
            self.argumentList.export(outfile, level, namespace_, name_='argumentList', pretty_print=pretty_print)
    def hasContent_(self):
        if (
            self.name is not None or
            self.argumentList is not None
            ):
            return True
        else:
            return False
    def exportLiteral(self, outfile, level, name_='ActionType'):
        level += 1
        self.exportLiteralAttributes(outfile, level, [], name_)
        if self.hasContent_():
            self.exportLiteralChildren(outfile, level, name_)
    def exportLiteralAttributes(self, outfile, level, already_processed, name_):
        pass
    def exportLiteralChildren(self, outfile, level, name_):
        if self.name is not None:
            showIndent(outfile, level)
            outfile.write('name=%s,\n' % quote_python(self.name).encode(ExternalEncoding))
        if self.argumentList is not None:
            showIndent(outfile, level)
            outfile.write('argumentList=model_.ArgumentListType(\n')
            self.argumentList.exportLiteral(outfile, level, name_='argumentList')
            showIndent(outfile, level)
            outfile.write('),\n')
    def build(self, node):
        self.buildAttributes(node, node.attrib, [])
        for child in node:
            nodeName_ = Tag_pattern_.match(child.tag).groups()[-1]
            self.buildChildren(child, node, nodeName_)
    def buildAttributes(self, node, attrs, al
Download .txt
gitextract_v9i5cwgu/

├── .gitignore
├── .travis.yml
├── AUTHORS.rst
├── CONTRIBUTING.rst
├── HISTORY.rst
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── client.py
├── docs/
│   ├── Makefile
│   ├── api.rst
│   ├── authors.rst
│   ├── conf.py
│   ├── configuration.rst
│   ├── contributing.rst
│   ├── history.rst
│   ├── index.rst
│   ├── installation.rst
│   ├── make.bat
│   ├── modules.rst
│   ├── ouimeaux.device.api.rst
│   ├── ouimeaux.device.api.xsd.rst
│   ├── ouimeaux.device.rst
│   ├── ouimeaux.examples.rst
│   ├── ouimeaux.pysignals.rst
│   ├── ouimeaux.rst
│   ├── ouimeaux.server.rst
│   ├── ouimeaux.xsd.rst
│   ├── readme.rst
│   ├── server.rst
│   └── wemo.rst
├── ouimeaux/
│   ├── __init__.py
│   ├── cli.py
│   ├── config.py
│   ├── device/
│   │   ├── __init__.py
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── service.py
│   │   │   └── xsd/
│   │   │       ├── __init__.py
│   │   │       ├── device.py
│   │   │       ├── device.xsd
│   │   │       ├── service.py
│   │   │       └── service.xsd
│   │   ├── bridge.py
│   │   ├── insight.py
│   │   ├── lightswitch.py
│   │   ├── maker.py
│   │   ├── motion.py
│   │   └── switch.py
│   ├── discovery.py
│   ├── environment.py
│   ├── examples/
│   │   ├── Randomize.py
│   │   ├── __init__.py
│   │   └── watch.py
│   ├── pysignals/
│   │   ├── LICENSE.txt
│   │   ├── __init__.py
│   │   ├── dispatcher.py
│   │   ├── inspect.py
│   │   ├── license.python.txt
│   │   └── weakref_backports.py
│   ├── server/
│   │   ├── __init__.py
│   │   ├── settings.py
│   │   ├── static/
│   │   │   ├── css/
│   │   │   │   ├── bootstrap-responsive.css
│   │   │   │   ├── bootstrap-theme.css
│   │   │   │   ├── bootstrap.css
│   │   │   │   └── main.css
│   │   │   ├── js/
│   │   │   │   ├── app.js
│   │   │   │   ├── bootstrap.js
│   │   │   │   ├── controllers.js
│   │   │   │   ├── directives.js
│   │   │   │   ├── filters.js
│   │   │   │   ├── services.js
│   │   │   │   └── socket.js
│   │   │   └── partials/
│   │   │       ├── about.html
│   │   │       └── landing.html
│   │   └── templates/
│   │       ├── 404.html
│   │       └── index.html
│   ├── signals.py
│   ├── subscribe.py
│   └── utils.py
├── requirements.txt
├── setup.cfg
├── setup.py
├── tests/
│   ├── __init__.py
│   └── test_ouimeaux.py
└── tox.ini
Download .txt
SYMBOL INDEX (734 symbols across 25 files)

FILE: client.py
  class SwitchAction (line 26) | class SwitchAction(enum.Enum):
  class Worker (line 32) | class Worker(multiprocessing.Process):
    method __init__ (line 35) | def __init__(self, request_queue: multiprocessing.Queue, response_queu...
    method send_stop (line 40) | def send_stop(self):
    method process_response (line 43) | def process_response(self, resp):
  class Workers (line 47) | class Workers:
    method __init__ (line 48) | def __init__(self, n_workers: int, worker_type: Type[Worker], *args, *...
    method start (line 54) | def start(self):
    method put (line 58) | def put(self, msg):
    method wait (line 61) | def wait(self) -> list:
    method send_stop (line 73) | def send_stop(self):
  class ScanWorker (line 78) | class ScanWorker(Worker):
    method __init__ (line 79) | def __init__(self, request_queue: multiprocessing.Queue, response_queu...
    method run (line 86) | def run(self):
  function _exec (line 104) | def _exec(device: str, action: SwitchAction, value=None, port: int = def...
  function on (line 133) | def on(device: str, *args, **kwargs):
  function off (line 137) | def off(device: str, *args, **kwargs):
  function get_state (line 141) | def get_state(device: str, *args, **kwargs):
  function get_name (line 145) | def get_name(device: str, *args, **kwargs):
  function get_device (line 149) | def get_device(device: str, *args, **kwargs):
  function main (line 157) | def main():

FILE: ouimeaux/cli.py
  function _state (line 16) | def _state(device, readable=False):
  function scan (line 24) | def scan(args, on_switch=NOOP, on_motion=NOOP, on_bridge=NOOP, on_maker=...
  function switch (line 41) | def switch(args):
  function light (line 76) | def light(args):
  function make_matcher (line 158) | def make_matcher(device_name):
  function maker (line 171) | def maker(args):
  function list_ (line 232) | def list_(args):
  function status (line 254) | def status(args):
  function server (line 289) | def server(args):
  function wemo (line 316) | def wemo():

FILE: ouimeaux/config.py
  function in_home (line 5) | def in_home(*path):
  function ensure_directory (line 15) | def ensure_directory(directory):
  class WemoConfiguration (line 21) | class WemoConfiguration(object):
    method __init__ (line 22) | def __init__(self, filename=None):
    method aliases (line 53) | def aliases(self):
    method bind (line 57) | def bind(self):
    method listen (line 61) | def listen(self):
    method auth (line 65) | def auth(self):

FILE: ouimeaux/device/__init__.py
  class DeviceUnreachable (line 12) | class DeviceUnreachable(Exception): pass
  class UnknownService (line 13) | class UnknownService(Exception): pass
  class Device (line 16) | class Device(object):
    method __init__ (line 17) | def __init__(self, url):
    method _update_state (line 33) | def _update_state(self, value):
    method get_state (line 36) | def get_state(self, force_update=False):
    method __getstate__ (line 44) | def __getstate__(self):
    method get_service (line 50) | def get_service(self, name):
    method list_services (line 56) | def list_services(self):
    method ping (line 59) | def ping(self):
    method explain (line 65) | def explain(self):
    method model (line 74) | def model(self):
    method name (line 78) | def name(self):
    method serialnumber (line 82) | def serialnumber(self):
  function test (line 86) | def test():

FILE: ouimeaux/device/api/service.py
  class Action (line 22) | class Action(object):
    method __init__ (line 23) | def __init__(self, service, action_config):
    method __call__ (line 41) | def __call__(self, **kwargs):
    method __repr__ (line 55) | def __repr__(self):
  class Service (line 59) | class Service(object):
    method __init__ (line 64) | def __init__(self, service, base_url):
    method hostname (line 78) | def hostname(self):
    method controlURL (line 82) | def controlURL(self):
    method serviceType (line 87) | def serviceType(self):

FILE: ouimeaux/device/api/xsd/device.py
  function parsexml_ (line 58) | def parsexml_(*args, **kwargs):
  class GeneratedsSuper (line 78) | class GeneratedsSuper(object):
    class _FixedOffsetTZ (line 80) | class _FixedOffsetTZ(tzinfo):
      method __init__ (line 81) | def __init__(self, offset, name):
      method utcoffset (line 84) | def utcoffset(self, dt):
      method tzname (line 86) | def tzname(self, dt):
      method dst (line 88) | def dst(self, dt):
    method gds_format_string (line 90) | def gds_format_string(self, input_data, input_name=''):
    method gds_validate_string (line 92) | def gds_validate_string(self, input_data, node, input_name=''):
    method gds_format_base64 (line 94) | def gds_format_base64(self, input_data, input_name=''):
    method gds_validate_base64 (line 96) | def gds_validate_base64(self, input_data, node, input_name=''):
    method gds_format_integer (line 98) | def gds_format_integer(self, input_data, input_name=''):
    method gds_validate_integer (line 100) | def gds_validate_integer(self, input_data, node, input_name=''):
    method gds_format_integer_list (line 102) | def gds_format_integer_list(self, input_data, input_name=''):
    method gds_validate_integer_list (line 104) | def gds_validate_integer_list(self, input_data, node, input_name=''):
    method gds_format_float (line 112) | def gds_format_float(self, input_data, input_name=''):
    method gds_validate_float (line 114) | def gds_validate_float(self, input_data, node, input_name=''):
    method gds_format_float_list (line 116) | def gds_format_float_list(self, input_data, input_name=''):
    method gds_validate_float_list (line 118) | def gds_validate_float_list(self, input_data, node, input_name=''):
    method gds_format_double (line 126) | def gds_format_double(self, input_data, input_name=''):
    method gds_validate_double (line 128) | def gds_validate_double(self, input_data, node, input_name=''):
    method gds_format_double_list (line 130) | def gds_format_double_list(self, input_data, input_name=''):
    method gds_validate_double_list (line 132) | def gds_validate_double_list(self, input_data, node, input_name=''):
    method gds_format_boolean (line 140) | def gds_format_boolean(self, input_data, input_name=''):
    method gds_validate_boolean (line 142) | def gds_validate_boolean(self, input_data, node, input_name=''):
    method gds_format_boolean_list (line 144) | def gds_format_boolean_list(self, input_data, input_name=''):
    method gds_validate_boolean_list (line 146) | def gds_validate_boolean_list(self, input_data, node, input_name=''):
    method gds_validate_datetime (line 154) | def gds_validate_datetime(self, input_data, node, input_name=''):
    method gds_format_datetime (line 156) | def gds_format_datetime(self, input_data, input_name=''):
    method gds_parse_datetime (line 177) | def gds_parse_datetime(self, input_data, node, input_name=''):
    method gds_validate_date (line 200) | def gds_validate_date(self, input_data, node, input_name=''):
    method gds_format_date (line 202) | def gds_format_date(self, input_data, input_name=''):
    method gds_parse_date (line 220) | def gds_parse_date(self, input_data, node, input_name=''):
    method gds_str_lower (line 237) | def gds_str_lower(self, instring):
    method get_path_ (line 239) | def get_path_(self, node):
    method get_path_list_ (line 246) | def get_path_list_(self, node, path_list):
    method get_class_obj_ (line 253) | def get_class_obj_(self, node, default_class=None):
    method gds_build_any (line 265) | def gds_build_any(self, node, type_name=None):
  function showIndent (line 297) | def showIndent(outfile, level, pretty_print=True):
  function quote_xml (line 302) | def quote_xml(inStr):
  function quote_attrib (line 312) | def quote_attrib(inStr):
  function quote_python (line 327) | def quote_python(inStr):
  function get_all_text_ (line 342) | def get_all_text_(node):
  function find_attr_value_ (line 352) | def find_attr_value_(attr_name, node):
  class GDSParseError (line 366) | class GDSParseError(Exception):
  function raise_parse_error (line 369) | def raise_parse_error(node, msg):
  class MixedContainer (line 378) | class MixedContainer:
    method __init__ (line 394) | def __init__(self, category, content_type, name, value):
    method getCategory (line 399) | def getCategory(self):
    method getContenttype (line 401) | def getContenttype(self, content_type):
    method getValue (line 403) | def getValue(self):
    method getName (line 405) | def getName(self):
    method export (line 407) | def export(self, outfile, level, name, namespace, pretty_print=True):
    method exportSimple (line 416) | def exportSimple(self, outfile, level, name):
    method exportLiteral (line 434) | def exportLiteral(self, outfile, level, name):
  class MemberSpec_ (line 452) | class MemberSpec_(object):
    method __init__ (line 453) | def __init__(self, name='', data_type='', container=0):
    method set_name (line 457) | def set_name(self, name): self.name = name
    method get_name (line 458) | def get_name(self): return self.name
    method set_data_type (line 459) | def set_data_type(self, data_type): self.data_type = data_type
    method get_data_type_chain (line 460) | def get_data_type_chain(self): return self.data_type
    method get_data_type (line 461) | def get_data_type(self):
    method set_container (line 469) | def set_container(self, container): self.container = container
    method get_container (line 470) | def get_container(self): return self.container
  function _cast (line 472) | def _cast(typ, value):
  class root (line 481) | class root(GeneratedsSuper):
    method __init__ (line 484) | def __init__(self, specVersion=None, URLBase=None, device=None):
    method factory (line 489) | def factory(*args_, **kwargs_):
    method get_specVersion (line 495) | def get_specVersion(self): return self.specVersion
    method set_specVersion (line 496) | def set_specVersion(self, specVersion): self.specVersion = specVersion
    method get_URLBase (line 497) | def get_URLBase(self): return self.URLBase
    method set_URLBase (line 498) | def set_URLBase(self, URLBase): self.URLBase = URLBase
    method get_device (line 499) | def get_device(self): return self.device
    method set_device (line 500) | def set_device(self, device): self.device = device
    method get_anyAttributes_ (line 501) | def get_anyAttributes_(self): return self.anyAttributes_
    method set_anyAttributes_ (line 502) | def set_anyAttributes_(self, anyAttributes_): self.anyAttributes_ = an...
    method export (line 503) | def export(self, outfile, level, namespace_='tns:', name_='root', name...
    method exportAttributes (line 519) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 552) | def exportChildren(self, outfile, level, namespace_='tns:', name_='roo...
    method hasContent_ (line 564) | def hasContent_(self):
    method exportLiteral (line 573) | def exportLiteral(self, outfile, level, name_='root'):
    method exportLiteralAttributes (line 578) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 582) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 598) | def build(self, node):
    method buildAttributes (line 603) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 608) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class SpecVersionType (line 624) | class SpecVersionType(GeneratedsSuper):
    method __init__ (line 627) | def __init__(self, major=None, minor=None):
    method factory (line 630) | def factory(*args_, **kwargs_):
    method get_major (line 636) | def get_major(self): return self.major
    method set_major (line 637) | def set_major(self, major): self.major = major
    method get_minor (line 638) | def get_minor(self): return self.minor
    method set_minor (line 639) | def set_minor(self, minor): self.minor = minor
    method export (line 640) | def export(self, outfile, level, namespace_='tns:', name_='SpecVersion...
    method exportAttributes (line 656) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 658) | def exportChildren(self, outfile, level, namespace_='tns:', name_='Spe...
    method hasContent_ (line 669) | def hasContent_(self):
    method exportLiteral (line 677) | def exportLiteral(self, outfile, level, name_='SpecVersionType'):
    method exportLiteralAttributes (line 682) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 684) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 691) | def build(self, node):
    method buildAttributes (line 696) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 698) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class DeviceType (line 718) | class DeviceType(GeneratedsSuper):
    method __init__ (line 721) | def __init__(self, deviceType=None, friendlyName=None, manufacturer=No...
    method factory (line 741) | def factory(*args_, **kwargs_):
    method get_deviceType (line 747) | def get_deviceType(self): return self.deviceType
    method set_deviceType (line 748) | def set_deviceType(self, deviceType): self.deviceType = deviceType
    method get_friendlyName (line 749) | def get_friendlyName(self): return self.friendlyName
    method set_friendlyName (line 750) | def set_friendlyName(self, friendlyName): self.friendlyName = friendly...
    method get_manufacturer (line 751) | def get_manufacturer(self): return self.manufacturer
    method set_manufacturer (line 752) | def set_manufacturer(self, manufacturer): self.manufacturer = manufact...
    method get_manufacturerURL (line 753) | def get_manufacturerURL(self): return self.manufacturerURL
    method set_manufacturerURL (line 754) | def set_manufacturerURL(self, manufacturerURL): self.manufacturerURL =...
    method get_modelDescription (line 755) | def get_modelDescription(self): return self.modelDescription
    method set_modelDescription (line 756) | def set_modelDescription(self, modelDescription): self.modelDescriptio...
    method get_modelName (line 757) | def get_modelName(self): return self.modelName
    method set_modelName (line 758) | def set_modelName(self, modelName): self.modelName = modelName
    method get_modelNumber (line 759) | def get_modelNumber(self): return self.modelNumber
    method set_modelNumber (line 760) | def set_modelNumber(self, modelNumber): self.modelNumber = modelNumber
    method get_modelURL (line 761) | def get_modelURL(self): return self.modelURL
    method set_modelURL (line 762) | def set_modelURL(self, modelURL): self.modelURL = modelURL
    method get_serialNumber (line 763) | def get_serialNumber(self): return self.serialNumber
    method set_serialNumber (line 764) | def set_serialNumber(self, serialNumber): self.serialNumber = serialNu...
    method get_UDN (line 765) | def get_UDN(self): return self.UDN
    method set_UDN (line 766) | def set_UDN(self, UDN): self.UDN = UDN
    method get_UPC (line 767) | def get_UPC(self): return self.UPC
    method set_UPC (line 768) | def set_UPC(self, UPC): self.UPC = UPC
    method get_iconList (line 769) | def get_iconList(self): return self.iconList
    method set_iconList (line 770) | def set_iconList(self, iconList): self.iconList = iconList
    method get_serviceList (line 771) | def get_serviceList(self): return self.serviceList
    method set_serviceList (line 772) | def set_serviceList(self, serviceList): self.serviceList = serviceList
    method get_deviceList (line 773) | def get_deviceList(self): return self.deviceList
    method set_deviceList (line 774) | def set_deviceList(self, deviceList): self.deviceList = deviceList
    method get_presentationURL (line 775) | def get_presentationURL(self): return self.presentationURL
    method set_presentationURL (line 776) | def set_presentationURL(self, presentationURL): self.presentationURL =...
    method get_anytypeobjs_ (line 777) | def get_anytypeobjs_(self): return self.anytypeobjs_
    method set_anytypeobjs_ (line 778) | def set_anytypeobjs_(self, anytypeobjs_): self.anytypeobjs_ = anytypeo...
    method add_anytypeobjs_ (line 779) | def add_anytypeobjs_(self, value): self.anytypeobjs_.append(value)
    method insert_anytypeobjs_ (line 780) | def insert_anytypeobjs_(self, index, value): self._anytypeobjs_[index]...
    method export (line 781) | def export(self, outfile, level, namespace_='tns:', name_='DeviceType'...
    method exportAttributes (line 797) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 799) | def exportChildren(self, outfile, level, namespace_='tns:', name_='Dev...
    method hasContent_ (line 848) | def hasContent_(self):
    method exportLiteral (line 870) | def exportLiteral(self, outfile, level, name_='DeviceType'):
    method exportLiteralAttributes (line 875) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 877) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 940) | def build(self, node):
    method buildAttributes (line 945) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 947) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class IconListType (line 1015) | class IconListType(GeneratedsSuper):
    method __init__ (line 1018) | def __init__(self, icon=None):
    method factory (line 1023) | def factory(*args_, **kwargs_):
    method get_icon (line 1029) | def get_icon(self): return self.icon
    method set_icon (line 1030) | def set_icon(self, icon): self.icon = icon
    method add_icon (line 1031) | def add_icon(self, value): self.icon.append(value)
    method insert_icon (line 1032) | def insert_icon(self, index, value): self.icon[index] = value
    method export (line 1033) | def export(self, outfile, level, namespace_='tns:', name_='IconListTyp...
    method exportAttributes (line 1049) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1051) | def exportChildren(self, outfile, level, namespace_='tns:', name_='Ico...
    method hasContent_ (line 1058) | def hasContent_(self):
    method exportLiteral (line 1065) | def exportLiteral(self, outfile, level, name_='IconListType'):
    method exportLiteralAttributes (line 1070) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1072) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1085) | def build(self, node):
    method buildAttributes (line 1090) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1092) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class ServiceListType (line 1100) | class ServiceListType(GeneratedsSuper):
    method __init__ (line 1103) | def __init__(self, service=None):
    method factory (line 1108) | def factory(*args_, **kwargs_):
    method get_service (line 1114) | def get_service(self): return self.service
    method set_service (line 1115) | def set_service(self, service): self.service = service
    method add_service (line 1116) | def add_service(self, value): self.service.append(value)
    method insert_service (line 1117) | def insert_service(self, index, value): self.service[index] = value
    method export (line 1118) | def export(self, outfile, level, namespace_='tns:', name_='ServiceList...
    method exportAttributes (line 1134) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1136) | def exportChildren(self, outfile, level, namespace_='tns:', name_='Ser...
    method hasContent_ (line 1143) | def hasContent_(self):
    method exportLiteral (line 1150) | def exportLiteral(self, outfile, level, name_='ServiceListType'):
    method exportLiteralAttributes (line 1155) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1157) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1170) | def build(self, node):
    method buildAttributes (line 1175) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1177) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class DeviceListType (line 1185) | class DeviceListType(GeneratedsSuper):
    method __init__ (line 1188) | def __init__(self, device=None):
    method factory (line 1193) | def factory(*args_, **kwargs_):
    method get_device (line 1199) | def get_device(self): return self.device
    method set_device (line 1200) | def set_device(self, device): self.device = device
    method add_device (line 1201) | def add_device(self, value): self.device.append(value)
    method insert_device (line 1202) | def insert_device(self, index, value): self.device[index] = value
    method export (line 1203) | def export(self, outfile, level, namespace_='tns:', name_='DeviceListT...
    method exportAttributes (line 1219) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1221) | def exportChildren(self, outfile, level, namespace_='tns:', name_='Dev...
    method hasContent_ (line 1228) | def hasContent_(self):
    method exportLiteral (line 1235) | def exportLiteral(self, outfile, level, name_='DeviceListType'):
    method exportLiteralAttributes (line 1240) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1242) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1255) | def build(self, node):
    method buildAttributes (line 1260) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1262) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class iconType (line 1270) | class iconType(GeneratedsSuper):
    method __init__ (line 1273) | def __init__(self, mimetype=None, width=None, height=None, depth=None,...
    method factory (line 1279) | def factory(*args_, **kwargs_):
    method get_mimetype (line 1285) | def get_mimetype(self): return self.mimetype
    method set_mimetype (line 1286) | def set_mimetype(self, mimetype): self.mimetype = mimetype
    method get_width (line 1287) | def get_width(self): return self.width
    method set_width (line 1288) | def set_width(self, width): self.width = width
    method get_height (line 1289) | def get_height(self): return self.height
    method set_height (line 1290) | def set_height(self, height): self.height = height
    method get_depth (line 1291) | def get_depth(self): return self.depth
    method set_depth (line 1292) | def set_depth(self, depth): self.depth = depth
    method get_url (line 1293) | def get_url(self): return self.url
    method set_url (line 1294) | def set_url(self, url): self.url = url
    method export (line 1295) | def export(self, outfile, level, namespace_='tns:', name_='iconType', ...
    method exportAttributes (line 1311) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1313) | def exportChildren(self, outfile, level, namespace_='tns:', name_='ico...
    method hasContent_ (line 1333) | def hasContent_(self):
    method exportLiteral (line 1344) | def exportLiteral(self, outfile, level, name_='iconType'):
    method exportLiteralAttributes (line 1349) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1351) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1367) | def build(self, node):
    method buildAttributes (line 1372) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1374) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class serviceType (line 1410) | class serviceType(GeneratedsSuper):
    method __init__ (line 1413) | def __init__(self, serviceType=None, serviceId=None, SCPDURL=None, con...
    method factory (line 1419) | def factory(*args_, **kwargs_):
    method get_serviceType (line 1425) | def get_serviceType(self): return self.serviceType
    method set_serviceType (line 1426) | def set_serviceType(self, serviceType): self.serviceType = serviceType
    method get_serviceId (line 1427) | def get_serviceId(self): return self.serviceId
    method set_serviceId (line 1428) | def set_serviceId(self, serviceId): self.serviceId = serviceId
    method get_SCPDURL (line 1429) | def get_SCPDURL(self): return self.SCPDURL
    method set_SCPDURL (line 1430) | def set_SCPDURL(self, SCPDURL): self.SCPDURL = SCPDURL
    method get_controlURL (line 1431) | def get_controlURL(self): return self.controlURL
    method set_controlURL (line 1432) | def set_controlURL(self, controlURL): self.controlURL = controlURL
    method get_eventSubURL (line 1433) | def get_eventSubURL(self): return self.eventSubURL
    method set_eventSubURL (line 1434) | def set_eventSubURL(self, eventSubURL): self.eventSubURL = eventSubURL
    method export (line 1435) | def export(self, outfile, level, namespace_='tns:', name_='serviceType...
    method exportAttributes (line 1451) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1453) | def exportChildren(self, outfile, level, namespace_='tns:', name_='ser...
    method hasContent_ (line 1473) | def hasContent_(self):
    method exportLiteral (line 1484) | def exportLiteral(self, outfile, level, name_='serviceType'):
    method exportLiteralAttributes (line 1489) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1491) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1507) | def build(self, node):
    method buildAttributes (line 1512) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1514) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  function usage (line 1553) | def usage():
  function get_root_tag (line 1558) | def get_root_tag(node):
  function parse (line 1566) | def parse(inFileName):
  function parseString (line 1580) | def parseString(inString):
  function parseLiteral (line 1595) | def parseLiteral(inFileName):
  function main (line 1615) | def main():

FILE: ouimeaux/device/api/xsd/service.py
  function parsexml_ (line 58) | def parsexml_(*args, **kwargs):
  class GeneratedsSuper (line 78) | class GeneratedsSuper(object):
    class _FixedOffsetTZ (line 80) | class _FixedOffsetTZ(tzinfo):
      method __init__ (line 81) | def __init__(self, offset, name):
      method utcoffset (line 84) | def utcoffset(self, dt):
      method tzname (line 86) | def tzname(self, dt):
      method dst (line 88) | def dst(self, dt):
    method gds_format_string (line 90) | def gds_format_string(self, input_data, input_name=''):
    method gds_validate_string (line 92) | def gds_validate_string(self, input_data, node, input_name=''):
    method gds_format_base64 (line 94) | def gds_format_base64(self, input_data, input_name=''):
    method gds_validate_base64 (line 96) | def gds_validate_base64(self, input_data, node, input_name=''):
    method gds_format_integer (line 98) | def gds_format_integer(self, input_data, input_name=''):
    method gds_validate_integer (line 100) | def gds_validate_integer(self, input_data, node, input_name=''):
    method gds_format_integer_list (line 102) | def gds_format_integer_list(self, input_data, input_name=''):
    method gds_validate_integer_list (line 104) | def gds_validate_integer_list(self, input_data, node, input_name=''):
    method gds_format_float (line 112) | def gds_format_float(self, input_data, input_name=''):
    method gds_validate_float (line 114) | def gds_validate_float(self, input_data, node, input_name=''):
    method gds_format_float_list (line 116) | def gds_format_float_list(self, input_data, input_name=''):
    method gds_validate_float_list (line 118) | def gds_validate_float_list(self, input_data, node, input_name=''):
    method gds_format_double (line 126) | def gds_format_double(self, input_data, input_name=''):
    method gds_validate_double (line 128) | def gds_validate_double(self, input_data, node, input_name=''):
    method gds_format_double_list (line 130) | def gds_format_double_list(self, input_data, input_name=''):
    method gds_validate_double_list (line 132) | def gds_validate_double_list(self, input_data, node, input_name=''):
    method gds_format_boolean (line 140) | def gds_format_boolean(self, input_data, input_name=''):
    method gds_validate_boolean (line 142) | def gds_validate_boolean(self, input_data, node, input_name=''):
    method gds_format_boolean_list (line 144) | def gds_format_boolean_list(self, input_data, input_name=''):
    method gds_validate_boolean_list (line 146) | def gds_validate_boolean_list(self, input_data, node, input_name=''):
    method gds_validate_datetime (line 154) | def gds_validate_datetime(self, input_data, node, input_name=''):
    method gds_format_datetime (line 156) | def gds_format_datetime(self, input_data, input_name=''):
    method gds_parse_datetime (line 177) | def gds_parse_datetime(self, input_data, node, input_name=''):
    method gds_validate_date (line 200) | def gds_validate_date(self, input_data, node, input_name=''):
    method gds_format_date (line 202) | def gds_format_date(self, input_data, input_name=''):
    method gds_parse_date (line 220) | def gds_parse_date(self, input_data, node, input_name=''):
    method gds_str_lower (line 237) | def gds_str_lower(self, instring):
    method get_path_ (line 239) | def get_path_(self, node):
    method get_path_list_ (line 246) | def get_path_list_(self, node, path_list):
    method get_class_obj_ (line 253) | def get_class_obj_(self, node, default_class=None):
    method gds_build_any (line 265) | def gds_build_any(self, node, type_name=None):
  function showIndent (line 297) | def showIndent(outfile, level, pretty_print=True):
  function quote_xml (line 302) | def quote_xml(inStr):
  function quote_attrib (line 312) | def quote_attrib(inStr):
  function quote_python (line 327) | def quote_python(inStr):
  function get_all_text_ (line 342) | def get_all_text_(node):
  function find_attr_value_ (line 352) | def find_attr_value_(attr_name, node):
  class GDSParseError (line 366) | class GDSParseError(Exception):
  function raise_parse_error (line 369) | def raise_parse_error(node, msg):
  class MixedContainer (line 378) | class MixedContainer:
    method __init__ (line 394) | def __init__(self, category, content_type, name, value):
    method getCategory (line 399) | def getCategory(self):
    method getContenttype (line 401) | def getContenttype(self, content_type):
    method getValue (line 403) | def getValue(self):
    method getName (line 405) | def getName(self):
    method export (line 407) | def export(self, outfile, level, name, namespace, pretty_print=True):
    method exportSimple (line 416) | def exportSimple(self, outfile, level, name):
    method exportLiteral (line 434) | def exportLiteral(self, outfile, level, name):
  class MemberSpec_ (line 452) | class MemberSpec_(object):
    method __init__ (line 453) | def __init__(self, name='', data_type='', container=0):
    method set_name (line 457) | def set_name(self, name): self.name = name
    method get_name (line 458) | def get_name(self): return self.name
    method set_data_type (line 459) | def set_data_type(self, data_type): self.data_type = data_type
    method get_data_type_chain (line 460) | def get_data_type_chain(self): return self.data_type
    method get_data_type (line 461) | def get_data_type(self):
    method set_container (line 469) | def set_container(self, container): self.container = container
    method get_container (line 470) | def get_container(self): return self.container
  function _cast (line 472) | def _cast(typ, value):
  class scpd (line 481) | class scpd(GeneratedsSuper):
    method __init__ (line 484) | def __init__(self, specVersion=None, actionList=None, serviceStateTabl...
    method factory (line 488) | def factory(*args_, **kwargs_):
    method get_specVersion (line 494) | def get_specVersion(self): return self.specVersion
    method set_specVersion (line 495) | def set_specVersion(self, specVersion): self.specVersion = specVersion
    method get_actionList (line 496) | def get_actionList(self): return self.actionList
    method set_actionList (line 497) | def set_actionList(self, actionList): self.actionList = actionList
    method get_serviceStateTable (line 498) | def get_serviceStateTable(self): return self.serviceStateTable
    method set_serviceStateTable (line 499) | def set_serviceStateTable(self, serviceStateTable): self.serviceStateT...
    method export (line 500) | def export(self, outfile, level, namespace_='', name_='scpd', namespac...
    method exportAttributes (line 516) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 518) | def exportChildren(self, outfile, level, namespace_='', name_='scpd', ...
    method hasContent_ (line 529) | def hasContent_(self):
    method exportLiteral (line 538) | def exportLiteral(self, outfile, level, name_='scpd'):
    method exportLiteralAttributes (line 543) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 545) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 564) | def build(self, node):
    method buildAttributes (line 569) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 571) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class SpecVersionType (line 587) | class SpecVersionType(GeneratedsSuper):
    method __init__ (line 590) | def __init__(self, major=None, minor=None):
    method factory (line 593) | def factory(*args_, **kwargs_):
    method get_major (line 599) | def get_major(self): return self.major
    method set_major (line 600) | def set_major(self, major): self.major = major
    method get_minor (line 601) | def get_minor(self): return self.minor
    method set_minor (line 602) | def set_minor(self, minor): self.minor = minor
    method export (line 603) | def export(self, outfile, level, namespace_='', name_='SpecVersionType...
    method exportAttributes (line 619) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 621) | def exportChildren(self, outfile, level, namespace_='', name_='SpecVer...
    method hasContent_ (line 632) | def hasContent_(self):
    method exportLiteral (line 640) | def exportLiteral(self, outfile, level, name_='SpecVersionType'):
    method exportLiteralAttributes (line 645) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 647) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 654) | def build(self, node):
    method buildAttributes (line 659) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 661) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class ActionListType (line 681) | class ActionListType(GeneratedsSuper):
    method __init__ (line 684) | def __init__(self, action=None):
    method factory (line 689) | def factory(*args_, **kwargs_):
    method get_action (line 695) | def get_action(self): return self.action
    method set_action (line 696) | def set_action(self, action): self.action = action
    method add_action (line 697) | def add_action(self, value): self.action.append(value)
    method insert_action (line 698) | def insert_action(self, index, value): self.action[index] = value
    method export (line 699) | def export(self, outfile, level, namespace_='', name_='ActionListType'...
    method exportAttributes (line 715) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 717) | def exportChildren(self, outfile, level, namespace_='', name_='ActionL...
    method hasContent_ (line 724) | def hasContent_(self):
    method exportLiteral (line 731) | def exportLiteral(self, outfile, level, name_='ActionListType'):
    method exportLiteralAttributes (line 736) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 738) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 751) | def build(self, node):
    method buildAttributes (line 756) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 758) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class ActionType (line 766) | class ActionType(GeneratedsSuper):
    method __init__ (line 769) | def __init__(self, name=None, argumentList=None):
    method factory (line 772) | def factory(*args_, **kwargs_):
    method get_name (line 778) | def get_name(self): return self.name
    method set_name (line 779) | def set_name(self, name): self.name = name
    method get_argumentList (line 780) | def get_argumentList(self): return self.argumentList
    method set_argumentList (line 781) | def set_argumentList(self, argumentList): self.argumentList = argument...
    method export (line 782) | def export(self, outfile, level, namespace_='', name_='ActionType', na...
    method exportAttributes (line 798) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 800) | def exportChildren(self, outfile, level, namespace_='', name_='ActionT...
    method hasContent_ (line 810) | def hasContent_(self):
    method exportLiteral (line 818) | def exportLiteral(self, outfile, level, name_='ActionType'):
    method exportLiteralAttributes (line 823) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 825) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 835) | def build(self, node):
    method buildAttributes (line 840) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 842) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class ArgumentListType (line 854) | class ArgumentListType(GeneratedsSuper):
    method __init__ (line 857) | def __init__(self, argument=None):
    method factory (line 862) | def factory(*args_, **kwargs_):
    method get_argument (line 868) | def get_argument(self): return self.argument
    method set_argument (line 869) | def set_argument(self, argument): self.argument = argument
    method add_argument (line 870) | def add_argument(self, value): self.argument.append(value)
    method insert_argument (line 871) | def insert_argument(self, index, value): self.argument[index] = value
    method export (line 872) | def export(self, outfile, level, namespace_='', name_='ArgumentListTyp...
    method exportAttributes (line 888) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 890) | def exportChildren(self, outfile, level, namespace_='', name_='Argumen...
    method hasContent_ (line 897) | def hasContent_(self):
    method exportLiteral (line 904) | def exportLiteral(self, outfile, level, name_='ArgumentListType'):
    method exportLiteralAttributes (line 909) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 911) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 924) | def build(self, node):
    method buildAttributes (line 929) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 931) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class ArgumentType (line 939) | class ArgumentType(GeneratedsSuper):
    method __init__ (line 942) | def __init__(self, name=None, direction=None, relatedStateVariable=Non...
    method factory (line 947) | def factory(*args_, **kwargs_):
    method get_name (line 953) | def get_name(self): return self.name
    method set_name (line 954) | def set_name(self, name): self.name = name
    method get_direction (line 955) | def get_direction(self): return self.direction
    method set_direction (line 956) | def set_direction(self, direction): self.direction = direction
    method get_relatedStateVariable (line 957) | def get_relatedStateVariable(self): return self.relatedStateVariable
    method set_relatedStateVariable (line 958) | def set_relatedStateVariable(self, relatedStateVariable): self.related...
    method get_retval (line 959) | def get_retval(self): return self.retval
    method set_retval (line 960) | def set_retval(self, retval): self.retval = retval
    method export (line 961) | def export(self, outfile, level, namespace_='', name_='ArgumentType', ...
    method exportAttributes (line 977) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 979) | def exportChildren(self, outfile, level, namespace_='', name_='Argumen...
    method hasContent_ (line 995) | def hasContent_(self):
    method exportLiteral (line 1005) | def exportLiteral(self, outfile, level, name_='ArgumentType'):
    method exportLiteralAttributes (line 1010) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1012) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1028) | def build(self, node):
    method buildAttributes (line 1033) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1035) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class ServiceStateTableType (line 1055) | class ServiceStateTableType(GeneratedsSuper):
    method __init__ (line 1058) | def __init__(self, stateVariable=None):
    method factory (line 1063) | def factory(*args_, **kwargs_):
    method get_stateVariable (line 1069) | def get_stateVariable(self): return self.stateVariable
    method set_stateVariable (line 1070) | def set_stateVariable(self, stateVariable): self.stateVariable = state...
    method add_stateVariable (line 1071) | def add_stateVariable(self, value): self.stateVariable.append(value)
    method insert_stateVariable (line 1072) | def insert_stateVariable(self, index, value): self.stateVariable[index...
    method export (line 1073) | def export(self, outfile, level, namespace_='', name_='ServiceStateTab...
    method exportAttributes (line 1089) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1091) | def exportChildren(self, outfile, level, namespace_='', name_='Service...
    method hasContent_ (line 1098) | def hasContent_(self):
    method exportLiteral (line 1105) | def exportLiteral(self, outfile, level, name_='ServiceStateTableType'):
    method exportLiteralAttributes (line 1110) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1112) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1125) | def build(self, node):
    method buildAttributes (line 1130) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1132) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class StateVariableType (line 1140) | class StateVariableType(GeneratedsSuper):
    method __init__ (line 1143) | def __init__(self, sendEvents='yes', name=None, dataType=None, default...
    method factory (line 1150) | def factory(*args_, **kwargs_):
    method get_name (line 1156) | def get_name(self): return self.name
    method set_name (line 1157) | def set_name(self, name): self.name = name
    method get_dataType (line 1158) | def get_dataType(self): return self.dataType
    method set_dataType (line 1159) | def set_dataType(self, dataType): self.dataType = dataType
    method get_defaultValue (line 1160) | def get_defaultValue(self): return self.defaultValue
    method set_defaultValue (line 1161) | def set_defaultValue(self, defaultValue): self.defaultValue = defaultV...
    method get_allowedValueList (line 1162) | def get_allowedValueList(self): return self.allowedValueList
    method set_allowedValueList (line 1163) | def set_allowedValueList(self, allowedValueList): self.allowedValueLis...
    method get_allowedValueRange (line 1164) | def get_allowedValueRange(self): return self.allowedValueRange
    method set_allowedValueRange (line 1165) | def set_allowedValueRange(self, allowedValueRange): self.allowedValueR...
    method get_sendEvents (line 1166) | def get_sendEvents(self): return self.sendEvents
    method set_sendEvents (line 1167) | def set_sendEvents(self, sendEvents): self.sendEvents = sendEvents
    method export (line 1168) | def export(self, outfile, level, namespace_='', name_='StateVariableTy...
    method exportAttributes (line 1184) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1188) | def exportChildren(self, outfile, level, namespace_='', name_='StateVa...
    method hasContent_ (line 1206) | def hasContent_(self):
    method exportLiteral (line 1217) | def exportLiteral(self, outfile, level, name_='StateVariableType'):
    method exportLiteralAttributes (line 1222) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1227) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1249) | def build(self, node):
    method buildAttributes (line 1254) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1259) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class AllowedValueListType (line 1283) | class AllowedValueListType(GeneratedsSuper):
    method __init__ (line 1286) | def __init__(self, allowedValue=None):
    method factory (line 1291) | def factory(*args_, **kwargs_):
    method get_allowedValue (line 1297) | def get_allowedValue(self): return self.allowedValue
    method set_allowedValue (line 1298) | def set_allowedValue(self, allowedValue): self.allowedValue = allowedV...
    method add_allowedValue (line 1299) | def add_allowedValue(self, value): self.allowedValue.append(value)
    method insert_allowedValue (line 1300) | def insert_allowedValue(self, index, value): self.allowedValue[index] ...
    method export (line 1301) | def export(self, outfile, level, namespace_='', name_='AllowedValueLis...
    method exportAttributes (line 1317) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1319) | def exportChildren(self, outfile, level, namespace_='', name_='Allowed...
    method hasContent_ (line 1327) | def hasContent_(self):
    method exportLiteral (line 1334) | def exportLiteral(self, outfile, level, name_='AllowedValueListType'):
    method exportLiteralAttributes (line 1339) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1341) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1351) | def build(self, node):
    method buildAttributes (line 1356) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1358) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class AllowedValueRangeType (line 1366) | class AllowedValueRangeType(GeneratedsSuper):
    method __init__ (line 1369) | def __init__(self, minimum=None, maximum=None, step=None):
    method factory (line 1373) | def factory(*args_, **kwargs_):
    method get_minimum (line 1379) | def get_minimum(self): return self.minimum
    method set_minimum (line 1380) | def set_minimum(self, minimum): self.minimum = minimum
    method get_maximum (line 1381) | def get_maximum(self): return self.maximum
    method set_maximum (line 1382) | def set_maximum(self, maximum): self.maximum = maximum
    method get_step (line 1383) | def get_step(self): return self.step
    method set_step (line 1384) | def set_step(self, step): self.step = step
    method export (line 1385) | def export(self, outfile, level, namespace_='', name_='AllowedValueRan...
    method exportAttributes (line 1401) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1403) | def exportChildren(self, outfile, level, namespace_='', name_='Allowed...
    method hasContent_ (line 1417) | def hasContent_(self):
    method exportLiteral (line 1426) | def exportLiteral(self, outfile, level, name_='AllowedValueRangeType'):
    method exportLiteralAttributes (line 1431) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1433) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1443) | def build(self, node):
    method buildAttributes (line 1448) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1450) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  class retvalType (line 1478) | class retvalType(GeneratedsSuper):
    method __init__ (line 1481) | def __init__(self):
    method factory (line 1483) | def factory(*args_, **kwargs_):
    method export (line 1489) | def export(self, outfile, level, namespace_='', name_='retvalType', na...
    method exportAttributes (line 1504) | def exportAttributes(self, outfile, level, already_processed, namespac...
    method exportChildren (line 1506) | def exportChildren(self, outfile, level, namespace_='', name_='retvalT...
    method hasContent_ (line 1508) | def hasContent_(self):
    method exportLiteral (line 1515) | def exportLiteral(self, outfile, level, name_='retvalType'):
    method exportLiteralAttributes (line 1520) | def exportLiteralAttributes(self, outfile, level, already_processed, n...
    method exportLiteralChildren (line 1522) | def exportLiteralChildren(self, outfile, level, name_):
    method build (line 1524) | def build(self, node):
    method buildAttributes (line 1529) | def buildAttributes(self, node, attrs, already_processed):
    method buildChildren (line 1531) | def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
  function usage (line 1554) | def usage():
  function get_root_tag (line 1559) | def get_root_tag(node):
  function parse (line 1567) | def parse(inFileName):
  function parseString (line 1581) | def parseString(inString):
  function parseLiteral (line 1596) | def parseLiteral(inFileName):
  function main (line 1616) | def main():

FILE: ouimeaux/device/bridge.py
  class Bridge (line 6) | class Bridge(Device):
    method __repr__ (line 10) | def __repr__(self):
    method bridge_get_lights (line 15) | def bridge_get_lights(self):
    method bridge_get_groups (line 27) | def bridge_get_groups(self):
    method light_attributes (line 39) | def light_attributes(self, light):
    method group_attributes (line 53) | def group_attributes(self, group):
    method light_name (line 61) | def light_name(self, light):
    method group_name (line 64) | def group_name(self, group):
    method light_get_id (line 67) | def light_get_id(self, light):
    method group_get_id (line 70) | def group_get_id(self, group):
    method light_get_state (line 73) | def light_get_state(self, light):
    method group_get_state (line 82) | def group_get_state(self, group):
    method light_set_state (line 94) | def light_set_state(self, light, state=None, dim=None, transition_dura...
    method group_set_state (line 102) | def group_set_state(self, group, state=None, dim=None):

FILE: ouimeaux/device/insight.py
  class Insight (line 4) | class Insight(Switch):
    method __repr__ (line 6) | def __repr__(self):
    method insight_params (line 10) | def insight_params(self):
    method today_kwh (line 35) | def today_kwh(self):
    method current_power (line 39) | def current_power(self):
    method today_on_time (line 46) | def today_on_time(self):
    method on_for (line 50) | def on_for(self):
    method last_change (line 54) | def last_change(self):
    method today_standby_time (line 58) | def today_standby_time(self):
    method ontotal (line 62) | def ontotal(self):
    method totalmw (line 66) | def totalmw(self):

FILE: ouimeaux/device/lightswitch.py
  class LightSwitch (line 3) | class LightSwitch(Switch):
    method __repr__ (line 5) | def __repr__(self):

FILE: ouimeaux/device/maker.py
  class Maker (line 6) | class Maker(Device):
    method __repr__ (line 8) | def __repr__(self):
    method get_state (line 11) | def get_state(self, force_update=False):
    method set_state (line 21) | def set_state(self, state):
    method off (line 28) | def off(self):
    method on (line 34) | def on(self):
    method maker_attribs (line 41) | def maker_attribs(self):
    method switch_state (line 62) | def switch_state(self):
    method sensor_state (line 66) | def sensor_state(self):
    method switch_mode (line 70) | def switch_mode(self):
    method has_sensor (line 74) | def has_sensor(self):

FILE: ouimeaux/device/motion.py
  class Motion (line 3) | class Motion(Device):
    method __repr__ (line 5) | def __repr__(self):

FILE: ouimeaux/device/switch.py
  class Switch (line 6) | class Switch(Device):
    method set_state (line 8) | def set_state(self, state):
    method off (line 15) | def off(self):
    method on (line 21) | def on(self):
    method toggle (line 27) | def toggle(self):
    method blink (line 33) | def blink(self, delay=1):
    method __repr__ (line 40) | def __repr__(self):

FILE: ouimeaux/discovery.py
  class UPnPLoopbackException (line 15) | class UPnPLoopbackException(Exception):
  class UPnP (line 21) | class UPnP(object):
    method __init__ (line 26) | def __init__(self, mcast_ip='239.255.255.250', mcast_port=1900, bind=N...
    method _response_received (line 39) | def _response_received(self, message, address):
    method server (line 59) | def server(self):
    method broadcast (line 70) | def broadcast(self):
  function test (line 84) | def test():

FILE: ouimeaux/environment.py
  class StopBroadcasting (line 28) | class StopBroadcasting(Exception):
  class UnknownDevice (line 32) | class UnknownDevice(Exception):
  class Environment (line 35) | class Environment(object):
    method __init__ (line 36) | def __init__(self, switch_callback=_NOOP, motion_callback=_NOOP, bridg...
    method __iter__ (line 72) | def __iter__(self):
    method start (line 75) | def start(self):
    method wait (line 88) | def wait(self, timeout=None):
    method discover (line 101) | def discover(self, seconds=2):
    method _found_device (line 120) | def _found_device(self, sender, **kwargs):
    method _process_device (line 143) | def _process_device(self, device):
    method list_switches (line 178) | def list_switches(self):
    method list_motions (line 184) | def list_motions(self):
    method list_makers (line 190) | def list_makers(self):
    method list_bridges (line 196) | def list_bridges(self):
    method get (line 202) | def get(self, name):
    method get_switch (line 216) | def get_switch(self, name):
    method get_motion (line 225) | def get_motion(self, name):
    method get_bridge (line 234) | def get_bridge(self, name):
    method get_maker (line 243) | def get_maker(self, name):

FILE: ouimeaux/examples/watch.py
  function mainloop (line 10) | def mainloop(name):

FILE: ouimeaux/pysignals/dispatcher.py
  function set_debug (line 22) | def set_debug( val ):
  function _make_id (line 26) | def _make_id(target):
  class Signal (line 36) | class Signal(object):
    method __init__ (line 45) | def __init__(self, providing_args=None, use_caching=False):
    method connect (line 66) | def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
    method disconnect (line 137) | def disconnect(self, receiver=None, sender=None, weak=None, dispatch_u...
    method has_listeners (line 175) | def has_listeners(self, sender=None):
    method send (line 178) | def send(self, sender, **named):
    method send_robust (line 205) | def send_robust(self, sender, **named):
    method _clear_dead_receivers (line 246) | def _clear_dead_receivers(self):
    method _live_receivers (line 257) | def _live_receivers(self, sender):
    method _remove_receiver (line 296) | def _remove_receiver(self, receiver=None):
    method receive (line 305) | def receive(self, **kwargs):
  class StateChange (line 321) | class StateChange( Signal ):
    method __init__ (line 323) | def __init__(self, providing_args=None):
    method send (line 327) | def send(self, sender, **named):
  function receiver (line 365) | def receiver(signal, **kwargs):

FILE: ouimeaux/pysignals/inspect.py
  function getargspec (line 8) | def getargspec(func):
  function get_func_args (line 34) | def get_func_args(func):
  function get_func_full_args (line 46) | def get_func_full_args(func):
  function func_accepts_kwargs (line 84) | def func_accepts_kwargs(func):
  function func_accepts_var_args (line 105) | def func_accepts_var_args(func):
  function func_has_no_args (line 118) | def func_has_no_args(func):
  function func_supports_parameter (line 126) | def func_supports_parameter(func, parameter):

FILE: ouimeaux/pysignals/weakref_backports.py
  class WeakMethod (line 17) | class WeakMethod(ref):
    method __new__ (line 25) | def __new__(cls, meth, callback=None):
    method __call__ (line 47) | def __call__(self):
    method __eq__ (line 54) | def __eq__(self, other):
    method __ne__ (line 61) | def __ne__(self, other):

FILE: ouimeaux/server/__init__.py
  function initialize (line 36) | def initialize(bind=None, auth=None):
  function serialize (line 53) | def serialize(device):
  function get_device (line 88) | def get_device(name, should_abort=True):
  class EnvironmentResource (line 98) | class EnvironmentResource(Resource):
    method get (line 100) | def get(self):
    method post (line 106) | def post(self):
  class DeviceResource (line 113) | class DeviceResource(Resource):
    method get (line 115) | def get(self, name):
    method post (line 118) | def post(self, name):
  class SocketNamespace (line 139) | class SocketNamespace(BaseNamespace):
    method update_state (line 141) | def update_state(self, sender, **kwargs):
    method on_statechange (line 146) | def on_statechange(self, data):
    method on_join (line 149) | def on_join(self, data):
    method __del__ (line 155) | def __del__(self):
  function run_socketio (line 161) | def run_socketio(**kwargs):
  function basic_pages (line 167) | def basic_pages(**kwargs):
  function favicon (line 173) | def favicon():
  function page_not_found (line 178) | def page_not_found(e):

FILE: ouimeaux/server/static/js/bootstrap.js
  function transitionEnd (line 34) | function transitionEnd() {
  function removeElement (line 119) | function removeElement() {
  function clearMenus (line 771) | function clearMenus() {
  function getParent (line 782) | function getParent($this) {
  function complete (line 1343) | function complete() {
  function ScrollSpy (line 1611) | function ScrollSpy(element, options) {
  function next (line 1812) | function next() {

FILE: ouimeaux/signals.py
  function _got_subscription (line 24) | def _got_subscription(sender, **kwargs):

FILE: ouimeaux/subscribe.py
  class SubscriptionRegistry (line 25) | class SubscriptionRegistry(object):
    method __init__ (line 26) | def __init__(self):
    method register (line 32) | def register(self, device):
    method _resubscribe (line 43) | def _resubscribe(self, url, sid=None):
    method _handle (line 66) | def _handle(self, environ, start_response):
    method _event (line 87) | def _event(self, device, type_, value):
    method on (line 92) | def on(self, device, type, callback):
    method server (line 96) | def server(self):

FILE: ouimeaux/utils.py
  function tz_hours (line 11) | def tz_hours():
  function is_dst (line 17) | def is_dst():
  function get_timesync (line 21) | def get_timesync():
  function get_ip_address (line 41) | def get_ip_address():
  function matcher (line 52) | def matcher(match_string):
  function get_retries (line 64) | def get_retries():
  function retry_with_delay (line 68) | def retry_with_delay(f, delay=60):

FILE: tests/test_ouimeaux.py
  class TestOuimeaux (line 16) | class TestOuimeaux(unittest.TestCase):
    method setUp (line 18) | def setUp(self):
    method test_something (line 21) | def test_something(self):
    method tearDown (line 24) | def tearDown(self):
Condensed preview — 86 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (562K chars).
[
  {
    "path": ".gitignore",
    "chars": 398,
    "preview": "*.py[cod]\n\n# C extensions\n*.so\n\n# Packages\n*.egg\n*.egg-info\ndist\nbuild\neggs\nparts\nbin\nvar\nsdist\ndevelop-eggs\n.installed."
  },
  {
    "path": ".travis.yml",
    "chars": 318,
    "preview": "# Config file for automatic testing at travis-ci.org\n\nlanguage: python\n\npython:\n  - \"2.7\"\n  - \"3.5\"\n  - \"3.6\"\n\n# command"
  },
  {
    "path": "AUTHORS.rst",
    "chars": 649,
    "preview": "=======\nCredits\n=======\n\nDevelopment Lead\n----------------\n\n* Ian McCracken <ian.mccracken@gmail.com>\n\nContributors\n----"
  },
  {
    "path": "CONTRIBUTING.rst",
    "chars": 3163,
    "preview": "============\nContributing\n============\n\nContributions are welcome, and they are greatly appreciated! Every\nlittle bit he"
  },
  {
    "path": "HISTORY.rst",
    "chars": 4769,
    "preview": ".. :changelog:\n\nHistory\n-------\n\nRelease 0.8.0 (July 30, 2016)\n+++++++++++++++++++++++++++++\n- Randomize subscription po"
  },
  {
    "path": "LICENSE",
    "chars": 1468,
    "preview": "Copyright (c) 2014, Ian McCracken\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or witho"
  },
  {
    "path": "MANIFEST.in",
    "chars": 139,
    "preview": "include AUTHORS.rst\ninclude CONTRIBUTING.rst\ninclude HISTORY.rst\ninclude LICENSE\ninclude README.md\ninclude requirements."
  },
  {
    "path": "Makefile",
    "chars": 1186,
    "preview": ".PHONY: clean-pyc clean-build docs\n\nhelp:\n\t@echo \"clean-build - remove build artifacts\"\n\t@echo \"clean-pyc - remove Pytho"
  },
  {
    "path": "README.md",
    "chars": 3259,
    "preview": "# ouimeaux\n\n⚠️ ⚠️ ⚠️\n\nThe ouimeaux project is no longer actively maintained. Please contact @iancmcc\nif you would like t"
  },
  {
    "path": "client.py",
    "chars": 7638,
    "preview": "#!/usr/bin/env python\n# :author: Fabio \"BlackLight\" Manganiello <info@fabiomanganiello.com>\n#\n# Requirements:\n#     - `r"
  },
  {
    "path": "docs/Makefile",
    "chars": 6777,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "docs/api.rst",
    "chars": 6203,
    "preview": "===========\nPython API\n===========\n\nEnvironment\n-----------\nThe main interface is presented by an ``Environment``, which"
  },
  {
    "path": "docs/authors.rst",
    "chars": 27,
    "preview": ".. include:: ../AUTHORS.rst"
  },
  {
    "path": "docs/conf.py",
    "chars": 8362,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n#\n# complexity documentation build configuration file, created by\n# sphinx"
  },
  {
    "path": "docs/configuration.rst",
    "chars": 775,
    "preview": "=============\nConfiguration\n=============\n\nA configuration file in YAML format will be created at ``~/.wemo/config.yml``"
  },
  {
    "path": "docs/contributing.rst",
    "chars": 32,
    "preview": ".. include:: ../CONTRIBUTING.rst"
  },
  {
    "path": "docs/history.rst",
    "chars": 27,
    "preview": ".. include:: ../HISTORY.rst"
  },
  {
    "path": "docs/index.rst",
    "chars": 531,
    "preview": ".. complexity documentation master file, created by\n   sphinx-quickstart on Tue Jul  9 22:26:36 2013.\n   You can adapt t"
  },
  {
    "path": "docs/installation.rst",
    "chars": 1110,
    "preview": "============\nInstallation\n============\n\nBasic\n-----\nAt the command line::\n\n    $ easy_install ouimeaux\n\nOr, if you have "
  },
  {
    "path": "docs/make.bat",
    "chars": 6466,
    "preview": "@ECHO OFF\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset BUI"
  },
  {
    "path": "docs/modules.rst",
    "chars": 61,
    "preview": "ouimeaux\n========\n\n.. toctree::\n   :maxdepth: 4\n\n   ouimeaux\n"
  },
  {
    "path": "docs/ouimeaux.device.api.rst",
    "chars": 448,
    "preview": "ouimeaux.device.api package\n===========================\n\nSubpackages\n-----------\n\n.. toctree::\n\n    ouimeaux.device.api."
  },
  {
    "path": "docs/ouimeaux.device.api.xsd.rst",
    "chars": 586,
    "preview": "ouimeaux.device.api.xsd package\n===============================\n\nSubmodules\n----------\n\nouimeaux.device.api.xsd.device m"
  },
  {
    "path": "docs/ouimeaux.device.rst",
    "chars": 909,
    "preview": "ouimeaux.device package\n=======================\n\nSubpackages\n-----------\n\n.. toctree::\n\n    ouimeaux.device.api\n\nSubmodu"
  },
  {
    "path": "docs/ouimeaux.examples.rst",
    "chars": 362,
    "preview": "ouimeaux.examples package\n=========================\n\nSubmodules\n----------\n\nouimeaux.examples.watch module\n-------------"
  },
  {
    "path": "docs/ouimeaux.pysignals.rst",
    "chars": 753,
    "preview": "ouimeaux.pysignals package\n==========================\n\nSubmodules\n----------\n\nouimeaux.pysignals.dispatcher module\n-----"
  },
  {
    "path": "docs/ouimeaux.rst",
    "chars": 1282,
    "preview": "ouimeaux package\n================\n\nSubpackages\n-----------\n\n.. toctree::\n\n    ouimeaux.device\n    ouimeaux.examples\n    "
  },
  {
    "path": "docs/ouimeaux.server.rst",
    "chars": 359,
    "preview": "ouimeaux.server package\n=======================\n\nSubmodules\n----------\n\nouimeaux.server.settings module\n----------------"
  },
  {
    "path": "docs/ouimeaux.xsd.rst",
    "chars": 487,
    "preview": "ouimeaux.xsd package\n====================\n\nSubmodules\n----------\n\nouimeaux.xsd.device module\n--------------------------\n"
  },
  {
    "path": "docs/readme.rst",
    "chars": 26,
    "preview": ".. include:: ../README.md\n"
  },
  {
    "path": "docs/server.rst",
    "chars": 2361,
    "preview": "=======\nServer\n=======\n\n``wemo server`` starts a process serving up both a Web app providing basic\ndevice control and a "
  },
  {
    "path": "docs/wemo.rst",
    "chars": 1785,
    "preview": "================\n``wemo`` Command\n================\n\nThe ``wemo`` script will discover devices in your environment and tu"
  },
  {
    "path": "ouimeaux/__init__.py",
    "chars": 136,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n__author__ = 'Ian McCracken'\n__email__ = 'ian.mccracken@gmail.com'\n__vers"
  },
  {
    "path": "ouimeaux/cli.py",
    "chars": 13472,
    "preview": "import sys\nimport logging\nimport argparse\n\nfrom .discovery import UPnPLoopbackException\nfrom .environment import Environ"
  },
  {
    "path": "ouimeaux/config.py",
    "chars": 1670,
    "preview": "import os\nimport yaml\n\n\ndef in_home(*path):\n    try:\n        from win32com.shell import shellcon, shell\n    except Impor"
  },
  {
    "path": "ouimeaux/device/__init__.py",
    "chars": 2544,
    "preview": "import logging\nfrom six.moves.urllib.parse import urlsplit\n\nfrom .api.service import Service\nfrom .api.xsd import device"
  },
  {
    "path": "ouimeaux/device/api/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ouimeaux/device/api/service.py",
    "chars": 2756,
    "preview": "import logging\nfrom xml.etree import ElementTree as et\n\nfrom ...utils import requests_get, requests_post\nfrom .xsd impor"
  },
  {
    "path": "ouimeaux/device/api/xsd/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ouimeaux/device/api/xsd/device.py",
    "chars": 72556,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n#\n# Generated Thu Jan 31 15:50:44 2013 by generateDS.py version 2.8b.\n#\n\n"
  },
  {
    "path": "ouimeaux/device/api/xsd/device.xsd",
    "chars": 4316,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<xs:schema\r\n  targetNamespace=\"urn:schemas-upnp-org:device-1-0\"\r\n  xmlns:tns=\"ur"
  },
  {
    "path": "ouimeaux/device/api/xsd/service.py",
    "chars": 70052,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n#\n# Generated Thu Jan 31 15:52:45 2013 by generateDS.py version 2.8b.\n#\n\n"
  },
  {
    "path": "ouimeaux/device/api/xsd/service.xsd",
    "chars": 3526,
    "preview": "<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n  xmlns=\"urn:schemas-upnp-org:service-1-0\" \n  targetNamespace=\"ur"
  },
  {
    "path": "ouimeaux/device/bridge.py",
    "chars": 5376,
    "preview": "from ouimeaux.device import Device\n\nfrom xml.etree import ElementTree as et\n\n\nclass Bridge(Device):\n    Lights = {}\n    "
  },
  {
    "path": "ouimeaux/device/insight.py",
    "chars": 1899,
    "preview": "from datetime import datetime\nfrom .switch import Switch\n\nclass Insight(Switch):\n\n    def __repr__(self):\n        return"
  },
  {
    "path": "ouimeaux/device/lightswitch.py",
    "chars": 148,
    "preview": "from .switch import Switch\n\nclass LightSwitch(Switch):\n\n    def __repr__(self):\n        return '<WeMo LightSwitch \"{name"
  },
  {
    "path": "ouimeaux/device/maker.py",
    "chars": 2397,
    "preview": "from datetime import datetime\nfrom ouimeaux.device import Device\nfrom xml.etree import ElementTree as et\n\n\nclass Maker(D"
  },
  {
    "path": "ouimeaux/device/motion.py",
    "chars": 146,
    "preview": "from ouimeaux.device import Device\n\nclass Motion(Device):\n\n    def __repr__(self):\n        return '<WeMo Motion \"{name}\""
  },
  {
    "path": "ouimeaux/device/switch.py",
    "chars": 980,
    "preview": "import gevent\n\nfrom ouimeaux.device import Device\n\n\nclass Switch(Device):\n\n    def set_state(self, state):\n        \"\"\"\n "
  },
  {
    "path": "ouimeaux/discovery.py",
    "chars": 3454,
    "preview": "import logging\n\nimport gevent\nfrom gevent import socket\nfrom gevent.server import DatagramServer\n\nfrom ouimeaux.utils im"
  },
  {
    "path": "ouimeaux/environment.py",
    "chars": 7925,
    "preview": "import logging\n\nimport gevent\nimport requests\n\nfrom ouimeaux.config import WemoConfiguration\nfrom ouimeaux.device import"
  },
  {
    "path": "ouimeaux/examples/Randomize.py",
    "chars": 1115,
    "preview": "\nimport random\nimport datetime\nimport time\nimport ouimeaux\nfrom ouimeaux.environment import Environment\n\n# http://pydoc."
  },
  {
    "path": "ouimeaux/examples/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ouimeaux/examples/watch.py",
    "chars": 1092,
    "preview": "#!/usr/bin/env python\nimport argparse\nimport sys\n\nfrom ouimeaux.environment import Environment\nfrom ouimeaux.utils impor"
  },
  {
    "path": "ouimeaux/pysignals/LICENSE.txt",
    "chars": 3359,
    "preview": "pysignals was originally forked from django.dispatch.\n\nCopyright (c) Django Software Foundation and individual contribut"
  },
  {
    "path": "ouimeaux/pysignals/__init__.py",
    "chars": 286,
    "preview": "\"\"\"Multi-consumer multi-producer dispatching mechanism\n\nOriginally based on pydispatch (BSD) http://pypi.python.org/pypi"
  },
  {
    "path": "ouimeaux/pysignals/dispatcher.py",
    "chars": 13464,
    "preview": "from __future__ import absolute_import\n\nimport sys\nimport threading\nimport weakref\n\nimport logging\n\nfrom future.builtins"
  },
  {
    "path": "ouimeaux/pysignals/inspect.py",
    "chars": 4177,
    "preview": "from __future__ import absolute_import\n\nimport inspect\n\nimport six\n\n\ndef getargspec(func):\n    if six.PY2:\n        retur"
  },
  {
    "path": "ouimeaux/pysignals/license.python.txt",
    "chars": 12755,
    "preview": "A. HISTORY OF THE SOFTWARE\n==========================\n\nPython was created in the early 1990s by Guido van Rossum at Stic"
  },
  {
    "path": "ouimeaux/pysignals/weakref_backports.py",
    "chars": 2151,
    "preview": "\"\"\"\nweakref_backports is a partial backport of the weakref module for python\nversions below 3.4.\n\nCopyright (C) 2013 Pyt"
  },
  {
    "path": "ouimeaux/server/__init__.py",
    "chars": 5655,
    "preview": "import os\nimport json\nimport gevent\nfrom flask import Flask, request, Response\nfrom flask import render_template, send_f"
  },
  {
    "path": "ouimeaux/server/settings.py",
    "chars": 77,
    "preview": "DEBUG = True\nSECRET_KEY = 'temporary_secret_key'  # make sure to change this\n"
  },
  {
    "path": "ouimeaux/server/static/css/bootstrap-responsive.css",
    "chars": 22111,
    "preview": "/*!\n * Bootstrap Responsive v2.3.2\n *\n * Copyright 2012 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http:/"
  },
  {
    "path": "ouimeaux/server/static/css/bootstrap-theme.css",
    "chars": 14716,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "ouimeaux/server/static/css/bootstrap.css",
    "chars": 122848,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "ouimeaux/server/static/css/main.css",
    "chars": 387,
    "preview": ".navbar {\n    padding-left: 25px;\n}\n\n.header-section {\n\tpadding: 30px 30px;\n\tbackground: #222;\n\tposition: absolute;\n\ttop"
  },
  {
    "path": "ouimeaux/server/static/js/app.js",
    "chars": 379,
    "preview": "'use strict';\n\nangular.module('Ouimeaux', ['Ouimeaux.controllers', 'btford.socket-io'])\n.config(['$routeProvider', '$loc"
  },
  {
    "path": "ouimeaux/server/static/js/bootstrap.js",
    "chars": 58533,
    "preview": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.or"
  },
  {
    "path": "ouimeaux/server/static/js/controllers.js",
    "chars": 496,
    "preview": "'use strict';\n\n/* Controllers */\n\nangular.module('Ouimeaux.controllers', []).\n  controller('IndexCtrl', function ($scope"
  },
  {
    "path": "ouimeaux/server/static/js/directives.js",
    "chars": 33,
    "preview": "'use strict';\n\n/* Directives */\n\n"
  },
  {
    "path": "ouimeaux/server/static/js/filters.js",
    "chars": 163,
    "preview": "'use strict';\n\n/* Filters */\n\nangular.module('wemoFilters', []).filter('uppercase', function() {\n  return function(input"
  },
  {
    "path": "ouimeaux/server/static/js/services.js",
    "chars": 253,
    "preview": "'use strict';\n\nangular.module('angularFlaskServices', ['ngResource'])\n .factory('Post', function($resource) {\n  return $"
  },
  {
    "path": "ouimeaux/server/static/js/socket.js",
    "chars": 792,
    "preview": "/*\n * angular-socket-io v0.0.2\n * (c) 2013 Brian Ford http://briantford.com\n * License: MIT\n */\n\n'use strict';\n\nangular."
  },
  {
    "path": "ouimeaux/server/static/partials/about.html",
    "chars": 71,
    "preview": "<div>\n    <p>This is a basic AngularJS + Flask application.</p>\n</div>\n"
  },
  {
    "path": "ouimeaux/server/static/partials/landing.html",
    "chars": 821,
    "preview": "<div class=\"header-section\">\n    <p ng-repeat=\"device in data\">\n    <a role=\"button\" \n        class=\"btn btn-lg btn-bloc"
  },
  {
    "path": "ouimeaux/server/templates/404.html",
    "chars": 1607,
    "preview": "<!doctype html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\">\n    <title>Ouimeaux</title>\n\n    <link rel=\"styleshee"
  },
  {
    "path": "ouimeaux/server/templates/index.html",
    "chars": 1273,
    "preview": "<!doctype html>\n<html lang=\"en\" ng-app=\"Ouimeaux\">\n<head>\n    <meta charset=\"utf-8\">\n    <meta name=\"viewport\" content=\""
  },
  {
    "path": "ouimeaux/signals.py",
    "chars": 773,
    "preview": "from ouimeaux.pysignals import Signal, StateChange, receiver\n\n# Work around a bug in pysignals when in the interactive i"
  },
  {
    "path": "ouimeaux/subscribe.py",
    "chars": 3722,
    "preview": "from collections import defaultdict\nimport logging\nfrom xml.etree import ElementTree\nfrom functools import partial\n\nimpo"
  },
  {
    "path": "ouimeaux/utils.py",
    "chars": 2252,
    "preview": "from functools import wraps\nimport re\nimport socket\nimport struct\nimport time\n\nimport gevent\nimport requests\n\n\ndef tz_ho"
  },
  {
    "path": "requirements.txt",
    "chars": 52,
    "preview": "gevent >= 1.3.0\nrequests >= 2.3.0\npyyaml\nsix\nfuture\n"
  },
  {
    "path": "setup.cfg",
    "chars": 24,
    "preview": "[egg_info]\ntag_build = \n"
  },
  {
    "path": "setup.py",
    "chars": 1926,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\nimport os\nimport sys\n\nhere = lambda *a: os.path.join(os.path.dirname(__fi"
  },
  {
    "path": "tests/__init__.py",
    "chars": 46,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n"
  },
  {
    "path": "tests/test_ouimeaux.py",
    "chars": 373,
    "preview": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\n\"\"\"\ntest_ouimeaux\n----------------------------------\n\nTests for `ouimeaux"
  },
  {
    "path": "tox.ini",
    "chars": 177,
    "preview": "[tox]\nenvlist = py27, py34, py35\n\n[testenv]\nsetenv =\n    PYTHONPATH = {toxinidir}:{toxinidir}/ouimeaux\ncommands = python"
  }
]

About this extraction

This page contains the full source code of the iancmcc/ouimeaux GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 86 files (521.5 KB), approximately 141.7k tokens, and a symbol index with 734 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!