implement async handlers for pulsing pw_sw

This commit is contained in:
Arthur Lu 2024-02-13 21:05:01 -08:00
parent c0e774c08c
commit 426c04116f
10 changed files with 176 additions and 147 deletions

2
.gitignore vendored
View File

@ -1,3 +1,3 @@
**/build/* **/build/*
**/secret.h **/secret.h
**/htmldata.c **/wwwdata.c

View File

@ -1,16 +1,13 @@
#TOPTARGETS := all clean .PHONY: all clean build makefsdata
SUBDIRS := build all: clean makefsdata build
all: makefsdata $(SUBDIRS) clean:
$(MAKE) -C build/ clean
rm -rf wwwdata.c
makefsdata: makefsdata:
python3 makefsdata.py python3 makefsdata.py
clean: $(SUBDIRS) build:
rm -rf htmldata.c $(MAKE) -C build/
$(SUBDIRS):
$(MAKE) -C $@ $(MAKECMDGOALS)
.PHONY: all makefsdata clean $(SUBDIRS)

44
cgi.h
View File

@ -1,32 +1,40 @@
#ifndef CGI_H
#define CGI_H
#include "lwip/apps/httpd.h" #include "lwip/apps/httpd.h"
#include "pico/cyw43_arch.h" #include "pico/cyw43_arch.h"
#include "handlers.h"
// CGI handler which is run when a request for /led.cgi is detected const char * cgi_power_handler (int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
const char * cgi_led_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) // Check if an request for power has been made (/power?requested_state=x)
{ if (strcmp(pcParam[0] , "requested_state") == 0){
// Check if an request for LED has been made (/led.cgi?led=x)
if (strcmp(pcParam[0] , "led") == 0){
// Look at the argument to check if LED is to be turned on (x=1) or off (x=0) // Look at the argument to check if LED is to be turned on (x=1) or off (x=0)
if(strcmp(pcValue[0], "0") == 0) if(strcmp(pcValue[0], "0") == 0) {
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0); bmc_power_handler(false);
else if(strcmp(pcValue[0], "1") == 0) }
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1); else if(strcmp(pcValue[0], "1") == 0) {
bmc_power_handler(true);
}
} }
// Send the index page back to the user // Send the index page back to the user
return "/index.shtml"; return "/power.ssi";
}
const char * cgi_status_handler (int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) {
return "/status.ssi";
} }
// tCGI Struct
// Fill this with all of the CGI requests and their respective handlers
static const tCGI cgi_handlers[] = { static const tCGI cgi_handlers[] = {
{ {
// Html request for "/led.cgi" triggers cgi_handler "/power", cgi_power_handler
"/led.cgi", cgi_led_handler
}, },
{
"/status", cgi_status_handler
}
}; };
void cgi_init(void) void cgi_init(void) {
{ http_set_cgi_handlers(cgi_handlers, 2);
http_set_cgi_handlers(cgi_handlers, 1);
} }
#endif

38
handlers.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef HANDLERS_H
#define HANDLERS_H
#include "pico/stdlib.h"
#define PW_SW_DELAY_MS 100
#define STATE_UPDATE_REPEAT_DELAY_MS 100
bool current_state = false;
int64_t pw_sw_on_async (alarm_id_t id, void * user_data) {
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
return 0; // do not reschedule alarm
}
int64_t pw_sw_off_async (alarm_id_t id, void * user_data) {
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
return 0; // do not reschedule alarm
}
bool update_current_state_async (repeating_timer_t * rt) {
return true; // continue repeating alarm
}
bool bmc_power_handler (bool requested_state) {
if (requested_state != current_state) {
add_alarm_in_ms(0, pw_sw_on_async, NULL, true);
add_alarm_in_ms(PW_SW_DELAY_MS, pw_sw_off_async, NULL, true);
}
}
struct repeating_timer * bmc_handler_init () {
struct repeating_timer * timer = malloc(sizeof(struct repeating_timer));
add_repeating_timer_ms(STATE_UPDATE_REPEAT_DELAY_MS, update_current_state_async, NULL, timer);
return timer;
}
#endif

View File

