espark-core 0.5.5__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.

Potentially problematic release.


This version of espark-core might be problematic. Click here for more details.

Files changed (49) hide show
  1. espark_core-0.5.5/LICENSE +21 -0
  2. espark_core-0.5.5/MANIFEST.in +4 -0
  3. espark_core-0.5.5/PKG-INFO +139 -0
  4. espark_core-0.5.5/README.md +102 -0
  5. espark_core-0.5.5/espark_core.egg-info/PKG-INFO +139 -0
  6. espark_core-0.5.5/espark_core.egg-info/SOURCES.txt +85 -0
  7. espark_core-0.5.5/espark_core.egg-info/dependency_links.txt +1 -0
  8. espark_core-0.5.5/espark_core.egg-info/requires.txt +21 -0
  9. espark_core-0.5.5/espark_core.egg-info/top_level.txt +1 -0
  10. espark_core-0.5.5/esparkcore/__init__.py +0 -0
  11. espark_core-0.5.5/esparkcore/constants.py +11 -0
  12. espark_core-0.5.5/esparkcore/data/__init__.py +1 -0
  13. espark_core-0.5.5/esparkcore/data/database.py +15 -0
  14. espark_core-0.5.5/esparkcore/data/models/__init__.py +6 -0
  15. espark_core-0.5.5/esparkcore/data/models/device.py +15 -0
  16. espark_core-0.5.5/esparkcore/data/models/notification.py +11 -0
  17. espark_core-0.5.5/esparkcore/data/models/outbox.py +20 -0
  18. espark_core-0.5.5/esparkcore/data/models/telemetry.py +12 -0
  19. espark_core-0.5.5/esparkcore/data/models/trigger.py +13 -0
  20. espark_core-0.5.5/esparkcore/data/models/version.py +6 -0
  21. espark_core-0.5.5/esparkcore/data/repositories/__init__.py +7 -0
  22. espark_core-0.5.5/esparkcore/data/repositories/base_repository.py +70 -0
  23. espark_core-0.5.5/esparkcore/data/repositories/device_repository.py +26 -0
  24. espark_core-0.5.5/esparkcore/data/repositories/notification_repository.py +7 -0
  25. espark_core-0.5.5/esparkcore/data/repositories/outbox_repository.py +22 -0
  26. espark_core-0.5.5/esparkcore/data/repositories/telemetry_repository.py +48 -0
  27. espark_core-0.5.5/esparkcore/data/repositories/trigger_repository.py +7 -0
  28. espark_core-0.5.5/esparkcore/data/repositories/version_repository.py +11 -0
  29. espark_core-0.5.5/esparkcore/notifications/__init__.py +2 -0
  30. espark_core-0.5.5/esparkcore/notifications/notifier.py +14 -0
  31. espark_core-0.5.5/esparkcore/notifications/slack_notifier.py +17 -0
  32. espark_core-0.5.5/esparkcore/routers/__init__.py +5 -0
  33. espark_core-0.5.5/esparkcore/routers/base_router.py +97 -0
  34. espark_core-0.5.5/esparkcore/routers/device_router.py +57 -0
  35. espark_core-0.5.5/esparkcore/routers/notification_router.py +10 -0
  36. espark_core-0.5.5/esparkcore/routers/telemetry_router.py +55 -0
  37. espark_core-0.5.5/esparkcore/routers/trigger_router.py +10 -0
  38. espark_core-0.5.5/esparkcore/routers/version_router.py +10 -0
  39. espark_core-0.5.5/esparkcore/schedules/__init__.py +2 -0
  40. espark_core-0.5.5/esparkcore/schedules/outbox.py +24 -0
  41. espark_core-0.5.5/esparkcore/schedules/scheduler.py +8 -0
  42. espark_core-0.5.5/esparkcore/services/__init__.py +1 -0
  43. espark_core-0.5.5/esparkcore/services/mqtt.py +175 -0
  44. espark_core-0.5.5/esparkcore/utils/__init__.py +1 -0
  45. espark_core-0.5.5/esparkcore/utils/logging.py +11 -0
  46. espark_core-0.5.5/requirements.dev.txt +11 -0
  47. espark_core-0.5.5/requirements.txt +8 -0
  48. espark_core-0.5.5/setup.cfg +7 -0
  49. espark_core-0.5.5/setup.py +30 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Alan Tai
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,4 @@
1
+ include requirements.txt
2
+ include requirements.dev.txt
3
+ include ../README.md
4
+ include LICENSE
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: espark-core
3
+ Version: 0.5.5
4
+ Summary: The core module of the Espark ESP32-based IoT device management framework.
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: aiomqtt>=2.5.0
10
+ Requires-Dist: apscheduler>=3.11.2
11
+ Requires-Dist: fastapi>=0.128.0
12
+ Requires-Dist: packaging>=25.0
13
+ Requires-Dist: slack-sdk==3.39.0
14
+ Requires-Dist: sqlalchemy>=2.0.45
15
+ Requires-Dist: sqlmodel>=0.0.31
16
+ Requires-Dist: uvicorn[standard]>=0.40.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: aiosqlite==0.22.1; extra == "dev"
19
+ Requires-Dist: autopep8==2.3.2; extra == "dev"
20
+ Requires-Dist: build==1.3.0; extra == "dev"
21
+ Requires-Dist: fastapi-cli[standard-no-fastapi-cloud-cli]==0.0.20; extra == "dev"
22
+ Requires-Dist: httpx==0.28.1; extra == "dev"
23
+ Requires-Dist: pycodestyle==2.14.0; extra == "dev"
24
+ Requires-Dist: pylint==4.0.4; extra == "dev"
25
+ Requires-Dist: pytest==9.0.2; extra == "dev"
26
+ Requires-Dist: pytest-asyncio==1.3.0; extra == "dev"
27
+ Requires-Dist: pytest-cov==7.0.0; extra == "dev"
28
+ Requires-Dist: twine==6.2.0; extra == "dev"
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ # Espark
39
+
40
+ Espark is a lightweight framework for building scalable and efficient ESP32-based IoT applications. It provides a modular architecture, easy-to-use APIs, and built-in support for common IoT protocols.
41
+
42
+ ## Project Goals
43
+
44
+ - Simplify the development of ESP32 applications.
45
+ - Provide a modular and extensible architecture.
46
+ - Support common IoT protocols like MQTT.
47
+ - Ensure efficient resource management for low-power devices.
48
+ - Provide a clean and easy-to-use API.
49
+ - Provide an user-friendly UI for configuration and monitoring.
50
+
51
+ ## Features
52
+
53
+ - **Device Provisioning**: Easy setup and configuration of ESP32 devices.
54
+ - **Telemetry Collection**: Built-in support for collecting and sending telemetry data.
55
+ - **Scalable Architecture**: Designed to handle a large number of devices efficiently.
56
+ - **Seamless Communication**: Support for MQTT protocol.
57
+
58
+ ## Hardware Requirements
59
+
60
+ - ESP32 Development Board
61
+ - USB Cable for programming and power
62
+ - Optional: Sensors and triggers for specific applications
63
+
64
+ ## Project Structure
65
+
66
+ ```
67
+ espark/
68
+ ├── espark-core/
69
+ │ ├── esparkcore/ # FastAPI backend framework
70
+ │ │ ├── data/ # Models, repositories
71
+ │ │ ├── routers/ # API endpoints
72
+ │ │ ├── schedules/ # Background tasks
73
+ │ │ ├── services/ # Business logic, MQTT handling
74
+ │ │ └── utils/ # Utility functions
75
+ │ └── Makefile
76
+ ├── espark-node/
77
+ │ ├── esparknode/ # MicroPython application framework
78
+ │ │ ├── actions/ # Action handlers
79
+ │ │ ├── data/ # Data storage
80
+ │ │ ├── libraries/ # External libraries
81
+ │ │ ├── networks/ # Network management
82
+ │ │ ├── sensors/ # Sensor interfaces
83
+ │ │ ├── triggers/ # Trigger interfaces
84
+ │ │ ├── utils/ # Utility functions
85
+ │ │ └── base_node.py # Main application file
86
+ │ └── Makefile
87
+ └── espark-react/ # React frontend application
88
+ ├── src/
89
+ │ ├── data/ # Data models and data providers
90
+ │ ├── i18n/ # Internationalization files
91
+ │ ├── pages/ # Application pages
92
+ │ ├── routes/ # Application routing
93
+ │ ├── utils/ # Utility functions
94
+ │ ├── App.tsx # Main application component
95
+ │ └── index.tsx # Application entry point
96
+ └── package.json
97
+ ```
98
+
99
+ ## Development Workflows
100
+
101
+ ### Setting up the backend
102
+
103
+ 1. Add espark-core as a dependency in your FastAPI project.
104
+ 2. Configure database connections and MQTT settings as environment variables.
105
+ 3. Implement additional data models, repositories, routers, and business logic if needed.
106
+ 4. Add the `DeviceRouter`, `TelemetryRouter`, and other additional routers to your FastAPI app.
107
+
108
+ ### Setting up the ESP32 application
109
+
110
+ 1. Clone the espark-node repository to your local machine.
111
+ 2. Copy `espark-core/Makefile.template` to `Makefile` and customize it for your device.
112
+ 3. Run `make upgrade` to copy the espark-core library to your device project.
113
+ 4. Implement device-specific actions, sensors, and triggers as needed.
114
+ 5. Run `make flash` to upload the firmware to your ESP32 device.
115
+ 6. Run `make deploy` to upload the application to the device.
116
+
117
+ ### Setting up the frontend
118
+
119
+ 1. Add espark-react as a dependency in your React project.
120
+ 2. Render `<EsparkApp />` in your main application file.
121
+
122
+ ### Configurations
123
+
124
+ - **espark-core**: Use environment variables, or `.env` file, for database and MQTT configurations.
125
+ - **espark-node**: Use `esparknode.configs` for device-specific configurations.
126
+ - **espark-react**: Customise `EsparkApp` props for application settings.
127
+
128
+ ## Examples and Patterns
129
+
130
+ - **Router Example**: `device_router.py` in `espark-core/esparkcore/routers/` demonstrates how to create API endpoints for device management.
131
+ - **Respository Example**: `device_repository.py` in `espark-core/esparkcore/data/repositories/` shows how to implement data access logic for devices.
132
+ - **Action Example**: `esp32_relay.py` in `espark-node/esparknode/actions/` illustrates how to define actions for ESP32 devices.
133
+ - **Sensor Example**: `sht20_sensor.py` in `espark-node/esparknode/sensors/` demonstrates how to read data from a SHT20 sensor.
134
+ - **Trigger Example**: `gpio_trigger.py` in `espark-node/esparknode/triggers/` shows how to create GPIO-based triggers for device actions.
135
+ - **List, Show, Edit Screens Example**: `DeviceList`, `DeviceShow`, and `DeviceEdit` components in `espark-react/src/pages/devices/` demonstrate how to create CRUD screens for device management.
136
+
137
+ ## Example Projects
138
+
139
+ - **Espartan**: A smart thermostat and open-door alert automation system using ESP32-C3 devices, leveraging espark for device management and telemetry, available at [https://github.com/ayltai/Espartan](https://github.com/ayltai/Espartan).
@@ -0,0 +1,102 @@
1
+ # Espark
2
+
3
+ Espark is a lightweight framework for building scalable and efficient ESP32-based IoT applications. It provides a modular architecture, easy-to-use APIs, and built-in support for common IoT protocols.
4
+
5
+ ## Project Goals
6
+
7
+ - Simplify the development of ESP32 applications.
8
+ - Provide a modular and extensible architecture.
9
+ - Support common IoT protocols like MQTT.
10
+ - Ensure efficient resource management for low-power devices.
11
+ - Provide a clean and easy-to-use API.
12
+ - Provide an user-friendly UI for configuration and monitoring.
13
+
14
+ ## Features
15
+
16
+ - **Device Provisioning**: Easy setup and configuration of ESP32 devices.
17
+ - **Telemetry Collection**: Built-in support for collecting and sending telemetry data.
18
+ - **Scalable Architecture**: Designed to handle a large number of devices efficiently.
19
+ - **Seamless Communication**: Support for MQTT protocol.
20
+
21
+ ## Hardware Requirements
22
+
23
+ - ESP32 Development Board
24
+ - USB Cable for programming and power
25
+ - Optional: Sensors and triggers for specific applications
26
+
27
+ ## Project Structure
28
+
29
+ ```
30
+ espark/
31
+ ├── espark-core/
32
+ │ ├── esparkcore/ # FastAPI backend framework
33
+ │ │ ├── data/ # Models, repositories
34
+ │ │ ├── routers/ # API endpoints
35
+ │ │ ├── schedules/ # Background tasks
36
+ │ │ ├── services/ # Business logic, MQTT handling
37
+ │ │ └── utils/ # Utility functions
38
+ │ └── Makefile
39
+ ├── espark-node/
40
+ │ ├── esparknode/ # MicroPython application framework
41
+ │ │ ├── actions/ # Action handlers
42
+ │ │ ├── data/ # Data storage
43
+ │ │ ├── libraries/ # External libraries
44
+ │ │ ├── networks/ # Network management
45
+ │ │ ├── sensors/ # Sensor interfaces
46
+ │ │ ├── triggers/ # Trigger interfaces
47
+ │ │ ├── utils/ # Utility functions
48
+ │ │ └── base_node.py # Main application file
49
+ │ └── Makefile
50
+ └── espark-react/ # React frontend application
51
+ ├── src/
52
+ │ ├── data/ # Data models and data providers
53
+ │ ├── i18n/ # Internationalization files
54
+ │ ├── pages/ # Application pages
55
+ │ ├── routes/ # Application routing
56
+ │ ├── utils/ # Utility functions
57
+ │ ├── App.tsx # Main application component
58
+ │ └── index.tsx # Application entry point
59
+ └── package.json
60
+ ```
61
+
62
+ ## Development Workflows
63
+
64
+ ### Setting up the backend
65
+
66
+ 1. Add espark-core as a dependency in your FastAPI project.
67
+ 2. Configure database connections and MQTT settings as environment variables.
68
+ 3. Implement additional data models, repositories, routers, and business logic if needed.
69
+ 4. Add the `DeviceRouter`, `TelemetryRouter`, and other additional routers to your FastAPI app.
70
+
71
+ ### Setting up the ESP32 application
72
+
73
+ 1. Clone the espark-node repository to your local machine.
74
+ 2. Copy `espark-core/Makefile.template` to `Makefile` and customize it for your device.
75
+ 3. Run `make upgrade` to copy the espark-core library to your device project.
76
+ 4. Implement device-specific actions, sensors, and triggers as needed.
77
+ 5. Run `make flash` to upload the firmware to your ESP32 device.
78
+ 6. Run `make deploy` to upload the application to the device.
79
+
80
+ ### Setting up the frontend
81
+
82
+ 1. Add espark-react as a dependency in your React project.
83
+ 2. Render `<EsparkApp />` in your main application file.
84
+
85
+ ### Configurations
86
+
87
+ - **espark-core**: Use environment variables, or `.env` file, for database and MQTT configurations.
88
+ - **espark-node**: Use `esparknode.configs` for device-specific configurations.
89
+ - **espark-react**: Customise `EsparkApp` props for application settings.
90
+
91
+ ## Examples and Patterns
92
+
93
+ - **Router Example**: `device_router.py` in `espark-core/esparkcore/routers/` demonstrates how to create API endpoints for device management.
94
+ - **Respository Example**: `device_repository.py` in `espark-core/esparkcore/data/repositories/` shows how to implement data access logic for devices.
95
+ - **Action Example**: `esp32_relay.py` in `espark-node/esparknode/actions/` illustrates how to define actions for ESP32 devices.
96
+ - **Sensor Example**: `sht20_sensor.py` in `espark-node/esparknode/sensors/` demonstrates how to read data from a SHT20 sensor.
97
+ - **Trigger Example**: `gpio_trigger.py` in `espark-node/esparknode/triggers/` shows how to create GPIO-based triggers for device actions.
98
+ - **List, Show, Edit Screens Example**: `DeviceList`, `DeviceShow`, and `DeviceEdit` components in `espark-react/src/pages/devices/` demonstrate how to create CRUD screens for device management.
99
+
100
+ ## Example Projects
101
+
102
+ - **Espartan**: A smart thermostat and open-door alert automation system using ESP32-C3 devices, leveraging espark for device management and telemetry, available at [https://github.com/ayltai/Espartan](https://github.com/ayltai/Espartan).
@@ -0,0 +1,139 @@
1
+ Metadata-Version: 2.4
2
+ Name: espark-core
3
+ Version: 0.5.5
4
+ Summary: The core module of the Espark ESP32-based IoT device management framework.
5
+ License: MIT
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ License-File: LICENSE
9
+ Requires-Dist: aiomqtt>=2.5.0
10
+ Requires-Dist: apscheduler>=3.11.2
11
+ Requires-Dist: fastapi>=0.128.0
12
+ Requires-Dist: packaging>=25.0
13
+ Requires-Dist: slack-sdk==3.39.0
14
+ Requires-Dist: sqlalchemy>=2.0.45
15
+ Requires-Dist: sqlmodel>=0.0.31
16
+ Requires-Dist: uvicorn[standard]>=0.40.0
17
+ Provides-Extra: dev
18
+ Requires-Dist: aiosqlite==0.22.1; extra == "dev"
19
+ Requires-Dist: autopep8==2.3.2; extra == "dev"
20
+ Requires-Dist: build==1.3.0; extra == "dev"
21
+ Requires-Dist: fastapi-cli[standard-no-fastapi-cloud-cli]==0.0.20; extra == "dev"
22
+ Requires-Dist: httpx==0.28.1; extra == "dev"
23
+ Requires-Dist: pycodestyle==2.14.0; extra == "dev"
24
+ Requires-Dist: pylint==4.0.4; extra == "dev"
25
+ Requires-Dist: pytest==9.0.2; extra == "dev"
26
+ Requires-Dist: pytest-asyncio==1.3.0; extra == "dev"
27
+ Requires-Dist: pytest-cov==7.0.0; extra == "dev"
28
+ Requires-Dist: twine==6.2.0; extra == "dev"
29
+ Dynamic: description
30
+ Dynamic: description-content-type
31
+ Dynamic: license
32
+ Dynamic: license-file
33
+ Dynamic: provides-extra
34
+ Dynamic: requires-dist
35
+ Dynamic: requires-python
36
+ Dynamic: summary
37
+
38
+ # Espark
39
+
40
+ Espark is a lightweight framework for building scalable and efficient ESP32-based IoT applications. It provides a modular architecture, easy-to-use APIs, and built-in support for common IoT protocols.
41
+
42
+ ## Project Goals
43
+
44
+ - Simplify the development of ESP32 applications.
45
+ - Provide a modular and extensible architecture.
46
+ - Support common IoT protocols like MQTT.
47
+ - Ensure efficient resource management for low-power devices.
48
+ - Provide a clean and easy-to-use API.
49
+ - Provide an user-friendly UI for configuration and monitoring.
50
+
51
+ ## Features
52
+
53
+ - **Device Provisioning**: Easy setup and configuration of ESP32 devices.
54
+ - **Telemetry Collection**: Built-in support for collecting and sending telemetry data.
55
+ - **Scalable Architecture**: Designed to handle a large number of devices efficiently.
56
+ - **Seamless Communication**: Support for MQTT protocol.
57
+
58
+ ## Hardware Requirements
59
+
60
+ - ESP32 Development Board
61
+ - USB Cable for programming and power
62
+ - Optional: Sensors and triggers for specific applications
63
+
64
+ ## Project Structure
65
+
66
+ ```
67
+ espark/
68
+ ├── espark-core/
69
+ │ ├── esparkcore/ # FastAPI backend framework
70
+ │ │ ├── data/ # Models, repositories
71
+ │ │ ├── routers/ # API endpoints
72
+ │ │ ├── schedules/ # Background tasks
73
+ │ │ ├── services/ # Business logic, MQTT handling
74
+ │ │ └── utils/ # Utility functions
75
+ │ └── Makefile
76
+ ├── espark-node/
77
+ │ ├── esparknode/ # MicroPython application framework
78
+ │ │ ├── actions/ # Action handlers
79
+ │ │ ├── data/ # Data storage
80
+ │ │ ├── libraries/ # External libraries
81
+ │ │ ├── networks/ # Network management
82
+ │ │ ├── sensors/ # Sensor interfaces
83
+ │ │ ├── triggers/ # Trigger interfaces
84
+ │ │ ├── utils/ # Utility functions
85
+ │ │ └── base_node.py # Main application file
86
+ │ └── Makefile
87
+ └── espark-react/ # React frontend application
88
+ ├── src/
89
+ │ ├── data/ # Data models and data providers
90
+ │ ├── i18n/ # Internationalization files
91
+ │ ├── pages/ # Application pages
92
+ │ ├── routes/ # Application routing
93
+ │ ├── utils/ # Utility functions
94
+ │ ├── App.tsx # Main application component
95
+ │ └── index.tsx # Application entry point
96
+ └── package.json
97
+ ```
98
+
99
+ ## Development Workflows
100
+
101
+ ### Setting up the backend
102
+
103
+ 1. Add espark-core as a dependency in your FastAPI project.
104
+ 2. Configure database connections and MQTT settings as environment variables.
105
+ 3. Implement additional data models, repositories, routers, and business logic if needed.
106
+ 4. Add the `DeviceRouter`, `TelemetryRouter`, and other additional routers to your FastAPI app.
107
+
108
+ ### Setting up the ESP32 application
109
+
110
+ 1. Clone the espark-node repository to your local machine.
111
+ 2. Copy `espark-core/Makefile.template` to `Makefile` and customize it for your device.
112
+ 3. Run `make upgrade` to copy the espark-core library to your device project.
113
+ 4. Implement device-specific actions, sensors, and triggers as needed.
114
+ 5. Run `make flash` to upload the firmware to your ESP32 device.
115
+ 6. Run `make deploy` to upload the application to the device.
116
+
117
+ ### Setting up the frontend
118
+
119
+ 1. Add espark-react as a dependency in your React project.
120
+ 2. Render `<EsparkApp />` in your main application file.
121
+
122
+ ### Configurations
123
+
124
+ - **espark-core**: Use environment variables, or `.env` file, for database and MQTT configurations.
125
+ - **espark-node**: Use `esparknode.configs` for device-specific configurations.
126
+ - **espark-react**: Customise `EsparkApp` props for application settings.
127
+
128
+ ## Examples and Patterns
129
+
130
+ - **Router Example**: `device_router.py` in `espark-core/esparkcore/routers/` demonstrates how to create API endpoints for device management.
131
+ - **Respository Example**: `device_repository.py` in `espark-core/esparkcore/data/repositories/` shows how to implement data access logic for devices.
132
+ - **Action Example**: `esp32_relay.py` in `espark-node/esparknode/actions/` illustrates how to define actions for ESP32 devices.
133
+ - **Sensor Example**: `sht20_sensor.py` in `espark-node/esparknode/sensors/` demonstrates how to read data from a SHT20 sensor.
134
+ - **Trigger Example**: `gpio_trigger.py` in `espark-node/esparknode/triggers/` shows how to create GPIO-based triggers for device actions.
135
+ - **List, Show, Edit Screens Example**: `DeviceList`, `DeviceShow`, and `DeviceEdit` components in `espark-react/src/pages/devices/` demonstrate how to create CRUD screens for device management.
136
+
137
+ ## Example Projects
138
+
139
+ - **Espartan**: A smart thermostat and open-door alert automation system using ESP32-C3 devices, leveraging espark for device management and telemetry, available at [https://github.com/ayltai/Espartan](https://github.com/ayltai/Espartan).
@@ -0,0 +1,85 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ README.md
4
+ requirements.dev.txt
5
+ requirements.txt
6
+ setup.cfg
7
+ setup.py
8
+ ../README.md
9
+ ./esparkcore/__init__.py
10
+ ./esparkcore/constants.py
11
+ ./esparkcore/data/__init__.py
12
+ ./esparkcore/data/database.py
13
+ ./esparkcore/data/models/__init__.py
14
+ ./esparkcore/data/models/device.py
15
+ ./esparkcore/data/models/notification.py
16
+ ./esparkcore/data/models/outbox.py
17
+ ./esparkcore/data/models/telemetry.py
18
+ ./esparkcore/data/models/trigger.py
19
+ ./esparkcore/data/models/version.py
20
+ ./esparkcore/data/repositories/__init__.py
21
+ ./esparkcore/data/repositories/base_repository.py
22
+ ./esparkcore/data/repositories/device_repository.py
23
+ ./esparkcore/data/repositories/notification_repository.py
24
+ ./esparkcore/data/repositories/outbox_repository.py
25
+ ./esparkcore/data/repositories/telemetry_repository.py
26
+ ./esparkcore/data/repositories/trigger_repository.py
27
+ ./esparkcore/data/repositories/version_repository.py
28
+ ./esparkcore/notifications/__init__.py
29
+ ./esparkcore/notifications/notifier.py
30
+ ./esparkcore/notifications/slack_notifier.py
31
+ ./esparkcore/routers/__init__.py
32
+ ./esparkcore/routers/base_router.py
33
+ ./esparkcore/routers/device_router.py
34
+ ./esparkcore/routers/notification_router.py
35
+ ./esparkcore/routers/telemetry_router.py
36
+ ./esparkcore/routers/trigger_router.py
37
+ ./esparkcore/routers/version_router.py
38
+ ./esparkcore/schedules/__init__.py
39
+ ./esparkcore/schedules/outbox.py
40
+ ./esparkcore/schedules/scheduler.py
41
+ ./esparkcore/services/__init__.py
42
+ ./esparkcore/services/mqtt.py
43
+ ./esparkcore/utils/__init__.py
44
+ ./esparkcore/utils/logging.py
45
+ espark_core.egg-info/PKG-INFO
46
+ espark_core.egg-info/SOURCES.txt
47
+ espark_core.egg-info/dependency_links.txt
48
+ espark_core.egg-info/requires.txt
49
+ espark_core.egg-info/top_level.txt
50
+ esparkcore/__init__.py
51
+ esparkcore/constants.py
52
+ esparkcore/data/__init__.py
53
+ esparkcore/data/database.py
54
+ esparkcore/data/models/__init__.py
55
+ esparkcore/data/models/device.py
56
+ esparkcore/data/models/notification.py
57
+ esparkcore/data/models/outbox.py
58
+ esparkcore/data/models/telemetry.py
59
+ esparkcore/data/models/trigger.py
60
+ esparkcore/data/models/version.py
61
+ esparkcore/data/repositories/__init__.py
62
+ esparkcore/data/repositories/base_repository.py
63
+ esparkcore/data/repositories/device_repository.py
64
+ esparkcore/data/repositories/notification_repository.py
65
+ esparkcore/data/repositories/outbox_repository.py
66
+ esparkcore/data/repositories/telemetry_repository.py
67
+ esparkcore/data/repositories/trigger_repository.py
68
+ esparkcore/data/repositories/version_repository.py
69
+ esparkcore/notifications/__init__.py
70
+ esparkcore/notifications/notifier.py
71
+ esparkcore/notifications/slack_notifier.py
72
+ esparkcore/routers/__init__.py
73
+ esparkcore/routers/base_router.py
74
+ esparkcore/routers/device_router.py
75
+ esparkcore/routers/notification_router.py
76
+ esparkcore/routers/telemetry_router.py
77
+ esparkcore/routers/trigger_router.py
78
+ esparkcore/routers/version_router.py
79
+ esparkcore/schedules/__init__.py
80
+ esparkcore/schedules/outbox.py
81
+ esparkcore/schedules/scheduler.py
82
+ esparkcore/services/__init__.py
83
+ esparkcore/services/mqtt.py
84
+ esparkcore/utils/__init__.py
85
+ esparkcore/utils/logging.py
@@ -0,0 +1,21 @@
1
+ aiomqtt>=2.5.0
2
+ apscheduler>=3.11.2
3
+ fastapi>=0.128.0
4
+ packaging>=25.0
5
+ slack-sdk==3.39.0
6
+ sqlalchemy>=2.0.45
7
+ sqlmodel>=0.0.31
8
+ uvicorn[standard]>=0.40.0
9
+
10
+ [dev]
11
+ aiosqlite==0.22.1
12
+ autopep8==2.3.2
13
+ build==1.3.0
14
+ fastapi-cli[standard-no-fastapi-cloud-cli]==0.0.20
15
+ httpx==0.28.1
16
+ pycodestyle==2.14.0
17
+ pylint==4.0.4
18
+ pytest==9.0.2
19
+ pytest-asyncio==1.3.0
20
+ pytest-cov==7.0.0
21
+ twine==6.2.0
@@ -0,0 +1 @@
1
+ esparkcore
File without changes
@@ -0,0 +1,11 @@
1
+ ENV_DATABASE_URL : str = 'DATABASE_URL'
2
+ ENV_MQTT_HOST : str = 'MQTT_HOST'
3
+ ENV_MQTT_PORT : str = 'MQTT_PORT'
4
+ ENV_UPLOAD_PATH : str = 'UPLOAD_PATH'
5
+
6
+ TOPIC_ACTION : str = 'espark/action'
7
+ TOPIC_DEVICE : str = 'espark/device'
8
+ TOPIC_REGISTRATION : str = 'espark/registration'
9
+ TOPIC_TELEMETRY : str = 'espark/telemetry'
10
+ TOPIC_OTA : str = 'espark/ota'
11
+ TOPIC_CRASH : str = 'espark/crash'
@@ -0,0 +1 @@
1
+ from .database import async_session, init_db
@@ -0,0 +1,15 @@
1
+ from os import getenv
2
+
3
+ from sqlalchemy.ext.asyncio import async_sessionmaker, AsyncSession, create_async_engine
4
+ from sqlmodel import SQLModel
5
+
6
+ from ..constants import ENV_DATABASE_URL
7
+
8
+ # pylint: disable=invalid-name
9
+ engine = create_async_engine(getenv(ENV_DATABASE_URL, 'sqlite+aiosqlite:///database.db'), echo=True)
10
+ async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
11
+
12
+
13
+ async def init_db():
14
+ async with engine.begin() as conn:
15
+ await conn.run_sync(SQLModel.metadata.create_all)
@@ -0,0 +1,6 @@
1
+ from .device import Device
2
+ from .notification import Notification
3
+ from .outbox import OutboxEvent
4
+ from .telemetry import Telemetry
5
+ from .trigger import Trigger
6
+ from .version import AppVersion
@@ -0,0 +1,15 @@
1
+ from datetime import datetime
2
+ from typing import Dict, Optional
3
+
4
+ from sqlalchemy import Column
5
+ from sqlmodel import SQLModel, Field, JSON
6
+
7
+
8
+ class Device(SQLModel, table=True):
9
+ id : str = Field(primary_key=True, description='Unique identifier for the device')
10
+ display_name : Optional[str] = Field(default=None, description='Human-readable name of the device')
11
+ app_name : Optional[str] = Field(default=None, foreign_key='appversion.id', ondelete='CASCADE', description='Name of the application running on the device')
12
+ app_version : Optional[str] = Field(default=None, description='Version of the application running on the device')
13
+ capabilities : Optional[str] = Field(default=None, description='Comma separated capabilities of the device')
14
+ parameters : Dict[str, str | int | bool] = Field(default_factory=dict, sa_column=Column(JSON), description='JSON string of capability-specific parameters')
15
+ last_seen : datetime = Field(index=True, description='Last time the device was seen online')
@@ -0,0 +1,11 @@
1
+ from typing import Dict
2
+
3
+ from sqlalchemy import Column
4
+ from sqlmodel import SQLModel, Field, JSON
5
+
6
+
7
+ class Notification(SQLModel, table=True):
8
+ id : int = Field(primary_key=True, description='Unique identifier for the notification')
9
+ name : str = Field(index=True, unique=True, description='Name of the notification')
10
+ provider : str = Field(index=True, description='Notification provider (e.g., Slack, Twilio)')
11
+ config : Dict[str, str] = Field(default_factory=dict, sa_column=Column(JSON), description='JSON string of provider-specific configuration parameters')
@@ -0,0 +1,20 @@
1
+ from datetime import datetime
2
+ from typing import Dict, Optional
3
+ from uuid import UUID, uuid4
4
+
5
+ from sqlalchemy import Column
6
+ from sqlmodel import SQLModel, Field, JSON, UniqueConstraint
7
+
8
+
9
+ class OutboxEvent(SQLModel, table=True):
10
+ __table_args__ = (
11
+ UniqueConstraint('device_id', 'event_type', 'is_processed', name='uq_device_event'),
12
+ )
13
+
14
+ id : UUID = Field(default_factory=uuid4, primary_key=True, description='Unique identifier for the outbox event')
15
+ device_id : str = Field(foreign_key='device.id', ondelete='CASCADE', index=True, description='Identifier of the device associated with the event')
16
+ event_type : str = Field(index=True, description='Type of the event')
17
+ payload : Dict[str, str] = Field(default_factory=dict, sa_column=Column(JSON), description='JSON string of event-specific payload data')
18
+ created_at : datetime = Field(default_factory=datetime.now, index=True, description='Timestamp when the event was created')
19
+ processed_at : Optional[datetime] = Field(default=None, index=True, description='Timestamp when the event was processed')
20
+ is_processed : bool = Field(default=False, index=True, description='Flag indicating whether the event has been processed')
@@ -0,0 +1,12 @@
1
+ from datetime import datetime
2
+ from typing import Optional
3
+
4
+ from sqlmodel import SQLModel, Field
5
+
6
+
7
+ class Telemetry(SQLModel, table=True):
8
+ id : Optional[int] = Field(primary_key=True, default=None)
9
+ device_id : str = Field(foreign_key='device.id', ondelete='CASCADE', description='Device that sent this data')
10
+ timestamp : datetime = Field(index=True, description='Timestamp of the data')
11
+ data_type : str = Field(index=True, description='Type of the data (e.g., motion, temperature)')
12
+ value : int = Field(description='Value of the data (e.g., temperature, human presence detected or not)')
@@ -0,0 +1,13 @@
1
+ from typing import Optional
2
+
3
+ from sqlmodel import Field, SQLModel
4
+
5
+
6
+ class Trigger(SQLModel, table=True):
7
+ id : Optional[int] = Field(primary_key=True, description='Unique identifier for the trigger')
8
+ name : str = Field(index=True, unique=True, description='Name of the trigger')
9
+ device_id : Optional[str] = Field(index=True, default=None, description='Identifier of the associated device')
10
+ data_type : Optional[str] = Field(index=True, default=None, description='Type of telemetry data the trigger monitors (e.g., temperature, humidity)')
11
+ condition : str = Field(description='Condition to evaluate (e.g., ">", "<=")')
12
+ value : int = Field(description='Value to compare against for the trigger condition')
13
+ notification_ids : Optional[str] = Field(default=None, description='Comma-separated list of associated notification IDs to be sent when the trigger condition is met')
@@ -0,0 +1,6 @@
1
+ from sqlmodel import SQLModel, Field
2
+
3
+
4
+ class AppVersion(SQLModel, table=True):
5
+ id : str = Field(primary_key=True, description='The app name, which is a unique identifier for the app version')
6
+ version : str = Field(description='Version of the application')
@@ -0,0 +1,7 @@
1
+ from .base_repository import AsyncRepository
2
+ from .device_repository import DeviceRepository
3
+ from .notification_repository import NotificationRepository
4
+ from .outbox_repository import OutboxRepository
5
+ from .telemetry_repository import TelemetryRepository
6
+ from .trigger_repository import TriggerRepository
7
+ from .version_repository import AppVersionRepository