1
1
2
2
##
3
- # @file mpy_rgb_ramp .py
3
+ # @file mpy_tmp117_server_ap .py
4
4
# @brief This MicroPython file contains a full implementation of a web server that reads
5
5
# temperature data from a TMP117 sensor and sends it to a client via a websocket.
6
6
# The complementary client code that is served can be found in the static directory.
19
19
# @license MIT
20
20
#
21
21
22
+ # -------------------- Import the necessary modules --------------------
22
23
from microdot import Microdot , send_file
23
24
from microdot .websocket import with_websocket
24
25
import json
25
26
import asyncio
26
27
import wlan_ap
27
28
import qwiic_tmp117
28
29
29
- # defines
30
+ # -------------------- Constants --------------------
30
31
kDoAlerts = True # Set to False to disable checking alerts. This will speed up temperature reads.
31
- kApSsid = "iot_redboard_tmp117"
32
- kApPass = "thermo_wave2"
32
+ kApSsid = "iot_redboard_tmp117" # This will be the SSID of the AP, the "Network Name" that you'll see when you scan for networks on your client device
33
+ kApPass = "thermo_wave2" # This will be the password for the AP, that you'll use when you connect to the network from your client device
33
34
34
- # fahrenheit to celcius
35
+ # -------------------- Shared Variables --------------------
36
+ # Create instance of our TMP117 device
37
+ myTMP117 = qwiic_tmp117 .QwiicTMP117 ()
38
+
39
+ # Use the Microdot framework to create a web server
40
+ app = Microdot ()
41
+
42
+ # -------------------- Fahrenheit to Celcius --------------------
35
43
def f_to_c (degreesF ):
36
44
return (degreesF - 32 ) * 5 / 9
37
45
38
46
def c_to_f (degreesC ):
39
47
return (degreesC * 9 / 5 ) + 32
40
48
41
- # Set up the AP
42
- print ("Formatting WIFI" )
43
- accessPointIp = wlan_ap .config_wlan_as_ap (kApSsid , kApPass )
44
- print ("WiFi Configured!" )
45
- # print("Active config: ", config)
46
-
47
- # Set up the TMP117
48
- print ("Setting up TMP117" )
49
- # Create instance of device
50
- myTMP117 = qwiic_tmp117 .QwiicTMP117 ()
49
+ # -------------------- Set up the TMP117 --------------------
50
+ def config_TMP117 (tmp117Device , doAlerts ):
51
+ """
52
+ @brief Function to configure the TMP117 sensor
51
53
52
- # Check if it's connected
53
- if myTMP117 .is_connected () == False :
54
- print ("The TMP117 device isn't connected to the system. Please check your connection" )
55
- exit ()
54
+ @param tmp117Device The QwiicTMP117 object to be configured.
56
55
57
- print ("TMP117 device connected!" )
58
-
59
- # Initialize the device
60
- myTMP117 .begin ()
56
+ @details
57
+ - This function initializes the TMP117 sensor and sets the high and low temperature limits.
58
+ - If doAlerts is set to True, the TMP117 will be set to alert mode.
59
+ """
60
+ print ("Setting up TMP117" )
61
+ # Create instance of device
62
+ tmp117Device = qwiic_tmp117 .QwiicTMP117 ()
61
63
62
- if kDoAlerts :
63
- myTMP117 .set_high_limit (25.50 )
64
- myTMP117 .set_low_limit (25 )
64
+ # Check if it's connected
65
+ if tmp117Device .is_connected () == False :
66
+ print ("The TMP117 device isn't connected to the system. Please check your connection" )
67
+ exit ()
65
68
66
- # Set to kAlertMode or kThermMode
67
- myTMP117 .set_alert_function_mode (myTMP117 .kAlertMode )
69
+ print ("TMP117 device connected!" )
70
+
71
+ # Initialize the device
72
+ tmp117Device .begin ()
68
73
69
- print ("TMP117 Configured!" )
74
+ if doAlerts :
75
+ tmp117Device .set_high_limit (25.50 )
76
+ tmp117Device .set_low_limit (25 )
70
77
71
- print ("\n Navigate to http://" + accessPointIp + ":5000/ to view the TMP117 temperature readings\n " )
78
+ # Set to kAlertMode or kThermMode
79
+ tmp117Device .set_alert_function_mode (tmp117Device .kAlertMode )
72
80
73
- # Use the Microdot framework to create a web server
74
- app = Microdot ()
81
+ print ("TMP117 Configured!" )
75
82
76
- # Route our root page to the index.html file
83
+ # -------------------- Asynchronous Microdot Functions --------------------
77
84
@app .route ('/' )
78
85
async def index (request ):
86
+ """
87
+ @brief Function/Route to the index.html file to serve it as the root page
88
+
89
+ @param request The Microdot "Request" object containing details about a client HTTP request.
90
+
91
+ @details
92
+ - This function is asynchronous and is called when a client requests the root "/" path from our server.
93
+ - The requested file is located in the "static" directory.
94
+ - The requested file is sent to the client.
95
+ """
79
96
return send_file ('static/index.html' )
80
-
81
- gTempSocket = None
82
97
83
98
# Create server-side coroutine for websocket to send temperature data to the client
84
- async def send_temperature ():
99
+ async def send_temperature (tempSocket ):
100
+ """
101
+ @brief Server-side coroutine for websocket to send temperature data to the client.
102
+
103
+ @param tempSocket The Microdot "WebSocket" object containing details about the websocket connection.
104
+
105
+ @details
106
+ - This coroutine is asynchronous and is started when the client connects to the websocket.
107
+ - It sends temperature data to the client every 0.5 seconds.
108
+ """
85
109
print ("Spawned send_temperature coroutine" )
86
110
while True :
87
111
if myTMP117 .data_ready ():
@@ -99,23 +123,35 @@ async def send_temperature():
99
123
data ['limitH' ] = c_to_f (myTMP117 .get_high_limit ())
100
124
101
125
data = json .dumps (data ) # Convert to a json string to be parsed by client
102
- await gTempSocket .send (data )
126
+ await tempSocket .send (data )
103
127
await asyncio .sleep (0.5 )
104
128
105
- # Create server-side coroutine for websocket to receive changes to the high and low temperature limits from the client
106
- # Since our client code creates a websocket connection to the /temperature route, we'll define our websocket coroutine there
107
129
@app .route ('/temperature' )
108
130
@with_websocket
109
131
async def handle_limits (request , ws ):
132
+ """
133
+ @brief Server-side coroutine for websocket to receive changes to the high and low temperature limits from the client
134
+
135
+ Since our client code creates a websocket connection to the /temperature route, we'll define our websocket coroutine there
136
+
137
+ @param request The Microdot "Request" object containing details about a client HTTP request.
138
+ @param ws The Microdot "WebSocket" object containing details about the websocket connection.
139
+
140
+ @details
141
+ - This function is asynchronous and is called when a client requests a file from the server.
142
+ - The requested file is located in the "static" directory.
143
+ - The requested file is sent to the client.
144
+ """
110
145
print ("Spawned handle_limits coroutine" )
111
- global gTempSocket
112
- gTempSocket = ws # Let's save the websocket object so we can send data to it from our send_temperature coroutine
113
146
# We won't start sending data until now, when we know the client has connected to the websocket
114
- asyncio .create_task (send_temperature ())
147
+ # Let's start the send_temperature coroutine and pass it the websocket object
148
+ asyncio .create_task (send_temperature (ws ))
115
149
while True :
150
+ # Lets block here until we receive a message from the client
116
151
data = await ws .receive ()
117
152
print ("Received new limit: " + data )
118
153
limitJson = json .loads (data )
154
+ # Check if the client sent a new high or low limit, and update the TMP117 accordingly
119
155
if 'low_input' in limitJson :
120
156
toSet = f_to_c (limitJson ['low_input' ])
121
157
print ("setting low limit to: " + str (toSet ))
@@ -127,18 +163,41 @@ async def handle_limits(request, ws):
127
163
myTMP117 .set_high_limit (toSet )
128
164
print ("New high limit: " + str (myTMP117 .get_high_limit ()))
129
165
130
- # Route to the static folder to serve up the HTML and CSS files
131
166
@app .route ('/static/<path:path>' )
132
167
async def static (request , path ):
168
+ """
169
+ @brief Function/Route to the static folder to serve up the HTML and CSS files
170
+
171
+ @param request The Microdot "Request" object containing details about a client HTTP request.
172
+ @param path The path to the requested file.
173
+
174
+ @details
175
+ - This function is asynchronous and is called when a client requests a file from the server.
176
+ - The requested file is located in the "static" directory.
177
+ - The requested file is sent to the client.
178
+ """
133
179
if '..' in path :
134
180
# directory traversal is not allowed
135
181
return 'Not found' , 404
136
182
return send_file ('static/' + path )
137
183
138
184
def run ():
139
185
"""
140
- @brief Run the web server
141
- """
186
+ @brief Configure the WLAN, and TMP117 and run the web server
187
+ """
188
+ # Set up the AP
189
+ print ("Formatting WIFI" )
190
+ accessPointIp = wlan_ap .config_wlan_as_ap (kApSsid , kApPass )
191
+ print ("WiFi Configured!" )
192
+
193
+ # Set up the TMP117
194
+ config_TMP117 (myTMP117 , kDoAlerts )
195
+
196
+ # Print the IP address of the server, port 5000 is the default port for Microdot
197
+ print ("\n Navigate to http://" + accessPointIp + ":5000/ to view the TMP117 temperature readings\n " )
198
+
199
+ # Start the web server
142
200
app .run ()
143
201
202
+ # Finally after we've defined all our functions, we'll call the run function to start the server!
144
203
run ()
0 commit comments