| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,5 @@ | |||
| 1 | + [flake8] | ||
| 2 | + ignore = E203, E266, E501, W503 | ||
| 3 | + max-line-length = 88 | ||
| 4 | + max-complexity = 18 | ||
| 5 | + select = B,C,E,F,W,T4 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,7 +14,6 @@ jobs: | |||
| 14 | 14 | strategy: | |
| 15 | 15 | matrix: | |
| 16 | 16 | python-version: [ | |
| 17 | - 2.7, | ||
| 18 | 17 | 3.5, | |
| 19 | 18 | 3.6, | |
| 20 | 19 | 3.7, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,9 +1,138 @@ | |||
| 1 | - *.egg | ||
| 2 | - *.egg-info/ | ||
| 3 | - *.py[cod] | ||
| 4 | - *.swp | ||
| 5 | - *~ | ||
| 6 | - /build/ | ||
| 7 | - /dist/ | ||
| 8 | - /requirements.txt | ||
| 1 | + # Byte-compiled / optimized / DLL files | ||
| 9 | 2 | __pycache__/ | |
| 3 | + *.py[cod] | ||
| 4 | + *$py.class | ||
| 5 | + | ||
| 6 | + # C extensions | ||
| 7 | + *.so | ||
| 8 | + | ||
| 9 | + # Distribution / packaging | ||
| 10 | + .Python | ||
| 11 | + build/ | ||
| 12 | + develop-eggs/ | ||
| 13 | + dist/ | ||
| 14 | + downloads/ | ||
| 15 | + eggs/ | ||
| 16 | + .eggs/ | ||
| 17 | + lib/ | ||
| 18 | + lib64/ | ||
| 19 | + parts/ | ||
| 20 | + sdist/ | ||
| 21 | + var/ | ||
| 22 | + wheels/ | ||
| 23 | + pip-wheel-metadata/ | ||
| 24 | + share/python-wheels/ | ||
| 25 | + *.egg-info/ | ||
| 26 | + .installed.cfg | ||
| 27 | + *.egg | ||
| 28 | + MANIFEST | ||
| 29 | + # We use poetry, so should ignore the generated setup.py | ||
| 30 | + /setup.py | ||
| 31 | + | ||
| 32 | + # PyInstaller | ||
| 33 | + # Usually these files are written by a python script from a template | ||
| 34 | + # before PyInstaller builds the exe, so as to inject date/other infos into it. | ||
| 35 | + *.manifest | ||
| 36 | + *.spec | ||
| 37 | + | ||
| 38 | + # Installer logs | ||
| 39 | + pip-log.txt | ||
| 40 | + pip-delete-this-directory.txt | ||
| 41 | + | ||
| 42 | + # Unit test / coverage reports | ||
| 43 | + htmlcov/ | ||
| 44 | + coverage_html_report/ | ||
| 45 | + .tox/ | ||
| 46 | + .nox/ | ||
| 47 | + .coverage | ||
| 48 | + .coverage.* | ||
| 49 | + .cache | ||
| 50 | + nosetests.xml | ||
| 51 | + coverage.xml | ||
| 52 | + *.cover | ||
| 53 | + *.py,cover | ||
| 54 | + .hypothesis/ | ||
| 55 | + .pytest_cache/ | ||
| 56 | + coverage_html_report/ | ||
| 57 | + prof/ | ||
| 58 | + | ||
| 59 | + # Translations | ||
| 60 | + *.mo | ||
| 61 | + *.pot | ||
| 62 | + | ||
| 63 | + # Django stuff: | ||
| 64 | + *.log | ||
| 65 | + local_settings.py | ||
| 66 | + db.sqlite3 | ||
| 67 | + db.sqlite3-journal | ||
| 68 | + | ||
| 69 | + # Flask stuff: | ||
| 70 | + instance/ | ||
| 71 | + .webassets-cache | ||
| 72 | + | ||
| 73 | + # Scrapy stuff: | ||
| 74 | + .scrapy | ||
| 75 | + | ||
| 76 | + # Sphinx documentation | ||
| 77 | + docs/_build/ | ||
| 78 | + | ||
| 79 | + # PyBuilder | ||
| 80 | + target/ | ||
| 81 | + | ||
| 82 | + # Jupyter Notebook | ||
| 83 | + .ipynb_checkpoints | ||
| 84 | + | ||
| 85 | + # IPython | ||
| 86 | + profile_default/ | ||
| 87 | + ipython_config.py | ||
| 88 | + | ||
| 89 | + # pyenv | ||
| 90 | + .python-version | ||
| 91 | + | ||
| 92 | + # pipenv | ||
| 93 | + # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. | ||
| 94 | + # However, in case of collaboration, if having platform-specific dependencies or dependencies | ||
| 95 | + # having no cross-platform support, pipenv may install dependencies that don't work, or not | ||
| 96 | + # install all needed dependencies. | ||
| 97 | + #Pipfile.lock | ||
| 98 | + | ||
| 99 | + # PEP 582; used by e.g. github.com/David-OConnor/pyflow | ||
| 100 | + __pypackages__/ | ||
| 101 | + | ||
| 102 | + # Celery stuff | ||
| 103 | + celerybeat-schedule | ||
| 104 | + celerybeat.pid | ||
| 105 | + | ||
| 106 | + # SageMath parsed files | ||
| 107 | + *.sage.py | ||
| 108 | + | ||
| 109 | + # Environments | ||
| 110 | + .env* | ||
| 111 | + .venv* | ||
| 112 | + env/ | ||
| 113 | + venv/ | ||
| 114 | + ENV/ | ||
| 115 | + env.bak/ | ||
| 116 | + venv.bak/ | ||
| 117 | + | ||
| 118 | + # Spyder project settings | ||
| 119 | + .spyderproject | ||
| 120 | + .spyproject | ||
| 121 | + | ||
| 122 | + # Rope project settings | ||
| 123 | + .ropeproject | ||
| 124 | + | ||
| 125 | + # mkdocs documentation | ||
| 126 | + /site | ||
| 127 | + | ||
| 128 | + # mypy | ||
| 129 | + .mypy_cache/ | ||
| 130 | + .dmypy.json | ||
| 131 | + dmypy.json | ||
| 132 | + | ||
| 133 | + # Pyre type checker | ||
| 134 | + .pyre/ | ||
| 135 | + | ||
| 136 | + # IDE files | ||
| 137 | + .vscode/* | ||
| 138 | + .idea/* | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -8,7 +8,7 @@ webthing | |||
| 8 | 8 | .. image:: https://img.shields.io/badge/license-MPL--2.0-blue.svg | |
| 9 | 9 | :target: https://github.com/mozilla-iot/webthing-python/blob/master/LICENSE.txt | |
| 10 | 10 | ||
| 11 | - Implementation of an HTTP `Web Thing <https://iot.mozilla.org/wot/>`_. This library is compatible with Python 2.7 and 3.5+. | ||
| 11 | + Implementation of an HTTP `Web Thing <https://iot.mozilla.org/wot/>`_. This library is compatible with Python 3.5+. | ||
| 12 | 12 | ||
| 13 | 13 | Installation | |
| 14 | 14 | ============ | |
@@ -63,15 +63,15 @@ First we create a new Thing: | |||
| 63 | 63 | ||
| 64 | 64 | Now we can add the required properties. | |
| 65 | 65 | ||
| 66 | - The ``on`` property reports and sets the on/off state of the light. For this, we need to have a ``Value`` object which holds the actual state and also a method to turn the light on/off. For our purposes, we just want to log the new state if the light is switched on/off. | ||
| 66 | + The on property reports and sets the on/off state of the light. For this, we need to have a Value object which holds the actual state and also a method to turn the light on/off. For our purposes, we just want to log the new state if the light is switched on/off. | ||
| 67 | 67 | ||
| 68 | 68 | .. code:: python | |
| 69 | 69 | ||
| 70 | 70 | light.add_property( | |
| 71 | 71 | Property( | |
| 72 | 72 | light, | |
| 73 | 73 | 'on', | |
| 74 | - Value(True, lambda v: print('On-State is now', v)), | ||
| 74 | + Value(True, None, lambda x: print(x)), | ||
| 75 | 75 | metadata={ | |
| 76 | 76 | '@type': 'OnOffProperty', | |
| 77 | 77 | 'title': 'On/Off', | |
@@ -87,7 +87,7 @@ The ``brightness`` property reports the brightness level of the light and sets t | |||
| 87 | 87 | Property( | |
| 88 | 88 | light, | |
| 89 | 89 | 'brightness', | |
| 90 | - Value(50, lambda v: print('Brightness is now', v)), | ||
| 90 | + Value(50, None, lambda x: print(x)), | ||
| 91 | 91 | metadata={ | |
| 92 | 92 | '@type': 'BrightnessProperty', | |
| 93 | 93 | 'title': 'Brightness', | |
@@ -102,9 +102,7 @@ Now we can add our newly created thing to the server and start it: | |||
| 102 | 102 | ||
| 103 | 103 | .. code:: python | |
| 104 | 104 | ||
| 105 | - # If adding more than one thing, use MultipleThings() with a name. | ||
| 106 | - # In the single thing case, the thing's name will be broadcast. | ||
| 107 | - server = WebThingServer(SingleThing(light), port=8888) | ||
| 105 | + server = WebThingServer(light, port=8888) | ||
| 108 | 106 | ||
| 109 | 107 | try: | |
| 110 | 108 | server.start() | |
@@ -134,33 +132,51 @@ First we create a new Thing: | |||
| 134 | 132 | 'A web connected humidity sensor' | |
| 135 | 133 | ) | |
| 136 | 134 | ||
| 137 | - Then we create and add the appropriate property: | ||
| 135 | + Then we create and add the appropriate property. | ||
| 138 | 136 | ||
| 139 | - * ``level``: tells us what the sensor is actually reading | ||
| 137 | + Contrary to the light, the value cannot be set via an API call, as it wouldn't make much sense, to SET what a sensor is reading. Therefore, we are creating a **readOnly** property. | ||
| 140 | 138 | ||
| 141 | - - Contrary to the light, the value cannot be set via an API call, as it wouldn't make much sense, to SET what a sensor is reading. Therefore, we are creating a **readOnly** property. | ||
| 139 | + .. code:: python | ||
| 140 | + | ||
| 141 | + sensor.add_property( | ||
| 142 | + Property( | ||
| 143 | + sensor, | ||
| 144 | + 'level', | ||
| 145 | + Value(None, self.read_from_gpio, None), | ||
| 146 | + metadata={ | ||
| 147 | + '@type': 'LevelProperty', | ||
| 148 | + 'title': 'Humidity', | ||
| 149 | + 'type': 'number', | ||
| 150 | + 'description': 'The current humidity in %', | ||
| 151 | + 'minimum': 0, | ||
| 152 | + 'maximum': 100, | ||
| 153 | + 'unit': 'percent', | ||
| 154 | + 'readOnly': True, | ||
| 155 | + })) | ||
| 142 | 156 | ||
| 143 | - .. code:: python | ||
| 157 | + In this example, we pass a `readproperty` method that will read and return the sensor value every time it is requested. | ||
| 144 | 158 | ||
| 145 | - level = Value(0.0); | ||
| 159 | + Alternatively, we can create a thread that queries the physical sensor every few seconds. We first remove the `readproperty` argument from our Property. | ||
| 146 | 160 | ||
| 147 | - sensor.add_property( | ||
| 148 | - Property( | ||
| 149 | - sensor, | ||
| 150 | - 'level', | ||
| 151 | - level, | ||
| 152 | - metadata={ | ||
| 153 | - '@type': 'LevelProperty', | ||
| 154 | - 'title': 'Humidity', | ||
| 155 | - 'type': 'number', | ||
| 156 | - 'description': 'The current humidity in %', | ||
| 157 | - 'minimum': 0, | ||
| 158 | - 'maximum': 100, | ||
| 159 | - 'unit': 'percent', | ||
| 160 | - 'readOnly': True, | ||
| 161 | - })) | ||
| 161 | + .. code:: python | ||
| 162 | + | ||
| 163 | + sensor.add_property( | ||
| 164 | + Property( | ||
| 165 | + sensor, | ||
| 166 | + 'level', | ||
| 167 | + Value(0.0), | ||
| 168 | + metadata={ | ||
| 169 | + '@type': 'LevelProperty', | ||
| 170 | + 'title': 'Humidity', | ||
| 171 | + 'type': 'number', | ||
| 172 | + 'description': 'The current humidity in %', | ||
| 173 | + 'minimum': 0, | ||
| 174 | + 'maximum': 100, | ||
| 175 | + 'unit': 'percent', | ||
| 176 | + 'readOnly': True, | ||
| 177 | + })) | ||
| 162 | 178 | ||
| 163 | - Now we have a sensor that constantly reports 0%. To make it usable, we need a thread or some kind of input when the sensor has a new reading available. For this purpose we start a thread that queries the physical sensor every few seconds. For our purposes, it just calls a fake method. | ||
| 179 | + We then create our looping function to periodically query the sensor and set the property value. | ||
| 164 | 180 | ||
| 165 | 181 | .. code:: python | |
| 166 | 182 | ||
@@ -171,13 +187,12 @@ Now we have a sensor that constantly reports 0%. To make it usable, we need a th | |||
| 171 | 187 | try: | |
| 172 | 188 | while True: | |
| 173 | 189 | await sleep(3) | |
| 174 | - new_level = self.read_from_gpio() | ||
| 190 | + sensor.properties["level"].value.set(self.read_from_gpio()) | ||
| 175 | 191 | logging.debug('setting new humidity level: %s', new_level) | |
| 176 | - self.level.notify_of_external_update(new_level) | ||
| 177 | 192 | except CancelledError: | |
| 178 | 193 | pass | |
| 179 | 194 | ||
| 180 | - This will update our ``Value`` object with the sensor readings via the ``self.level.notify_of_external_update(read_from_gpio())`` call. The ``Value`` object now notifies the property and the thing that the value has changed, which in turn notifies all websocket listeners. | ||
| 195 | + This will update our ``Value`` object with the sensor readings via the ``sensor.properties["level"].value.set(self.read_from_gpio())`` call. The ``Value`` object now notifies the property and the thing that the value has changed, which in turn notifies all websocket listeners. | ||
| 181 | 196 | ||
| 182 | 197 | Adding to Gateway | |
| 183 | 198 | ================= | |
| Back | FazBrowse Home | New Git URL |
0 commit comments