micropidash 1.0.0__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kritish
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,183 @@
1
+ Metadata-Version: 2.1
2
+ Name: micropidash
3
+ Version: 1.0.0
4
+ Summary: A lightweight web dashboard for MicroPython (ESP32, Pico W)
5
+ Home-page: https://github.com/kritishmohapatra/micropidash
6
+ Author: Kritish Mohapatra
7
+ Author-email: kritishmohapatra06norisk@gmail.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+
15
+ # 🚀 micropidash: Lightweight MicroPython IoT Dashboard
16
+
17
+ **micropidash** is a high-performance, asynchronous web dashboard library specifically designed for microcontrollers like the **Raspberry Pi Pico 2W** (RP2350/RP2040) and ESP32. It enables the creation of real-time, responsive web interfaces for IoT projects using minimal MicroPython code.
18
+
19
+ <p align="center">
20
+ <a href="https://micropython.org/"><img src="https://img.shields.io/badge/MicroPython-✓-green?logo=micropython&logoColor=white" alt="MicroPython"></a>
21
+ <a href="https://www.espressif.com/en/products/socs/esp32"><img src="https://img.shields.io/badge/ESP32-Supported-orange?logo=espressif&logoColor=white" alt="ESP32"></a>
22
+ <a href="https://www.raspberrypi.com/products/raspberry-pi-pico/"><img src="https://img.shields.io/badge/Raspberry%20Pi%20Pico%20 2 W-Compatible-darkgreen?logo=raspberrypi&logoColor=white" alt="Pico 2 W"></a>
23
+ <a href="https://github.com/kritishmohapatra/micropython-sevenseg/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green?logo=open-source-initiative&logoColor=white" alt="License"></a>
24
+
25
+
26
+ </p>
27
+
28
+ **Author:** [Kritish Mohapatra]
29
+
30
+
31
+ ---
32
+
33
+ ## ✨ Key Features
34
+ * **Asynchronous Engine:** Built on `uasyncio` for non-blocking, multi-tasking performance.
35
+ * **Real-Time Sync:** AJAX-based polling ensures all connected devices (Mobile & Laptop) stay synced without page refreshes.
36
+ * **Client-Side Theming:** Every connected user can independently toggle between Dark and Light modes.
37
+ * **Order Preservation:** Uses alphabetical sorting for widget IDs to ensure your layout stays exactly as intended.
38
+ * **Memory Efficient:** Optimized for devices with limited RAM, featuring chunked data transmission and frequent garbage collection.
39
+
40
+ ---
41
+
42
+ ## 📦 Installation
43
+
44
+ 1. Upload `micropidash.py` to your microcontroller's root directory.
45
+ 2. Create a `main.py` file to implement your project logic.
46
+ 3. Ensure your device is connected to a stable 2.4GHz Wi-Fi network.
47
+
48
+ ---
49
+ ## 📂 Project Structure
50
+ ├── micropidash/
51
+ │ ├── init.py
52
+ │ └── micropidash.py
53
+
54
+ ├── examples/
55
+ | ├── basic_1.py
56
+ │ └── esp_32_example.py
57
+
58
+ ├── README.md
59
+ └── LICENSE
60
+ ## 📚 API Documentation
61
+
62
+ ### `Dashboard(title)`
63
+ Creates a new dashboard instance with the specified title.
64
+ * **title**: (String) The name displayed at the top of your web dashboard.
65
+
66
+ ---
67
+
68
+ ### `add_toggle(id, label)`
69
+ Adds a binary switch (On/Off) to the dashboard.
70
+ * **id**: (String) Unique identifier for the widget. Also used for alphabetical sorting on the UI.
71
+ * **label**: (String) The text displayed above the switch.
72
+
73
+ ---
74
+
75
+ ### `add_label(id, label)`
76
+ Adds a text box designed for displaying live sensor data or status strings.
77
+ * **id**: (String) Unique identifier for the widget.
78
+ * **label**: (String) The descriptive text for the data being shown.
79
+
80
+ ---
81
+
82
+ ### `add_level(id, label, color)`
83
+ Adds a graphical progress bar, perfect for humidity, tank levels, or battery percentage.
84
+ * **id**: (String) Unique identifier for the widget.
85
+ * **label**: (String) The descriptive text for the progress bar.
86
+ * **color**: (Hex/CSS Color) The color of the fill bar (e.g., `#2196F3` or `red`).
87
+ * **Value Range**: Expects an integer between $0$ and $100$.
88
+
89
+ ---
90
+
91
+ ### `update_value(id, value)`
92
+ Injects new data into an existing widget. This change is pushed instantly to all connected web clients via the next poll.
93
+ * **id**: (String) The ID of the widget you want to update.
94
+ * **value**: (String/Int) The new data to display.
95
+
96
+ ---
97
+ ## 🚀 Quick Start (Simple Example)
98
+
99
+ Use this minimal example to test your connection and ensure the dashboard is being served correctly on your local network.
100
+
101
+ ```python
102
+ from micropidash import Dashboard
103
+ import network
104
+
105
+ # 1. WiFi Setup
106
+ wlan = network.WLAN(network.STA_IF)
107
+ wlan.active(True)
108
+
109
+ wlan.connect('YOUR_SSID', 'YOUR_PASSWORD')
110
+
111
+ print("Connecting...")
112
+ while not wlan.isconnected(): pass
113
+ print("Connected! IP:", wlan.ifconfig()[0])
114
+
115
+ # 2. Dashboard Initialization
116
+ dash = Dashboard("MicroPiDash v1.0")
117
+
118
+ # 3. Adding Basic Widgets
119
+ dash.add_toggle("led", "Test Switch") # A binary toggle
120
+ dash.add_label("status", "System Status") # A text display
121
+ dash.add_level("level", "Signal Strength") # A progress bar (0-100)
122
+
123
+ # 4. Start the Web Server
124
+ # Access the dashboard via the IP address printed above
125
+ dash.run()
126
+ ```
127
+
128
+ ### 🔌 ESP32 Onboard LED Example
129
+
130
+
131
+ ```python
132
+ import machine, network, uasyncio as asyncio
133
+ from micropidash import Dashboard
134
+
135
+ # 1. ESP32 Pin Setup (Most boards use GPIO 2 for built-in LED)
136
+ led = machine.Pin(2, machine.Pin.OUT)
137
+
138
+ # 2. WiFi Connectivity
139
+ wlan = network.WLAN(network.STA_IF)
140
+ wlan.active(True)
141
+ wlan.connect('YOUR_SSID', 'YOUR_PASSWORD')
142
+
143
+ print("Connecting...")
144
+ while not wlan.isconnected(): pass
145
+ print("Server Live at IP:", wlan.ifconfig()[0])
146
+
147
+ # 3. Dashboard Configuration
148
+ dash = Dashboard("ESP32 Control Hub")
149
+ dash.add_toggle("1_led", "Built-in LED")
150
+ dash.add_label("2_status", "Live Status")
151
+
152
+ # 4. Hardware & Web UI Sync Task
153
+ async def sync_task():
154
+ while True:
155
+ # Dashboard UI state ko physical LED se link karna
156
+ led.value(dash.elements["1_led"]["value"])
157
+
158
+ # Dashboard par status update bhejni
159
+ state = "GLOWING" if led.value() else "OFF"
160
+ dash.update_value("2_status", f"LED is {state}")
161
+
162
+ await asyncio.sleep(0.5)
163
+
164
+ # 5. Execution
165
+ async def main():
166
+ asyncio.create_task(sync_task())
167
+ dash.run()
168
+
169
+ asyncio.run(main())
170
+ ```
171
+ ## 🤝 Contributing
172
+ As an **Electrical Engineering student**, I built **micropidash** to simplify MicroPython IoT development and bridge the gap between hardware and web interfaces.
173
+
174
+ If you find bugs, have feature ideas, or want to optimize the code further, feel free to open an **issue** or submit a **pull request**! Let's build the future of embedded systems together.
175
+
176
+ ---
177
+ ## 🌐 Author
178
+
179
+ **Kritish Mohapatra**
180
+ 🔗 [GitHub](https://github.com/kritishmohapatra)
181
+ 📧 kritishmohapatra06norisk@gmail.com
182
+
183
+ ✨ *Made with passion for Embedded Systems and MicroPython learners.*
@@ -0,0 +1,169 @@
1
+ # 🚀 micropidash: Lightweight MicroPython IoT Dashboard
2
+
3
+ **micropidash** is a high-performance, asynchronous web dashboard library specifically designed for microcontrollers like the **Raspberry Pi Pico 2W** (RP2350/RP2040) and ESP32. It enables the creation of real-time, responsive web interfaces for IoT projects using minimal MicroPython code.
4
+
5
+ <p align="center">
6
+ <a href="https://micropython.org/"><img src="https://img.shields.io/badge/MicroPython-✓-green?logo=micropython&logoColor=white" alt="MicroPython"></a>
7
+ <a href="https://www.espressif.com/en/products/socs/esp32"><img src="https://img.shields.io/badge/ESP32-Supported-orange?logo=espressif&logoColor=white" alt="ESP32"></a>
8
+ <a href="https://www.raspberrypi.com/products/raspberry-pi-pico/"><img src="https://img.shields.io/badge/Raspberry%20Pi%20Pico%20 2 W-Compatible-darkgreen?logo=raspberrypi&logoColor=white" alt="Pico 2 W"></a>
9
+ <a href="https://github.com/kritishmohapatra/micropython-sevenseg/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green?logo=open-source-initiative&logoColor=white" alt="License"></a>
10
+
11
+
12
+ </p>
13
+
14
+ **Author:** [Kritish Mohapatra]
15
+
16
+
17
+ ---
18
+
19
+ ## ✨ Key Features
20
+ * **Asynchronous Engine:** Built on `uasyncio` for non-blocking, multi-tasking performance.
21
+ * **Real-Time Sync:** AJAX-based polling ensures all connected devices (Mobile & Laptop) stay synced without page refreshes.
22
+ * **Client-Side Theming:** Every connected user can independently toggle between Dark and Light modes.
23
+ * **Order Preservation:** Uses alphabetical sorting for widget IDs to ensure your layout stays exactly as intended.
24
+ * **Memory Efficient:** Optimized for devices with limited RAM, featuring chunked data transmission and frequent garbage collection.
25
+
26
+ ---
27
+
28
+ ## 📦 Installation
29
+
30
+ 1. Upload `micropidash.py` to your microcontroller's root directory.
31
+ 2. Create a `main.py` file to implement your project logic.
32
+ 3. Ensure your device is connected to a stable 2.4GHz Wi-Fi network.
33
+
34
+ ---
35
+ ## 📂 Project Structure
36
+ ├── micropidash/
37
+ │ ├── init.py
38
+ │ └── micropidash.py
39
+
40
+ ├── examples/
41
+ | ├── basic_1.py
42
+ │ └── esp_32_example.py
43
+
44
+ ├── README.md
45
+ └── LICENSE
46
+ ## 📚 API Documentation
47
+
48
+ ### `Dashboard(title)`
49
+ Creates a new dashboard instance with the specified title.
50
+ * **title**: (String) The name displayed at the top of your web dashboard.
51
+
52
+ ---
53
+
54
+ ### `add_toggle(id, label)`
55
+ Adds a binary switch (On/Off) to the dashboard.
56
+ * **id**: (String) Unique identifier for the widget. Also used for alphabetical sorting on the UI.
57
+ * **label**: (String) The text displayed above the switch.
58
+
59
+ ---
60
+
61
+ ### `add_label(id, label)`
62
+ Adds a text box designed for displaying live sensor data or status strings.
63
+ * **id**: (String) Unique identifier for the widget.
64
+ * **label**: (String) The descriptive text for the data being shown.
65
+
66
+ ---
67
+
68
+ ### `add_level(id, label, color)`
69
+ Adds a graphical progress bar, perfect for humidity, tank levels, or battery percentage.
70
+ * **id**: (String) Unique identifier for the widget.
71
+ * **label**: (String) The descriptive text for the progress bar.
72
+ * **color**: (Hex/CSS Color) The color of the fill bar (e.g., `#2196F3` or `red`).
73
+ * **Value Range**: Expects an integer between $0$ and $100$.
74
+
75
+ ---
76
+
77
+ ### `update_value(id, value)`
78
+ Injects new data into an existing widget. This change is pushed instantly to all connected web clients via the next poll.
79
+ * **id**: (String) The ID of the widget you want to update.
80
+ * **value**: (String/Int) The new data to display.
81
+
82
+ ---
83
+ ## 🚀 Quick Start (Simple Example)
84
+
85
+ Use this minimal example to test your connection and ensure the dashboard is being served correctly on your local network.
86
+
87
+ ```python
88
+ from micropidash import Dashboard
89
+ import network
90
+
91
+ # 1. WiFi Setup
92
+ wlan = network.WLAN(network.STA_IF)
93
+ wlan.active(True)
94
+
95
+ wlan.connect('YOUR_SSID', 'YOUR_PASSWORD')
96
+
97
+ print("Connecting...")
98
+ while not wlan.isconnected(): pass
99
+ print("Connected! IP:", wlan.ifconfig()[0])
100
+
101
+ # 2. Dashboard Initialization
102
+ dash = Dashboard("MicroPiDash v1.0")
103
+
104
+ # 3. Adding Basic Widgets
105
+ dash.add_toggle("led", "Test Switch") # A binary toggle
106
+ dash.add_label("status", "System Status") # A text display
107
+ dash.add_level("level", "Signal Strength") # A progress bar (0-100)
108
+
109
+ # 4. Start the Web Server
110
+ # Access the dashboard via the IP address printed above
111
+ dash.run()
112
+ ```
113
+
114
+ ### 🔌 ESP32 Onboard LED Example
115
+
116
+
117
+ ```python
118
+ import machine, network, uasyncio as asyncio
119
+ from micropidash import Dashboard
120
+
121
+ # 1. ESP32 Pin Setup (Most boards use GPIO 2 for built-in LED)
122
+ led = machine.Pin(2, machine.Pin.OUT)
123
+
124
+ # 2. WiFi Connectivity
125
+ wlan = network.WLAN(network.STA_IF)
126
+ wlan.active(True)
127
+ wlan.connect('YOUR_SSID', 'YOUR_PASSWORD')
128
+
129
+ print("Connecting...")
130
+ while not wlan.isconnected(): pass
131
+ print("Server Live at IP:", wlan.ifconfig()[0])
132
+
133
+ # 3. Dashboard Configuration
134
+ dash = Dashboard("ESP32 Control Hub")
135
+ dash.add_toggle("1_led", "Built-in LED")
136
+ dash.add_label("2_status", "Live Status")
137
+
138
+ # 4. Hardware & Web UI Sync Task
139
+ async def sync_task():
140
+ while True:
141
+ # Dashboard UI state ko physical LED se link karna
142
+ led.value(dash.elements["1_led"]["value"])
143
+
144
+ # Dashboard par status update bhejni
145
+ state = "GLOWING" if led.value() else "OFF"
146
+ dash.update_value("2_status", f"LED is {state}")
147
+
148
+ await asyncio.sleep(0.5)
149
+
150
+ # 5. Execution
151
+ async def main():
152
+ asyncio.create_task(sync_task())
153
+ dash.run()
154
+
155
+ asyncio.run(main())
156
+ ```
157
+ ## 🤝 Contributing
158
+ As an **Electrical Engineering student**, I built **micropidash** to simplify MicroPython IoT development and bridge the gap between hardware and web interfaces.
159
+
160
+ If you find bugs, have feature ideas, or want to optimize the code further, feel free to open an **issue** or submit a **pull request**! Let's build the future of embedded systems together.
161
+
162
+ ---
163
+ ## 🌐 Author
164
+
165
+ **Kritish Mohapatra**
166
+ 🔗 [GitHub](https://github.com/kritishmohapatra)
167
+ 📧 kritishmohapatra06norisk@gmail.com
168
+
169
+ ✨ *Made with passion for Embedded Systems and MicroPython learners.*
@@ -0,0 +1,8 @@
1
+ # micropidash MicroPython Library
2
+ # Author: Kritish Mohapatra
3
+ # Year: 2026
4
+
5
+ from .micropidash import Dashboard
6
+
7
+ __all__ = ["Dashboard"]
8
+ __version__ = "1.0.0"
@@ -0,0 +1,192 @@
1
+ import uasyncio as asyncio
2
+ import json, gc
3
+
4
+ class Dashboard:
5
+ def __init__(self, title="Pi IoT Lab"):
6
+ self.title = title
7
+ self.elements = {}
8
+
9
+ def add_toggle(self, id, label):
10
+ self.elements[id] = {"type": "toggle", "label": label, "value": 0}
11
+
12
+ def add_label(self, id, label):
13
+ self.elements[id] = {"type": "label", "label": label, "value": "---"}
14
+
15
+ def add_level(self, id, label, color="#4CAF50"):
16
+ self.elements[id] = {"type": "level", "label": label, "value": 0, "color": color}
17
+
18
+ def update_value(self, id, value):
19
+ if id in self.elements:
20
+ self.elements[id]["value"] = value
21
+
22
+ async def _send_html(self, writer):
23
+ # Header + CSS
24
+ html_start = f"""<!DOCTYPE html><html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1">
25
+ <title>{self.title}</title>
26
+ <style>
27
+ :root {{
28
+ --bg:#f4f4f4;
29
+ --card:#fff;
30
+ --text:#000;
31
+ --primary:#4CAF50; }}
32
+ body {{
33
+ margin:0;
34
+ font-family:
35
+ sans-serif;
36
+ background:var(--bg);
37
+ color:var(--text);
38
+ text-align:center;
39
+ padding:10px; }}
40
+ .header {{
41
+ display:flex;
42
+ justify-content:
43
+ space-between;
44
+ align-items:center;
45
+ max-width:600px;
46
+ margin:0 auto 20px; }}
47
+ .grid {{ display: grid;
48
+ repeat(auto-fit, minmax(160px, 1fr));
49
+ gap: 15px;
50
+ max-width: 800px;
51
+ margin: 0 auto; }}
52
+ .card {{ background:var(--card);
53
+ padding:15px;
54
+ border-radius:12px;
55
+ box-shadow:0 3px 6px rgba(0,0,0,.1);
56
+ display:flex;
57
+ flex-direction:column;
58
+ align-items:center; gap:8px; }}
59
+ .p-bg {{ width:100%;
60
+ height:12px;
61
+ background:#bbb;
62
+ border-radius:6px;
63
+ overflow:hidden; }}
64
+ .p-fill {{
65
+ height:100%;
66
+ transition:width .4s; }}
67
+ .switch {{
68
+ position:relative;
69
+ width:48px;
70
+ height:26px; }}
71
+ .switch input {{
72
+ opacity:0;
73
+ width:0;
74
+ height:0; }}
75
+ .slider {{
76
+ position:absolute;
77
+ cursor:pointer;
78
+ inset:0;
79
+ background:#ccc;
80
+ border-radius:26px;
81
+ transition:.3s; }}
82
+ .slider:before {{
83
+ content:"";
84
+ position:absolute;
85
+ height:20px;
86
+ width:20px;
87
+ left:3px;
88
+ bottom:3px;
89
+ background:#fff;
90
+ border-radius:50%;
91
+ transition:.3s; }}
92
+ input:checked + .slider {{ background:var(--primary); }}
93
+ input:checked + .slider:before {{ transform:translateX(22px); }}
94
+ </style>
95
+ <script>
96
+ let dark = window.matchMedia('(prefers-color-scheme: dark)').matches;
97
+ function applyTheme() {{
98
+ document.documentElement.style.setProperty('--bg', dark ? '#121212' : '#f4f4f4');
99
+ document.documentElement.style.setProperty('--card', dark ? '#1e1e1e' : '#fff');
100
+ document.documentElement.style.setProperty('--text', dark ? '#fff' : '#000');
101
+ }}
102
+ function updateData(){{
103
+ fetch('/data').then(r=>r.json()).then(d=>{{
104
+ for(let id in d){{
105
+ let i=d[id]; let tx=document.getElementById(id); let sw=document.getElementById(id+"-sw");
106
+ if(!tx)continue;
107
+ if(i.type==="level"){{ tx.style.width=i.value+"%"; document.getElementById(id+"-txt").innerText=i.value+"%"; }}
108
+ else if(i.type==="toggle"){{ tx.innerText=i.value?"ON":"OFF"; tx.style.color=i.value? "var(--primary)":"#888"; if(sw) sw.checked=!!i.value; }}
109
+ else {{ tx.innerText=i.value; }}
110
+ }}
111
+ }});
112
+ }}
113
+ setInterval(updateData, 1200);
114
+ function sendCmd(id){{ fetch('/?'+id+'=toggle'); }}
115
+
116
+ // FIXED BRACES HERE
117
+ function toggleTheme() {{
118
+ dark=!dark;
119
+ applyTheme();
120
+ document.getElementById("themeBtn").innerText = dark ? "☀️" : "🌙";
121
+ }}
122
+
123
+ </script></head><body onload="applyTheme()">
124
+ <div class="header">
125
+ <h1>{self.title}</h1>
126
+ <button id="themeBtn" onclick="toggleTheme()" style="background:none;border:none;font-size:24px;cursor:pointer;">🌙</button>
127
+ </div>
128
+ <div class="grid">"""
129
+
130
+ writer.write(b"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n")
131
+ writer.write(html_start.encode())
132
+
133
+ # Cards generation
134
+ sorted_keys = sorted(self.elements.keys())
135
+
136
+ for id in sorted_keys:
137
+ info = self.elements[id]
138
+ card = f"<div class='card'><strong>{info['label']}</strong>"
139
+ if info["type"] == "level":
140
+ card += f'<div id="{id}-txt">{info["value"]}%</div><div class="p-bg"><div id="{id}" class="p-fill" style="width:{info["value"]}%;background:{info["color"]}"></div></div>'
141
+ elif info["type"] == "toggle":
142
+ state = "ON" if info["value"] else "OFF"
143
+ c = "checked" if info["value"] else ""
144
+
145
+ card += f'''
146
+ <div style="display:flex;align-items:center;gap:10px;">
147
+ <span id="{id}" style="font-weight:bold;color:{'var(--primary)' if info["value"] else '#888'}">
148
+ {state}
149
+ </span>
150
+ <label class="switch">
151
+ <input type="checkbox" id="{id}-sw" onchange="sendCmd('{id}')" {c}>
152
+ <span class="slider"></span>
153
+ </label>
154
+ </div>
155
+ '''
156
+ else:
157
+ card += f"<div id='{id}' style='font-size:20px;font-weight:bold;'>{info['value']}</div>"
158
+ card += "</div>"
159
+ writer.write(card.encode())
160
+
161
+ writer.write(b"</div></body></html>")
162
+ await writer.drain()
163
+
164
+ async def _handle_request(self, reader, writer):
165
+ try:
166
+ raw = await reader.readline()
167
+ if not raw: return
168
+ req = raw.decode()
169
+ while await reader.readline() != b'\r\n': pass
170
+
171
+ if "/data" in req:
172
+ body = json.dumps({k: {"type": v["type"], "value": v["value"]} for k,v in self.elements.items()})
173
+ writer.write(b"HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n")
174
+ writer.write(body.encode())
175
+ elif "toggle" in req:
176
+ for k,v in self.elements.items():
177
+ if f"{k}=toggle" in req: v["value"] ^= 1
178
+ writer.write(b"HTTP/1.1 200 OK\r\n\r\n")
179
+ else:
180
+ await self._send_html(writer)
181
+ await writer.drain()
182
+ except Exception as e:
183
+ print("Dashboard error:", e)
184
+ finally:
185
+ await writer.wait_closed()
186
+ gc.collect()
187
+
188
+ def run(self, port=80):
189
+ print(f"Pico Dashboard Live on Port {port}")
190
+ loop = asyncio.get_event_loop()
191
+ loop.create_task(asyncio.start_server(self._handle_request, "0.0.0.0", port))
192
+ loop.run_forever()
@@ -0,0 +1,183 @@
1
+ Metadata-Version: 2.1
2
+ Name: micropidash
3
+ Version: 1.0.0
4
+ Summary: A lightweight web dashboard for MicroPython (ESP32, Pico W)
5
+ Home-page: https://github.com/kritishmohapatra/micropidash
6
+ Author: Kritish Mohapatra
7
+ Author-email: kritishmohapatra06norisk@gmail.com
8
+ License: MIT
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+
15
+ # 🚀 micropidash: Lightweight MicroPython IoT Dashboard
16
+
17
+ **micropidash** is a high-performance, asynchronous web dashboard library specifically designed for microcontrollers like the **Raspberry Pi Pico 2W** (RP2350/RP2040) and ESP32. It enables the creation of real-time, responsive web interfaces for IoT projects using minimal MicroPython code.
18
+
19
+ <p align="center">
20
+ <a href="https://micropython.org/"><img src="https://img.shields.io/badge/MicroPython-✓-green?logo=micropython&logoColor=white" alt="MicroPython"></a>
21
+ <a href="https://www.espressif.com/en/products/socs/esp32"><img src="https://img.shields.io/badge/ESP32-Supported-orange?logo=espressif&logoColor=white" alt="ESP32"></a>
22
+ <a href="https://www.raspberrypi.com/products/raspberry-pi-pico/"><img src="https://img.shields.io/badge/Raspberry%20Pi%20Pico%20 2 W-Compatible-darkgreen?logo=raspberrypi&logoColor=white" alt="Pico 2 W"></a>
23
+ <a href="https://github.com/kritishmohapatra/micropython-sevenseg/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green?logo=open-source-initiative&logoColor=white" alt="License"></a>
24
+
25
+
26
+ </p>
27
+
28
+ **Author:** [Kritish Mohapatra]
29
+
30
+
31
+ ---
32
+
33
+ ## ✨ Key Features
34
+ * **Asynchronous Engine:** Built on `uasyncio` for non-blocking, multi-tasking performance.
35
+ * **Real-Time Sync:** AJAX-based polling ensures all connected devices (Mobile & Laptop) stay synced without page refreshes.
36
+ * **Client-Side Theming:** Every connected user can independently toggle between Dark and Light modes.
37
+ * **Order Preservation:** Uses alphabetical sorting for widget IDs to ensure your layout stays exactly as intended.
38
+ * **Memory Efficient:** Optimized for devices with limited RAM, featuring chunked data transmission and frequent garbage collection.
39
+
40
+ ---
41
+
42
+ ## 📦 Installation
43
+
44
+ 1. Upload `micropidash.py` to your microcontroller's root directory.
45
+ 2. Create a `main.py` file to implement your project logic.
46
+ 3. Ensure your device is connected to a stable 2.4GHz Wi-Fi network.
47
+
48
+ ---
49
+ ## 📂 Project Structure
50
+ ├── micropidash/
51
+ │ ├── init.py
52
+ │ └── micropidash.py
53
+
54
+ ├── examples/
55
+ | ├── basic_1.py
56
+ │ └── esp_32_example.py
57
+
58
+ ├── README.md
59
+ └── LICENSE
60
+ ## 📚 API Documentation
61
+
62
+ ### `Dashboard(title)`
63
+ Creates a new dashboard instance with the specified title.
64
+ * **title**: (String) The name displayed at the top of your web dashboard.
65
+
66
+ ---
67
+
68
+ ### `add_toggle(id, label)`
69
+ Adds a binary switch (On/Off) to the dashboard.
70
+ * **id**: (String) Unique identifier for the widget. Also used for alphabetical sorting on the UI.
71
+ * **label**: (String) The text displayed above the switch.
72
+
73
+ ---
74
+
75
+ ### `add_label(id, label)`
76
+ Adds a text box designed for displaying live sensor data or status strings.
77
+ * **id**: (String) Unique identifier for the widget.
78
+ * **label**: (String) The descriptive text for the data being shown.
79
+
80
+ ---
81
+
82
+ ### `add_level(id, label, color)`
83
+ Adds a graphical progress bar, perfect for humidity, tank levels, or battery percentage.
84
+ * **id**: (String) Unique identifier for the widget.
85
+ * **label**: (String) The descriptive text for the progress bar.
86
+ * **color**: (Hex/CSS Color) The color of the fill bar (e.g., `#2196F3` or `red`).
87
+ * **Value Range**: Expects an integer between $0$ and $100$.
88
+
89
+ ---
90
+
91
+ ### `update_value(id, value)`
92
+ Injects new data into an existing widget. This change is pushed instantly to all connected web clients via the next poll.
93
+ * **id**: (String) The ID of the widget you want to update.
94
+ * **value**: (String/Int) The new data to display.
95
+
96
+ ---
97
+ ## 🚀 Quick Start (Simple Example)
98
+
99
+ Use this minimal example to test your connection and ensure the dashboard is being served correctly on your local network.
100
+
101
+ ```python
102
+ from micropidash import Dashboard
103
+ import network
104
+
105
+ # 1. WiFi Setup
106
+ wlan = network.WLAN(network.STA_IF)
107
+ wlan.active(True)
108
+
109
+ wlan.connect('YOUR_SSID', 'YOUR_PASSWORD')
110
+
111
+ print("Connecting...")
112
+ while not wlan.isconnected(): pass
113
+ print("Connected! IP:", wlan.ifconfig()[0])
114
+
115
+ # 2. Dashboard Initialization
116
+ dash = Dashboard("MicroPiDash v1.0")
117
+
118
+ # 3. Adding Basic Widgets
119
+ dash.add_toggle("led", "Test Switch") # A binary toggle
120
+ dash.add_label("status", "System Status") # A text display
121
+ dash.add_level("level", "Signal Strength") # A progress bar (0-100)
122
+
123
+ # 4. Start the Web Server
124
+ # Access the dashboard via the IP address printed above
125
+ dash.run()
126
+ ```
127
+
128
+ ### 🔌 ESP32 Onboard LED Example
129
+
130
+
131
+ ```python
132
+ import machine, network, uasyncio as asyncio
133
+ from micropidash import Dashboard
134
+
135
+ # 1. ESP32 Pin Setup (Most boards use GPIO 2 for built-in LED)
136
+ led = machine.Pin(2, machine.Pin.OUT)
137
+
138
+ # 2. WiFi Connectivity
139
+ wlan = network.WLAN(network.STA_IF)
140
+ wlan.active(True)
141
+ wlan.connect('YOUR_SSID', 'YOUR_PASSWORD')
142
+
143
+ print("Connecting...")
144
+ while not wlan.isconnected(): pass
145
+ print("Server Live at IP:", wlan.ifconfig()[0])
146
+
147
+ # 3. Dashboard Configuration
148
+ dash = Dashboard("ESP32 Control Hub")
149
+ dash.add_toggle("1_led", "Built-in LED")
150
+ dash.add_label("2_status", "Live Status")
151
+
152
+ # 4. Hardware & Web UI Sync Task
153
+ async def sync_task():
154
+ while True:
155
+ # Dashboard UI state ko physical LED se link karna
156
+ led.value(dash.elements["1_led"]["value"])
157
+
158
+ # Dashboard par status update bhejni
159
+ state = "GLOWING" if led.value() else "OFF"
160
+ dash.update_value("2_status", f"LED is {state}")
161
+
162
+ await asyncio.sleep(0.5)
163
+
164
+ # 5. Execution
165
+ async def main():
166
+ asyncio.create_task(sync_task())
167
+ dash.run()
168
+
169
+ asyncio.run(main())
170
+ ```
171
+ ## 🤝 Contributing
172
+ As an **Electrical Engineering student**, I built **micropidash** to simplify MicroPython IoT development and bridge the gap between hardware and web interfaces.
173
+
174
+ If you find bugs, have feature ideas, or want to optimize the code further, feel free to open an **issue** or submit a **pull request**! Let's build the future of embedded systems together.
175
+
176
+ ---
177
+ ## 🌐 Author
178
+
179
+ **Kritish Mohapatra**
180
+ 🔗 [GitHub](https://github.com/kritishmohapatra)
181
+ 📧 kritishmohapatra06norisk@gmail.com
182
+
183
+ ✨ *Made with passion for Embedded Systems and MicroPython learners.*
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ micropidash/__init__.py
6
+ micropidash/micropidash.py
7
+ micropidash.egg-info/PKG-INFO
8
+ micropidash.egg-info/SOURCES.txt
9
+ micropidash.egg-info/dependency_links.txt
10
+ micropidash.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ micropidash
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools<69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,19 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="micropidash",
5
+ version="1.0.0",
6
+ description="A lightweight web dashboard for MicroPython (ESP32, Pico W)",
7
+ long_description=open("README.md", encoding="utf-8").read(),
8
+ long_description_content_type="text/markdown",
9
+ author="Kritish Mohapatra",
10
+ author_email="kritishmohapatra06norisk@gmail.com",
11
+ url="https://github.com/kritishmohapatra/micropidash",
12
+ license="MIT",
13
+ packages=find_packages(),
14
+ classifiers=[
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ],
19
+ )