@ -1,20 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>PicoW Webserver</title>
</head>
<body> <h1>PicoW Webserver Tutorial</h1>
<br>
<h2>This bit is SSI:</h2>
<p>Voltage: <!--#volt--></p>
<p>Temp: <!--#temp--> C</p>
<p>LED is: <!--#led--></p>
<br>
<h2>This bit is CGI:</h2>
<a href="/led.cgi?led=1"><button>LED ON</button></a>
<a href="/led.cgi?led=0"><button>LED OFF</button></a>
<br>
<br>
<a href="/index.shtml">Refresh</a>
</body>
</html>

View File

@ -90,4 +90,4 @@
#define LWIP_HTTPD_CGI 1 #define LWIP_HTTPD_CGI 1
#define LWIP_HTTPD_SSI_INCLUDE_TAG 0 #define LWIP_HTTPD_SSI_INCLUDE_TAG 0
#define HTTPD_SERVER_PORT 80 #define HTTPD_SERVER_PORT 80
#define HTTPD_FSDATA_FILE "htmldata.c" #define HTTPD_FSDATA_FILE "wwwdata.c"

View File

@ -8,11 +8,11 @@ import os
import binascii import binascii
#Create file to write output into #Create file to write output into
output = open('htmldata.c', 'w') output = open('wwwdata.c', 'w')
#Traverse directory, generate list of files #Traverse directory, generate list of files
files = list() files = list()
os.chdir('./html_files') os.chdir('./www')
for(dirpath, dirnames, filenames) in os.walk('.'): for(dirpath, dirnames, filenames) in os.walk('.'):
files += [os.path.join(dirpath, file) for file in filenames] files += [os.path.join(dirpath, file) for file in filenames]
@ -47,6 +47,8 @@ for file in files:
header += "Content-type: text/css\r\n" header += "Content-type: text/css\r\n"
elif '.svg' in file: elif '.svg' in file:
header += "Content-type: image/svg+xml\r\n" header += "Content-type: image/svg+xml\r\n"
elif ".ssi" in file:
header += "Content-type: application/json\r\n"
else: else:
header += "Content-type: text/plain\r\n" header += "Content-type: text/plain\r\n"

24
ssi.h
View File

@ -1,9 +1,12 @@
#ifndef SSI_H
#define SSI_H
#include "lwip/apps/httpd.h" #include "lwip/apps/httpd.h"
#include "pico/cyw43_arch.h" #include "pico/cyw43_arch.h"
#include "hardware/adc.h" #include "hardware/adc.h"
#include "handlers.h"
// SSI tags - tag length limited to 8 bytes by default const char * ssi_tags[] = {"volt", "temp", "power"};
const char * ssi_tags[] = {"volt","temp","led"};
u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) { u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
size_t printed; size_t printed;
@ -21,31 +24,26 @@ u16_t ssi_handler(int iIndex, char *pcInsert, int iInsertLen) {
printed = snprintf(pcInsert, iInsertLen, "%f", tempC); printed = snprintf(pcInsert, iInsertLen, "%f", tempC);
} }
break; break;
case 2: // led case 2: // power
{ {
bool led_status = cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN); printed = snprintf(pcInsert, iInsertLen, "%d", current_state);
if(led_status == true){
printed = snprintf(pcInsert, iInsertLen, "ON");
}
else{
printed = snprintf(pcInsert, iInsertLen, "OFF");
}
} }
break; break;
default: default:
{
printed = 0; printed = 0;
}
break; break;
} }
return (u16_t) printed; return (u16_t) printed;
} }
// Initialise the SSI handler
void ssi_init() { void ssi_init() {
// Initialise ADC (internal pin)
adc_init(); adc_init();
adc_set_temp_sensor_enabled(true); adc_set_temp_sensor_enabled(true);
adc_select_input(4); adc_select_input(4);
http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags)); http_set_ssi_handler(ssi_handler, ssi_tags, LWIP_ARRAYSIZE(ssi_tags));
} }
#endif

1
www/power.ssi Normal file
View File

@ -0,0 +1 @@
{}

5
www/status.ssi Normal file
View File

@ -0,0 +1,5 @@
{
"volt": <!--#volt-->,
"temp": <!--#temp-->,
"power": <!--#power-->
}