telegen-iot 0.1.4.dev9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. telegen_iot-0.1.4.dev9/LICENSE +21 -0
  2. telegen_iot-0.1.4.dev9/MANIFEST.in +2 -0
  3. telegen_iot-0.1.4.dev9/PKG-INFO +71 -0
  4. telegen_iot-0.1.4.dev9/README.md +40 -0
  5. telegen_iot-0.1.4.dev9/pyproject.toml +3 -0
  6. telegen_iot-0.1.4.dev9/setup.cfg +51 -0
  7. telegen_iot-0.1.4.dev9/setup.py +11 -0
  8. telegen_iot-0.1.4.dev9/src/TeleGen/__init__.py +9 -0
  9. telegen_iot-0.1.4.dev9/src/TeleGen/actuators.py +102 -0
  10. telegen_iot-0.1.4.dev9/src/TeleGen/binary_sensors.py +75 -0
  11. telegen_iot-0.1.4.dev9/src/TeleGen/i2c_sensors.py +199 -0
  12. telegen_iot-0.1.4.dev9/src/TeleGen/sensors.py +375 -0
  13. telegen_iot-0.1.4.dev9/src/TeleGen/serial_sensors.py +296 -0
  14. telegen_iot-0.1.4.dev9/src/TeleGen/static/images/CounterFitLogo.png +0 -0
  15. telegen_iot-0.1.4.dev9/src/TeleGen/static/images/favicon.png +0 -0
  16. telegen_iot-0.1.4.dev9/src/TeleGen/static/socket.io.min.js +7 -0
  17. telegen_iot-0.1.4.dev9/src/TeleGen/static/socket.io.min.js.map +1 -0
  18. telegen_iot-0.1.4.dev9/src/TeleGen/static/style.css +14 -0
  19. telegen_iot-0.1.4.dev9/src/TeleGen/telegen.py +508 -0
  20. telegen_iot-0.1.4.dev9/src/TeleGen/templates/binary_sensor_create_settings.html +8 -0
  21. telegen_iot-0.1.4.dev9/src/TeleGen/templates/boolean_sensor.html +94 -0
  22. telegen_iot-0.1.4.dev9/src/TeleGen/templates/camera_sensor.html +268 -0
  23. telegen_iot-0.1.4.dev9/src/TeleGen/templates/float_sensor.html +142 -0
  24. telegen_iot-0.1.4.dev9/src/TeleGen/templates/gps_sensor.html +232 -0
  25. telegen_iot-0.1.4.dev9/src/TeleGen/templates/home.html +404 -0
  26. telegen_iot-0.1.4.dev9/src/TeleGen/templates/i2c_float_sensor.html +142 -0
  27. telegen_iot-0.1.4.dev9/src/TeleGen/templates/i2c_integer_sensor.html +142 -0
  28. telegen_iot-0.1.4.dev9/src/TeleGen/templates/i2c_sensor_create_settings.html +21 -0
  29. telegen_iot-0.1.4.dev9/src/TeleGen/templates/integer_sensor.html +142 -0
  30. telegen_iot-0.1.4.dev9/src/TeleGen/templates/led_actuator.html +125 -0
  31. telegen_iot-0.1.4.dev9/src/TeleGen/templates/pin_sensor_create_settings.html +21 -0
  32. telegen_iot-0.1.4.dev9/src/TeleGen/templates/relay_actuator.html +97 -0
  33. telegen_iot-0.1.4.dev9/src/TeleGen/templates/serial_sensor_create_settings.html +8 -0
  34. telegen_iot-0.1.4.dev9/src/telegen_iot.egg-info/PKG-INFO +71 -0
  35. telegen_iot-0.1.4.dev9/src/telegen_iot.egg-info/SOURCES.txt +40 -0
  36. telegen_iot-0.1.4.dev9/src/telegen_iot.egg-info/dependency_links.txt +1 -0
  37. telegen_iot-0.1.4.dev9/src/telegen_iot.egg-info/entry_points.txt +2 -0
  38. telegen_iot-0.1.4.dev9/src/telegen_iot.egg-info/requires.txt +2 -0
  39. telegen_iot-0.1.4.dev9/src/telegen_iot.egg-info/top_level.txt +2 -0
  40. telegen_iot-0.1.4.dev9/src/tests/__init__.py +0 -0
  41. telegen_iot-0.1.4.dev9/src/tests/test_serial_sensors.py +417 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Jim Bennett
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ recursive-include src/TeleGen/static *
2
+ recursive-include src/TeleGen/templates *
@@ -0,0 +1,71 @@
1
+ Metadata-Version: 2.4
2
+ Name: telegen-iot
3
+ Version: 0.1.4.dev9
4
+ Summary: A virtual IoT hardware simulator.
5
+ Home-page: https://github.com/Jeansonnej23/TeleGen
6
+ Author: Jim Bennett
7
+ Maintainer: Jim Bennett
8
+ License: MIT
9
+ Project-URL: Documentation, https://github.com/Jeansonnej23/TeleGen
10
+ Project-URL: Source Code, https://github.com/Jeansonnej23/TeleGen
11
+ Project-URL: Issue Tracker, https://github.com/Jeansonnej23/TeleGen/issues
12
+ Classifier: Development Status :: 2 - Pre-Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Topic :: System :: Hardware
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Programming Language :: Python :: 3.14
24
+ Requires-Python: >=3.9
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: Flask==3.1.1
28
+ Requires-Dist: Flask-SocketIO==5.5.1
29
+ Dynamic: license-file
30
+ Dynamic: requires-dist
31
+
32
+ # Telegen-IoT
33
+
34
+ IoT is great fun, but has a downside - hardware. You need access to a range of devices such as sensors and actuators to build your IoT projects. Sometimes you might have these devices, other times you may not - maybe you are waiting for a delivery, or parts are out of stock, or they are too expensive.
35
+
36
+ That's where this tool comes in.
37
+
38
+ ## What is Telegen-IoT
39
+
40
+ Telegen-IoT is a tool that is designed to fake various IoT hardware components, such as LEDs, buttons, temperature sensors and the like, that you can then access from IoT device code running on your computer rather than on an IoT device. It is made of two parts:
41
+
42
+ * The Telegen-IoT app - this is a web app run locally where you can connect fake sensors and actuators to your virtual hardware
43
+ * Shims - these are libraries that mimic popular hardware APIs so you can take code that runs against well known hardware and run it against the Telegen-IoT app.
44
+
45
+ ## Getting started
46
+
47
+ * Install the Telegen-IoT app:
48
+
49
+ ```sh
50
+ pip install telegen-iot
51
+ ```
52
+
53
+ * Run the app:
54
+
55
+ ```sh
56
+ telegen-iot
57
+ ```
58
+
59
+ * The app will launch, listening for web requests on port 5000, and open a web browser for you to start adding virtual sensors and actuators to your project
60
+
61
+ ### Running on a different port
62
+
63
+ To use a different port than the default 5000, set the `--port` option when you run the app:
64
+
65
+ ```sh
66
+ telegen-iot --port 5050
67
+ ```
68
+
69
+ ## Connecting your code
70
+
71
+ You can connect your device code to Telegen-IoT, using one of the available shims. See the [shim list for more details](https://github.com/Jeansonnej23/TeleGen#shims).
@@ -0,0 +1,40 @@
1
+ # Telegen-IoT
2
+
3
+ IoT is great fun, but has a downside - hardware. You need access to a range of devices such as sensors and actuators to build your IoT projects. Sometimes you might have these devices, other times you may not - maybe you are waiting for a delivery, or parts are out of stock, or they are too expensive.
4
+
5
+ That's where this tool comes in.
6
+
7
+ ## What is Telegen-IoT
8
+
9
+ Telegen-IoT is a tool that is designed to fake various IoT hardware components, such as LEDs, buttons, temperature sensors and the like, that you can then access from IoT device code running on your computer rather than on an IoT device. It is made of two parts:
10
+
11
+ * The Telegen-IoT app - this is a web app run locally where you can connect fake sensors and actuators to your virtual hardware
12
+ * Shims - these are libraries that mimic popular hardware APIs so you can take code that runs against well known hardware and run it against the Telegen-IoT app.
13
+
14
+ ## Getting started
15
+
16
+ * Install the Telegen-IoT app:
17
+
18
+ ```sh
19
+ pip install telegen-iot
20
+ ```
21
+
22
+ * Run the app:
23
+
24
+ ```sh
25
+ telegen-iot
26
+ ```
27
+
28
+ * The app will launch, listening for web requests on port 5000, and open a web browser for you to start adding virtual sensors and actuators to your project
29
+
30
+ ### Running on a different port
31
+
32
+ To use a different port than the default 5000, set the `--port` option when you run the app:
33
+
34
+ ```sh
35
+ telegen-iot --port 5050
36
+ ```
37
+
38
+ ## Connecting your code
39
+
40
+ You can connect your device code to Telegen-IoT, using one of the available shims. See the [shim list for more details](https://github.com/Jeansonnej23/TeleGen#shims).
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools>=65", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,51 @@
1
+ [metadata]
2
+ name = telegen-iot
3
+ version = attr: TeleGen.__version__
4
+ url = https://github.com/Jeansonnej23/TeleGen
5
+ project_urls =
6
+ Documentation = https://github.com/Jeansonnej23/TeleGen
7
+ Source Code = https://github.com/Jeansonnej23/TeleGen
8
+ Issue Tracker = https://github.com/Jeansonnej23/TeleGen/issues
9
+ license = MIT
10
+ author = Jim Bennett
11
+ maintainer = Jim Bennett
12
+ description = A virtual IoT hardware simulator.
13
+ long_description = file: README.md
14
+ long_description_content_type = text/markdown
15
+ classifiers =
16
+ Development Status :: 2 - Pre-Alpha
17
+ Intended Audience :: Developers
18
+ Topic :: System :: Hardware
19
+ License :: OSI Approved :: MIT License
20
+ Operating System :: OS Independent
21
+ Programming Language :: Python
22
+ Programming Language :: Python :: 3
23
+ Programming Language :: Python :: 3.10
24
+ Programming Language :: Python :: 3.11
25
+ Programming Language :: Python :: 3.12
26
+ Programming Language :: Python :: 3.13
27
+ Programming Language :: Python :: 3.14
28
+
29
+ [options]
30
+ packages = find:
31
+ package_dir = = src
32
+ include_package_data = true
33
+ python_requires = >= 3.9
34
+
35
+ [options.packages.find]
36
+ where = src
37
+
38
+ [options.entry_points]
39
+ console_scripts =
40
+ telegen-iot = TeleGen.telegen:main
41
+
42
+ [tool:pytest]
43
+ testpaths =
44
+ src/tests
45
+ pythonpath =
46
+ src
47
+
48
+ [egg_info]
49
+ tag_build =
50
+ tag_date = 0
51
+
@@ -0,0 +1,11 @@
1
+ from setuptools import setup
2
+
3
+ setup(
4
+ name='telegen-iot',
5
+ install_requires=[
6
+ "Flask==3.1.1",
7
+ "Flask-SocketIO==5.5.1"
8
+ ],
9
+ tests_require=['pytest==7.2.2'],
10
+ test_suite='tests',
11
+ )
@@ -0,0 +1,9 @@
1
+ # pylint: disable=C0103
2
+
3
+ from TeleGen.sensors import *
4
+ from TeleGen.serial_sensors import *
5
+ from TeleGen.binary_sensors import *
6
+ from TeleGen.i2c_sensors import *
7
+ from TeleGen.actuators import *
8
+
9
+ __version__ = "0.1.4.dev09"
@@ -0,0 +1,102 @@
1
+ from abc import ABC, abstractmethod
2
+ from enum import Enum
3
+
4
+
5
+ class ActuatorType(Enum):
6
+ FLOAT = 1
7
+ BOOLEAN = 2
8
+
9
+
10
+ class ActuatorBase(ABC):
11
+ def __init__(self, port: str):
12
+ self.__port = port
13
+
14
+ @staticmethod
15
+ @abstractmethod
16
+ def actuator_name() -> str:
17
+ pass
18
+
19
+ @staticmethod
20
+ @abstractmethod
21
+ def actuator_type() -> ActuatorType:
22
+ pass
23
+
24
+ @property
25
+ def port(self) -> str:
26
+ return self.__port
27
+
28
+ @property
29
+ # pylint: disable=invalid-name
30
+ def id(self) -> str:
31
+ return self.__port
32
+
33
+
34
+ class FloatActuatorBase(ActuatorBase):
35
+ def __init__(self, port: str):
36
+ super().__init__(port)
37
+ self.__value = 0
38
+
39
+ @staticmethod
40
+ @abstractmethod
41
+ def actuator_name() -> str:
42
+ pass
43
+
44
+ @staticmethod
45
+ def actuator_type() -> ActuatorType:
46
+ return ActuatorType.FLOAT
47
+
48
+ @property
49
+ def value(self) -> float:
50
+ return self.__value
51
+
52
+ @value.setter
53
+ def value(self, val: float):
54
+ self.__value = val
55
+
56
+
57
+ class BooleanActuatorBase(ActuatorBase):
58
+ def __init__(self, port: str):
59
+ super().__init__(port)
60
+
61
+ self.__value = False
62
+
63
+ @staticmethod
64
+ @abstractmethod
65
+ def actuator_name() -> str:
66
+ pass
67
+
68
+ @staticmethod
69
+ def actuator_type() -> ActuatorType:
70
+ return ActuatorType.BOOLEAN
71
+
72
+ @property
73
+ def value(self) -> bool:
74
+ return self.__value
75
+
76
+ @value.setter
77
+ def value(self, val: bool):
78
+ self.__value = val
79
+
80
+
81
+ class RelayActuator(BooleanActuatorBase):
82
+ @staticmethod
83
+ def actuator_name() -> str:
84
+ return "Relay"
85
+
86
+
87
+ class LedActuator(BooleanActuatorBase):
88
+ def __init__(self, port: str):
89
+ super().__init__(port)
90
+ self.__color = "#FF0000"
91
+
92
+ @staticmethod
93
+ def actuator_name() -> str:
94
+ return "LED"
95
+
96
+ @property
97
+ def color(self) -> str:
98
+ return self.__color
99
+
100
+ @color.setter
101
+ def color(self, val: str):
102
+ self.__color = val
@@ -0,0 +1,75 @@
1
+ from abc import abstractmethod
2
+ from enum import Enum
3
+ import io
4
+
5
+ from TeleGen.sensors import SensorBase, SensorType
6
+
7
+
8
+ class BinarySensorBase(SensorBase):
9
+ def __init__(self, name: str):
10
+ super().__init__(name)
11
+ self.__value = io.BytesIO()
12
+ self._next_repeat_time = None
13
+ self._value_position = 0
14
+
15
+ @staticmethod
16
+ def sensor_type() -> SensorType:
17
+ return SensorType.BINARY
18
+
19
+ @staticmethod
20
+ @abstractmethod
21
+ def sensor_name() -> str:
22
+ pass
23
+
24
+ @property
25
+ def id(self) -> str:
26
+ return self.port.replace("/", "").replace(" ", "")
27
+
28
+ @property
29
+ def value(self) -> io.BytesIO:
30
+ return self.__value
31
+
32
+ @value.setter
33
+ def value(self, val: io.BytesIO):
34
+ self.__value = val
35
+
36
+
37
+ class CameraImageSource(Enum):
38
+ FILE = 1
39
+ WEBCAM = 2
40
+
41
+
42
+ class CameraSensor(BinarySensorBase):
43
+ def __init__(self, name: str):
44
+ super().__init__(name)
45
+ self.__image_source = CameraImageSource.FILE
46
+ self.__image_file_name = ""
47
+ self.__web_cam_device_id = ""
48
+
49
+ @staticmethod
50
+ def sensor_name() -> str:
51
+ return "Camera"
52
+
53
+ @property
54
+ def image_source(self) -> CameraImageSource:
55
+ return self.__image_source
56
+
57
+ @image_source.setter
58
+ def image_source(self, val: CameraImageSource):
59
+ self.__image_source = val
60
+
61
+ @property
62
+ def image_file_name(self) -> str:
63
+ return self.__image_file_name
64
+
65
+ @image_file_name.setter
66
+ def image_file_name(self, val: str):
67
+ self.__image_file_name = val
68
+
69
+ @property
70
+ def web_cam_device_id(self) -> str:
71
+ return self.__web_cam_device_id
72
+
73
+ @web_cam_device_id.setter
74
+ def web_cam_device_id(self, val: str):
75
+ self.__web_cam_device_id = val
@@ -0,0 +1,199 @@
1
+ from abc import abstractmethod
2
+ from enum import Enum
3
+ from typing import List
4
+ import random
5
+
6
+ from TeleGen.sensors import SensorBase, SensorType
7
+
8
+
9
+ class I2CSensorBase(SensorBase):
10
+ @staticmethod
11
+ def sensor_type() -> SensorType:
12
+ return SensorType.I2C
13
+
14
+ @staticmethod
15
+ @abstractmethod
16
+ def sensor_unit_type() -> SensorType:
17
+ pass
18
+
19
+ @staticmethod
20
+ @abstractmethod
21
+ def sensor_name() -> str:
22
+ pass
23
+
24
+ @property
25
+ def id(self) -> str:
26
+ return self.port
27
+
28
+ @property
29
+ def address(self) -> str:
30
+ return f"0x{int(self.port):02x}"
31
+
32
+
33
+ class FloatI2CSensorBase(I2CSensorBase):
34
+ def __init__(self, port: str, valid_min: float, valid_max: float):
35
+ super().__init__(port)
36
+
37
+ self.__valid_min = valid_min
38
+ self.__valid_max = valid_max
39
+ self.value = valid_min
40
+ self.random_min = float(valid_min)
41
+ self.random_max = float(valid_max)
42
+
43
+ @staticmethod
44
+ @abstractmethod
45
+ def sensor_name() -> str:
46
+ pass
47
+
48
+ @staticmethod
49
+ @abstractmethod
50
+ def sensor_units() -> List[str]:
51
+ pass
52
+
53
+ @staticmethod
54
+ def sensor_unit_type() -> SensorType:
55
+ return SensorType.FLOAT
56
+
57
+ @property
58
+ @abstractmethod
59
+ def unit(self) -> str:
60
+ pass
61
+
62
+ @property
63
+ def value(self) -> float:
64
+ if self._random:
65
+ return round(random.uniform(self.__random_min, self.__random_max), 2)
66
+
67
+ return self.__value
68
+
69
+ @value.setter
70
+ def value(self, val: float):
71
+ if val < self.__valid_min or val > self.__valid_max:
72
+ raise ValueError()
73
+ self.__value = val
74
+
75
+ @property
76
+ def random_min(self) -> float:
77
+ return self.__random_min
78
+
79
+ @random_min.setter
80
+ def random_min(self, val: float):
81
+ if val < self.__valid_min or val > self.__valid_max:
82
+ raise ValueError()
83
+ self.__random_min = val
84
+
85
+ @property
86
+ def random_max(self) -> float:
87
+ return self.__random_max
88
+
89
+ @random_max.setter
90
+ def random_max(self, val: float):
91
+ if val < self.__valid_min or val > self.__valid_max:
92
+ raise ValueError()
93
+ self.__random_max = val
94
+
95
+ @property
96
+ def valid_min(self) -> float:
97
+ return self.__valid_min
98
+
99
+ @property
100
+ def valid_max(self) -> float:
101
+ return self.__valid_max
102
+
103
+
104
+ class IntegerI2CSensorBase(I2CSensorBase):
105
+ def __init__(self, port: str, valid_min: int, valid_max: int):
106
+ super().__init__(port)
107
+
108
+ self.__valid_min = valid_min
109
+ self.__valid_max = valid_max
110
+ self.value = valid_min
111
+ self.random_min = int(valid_min)
112
+ self.random_max = int(valid_max)
113
+
114
+ @staticmethod
115
+ @abstractmethod
116
+ def sensor_name() -> str:
117
+ pass
118
+
119
+ @staticmethod
120
+ @abstractmethod
121
+ def sensor_units() -> List[str]:
122
+ pass
123
+
124
+ @staticmethod
125
+ def sensor_unit_type() -> SensorType:
126
+ return SensorType.INTEGER
127
+
128
+ @property
129
+ @abstractmethod
130
+ def unit(self) -> str:
131
+ pass
132
+
133
+ @property
134
+ def value(self) -> int:
135
+ if self._random:
136
+ return random.randint(self.__random_min, self.__random_max)
137
+
138
+ return self.__value
139
+
140
+ @value.setter
141
+ def value(self, val: int):
142
+ if val < self.__valid_min or val > self.__valid_max:
143
+ raise ValueError()
144
+ self.__value = val
145
+
146
+ @property
147
+ def random_min(self) -> int:
148
+ return self.__random_min
149
+
150
+ @random_min.setter
151
+ def random_min(self, val: int):
152
+ if val < self.__valid_min or val > self.__valid_max:
153
+ raise ValueError()
154
+ self.__random_min = val
155
+
156
+ @property
157
+ def random_max(self) -> int:
158
+ return self.__random_max
159
+
160
+ @random_max.setter
161
+ def random_max(self, val: int):
162
+ if val < self.__valid_min or val > self.__valid_max:
163
+ raise ValueError()
164
+ self.__random_max = val
165
+
166
+ @property
167
+ def valid_min(self) -> int:
168
+ return self.__valid_min
169
+
170
+ @property
171
+ def valid_max(self) -> int:
172
+ return self.__valid_max
173
+
174
+
175
+ # pylint: disable=C0103
176
+ class DistanceUnit(Enum):
177
+ Millimeter = 1
178
+
179
+
180
+ class DistanceSensor(IntegerI2CSensorBase):
181
+ def __init__(self, port: str, unit):
182
+ if isinstance(unit, str):
183
+ unit = DistanceUnit[unit]
184
+
185
+ self.__unit = unit
186
+
187
+ super().__init__(port, 0, 999999)
188
+
189
+ @staticmethod
190
+ def sensor_name() -> str:
191
+ return "Distance"
192
+
193
+ @property
194
+ def unit(self) -> str:
195
+ return self.__unit.name
196
+
197
+ @staticmethod
198
+ def sensor_units() -> List[str]:
199
+ return [DistanceUnit.Millimeter.name]