forked from j3d1/fiatlux
		
	basic webconf
This commit is contained in:
		
							parent
							
								
									0814fc837f
								
							
						
					
					
						commit
						f89f3e1816
					
				
					 5 changed files with 1349 additions and 2 deletions
				
			
		|  | @ -8,13 +8,805 @@ | |||
| #include "mqtt.h" | ||||
| #include "lux.h" | ||||
| 
 | ||||
| #define LED_PIN 2 | ||||
| #define SWITCH_PIN 2 | ||||
| 
 | ||||
| void user_init(void) | ||||
| { | ||||
| /* Add extras/sntp component to makefile for this include to work */ | ||||
| #include <sntp.h> | ||||
| #include <time.h> | ||||
| 
 | ||||
| const int cs0 = 15; | ||||
| const int gpio4 = 4; | ||||
| const int gpio5 = 5; | ||||
| 
 | ||||
| const int led_number = 8; | ||||
| 
 | ||||
| static ws2812_pixel_t next_colour(int i) { | ||||
|     ws2812_pixel_t colour = {{0, 0, 0, 0}}; | ||||
|     if(i == 8) { | ||||
|         colour.white = 32; | ||||
|     } else { | ||||
|         colour.red = i & 1 ? 32 : 0; | ||||
|         colour.green = i & 2 ? 32 : 0; | ||||
|         colour.blue = i & 4 ? 32 : 0; | ||||
|     } | ||||
| 
 | ||||
|     return colour; | ||||
| } | ||||
| 
 | ||||
| void spi_dac(int id, int val) { | ||||
|     int dac_val = (val << 2) & 0x3FFC; | ||||
| 
 | ||||
|     spi_transfer_8(1, ~(0x00)); | ||||
|     gpio_write(cs0, 1); | ||||
|     gpio_write(cs0, 0); | ||||
|     spi_transfer_8(1, ~(0x01 << id)); | ||||
|     gpio_write(cs0, 1); | ||||
|     gpio_write(cs0, 0); | ||||
| 
 | ||||
|     spi_transfer_16(1, dac_val); | ||||
| 
 | ||||
|     spi_transfer_8(1, ~(0x00)); | ||||
|     gpio_write(cs0, 1); | ||||
|     gpio_write(cs0, 0); | ||||
|     spi_transfer_8(1, ~(0x01 << id)); | ||||
|     gpio_write(cs0, 1); | ||||
|     gpio_write(cs0, 0); | ||||
| } | ||||
| 
 | ||||
| /* This task uses the high level GPIO API (esp_gpio.h) to blink an LED.
 | ||||
|  * | ||||
|  */ | ||||
| void blinkenTask(void *pvParameters) { | ||||
| 
 | ||||
|     gpio_enable(9, GPIO_INPUT); | ||||
|     gpio_enable(10, GPIO_INPUT); | ||||
| 
 | ||||
|     ws2812_pixel_t pixels[led_number]; | ||||
|     ws2812_i2s_init(led_number, PIXEL_RGBW); | ||||
|     memset(pixels, 0, sizeof(ws2812_pixel_t) * led_number); | ||||
| 
 | ||||
|     gpio_enable(cs0, GPIO_OUTPUT); | ||||
|     gpio_enable(gpio4, GPIO_OUTPUT); | ||||
|     gpio_enable(gpio5, GPIO_OUTPUT); | ||||
|     spi_init(1, SPI_MODE0, SPI_FREQ_DIV_1M, 1, SPI_BIG_ENDIAN, 1); | ||||
|     while (1) { | ||||
|         gpio_write(gpio4, 1); | ||||
|         vTaskDelay(200 / portTICK_PERIOD_MS); | ||||
|         gpio_write(gpio4, 0); | ||||
|         for (int j = 0; j < 64; j++) { | ||||
|             for (int i = 0; i < 8; i++) | ||||
|                 spi_dac(i, 64 * j); | ||||
|             //printf("> %d\n", 64*j);
 | ||||
|             vTaskDelay(1000 / portTICK_PERIOD_MS); | ||||
|         } | ||||
|         for (int i = 0; i < 8; i++) | ||||
|             spi_dac(i, 0); | ||||
| 
 | ||||
|         gpio_write(gpio5, 1); | ||||
|         vTaskDelay(200 / portTICK_PERIOD_MS); | ||||
|         gpio_write(gpio5, 0); | ||||
| 
 | ||||
|         for (int c = 8; c >= 0; c--) { | ||||
| 
 | ||||
|             for (int i = 0; i < led_number; i++) { | ||||
|                 pixels[i] = next_colour(c); | ||||
|             } | ||||
|             ws2812_i2s_update(pixels, PIXEL_RGBW); | ||||
|             vTaskDelay(200 / portTICK_PERIOD_MS); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #define SNTP_SERVERS     "0.pool.ntp.org", "1.pool.ntp.org", \ | ||||
|                         "2.pool.ntp.org", "3.pool.ntp.org" | ||||
| 
 | ||||
| #define vTaskDelayMs(ms)    vTaskDelay((ms)/portTICK_PERIOD_MS) | ||||
| #define UNUSED_ARG(x)    (void)x | ||||
| 
 | ||||
| const gpio_inttype_t int_type = GPIO_INTTYPE_EDGE_NEG; | ||||
| 
 | ||||
| 
 | ||||
| const char *gpio_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[]) { | ||||
|     for (int i = 0; i < iNumParams; i++) { | ||||
|         if(strcmp(pcParam[i], "on") == 0) { | ||||
|             uint8_t gpio_num = atoi(pcValue[i]); | ||||
|             gpio_enable(gpio_num, GPIO_OUTPUT); | ||||
|             gpio_write(gpio_num, true); | ||||
|         } else if(strcmp(pcParam[i], "off") == 0) { | ||||
|             uint8_t gpio_num = atoi(pcValue[i]); | ||||
|             gpio_enable(gpio_num, GPIO_OUTPUT); | ||||
|             gpio_write(gpio_num, false); | ||||
|         } else if(strcmp(pcParam[i], "toggle") == 0) { | ||||
|             uint8_t gpio_num = atoi(pcValue[i]); | ||||
|             gpio_enable(gpio_num, GPIO_OUTPUT); | ||||
|             gpio_toggle(gpio_num); | ||||
|         } | ||||
|     } | ||||
|     return "/index.html"; | ||||
| } | ||||
| 
 | ||||
| void websocket_task(void *pvParameter) { | ||||
|     struct tcp_pcb *pcb = (struct tcp_pcb *) pvParameter; | ||||
| 
 | ||||
|     int connstarttime = xTaskGetTickCount(); | ||||
| 
 | ||||
|     for (;;) { | ||||
|         if(pcb == NULL || pcb->state != ESTABLISHED) { | ||||
|             printf("Connection closed, deleting task\n"); | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         //Global Info
 | ||||
|         { | ||||
|             struct timeval tv; | ||||
|             gettimeofday(&tv, NULL); | ||||
|             int uptime = xTaskGetTickCount() * portTICK_PERIOD_MS / 1000; | ||||
|             int heap = (int) xPortGetFreeHeapSize(); | ||||
|             uint32_t chip_id = sdk_system_get_chip_id(); | ||||
|             uint32_t flash_id = sdk_spi_flash_get_id(); | ||||
|             uint32_t flash_size = sdk_flashchip.chip_size >> 10; | ||||
|             char *hostname = NULL; | ||||
| 
 | ||||
|             sysparam_get_string("hostname", &hostname); | ||||
|             /* Generate response in JSON format */ | ||||
|             char response[160]; | ||||
|             int len = snprintf(response, sizeof(response), | ||||
|                                "{\"walltime\" : \"%d\"," | ||||
|                                "\"uptime\" : \"%d\"," | ||||
|                                " \"heap\" : \"%d\"," | ||||
|                                " \"chipid\" : \"%08x\"," | ||||
|                                " \"flashid\" : \"0x%08x\"," | ||||
|                                " \"flashsize\" : \"%u\"," | ||||
|                                " \"hostname\" : \"%s\"" | ||||
|                                "}", (int) tv.tv_sec, uptime, heap, chip_id, flash_id, flash_size, hostname); | ||||
|             free(hostname); | ||||
|             if(len < sizeof(response)) { | ||||
|                 LOCK_TCPIP_CORE(); | ||||
|                 websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); | ||||
|                 UNLOCK_TCPIP_CORE(); | ||||
|             } else | ||||
|                 printf("buffer too small 1"); | ||||
|         } | ||||
| 
 | ||||
|         vTaskDelay(2000 / portTICK_PERIOD_MS); | ||||
| 
 | ||||
| 
 | ||||
|         //Connection Info
 | ||||
|         { | ||||
|             struct timeval tv; | ||||
|             gettimeofday(&tv, NULL); | ||||
|             int connuptime = (xTaskGetTickCount() - connstarttime) * portTICK_PERIOD_MS / 1000; | ||||
| 
 | ||||
|             printf("conn %d: " | ||||
|             IPSTR | ||||
|             " <-> " | ||||
|             IPSTR | ||||
|             " \n", pcb->netif_idx, IP2STR(&pcb->local_ip), IP2STR(&pcb->remote_ip)); | ||||
|             char response[160]; | ||||
|             int len = snprintf(response, sizeof(response), | ||||
|                                "{\"connage\" : \"%d\"," | ||||
|             "\"clientip\" : \"" | ||||
|             IPSTR | ||||
|             "\"" | ||||
|             "}", connuptime, IP2STR(&pcb->remote_ip)); | ||||
|             if(len < sizeof(response)) { | ||||
|                 LOCK_TCPIP_CORE(); | ||||
|                 websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); | ||||
|                 UNLOCK_TCPIP_CORE(); | ||||
|             } else | ||||
|                 printf("buffer too small 1"); | ||||
|         } | ||||
| 
 | ||||
|         vTaskDelay(2000 / portTICK_PERIOD_MS); | ||||
| 
 | ||||
|         { | ||||
|             uint8_t opmode = sdk_wifi_get_opmode(); | ||||
|             const char *opmode_str = "??"; | ||||
|             switch (opmode) { | ||||
|                 case NULL_MODE: | ||||
|                     opmode_str = "Null"; | ||||
|                     break; | ||||
|                 case STATION_MODE: | ||||
|                     opmode_str = "Station"; | ||||
|                     break; | ||||
|                 case SOFTAP_MODE: | ||||
|                     opmode_str = "SoftAP"; | ||||
|                     break; | ||||
|                 case STATIONAP_MODE: | ||||
|                     opmode_str = "StationAP"; | ||||
|                     break; | ||||
|                 default: | ||||
|                     break; | ||||
|             } | ||||
| 
 | ||||
| 
 | ||||
|             /*struct sockaddr_storage addr;
 | ||||
|             socklen_t addr_len = sizeof(addr); | ||||
|             if (getpeername(s, (struct sockaddr *)&addr, &addr_len) == 0) { | ||||
|                 printf("peer\n"); | ||||
|             }*/ | ||||
| 
 | ||||
| 
 | ||||
|             if(opmode == SOFTAP_MODE || opmode == STATIONAP_MODE) { | ||||
|                 uint8_t hwaddr[6]; | ||||
|                 sdk_wifi_get_macaddr(SOFTAP_IF, hwaddr); | ||||
|                 struct ip_info info; | ||||
|                 sdk_wifi_get_ip_info(SOFTAP_IF, &info); | ||||
| 
 | ||||
|                 char *apssid = NULL; | ||||
|                 sysparam_get_string("wifi_ap_ssid", &apssid); | ||||
| 
 | ||||
|                 /* Generate response in JSON format */ | ||||
|                 char response[128]; | ||||
|                 int len = snprintf(response, sizeof(response), | ||||
|                                    "{\"opmode\" : \"%s\"," | ||||
|                                    " \"apssid\" : \"%s\"," | ||||
|                 " \"apip\" : \"" | ||||
|                 IPSTR | ||||
|                 "\"," | ||||
|                 " \"apmac\" : \"" | ||||
|                 MACSTR | ||||
|                 "\"" | ||||
|                 "}", opmode_str, apssid, IP2STR(&info.ip), MAC2STR(hwaddr)); | ||||
|                 free(apssid); | ||||
|                 if(len < sizeof(response)) { | ||||
|                     LOCK_TCPIP_CORE(); | ||||
|                     websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); | ||||
|                     UNLOCK_TCPIP_CORE(); | ||||
|                 } else | ||||
|                     printf("buffer too small 2"); | ||||
|             } | ||||
| 
 | ||||
|             vTaskDelay(2000 / portTICK_PERIOD_MS); | ||||
| 
 | ||||
|             if(opmode == STATION_MODE || opmode == STATIONAP_MODE) { | ||||
|                 uint8_t hwaddr[6]; | ||||
|                 sdk_wifi_get_macaddr(STATION_IF, hwaddr); | ||||
|                 struct ip_info info; | ||||
|                 sdk_wifi_get_ip_info(STATION_IF, &info); | ||||
|                 char *stassid = NULL; | ||||
|                 sysparam_get_string("wifi_sta_ssid", &stassid); | ||||
| 
 | ||||
|                 /* Generate response in JSON format */ | ||||
|                 char response[128]; | ||||
|                 int len = snprintf(response, sizeof(response), | ||||
|                                    "{\"opmode\" : \"%s\"," | ||||
|                                    " \"stassid\" : \"%s\"," | ||||
|                 " \"staip\" : \"" | ||||
|                 IPSTR | ||||
|                 "\"," | ||||
|                 " \"stamac\" : \"" | ||||
|                 MACSTR | ||||
|                 "\"" | ||||
|                 "}", opmode_str, stassid, IP2STR(&info.ip), MAC2STR(hwaddr)); | ||||
|                 free(stassid); | ||||
|                 if(len < sizeof(response)) { | ||||
|                     LOCK_TCPIP_CORE(); | ||||
|                     websocket_write(pcb, (unsigned char *) response, len, WS_TEXT_MODE); | ||||
|                     UNLOCK_TCPIP_CORE(); | ||||
|                 } else | ||||
|                     printf("buffer too small 3"); | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         vTaskDelay(2000 / portTICK_PERIOD_MS); | ||||
|         //printf("9: %d\n",gpio_read(9));
 | ||||
|         //printf("10: %d\n",gpio_read(10));
 | ||||
|     } | ||||
| 
 | ||||
|     vTaskDelete(NULL); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * This function is called when websocket frame is received. | ||||
|  * | ||||
|  * Note: this function is executed on TCP thread and should return as soon | ||||
|  * as possible. | ||||
|  */ | ||||
| void websocket_cb(struct tcp_pcb *pcb, char *data, u16_t data_len, uint8_t mode) { | ||||
| 
 | ||||
|     uint8_t response[3]; | ||||
|     uint16_t val = 0; | ||||
|     char cmd = '0'; | ||||
| 
 | ||||
|     uint8_t en = 0; | ||||
|     /*uint8_t ap_disable_if_sta = 0;
 | ||||
|     uint8_t ssid_hidden = 0; | ||||
|     uint8_t dns_enable = 0; | ||||
|     uint8_t mdns_enable = 0;*/ | ||||
| 
 | ||||
|     switch (data[0]) { | ||||
|         case 'V': // ADC
 | ||||
|             /* This should be done on a separate thread in 'real' applications */ | ||||
|             val = sdk_system_adc_read(); | ||||
|             cmd = 'V'; | ||||
|             break; | ||||
|         case 'R': // Restart
 | ||||
|             cmd = 'R'; | ||||
|             break; | ||||
|         case 'X': // Clear Config
 | ||||
|             cmd = 'X'; | ||||
|             break; | ||||
|         case 'D': // Disable LED
 | ||||
|             gpio_write(LED_PIN, true); | ||||
|             val = 0xDEAD; | ||||
|             cmd = 'G'; | ||||
|             break; | ||||
|         case 'E': // Enable LED
 | ||||
|             gpio_write(LED_PIN, false); | ||||
|             val = 0xBEEF; | ||||
|             cmd = 'G'; | ||||
|             break; | ||||
|         case 'S': { | ||||
|             if(data[1] == 'E') | ||||
|                 en = 1; | ||||
|             char *ssid = &data[2]; | ||||
|             size_t ssid_len = strlen(ssid); | ||||
|             char *password = &data[3 + ssid_len]; | ||||
|             size_t password_len = strlen(password); | ||||
| 
 | ||||
|             sysparam_set_int8("wifi_sta_enable", en); | ||||
|             sysparam_set_string("wifi_sta_ssid", ssid); | ||||
|             sysparam_set_string("wifi_sta_password", password); | ||||
|         } | ||||
|             cmd = 'S'; | ||||
|             break; | ||||
|         case 'A': { | ||||
|             if(data[1] == 'E') | ||||
|                 en = 1; | ||||
|             char *ssid = &data[2]; | ||||
|             size_t ssid_len = strlen(ssid); | ||||
|             char *password = &data[3 + ssid_len]; | ||||
|             size_t password_len = strlen(password); | ||||
| 
 | ||||
|             sysparam_set_int8("wifi_ap_enable", en); | ||||
|             sysparam_set_string("wifi_ap_ssid", ssid); | ||||
|             sysparam_set_string("wifi_ap_password", password); | ||||
| 
 | ||||
|             //sysparam_set_int8("wifi_ap_disable_if_sta", ap_disable_if_sta);
 | ||||
|             //sysparam_set_int8("wifi_ap_ssid_hidden", ssid_hidden);
 | ||||
|             //sysparam_set_int8("wifi_ap_dns", dns_enable);
 | ||||
|             //sysparam_set_int8("wifi_ap_mdns", mdns_enable);
 | ||||
|         } | ||||
|             cmd = 'A'; | ||||
|             break; | ||||
|         default: | ||||
|             printf("[websocket_callback]:\n%.*s\n", (int) data_len, (char *) data); | ||||
|             printf("Unknown command\n"); | ||||
|             val = 0; | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     response[2] = (uint8_t) val; | ||||
|     response[1] = val >> 8; | ||||
|     response[0] = cmd; | ||||
| 
 | ||||
|     websocket_write(pcb, response, 3, WS_BIN_MODE); | ||||
| 
 | ||||
|     if(data[0] == 'R') { // Restart
 | ||||
|         vTaskDelay(500 / portTICK_PERIOD_MS); | ||||
|         vPortEnterCritical(); | ||||
|         sdk_system_restart(); | ||||
|     } else if(data[0] == 'X') { // Clear Config
 | ||||
|         vTaskDelay(500 / portTICK_PERIOD_MS); | ||||
|         vPortEnterCritical(); | ||||
|         uint32_t num_sectors = 5 + DEFAULT_SYSPARAM_SECTORS; | ||||
|         uint32_t start = sdk_flashchip.chip_size - num_sectors * sdk_flashchip.sector_size; | ||||
|         for (uint32_t i = 0; i < num_sectors; i++) { | ||||
|             spiflash_erase_sector(start + i * sdk_flashchip.sector_size); | ||||
|         } | ||||
|         sdk_system_restart(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * This function is called when new websocket is open and | ||||
|  * creates a new websocket_task if requested URI equals '/stream'. | ||||
|  */ | ||||
| void websocket_open_cb(struct tcp_pcb *pcb, const char *uri) { | ||||
|     printf("WS URI: %s\n", uri); | ||||
|     if(!strcmp(uri, "/stream")) { | ||||
|         xTaskCreate(&websocket_task, "websocket_task", 512, (void *) pcb, 2, NULL); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void httpd_task(void *pvParameters) { | ||||
|     tCGI pCGIs[] = { | ||||
|             {"/gpio", (tCGIHandler) gpio_cgi_handler}, | ||||
|     }; | ||||
| 
 | ||||
|     /* register handlers and start the server */ | ||||
|     http_set_cgi_handlers(pCGIs, sizeof(pCGIs) / sizeof(pCGIs[0])); | ||||
|     websocket_register_callbacks((tWsOpenHandler) websocket_open_cb, | ||||
|                                  (tWsHandler) websocket_cb); | ||||
|     httpd_init(); | ||||
| 
 | ||||
|     for (;;); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void sntp_task(void *pvParameters) { | ||||
|     const char *servers[] = {SNTP_SERVERS}; | ||||
|     UNUSED_ARG(pvParameters); | ||||
| 
 | ||||
|     /* Wait until we have joined AP and are assigned an IP */ | ||||
|     while (sdk_wifi_station_get_connect_status() != STATION_GOT_IP) { | ||||
|         vTaskDelayMs(100); | ||||
|     } | ||||
| 
 | ||||
|     /* Start SNTP */ | ||||
|     printf("Starting SNTP... "); | ||||
|     /* SNTP will request an update each 5 minutes */ | ||||
|     sntp_set_update_delay(5 * 60000); | ||||
|     /* Set GMT+1 zone, daylight savings off */ | ||||
|     const struct timezone tz = {1 * 60, 1}; | ||||
|     /* SNTP initialization */ | ||||
|     sntp_initialize(&tz); | ||||
|     /* Servers must be configured right after initialization */ | ||||
|     sntp_set_servers(servers, sizeof(servers) / sizeof(char *)); | ||||
|     printf("DONE!\n"); | ||||
| 
 | ||||
|     /* Print date and time each 5 seconds */ | ||||
|     while (1) { | ||||
|         vTaskDelayMs(5000); | ||||
|         //time_t ts = time(NULL);
 | ||||
|         //int t = ts;
 | ||||
|         //printf("TIME: %d %d %s", t,(int) day_seconds(), ctime(&ts));
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void dns_task(void *pvParameters) { | ||||
|     char *wifi_ap_ip_addr = NULL; | ||||
|     sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); | ||||
|     if(!wifi_ap_ip_addr) { | ||||
|         printf("dns: no ip address\n"); | ||||
|         vTaskDelete(NULL); | ||||
|     } | ||||
|     ip4_addr_t server_addr; | ||||
|     server_addr.addr = ipaddr_addr(wifi_ap_ip_addr); | ||||
| 
 | ||||
| #if LWIP_IPV6 | ||||
|     int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); | ||||
|     struct sockaddr_in6 serv_addr; | ||||
|     memset(&serv_addr, '0', sizeof(serv_addr)); | ||||
|     serv_addr.sin6_family = AF_INET6; | ||||
|     serv_addr.sin6_port = htons(53); | ||||
|     serv_addr.sin6_flowinfo = 0; | ||||
|     serv_addr.sin6_addr = in6addr_any; | ||||
|     serv_addr.sin6_scope_id = IP6_NO_ZONE; | ||||
| #else | ||||
|     int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||||
|     struct sockaddr_in serv_addr; | ||||
|     memset(&serv_addr, '0', sizeof(serv_addr)); | ||||
|     serv_addr.sin_family = AF_INET; | ||||
|     serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); | ||||
|     serv_addr.sin_port = htons(53); | ||||
| #endif | ||||
|     bind(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); | ||||
| 
 | ||||
|     const struct ifreq ifreq0 = {"en0"}; | ||||
|     const struct ifreq ifreq1 = {"en1"}; | ||||
|     setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, | ||||
|                sdk_wifi_get_opmode() == STATIONAP_MODE ? &ifreq1 : &ifreq0, | ||||
|                sizeof(ifreq0)); | ||||
| 
 | ||||
|     for (;;) { | ||||
|         char buffer[96]; | ||||
|         struct sockaddr_storage src_addr; | ||||
|         socklen_t src_addr_len = sizeof(src_addr); | ||||
|         ssize_t count = recvfrom(fd, buffer, sizeof(buffer), 0, (struct sockaddr *) &src_addr, &src_addr_len); | ||||
| 
 | ||||
|         /* Drop messages that are too large to send a response in the buffer */ | ||||
|         if(count > 0 && count <= sizeof(buffer) - 16) { | ||||
|             size_t qname_len = strlen(buffer + 12) + 1; | ||||
|             uint32_t reply_len = 2 + 10 + qname_len + 16 + 4; | ||||
| 
 | ||||
|             char *head = buffer + 2; | ||||
|             *head++ = 0x80; // Flags
 | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x00; // Q count
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // A count
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // Auth count
 | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x00; // Add count
 | ||||
|             *head++ = 0x00; | ||||
|             head += qname_len; | ||||
|             *head++ = 0x00; // Q type
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // Q class
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0xC0; // LBL offs
 | ||||
|             *head++ = 0x0C; | ||||
|             *head++ = 0x00; // Type
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // Class
 | ||||
|             *head++ = 0x01; | ||||
|             *head++ = 0x00; // TTL
 | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x00; | ||||
|             *head++ = 0x78; | ||||
|             *head++ = 0x00; // RD len
 | ||||
|             *head++ = 0x04; | ||||
|             *head++ = ip4_addr1(&server_addr); | ||||
|             *head++ = ip4_addr2(&server_addr); | ||||
|             *head++ = ip4_addr3(&server_addr); | ||||
|             *head++ = ip4_addr4(&server_addr); | ||||
| 
 | ||||
|             sendto(fd, buffer, reply_len, 0, (struct sockaddr *) &src_addr, src_addr_len); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| const char *wificfg_default_ssid = "fiatlux_%02X%02X%02X"; | ||||
| const char *wificfg_default_password = "fiatlux02"; | ||||
| const char *wificfg_default_hostname = "fiatlux-%02x%02x%02x"; | ||||
| 
 | ||||
| void user_init(void) { | ||||
|     uart_set_baud(0, 115200); | ||||
|     printf("SDK version: %s\n", sdk_system_get_sdk_version()); | ||||
| 
 | ||||
|     sdk_wifi_set_sleep_type(WIFI_SLEEP_MODEM); | ||||
| 
 | ||||
|     system_init_config(); | ||||
|     char *wifi_sta_ssid = NULL; | ||||
|     char *wifi_sta_password = NULL; | ||||
|     char *wifi_ap_ssid = NULL; | ||||
|     char *wifi_ap_password = NULL; | ||||
| 
 | ||||
|     /* Default a hostname. */ | ||||
|     char *hostname = NULL; | ||||
|     sysparam_get_string("hostname", &hostname); | ||||
|     if(!hostname && wificfg_default_hostname) { | ||||
|         uint8_t macaddr[6]; | ||||
|         char name[32]; | ||||
|         sdk_wifi_get_macaddr(1, macaddr); | ||||
|         snprintf(name, sizeof(name), wificfg_default_hostname, macaddr[3], | ||||
|                  macaddr[4], macaddr[5]); | ||||
|         sysparam_set_string("hostname", name); | ||||
|     } | ||||
|     if(hostname) { | ||||
|         free(hostname); | ||||
|     } | ||||
| 
 | ||||
|     sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); | ||||
|     sysparam_get_string("wifi_ap_password", &wifi_ap_password); | ||||
|     sysparam_get_string("wifi_sta_ssid", &wifi_sta_ssid); | ||||
|     sysparam_get_string("wifi_sta_password", &wifi_sta_password); | ||||
| 
 | ||||
|     int8_t wifi_sta_enable = 1; | ||||
|     int8_t wifi_ap_enable = 1; | ||||
|     sysparam_get_int8("wifi_sta_enable", &wifi_sta_enable); | ||||
|     sysparam_get_int8("wifi_ap_enable", &wifi_ap_enable); | ||||
| 
 | ||||
|     if(!wifi_sta_enable) | ||||
|         wifi_ap_enable = 1; | ||||
| 
 | ||||
|     int8_t wifi_sta_disabled_restarts = 0; | ||||
|     sysparam_get_int8("wifi_sta_disabled_restarts", &wifi_sta_disabled_restarts); | ||||
|     if(wifi_sta_disabled_restarts > 0) { | ||||
|         wifi_sta_enable = 0; | ||||
|         wifi_sta_disabled_restarts--; | ||||
|         sysparam_set_int8("wifi_sta_disabled_restarts", wifi_sta_disabled_restarts); | ||||
|     } | ||||
| 
 | ||||
|     int8_t wifi_ap_disabled_restarts = 0; | ||||
|     sysparam_get_int8("wifi_ap_disabled_restarts", &wifi_ap_disabled_restarts); | ||||
|     if(wifi_ap_disabled_restarts > 0) { | ||||
|         wifi_ap_enable = 0; | ||||
|         wifi_ap_disabled_restarts--; | ||||
|         sysparam_set_int8("wifi_ap_disabled_restarts", wifi_ap_disabled_restarts); | ||||
|     } | ||||
| 
 | ||||
|     /* Validate the configuration. */ | ||||
| 
 | ||||
|     if(wifi_sta_enable && (!wifi_sta_ssid || !wifi_sta_password || | ||||
|                            strlen(wifi_sta_ssid) < 1 || | ||||
|                            strlen(wifi_sta_ssid) > 32 || | ||||
|                            !wifi_sta_password || | ||||
|                            strlen(wifi_sta_password) < 8 || | ||||
|                            strlen(wifi_sta_password) >= 64)) { | ||||
|         wifi_sta_enable = 0; | ||||
|     } | ||||
| 
 | ||||
|     if(wifi_ap_enable) { | ||||
|         /* Default AP ssid and password. */ | ||||
|         if(!wifi_ap_ssid && wificfg_default_ssid) { | ||||
|             uint8_t macaddr[6]; | ||||
|             char ssid[32]; | ||||
|             sdk_wifi_get_macaddr(1, macaddr); | ||||
|             snprintf(ssid, sizeof(ssid), wificfg_default_ssid, macaddr[3], | ||||
|                      macaddr[4], macaddr[5]); | ||||
|             sysparam_set_string("wifi_ap_ssid", ssid); | ||||
|             sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid); | ||||
| 
 | ||||
|             if(!wifi_ap_password && wificfg_default_password) { | ||||
|                 sysparam_set_string("wifi_ap_password", wificfg_default_password); | ||||
|                 sysparam_get_string("wifi_ap_password", &wifi_ap_password); | ||||
|             } | ||||
|         } | ||||
|         printf("ssid: %s\n", wifi_ap_ssid); | ||||
| 
 | ||||
|         /* If the ssid and password are not valid then disable the AP interface. */ | ||||
|         if(!wifi_ap_ssid || strlen(wifi_ap_ssid) < 1 || strlen(wifi_ap_ssid) >= 32 || | ||||
|            !wifi_ap_password || strlen(wifi_ap_password) < 8 || strlen(wifi_ap_password) >= 64) { | ||||
|             printf("len err\n"); | ||||
|             wifi_ap_enable = 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     int8_t wifi_mode = NULL_MODE; | ||||
|     if(wifi_sta_enable && wifi_ap_enable) | ||||
|         wifi_mode = STATIONAP_MODE; | ||||
|     else if(wifi_sta_enable) | ||||
|         wifi_mode = STATION_MODE; | ||||
|     else if(wifi_ap_enable) | ||||
|         wifi_mode = SOFTAP_MODE; | ||||
|     sdk_wifi_set_opmode(wifi_mode); | ||||
| 
 | ||||
|     if(wifi_sta_enable) { | ||||
|         printf("try STA Mode\n"); | ||||
|         struct sdk_station_config config; | ||||
|         strcpy((char *) config.ssid, wifi_sta_ssid); | ||||
|         strcpy((char *) config.password, wifi_sta_password); | ||||
|         config.bssid_set = 0; | ||||
| 
 | ||||
|         int8_t wifi_sta_dhcp = 1; | ||||
|         sysparam_get_int8("wifi_sta_dhcp", &wifi_sta_dhcp); | ||||
| 
 | ||||
|         if(!wifi_sta_dhcp) { | ||||
|             char *wifi_sta_ip_addr = NULL; | ||||
|             char *wifi_sta_netmask = NULL; | ||||
|             char *wifi_sta_gateway = NULL; | ||||
|             sysparam_get_string("wifi_sta_ip_addr", &wifi_sta_ip_addr); | ||||
|             sysparam_get_string("wifi_sta_netmask", &wifi_sta_netmask); | ||||
|             sysparam_get_string("wifi_sta_gateway", &wifi_sta_gateway); | ||||
| 
 | ||||
|             if(wifi_sta_ip_addr && strlen(wifi_sta_ip_addr) > 4 && | ||||
|                wifi_sta_netmask && strlen(wifi_sta_netmask) > 4 && | ||||
|                wifi_sta_gateway && strlen(wifi_sta_gateway) > 4) { | ||||
|                 sdk_wifi_station_dhcpc_stop(); | ||||
|                 struct ip_info info; | ||||
|                 memset(&info, 0x0, sizeof(info)); | ||||
|                 info.ip.addr = ipaddr_addr(wifi_sta_ip_addr); | ||||
|                 info.netmask.addr = ipaddr_addr(wifi_sta_netmask); | ||||
|                 info.gw.addr = ipaddr_addr(wifi_sta_gateway); | ||||
|                 sdk_wifi_set_ip_info(STATION_IF, &info); | ||||
|             } | ||||
|             if(wifi_sta_ip_addr) free(wifi_sta_ip_addr); | ||||
|             if(wifi_sta_netmask) free(wifi_sta_netmask); | ||||
|             if(wifi_sta_gateway) free(wifi_sta_gateway); | ||||
|         } | ||||
| 
 | ||||
|         sdk_wifi_station_set_config(&config); | ||||
|     } | ||||
| 
 | ||||
|     if(wifi_ap_enable) { | ||||
|         printf("try AP Mode\n"); | ||||
|         /* Read and validate paramenters. */ | ||||
|         int8_t wifi_ap_ssid_hidden = 0; | ||||
|         sysparam_get_int8("wifi_ap_ssid_hidden", &wifi_ap_ssid_hidden); | ||||
|         if(wifi_ap_ssid_hidden < 0 || wifi_ap_ssid_hidden > 1) { | ||||
|             wifi_ap_ssid_hidden = 1; | ||||
|         } | ||||
| 
 | ||||
|         int8_t wifi_ap_channel = 6; | ||||
|         sysparam_get_int8("wifi_ap_channel", &wifi_ap_channel); | ||||
| 
 | ||||
| 
 | ||||
| #if 0 | ||||
|         /* AU does not allow channels above 13, although 14 works. */ | ||||
|         if(wifi_ap_channel > 13) { | ||||
|             wifi_ap_channel = 13; | ||||
|         } | ||||
|         /* US does not allow channels above 11, although they work. */ | ||||
|         if (wifi_ap_channel > 11) { | ||||
|             wifi_ap_channel = 11; | ||||
|         } | ||||
| #endif | ||||
|         if(wifi_ap_channel < 1 || wifi_ap_channel > 14) { | ||||
|             wifi_ap_channel = 6; | ||||
|         } | ||||
| 
 | ||||
|         int8_t wifi_ap_authmode = AUTH_WPA_WPA2_PSK; | ||||
|         sysparam_get_int8("wifi_ap_authmode", &wifi_ap_authmode); | ||||
|         if(wifi_ap_authmode != AUTH_OPEN && wifi_ap_authmode != AUTH_WPA_PSK && | ||||
|            wifi_ap_authmode != AUTH_WPA2_PSK && wifi_ap_authmode != AUTH_WPA_WPA2_PSK) { | ||||
|             wifi_ap_authmode = AUTH_WPA_WPA2_PSK; | ||||
|         } | ||||
| 
 | ||||
|         int8_t wifi_ap_max_conn = 3; | ||||
|         sysparam_get_int8("wifi_ap_max_conn", &wifi_ap_max_conn); | ||||
|         if(wifi_ap_max_conn < 1 || wifi_ap_max_conn > 8) { | ||||
|             wifi_ap_max_conn = 3; | ||||
|         } | ||||
| 
 | ||||
|         int32_t wifi_ap_beacon_interval = 100; | ||||
|         sysparam_get_int32("wifi_ap_beacon_interval", &wifi_ap_beacon_interval); | ||||
|         if(wifi_ap_beacon_interval < 0 || wifi_ap_beacon_interval > 1000) { | ||||
|             wifi_ap_beacon_interval = 100; | ||||
|         } | ||||
| 
 | ||||
|         /* Default AP IP address and netmask. */ | ||||
|         char *wifi_ap_ip_addr = NULL; | ||||
|         sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); | ||||
|         if(!wifi_ap_ip_addr) { | ||||
|             sysparam_set_string("wifi_ap_ip_addr", "172.16.0.1"); | ||||
|             sysparam_get_string("wifi_ap_ip_addr", &wifi_ap_ip_addr); | ||||
|         } | ||||
|         char *wifi_ap_netmask = NULL; | ||||
|         sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); | ||||
|         if(!wifi_ap_netmask) { | ||||
|             sysparam_set_string("wifi_ap_netmask", "255.255.0.0"); | ||||
|             sysparam_get_string("wifi_ap_netmask", &wifi_ap_netmask); | ||||
|         } | ||||
| 
 | ||||
|         if(strlen(wifi_ap_ip_addr) >= 7 && strlen(wifi_ap_netmask) >= 7) { | ||||
|             struct ip_info ap_ip; | ||||
|             ap_ip.ip.addr = ipaddr_addr(wifi_ap_ip_addr); | ||||
|             ap_ip.netmask.addr = ipaddr_addr(wifi_ap_netmask); | ||||
|             IP4_ADDR(&ap_ip.gw, 0, 0, 0, 0); | ||||
|             sdk_wifi_set_ip_info(1, &ap_ip); | ||||
| 
 | ||||
|             struct sdk_softap_config ap_config = { | ||||
|                     .ssid_hidden = wifi_ap_ssid_hidden, | ||||
|                     .channel = wifi_ap_channel, | ||||
|                     .authmode = wifi_ap_authmode, | ||||
|                     .max_connection = wifi_ap_max_conn, | ||||
|                     .beacon_interval = wifi_ap_beacon_interval, | ||||
|             }; | ||||
|             strcpy((char *) ap_config.ssid, wifi_ap_ssid); | ||||
|             ap_config.ssid_len = strlen(wifi_ap_ssid); | ||||
|             strcpy((char *) ap_config.password, wifi_ap_password); | ||||
|             sdk_wifi_softap_set_config(&ap_config); | ||||
| 
 | ||||
|             int8_t wifi_ap_dhcp_leases = 4; | ||||
|             sysparam_get_int8("wifi_ap_dhcp_leases", &wifi_ap_dhcp_leases); | ||||
| 
 | ||||
|             if(wifi_ap_dhcp_leases) { | ||||
|                 ip4_addr_t first_client_ip; | ||||
|                 first_client_ip.addr = ap_ip.ip.addr + htonl(1); | ||||
| 
 | ||||
|                 int8_t wifi_ap_dns = 1; | ||||
|                 sysparam_get_int8("wifi_ap_dns", &wifi_ap_dns); | ||||
|                 if(wifi_ap_dns < 0 || wifi_ap_dns > 1) | ||||
|                     wifi_ap_dns = 1; | ||||
| 
 | ||||
|                 dhcpserver_start(&first_client_ip, wifi_ap_dhcp_leases); | ||||
|                 dhcpserver_set_router(&ap_ip.ip); | ||||
|                 if(wifi_ap_dns) { | ||||
|                     dhcpserver_set_dns(&ap_ip.ip); | ||||
|                     xTaskCreate(dns_task, "WiFi Cfg DNS", 384, NULL, 2, NULL); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         free(wifi_ap_ip_addr); | ||||
|         free(wifi_ap_netmask); | ||||
|     } | ||||
| 
 | ||||
|     if(wifi_sta_ssid) free(wifi_sta_ssid); | ||||
|     if(wifi_sta_password) free(wifi_sta_password); | ||||
|     if(wifi_ap_ssid) free(wifi_ap_ssid); | ||||
|     if(wifi_ap_password) free(wifi_ap_password); | ||||
| 
 | ||||
|     if(wifi_mode != NULL_MODE) { | ||||
| 
 | ||||
|         /* turn off LED */ | ||||
|         //gpio_enable(LED_PIN, GPIO_OUTPUT);
 | ||||
|         //gpio_write(LED_PIN, true);
 | ||||
|         xTaskCreate(blinkenTask, "blinkenTask", 256, NULL, 2, NULL); | ||||
| 
 | ||||
|         /* initialize tasks */ | ||||
|         xTaskCreate(&httpd_task, "HTTP Daemon", 2048, NULL, 2, NULL); | ||||
| 
 | ||||
|         xTaskCreate(&sntp_task, "SNTP", 512, NULL, 1, NULL); | ||||
|     } | ||||
| >>>>>>> 4b8d354 (basic webconf) | ||||
| } | ||||
|  |  | |||
							
								
								
									
										1
									
								
								firmware/fsdata/fs/css/picnic.min.css
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								firmware/fsdata/fs/css/picnic.min.css
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										62
									
								
								firmware/fsdata/fs/css/style.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								firmware/fsdata/fs/css/style.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,62 @@ | |||
| main { | ||||
| 	padding: 4em 2em 2em 2em; | ||||
| 	max-width: 960px; | ||||
| 	width: 100%; | ||||
| 	margin-left: auto; | ||||
| 	margin-right: auto; | ||||
| } | ||||
| section { | ||||
| 	display: none; | ||||
| } | ||||
| 
 | ||||
| canvas{ | ||||
| 	width: 100%; | ||||
| } | ||||
| 
 | ||||
| main[data-page="dashboard"] section[id="dashboard"] { | ||||
| 	display: block; | ||||
| } | ||||
| 
 | ||||
| main[data-page="ota"] section[id="ota"] { | ||||
| 	display: block; | ||||
| } | ||||
| 
 | ||||
| main[data-page="wifi"] section[id="wifi"] { | ||||
| 	display: block; | ||||
| } | ||||
| 
 | ||||
| main[data-page="io"] section[id="io"] { | ||||
| 	display: block; | ||||
| } | ||||
| 
 | ||||
| .table { | ||||
| 	width: 100%; | ||||
| 	display: table; | ||||
| } | ||||
| .table>.row{ | ||||
| 	display: table-row; | ||||
| } | ||||
| .table>.row:nth-child(2n) { | ||||
| 	background: rgba(17,17,17,0.05); | ||||
| } | ||||
| .table>.row>*{ | ||||
| 	display: table-cell; | ||||
| 	padding: .3em 2.4em .3em .6em; | ||||
| } | ||||
| .table>header.row>*{ | ||||
| 	text-align: left; | ||||
| 	font-weight: 900; | ||||
| 	color: #fff; | ||||
| 	background-color: #0074d9; | ||||
| } | ||||
| 
 | ||||
| .table>.row>input{ | ||||
| 	border: none; | ||||
| 	background: none; | ||||
| 	font-weight: 900; | ||||
| } | ||||
| 
 | ||||
| .plain{ | ||||
| 	opacity: initial; | ||||
| 	width: initial; | ||||
| } | ||||
							
								
								
									
										477
									
								
								firmware/fsdata/fs/index.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										477
									
								
								firmware/fsdata/fs/index.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,477 @@ | |||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
| <head> | ||||
|     <meta charset="utf-8"/> | ||||
|     <title>fiatlux v0.2</title> | ||||
|     <link rel="stylesheet" href="css/picnic.min.css"> | ||||
|     <link rel="stylesheet" href="css/style.css"> | ||||
| </head> | ||||
| <body> | ||||
| <nav> | ||||
|     <a href="#" class="brand"> | ||||
|         <!--img class="logo" src="/img/basket.png" /--> | ||||
|         <span>fiatlux v0.2</span> | ||||
|         <span class="label warning" id="status_box">Loading...</span> | ||||
|     </a> | ||||
| 
 | ||||
|     <!-- responsive--> | ||||
|     <input id="bmenub" type="checkbox" class="show"> | ||||
|     <label for="bmenub" class="burger pseudo button">☰</label> | ||||
| 
 | ||||
|     <div class="menu"> | ||||
|         <a href="/" class="button icon-picture" onclick="use_page('dashboard'); return false">Dashboard</a> | ||||
|         <a href="/io" class="button icon-puzzle" onclick="use_page('io'); return false">I/O</a> | ||||
|         <a href="/wifi" class="button icon-puzzle" onclick="use_page('wifi'); return false">Wifi Settings</a> | ||||
|         <a href="/ota" class="button icon-picture" onclick="use_page('ota'); return false">System</a> | ||||
|     </div> | ||||
| </nav> | ||||
| <main data-page="dashboard" id="page"> | ||||
|     <section id="dashboard"> | ||||
|         <h2>Status</h2> | ||||
|         <div class="flex"> | ||||
|             <div> | ||||
|                 <article class="card"> | ||||
|                     <header> | ||||
|                         <h3>System</h3> | ||||
|                     </header> | ||||
|                     <div class="table"> | ||||
|                         <div class="row"> | ||||
|                             <span>Chip ID</span> | ||||
|                             <span><span class="postfill_chipid">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Hostname</span> | ||||
|                             <span><span class="postfill_hostname">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Firmware Version</span> | ||||
|                             <span>N/A</span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Flash ID</span> | ||||
|                             <span><span class="postfill_flashid">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Flash size</span> | ||||
|                             <span><span class="postfill_flashsize">N/A</span> KiB</span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Free heap</span> | ||||
|                             <span><span class="postfill_heap">N/A</span> bytes</span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Uptime</span> | ||||
|                             <span><span class="postfill_uptime">N/A</span> s</span> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </article> | ||||
|             </div> | ||||
|             <div> | ||||
|                 <article class="card"> | ||||
|                     <header> | ||||
|                         <h3>Network <span class="label success postfill_clientip">current connection</span></h3> | ||||
|                     </header> | ||||
|                     <div class="table"> | ||||
|                         <div class="row"> | ||||
|                             <span>Mode</span> | ||||
|                             <span><span class="postfill_opmode">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Station SSID</span> | ||||
|                             <span><span class="postfill_stassid">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Station IP</span> | ||||
|                             <span><span class="postfill_staip">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Station MAC</span> | ||||
|                             <span><span class="postfill_stamac">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>AP SSID</span> | ||||
|                             <span><span class="postfill_apssid">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>AP IP</span> | ||||
|                             <span><span class="postfill_apip">N/A</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>AP MAC</span> | ||||
|                             <span><span class="postfill_apmac">N/A</span></span> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </article> | ||||
|             </div> | ||||
|             <div> | ||||
|                 <article class="card"> | ||||
|                     <header> | ||||
|                         <h3>Power</h3> | ||||
|                     </header> | ||||
|                     <div class="table"> | ||||
|                         <div class="row"> | ||||
|                             <span>Input</span> | ||||
|                             <span><span class="label success">5V</span><span class="label success">12V</span></span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Output</span> | ||||
|                             <span><span class="label warning"><span id="out_voltage">11.2</span>V</span></span> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <canvas id="chartCanvas" style="height:100px"></canvas> | ||||
|                 </article> | ||||
|             </div> | ||||
|             <div> | ||||
|                 <article class="card"> | ||||
|                     <header> | ||||
|                         <h3>I/O</h3> | ||||
|                     </header> | ||||
|                     <div class="table"> | ||||
|                         <div class="row"> | ||||
|                             <span>Channel 1-6</span> | ||||
|                             <span>SPI Dimmer</span> | ||||
|                         </div> | ||||
|                         <div class="row"> | ||||
|                             <span>Channel 7-127</span> | ||||
|                             <span>WS2812 via I2S</span> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <footer> | ||||
|                         <label> | ||||
|                             <input type="checkbox" name="onoffswitch" id="led-switch" onclick="gpio()"> | ||||
|                             <span class="toggle button">Toggle Something</span> | ||||
|                         </label> | ||||
|                     </footer> | ||||
|                 </article> | ||||
|             </div> | ||||
|         </div> | ||||
|     </section> | ||||
|     <section id="ota"> | ||||
|         <h2>System</h2> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>Firmware Update</h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="file"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="submit" value="Upload"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>Restart</h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="submit" value="Restart" onclick="wsWrite('R')"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>Reset Config</h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="submit" class="warning" value="Reset" onclick="wsWrite('X')"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
| 
 | ||||
|     </section> | ||||
|     <section id="io"> | ||||
|         <h2>I/O</h2> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>Protocols</h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <label>MQTT</label> | ||||
|                     <span><input type="checkbox" class="plain"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="reset" class="button"/></span> | ||||
|                     <span><input type="submit" value="Save"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>Station Mode <span class="label success">current connection</span></h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <label>WS2812 via I2S</label> | ||||
|                     <span><input type="checkbox" class="plain"/></span> | ||||
|                     <span><input type="color"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>APA102C via SPI</label> | ||||
|                     <span><input type="checkbox" class="plain"/></span> | ||||
|                     <span><input type="color"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>6 Channel SPI Dimmer</label> | ||||
|                     <span><input type="checkbox" class="plain"/></span> | ||||
|                     <span><input type="color"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>Binary Output on GPIO4</label> | ||||
|                     <span><input type="checkbox" class="plain"/></span> | ||||
|                     <span><button class="toggle button">Toggle</button></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>Binary Output on GPIO5</label> | ||||
|                     <span><input type="checkbox" class="plain"/></span> | ||||
|                     <span><button class="toggle button">Toggle</button></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="reset" class="button"/></span> | ||||
|                     <span><input type="submit" value="Save"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
|     </section> | ||||
|     <section id="wifi"> | ||||
|         <h2>Wifi Settings</h2> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>AP Mode</h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <label>Enable</label> | ||||
|                     <span><input id="ap_toggle" type="checkbox" class="plain"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>SSID</label> | ||||
|                     <span><input id="ap_ssid" type="text" placeholder="SSID"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>Password</label> | ||||
|                     <span><input id="ap_pw" type="password" placeholder="Password"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span>AP IP</span> | ||||
|                     <span><span class="postfill_apip">N/A</span></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span>AP MAC</span> | ||||
|                     <span><span class="postfill_apmac">N/A</span></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="reset" class="button"/></span> | ||||
|                     <span><input onclick="ap_update();" type="submit" value="Save"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
|         <article class="card"> | ||||
|             <header> | ||||
|                 <h3>Station Mode <span class="label success">current connection</span></h3> | ||||
|             </header> | ||||
|             <div class="table"> | ||||
|                 <div class="row"> | ||||
|                     <label>Eanable</label> | ||||
|                     <span><input id="sta_toggle" type="checkbox" class="plain"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>SSID</label> | ||||
|                     <span><input id="sta_ssid" type="text" placeholder="SSID"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <label>Password</label> | ||||
|                     <span><input id="sta_pw" type="password" placeholder="Password"/></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span>Sation IP</span> | ||||
|                     <span><span class="postfill_staip">N/A</span></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span>Station MAC</span> | ||||
|                     <span><span class="postfill_stamac">N/A</span></span> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <span><input type="reset" class="button"/></span> | ||||
|                     <span><input onclick="sta_update();" type="submit" value="Save"></span> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </article> | ||||
|     </section> | ||||
| </main> | ||||
| <div id="unused_values" style="display:none;"></div> | ||||
| <script type="text/javascript" src="js/smoothie_min.js"></script> | ||||
| <script> | ||||
|     var section = document.getElementById("page"); | ||||
|     var menu = document.getElementById("bmenub"); | ||||
|     var voltage = document.getElementById("out_voltage"); | ||||
| 
 | ||||
|     var unused_values = {}; | ||||
| 
 | ||||
|     DataView.prototype.setChar = function(pos, char) { | ||||
|         this.setInt8(pos++, char.charCodeAt(0)); | ||||
|         return pos; | ||||
|     }; | ||||
| 
 | ||||
|     DataView.prototype.setString = function(pos, str) { | ||||
|         for(var i = 0; i < str.length; i++) { | ||||
|             this.setInt8(pos++, str.charCodeAt(i)); | ||||
|         } | ||||
|         this.setInt8(pos++, 0); | ||||
|         return pos; | ||||
|     }; | ||||
| 
 | ||||
|     function use_page(name) { | ||||
|         section.dataset.page = name; | ||||
|         menu.checked = false | ||||
|     } | ||||
| 
 | ||||
|     var ws; | ||||
|     var retries; | ||||
|     var series = new TimeSeries(); | ||||
| 
 | ||||
|     function setMsg(cls, text) { | ||||
|         sbox = document.getElementById('status_box'); | ||||
|         sbox.className = "label " + cls; | ||||
|         sbox.innerHTML = text; | ||||
|         console.log(text); | ||||
|     } | ||||
| 
 | ||||
|     function startPolling() { | ||||
|         var chart = new SmoothieChart({ | ||||
|             millisPerPixel: 111, grid: {fillStyle: '#ffffff', strokeStyle: '#ffffff', borderVisible: false}, | ||||
|             labels: {fillStyle: '#000000'}, maxValue: 1024, minValue: 0 | ||||
|         }); | ||||
|         chart.addTimeSeries(series, {lineWidth: 2, strokeStyle: '#03a9f4', fillStyle: '#f1f5fa'}); | ||||
|         var canvas = document.getElementById("chartCanvas"); | ||||
|         canvas.width = canvas.clientWidth; | ||||
|         canvas.height = canvas.clientHeight; | ||||
|         chart.streamTo(canvas, 500); | ||||
|         setInterval(function () { | ||||
|             wsWrite('V'); | ||||
|         }, 500); | ||||
|     } | ||||
| 
 | ||||
|     function onMessage(evt) { | ||||
|         retries = 0; | ||||
|         if (typeof evt.data == 'string') { | ||||
|             var data = JSON.parse(evt.data); | ||||
|             for (const [key, value] of Object.entries(data)) { | ||||
|                 const elements = document.querySelectorAll(".postfill_" + key); | ||||
|                 if (!elements.length) | ||||
|                     unused_values[key] = value; | ||||
|                 else | ||||
|                     for (i = 0; i < elements.length; ++i) { | ||||
|                         elements[i].innerHTML = value; | ||||
|                     } | ||||
|             } | ||||
|             document.getElementById("unused_values").innerHTML = JSON.stringify(unused_values); | ||||
|         } else { | ||||
|             var dv = new DataView(evt.data); | ||||
|             var cmd = String.fromCharCode(dv.getUint8(0)); | ||||
|             var val = dv.getUint16(1); | ||||
| 
 | ||||
|             if (cmd === 'G') | ||||
|                 console.log("LED switched"); | ||||
|             else if (cmd === 'V') { | ||||
|                 voltage.innerHTML = (val * 13 / 1024).toFixed(2); | ||||
|                 series.append(new Date().getTime(), val); | ||||
|             } else | ||||
|                 console.log('unknown command', cmd, val); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function wsOpen() { | ||||
|         var uri = "/stream" | ||||
|         if (ws === undefined || ws.readyState != 0) { | ||||
|             if (retries) | ||||
|                 setMsg("warning", "WebSocket timeout, retrying.."); | ||||
|             else | ||||
|                 setMsg("primary", "Opening WebSocket.."); | ||||
|             ws = new WebSocket("ws://" + location.host + uri); | ||||
|             ws.binaryType = 'arraybuffer'; | ||||
|             ws.onopen = function (evt) { | ||||
|                 retries = 0; | ||||
|                 setMsg("success", "WebSocket is open."); | ||||
|             }; | ||||
|             ws.onerror = function (evt) { | ||||
|                 console.error(evt); | ||||
|                 setMsg("error", "WebSocket error!"); /*window.location.reload(true);*/ | ||||
|             }; | ||||
|             ws.onmessage = function (evt) { | ||||
|                 onMessage(evt); | ||||
|             }; | ||||
|             retries = 0; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function buf2hex(buffer) { // buffer is an ArrayBuffer | ||||
|         return [...new Uint8Array(buffer)].map(x => x.toString(16).padStart(2, '0')).join(''); | ||||
|     } | ||||
| 
 | ||||
|     function wsWrite(data) { | ||||
|         console.log(buf2hex(data)); | ||||
|         if (ws.readyState === 3 || retries++ > 5) | ||||
|             wsOpen(); | ||||
|         else if (ws.readyState === 1) | ||||
|             ws.send(data); | ||||
|     } | ||||
| 
 | ||||
|     function gpio() { | ||||
|         if (document.getElementById('led-switch').checked) | ||||
|             wsWrite('E'); | ||||
|         else | ||||
|             wsWrite('D'); | ||||
|     } | ||||
| 
 | ||||
|     var sta_toggle = document.getElementById("sta_toggle"); | ||||
|     var sta_ssid = document.getElementById("sta_ssid"); | ||||
|     var sta_pw = document.getElementById("sta_pw"); | ||||
| 
 | ||||
|     function sta_update() { | ||||
|         var en = sta_toggle.checked; | ||||
| 
 | ||||
|         const ssid = sta_ssid.value; | ||||
|         const password = sta_pw.value; | ||||
| 
 | ||||
|         const buffer = new ArrayBuffer(ssid.length + password.length + 4); | ||||
|         const view1 = new DataView(buffer); | ||||
|         var tx_len = 0; | ||||
|         view1.setChar(tx_len++, 'S'); | ||||
|         view1.setChar(tx_len++, (en ? "E" : "D")); | ||||
|         tx_len = view1.setString(tx_len, ssid); | ||||
|         tx_len = view1.setString(tx_len, password); | ||||
|         wsWrite(buffer); | ||||
|     } | ||||
| 
 | ||||
|     var ap_toggle = document.getElementById("ap_toggle"); | ||||
|     var ap_ssid = document.getElementById("ap_ssid"); | ||||
|     var ap_pw = document.getElementById("ap_pw"); | ||||
| 
 | ||||
|     function ap_update() { | ||||
|         var en = ap_toggle.checked; | ||||
| 
 | ||||
|         const ssid = ap_ssid.value; | ||||
|         const password = ap_pw.value; | ||||
| 
 | ||||
|         const buffer = new ArrayBuffer(ssid.length + password.length + 4); | ||||
|         const view1 = new DataView(buffer); | ||||
|         var tx_len = 0; | ||||
|         view1.setChar(tx_len++, 'A'); | ||||
|         view1.setChar(tx_len++, (en ? "E" : "D")); | ||||
|         tx_len = view1.setString(tx_len, ssid); | ||||
|         tx_len = view1.setString(tx_len, password); | ||||
|         wsWrite(buffer); | ||||
|     } | ||||
| 
 | ||||
|     window.onload = function () { | ||||
|         wsOpen(); | ||||
|         startPolling(); | ||||
|     } | ||||
| </script> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										15
									
								
								firmware/fsdata/fs/js/smoothie_min.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								firmware/fsdata/fs/js/smoothie_min.js
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue