static void JSONState(const KVPairs & key_value_pairs, FILE * stream_file) { ServeHeader(stream_file, 200, "OK", false, "text/plain"); fprintf_P(stream_file, PSTR("{\n\t\"version\" : \"%s\",\n\t\"run\" : \"%s\",\n\t\"zones\" : \"%d\",\n\t\"schedules\" : \"%d\",\n\t\"timenow\" : \"%lu\",\n\t\"events\" : \"%d\""), VERSION, GetRunSchedules() ? "on" : "off", GetNumEnabledZones(), GetNumSchedules(), nntpTimeServer.LocalNow(), iNumEvents); if (runState.isSchedule() || runState.isManual()) { FullZone zone; LoadZone(runState.getZone() - 1, &zone); long time_check = runState.getEndTime() * 60L - (nntpTimeServer.LocalNow() - previousMidnight(nntpTimeServer.LocalNow())); if (runState.isManual()) time_check = 99999; fprintf_P(stream_file, PSTR(",\n\t\"onzone\" : \"%s\",\n\t\"offtime\" : \"%ld\""), zone.name, time_check); } fprintf_P(stream_file, (PSTR("\n}"))); }
// Print station bits void OSLocalUI::lcd_print_station(byte line, char c) { lcd.setCursor(0, line); if (display_board == 0) { lcd_print_pgm(PSTR("MC:")); // Master controller is display as 'MC' } else { lcd_print_pgm(PSTR("E")); lcd.print((int)display_board); lcd_print_pgm(PSTR(":")); // extension boards are displayed as E1, E2... } if (!GetRunSchedules() && (ActiveZoneNum() == -1) ) { // "disabled" banner is displayed when schedules are disabled AND there are no currently running zones (to account for manual runs) lcd_print_line_clear_pgm(PSTR("-Disabled!-"), 1); } else { for (byte s=0; s<8; s++) { lcd.print(isZoneOn(1+s+display_board*8) ? (char)c : '_'); // note zone number correction - zones are numbered from 1. } } lcd_print_pgm(PSTR(" ")); lcd.setCursor(15, 1); lcd.write(nntpTimeServer.GetNetworkStatus()?0:1); }
void web::ProcessWebClients() { // listen for incoming clients EthernetClient client = m_server->available(); if (client) { bool bReset = false; #ifdef ARDUINO FILE stream_file; FILE * pFile = &stream_file; setup_sendbuf(); fdev_setup_stream(pFile, stream_putchar, NULL, _FDEV_SETUP_WRITE); stream_file.udata = &client; #else FILE * pFile = fdopen(client.GetSocket(), "w"); #endif freeMemory(); trace(F("Got a client\n")); //ShowSockStatus(); KVPairs key_value_pairs; char sPage[35]; if (!ParseHTTPHeader(client, &key_value_pairs, sPage, sizeof(sPage))) { trace(F("ERROR!\n")); ServeError(pFile); } else { trace(F("Page:%s\n"), sPage); //ShowSockStatus(); if (strcmp(sPage, "bin/setSched") == 0) { if (SetSchedule(key_value_pairs)) { if (GetRunSchedules()) ReloadEvents(); ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/setZones") == 0) { if (SetZones(key_value_pairs)) { ReloadEvents(); ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/delSched") == 0) { if (DeleteSchedule(key_value_pairs)) { if (GetRunSchedules()) ReloadEvents(); ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/setQSched") == 0) { if (SetQSched(key_value_pairs)) { ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/settings") == 0) { if (SetSettings(key_value_pairs)) { ReloadEvents(); ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/manual") == 0) { if (ManualZone(key_value_pairs)) { ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/run") == 0) { if (RunSchedules(key_value_pairs)) { ReloadEvents(); ServeHeader(pFile, 200, "OK", false); } else ServeError(pFile); } else if (strcmp(sPage, "bin/factory") == 0) { ResetEEPROM(); ReloadEvents(); ServeHeader(pFile, 200, "OK", false); } else if (strcmp(sPage, "bin/reset") == 0) { ServeHeader(pFile, 200, "OK", false); bReset = true; } else if (strcmp(sPage, "json/schedules") == 0) { JSONSchedules(key_value_pairs, pFile); } else if (strcmp(sPage, "json/zones") == 0) { JSONZones(key_value_pairs, pFile); } else if (strcmp(sPage, "json/settings") == 0) { JSONSettings(key_value_pairs, pFile); } else if (strcmp(sPage, "json/state") == 0) { JSONState(key_value_pairs, pFile); } else if (strcmp(sPage, "json/schedule") == 0) { JSONSchedule(key_value_pairs, pFile); } else if (strcmp(sPage, "json/wcheck") == 0) { JSONwCheck(key_value_pairs, pFile); } #ifdef LOGGING else if (strcmp(sPage, "json/logs") == 0) { JSONLogs(key_value_pairs, pFile); } else if (strcmp(sPage, "json/tlogs") == 0) { JSONtLogs(key_value_pairs, pFile); } #endif else if (strcmp(sPage, "ShowSched") == 0) { freeMemory(); ServeSchedPage(pFile); } else if (strcmp(sPage, "ShowZones") == 0) { freeMemory(); ServeZonesPage(pFile); } else if (strcmp(sPage, "ShowEvent") == 0) { ServeEventPage(pFile); } else if (strcmp(sPage, "ReloadEvent") == 0) { ReloadEvents(true); ServeEventPage(pFile); } else { if (strlen(sPage) == 0) strcpy(sPage, "index.htm"); // prepend path memmove(sPage + 5, sPage, sizeof(sPage) - 5); memcpy(sPage, "/web/", 5); sPage[sizeof(sPage)-1] = 0; trace(F("Serving Page: %s\n"), sPage); SdFile theFile; if (!theFile.open(sPage, O_READ)) Serve404(pFile); else { if (theFile.isFile()) ServeFile(pFile, sPage, theFile, client); else Serve404(pFile); theFile.close(); } } } #ifdef ARDUINO flush_sendbuf(client); // give the web browser time to receive the data delay(1); #else fflush(pFile); fclose(pFile); #endif // close the connection: client.stop(); if (bReset) sysreset(); } }
// Home screen mode handler. // It is responsible for updating the UI and handling input keys. All operations are asynchronous - must return right away. // Typically it is called from loop(), but could be called from other places as well, usually to force UI refresh. // Parameter indicates whether UI refresh is required (e.g. if the screen was previously modified by some other code). // TRUE means that refresh is required, FALSE means nobody touched LCD since the last call to this handler and UI updates could be more targeted. // byte OSLocalUI::modeHandler_Home(byte forceRefresh) { static unsigned long old_millis = 0; // assert if( osUI_Mode != OSUI_MODE_HOME ) return false; // Basic protection to ensure current UI mode is actually HOME mode. if( forceRefresh == 2 ){ // entering this Mode display_board = 0; // set initial view to board 0; } char btn = get_button_async(0); // handle input if( btn == BUTTON_MODE ){ set_mode( OSUI_MODE_MANUAL ); // change mode to "view settings" which is the next mode return true; } else if( btn == BUTTON_CONFIRM ){ if( GetRunSchedules() ) SetRunSchedules(false); // schedules are currently enabled, disable it else { if( ActiveZoneNum() != -1 ){ // schedules are disabled, but something is currently running (manual mode), turn it off TurnOffZones(); runState.SetManual(false); } else { SetRunSchedules(true); // schedules are currently disabled and no manual channels running, enable schedules } } // Apply changes to stop/start schedules as required. ReloadEvents(); forceRefresh = 1; // force UI refresh to provide immediate visual feedback } // Show time and station status // if 1 second has passed unsigned long new_millis = millis(); // Note: we are using built-in Arduino millis() function instead of now() or time-zone adjusted LocalNow(), because it is a lot faster // and for detecting second change it does not make any difference. if( ((new_millis - old_millis) >= 1000) || (forceRefresh != 0) ){ // update UI once a second, OR if explicit refresh is required old_millis = new_millis; lcd_print_time(0); // print time // process LCD display if(SHOW_MEMORY) lcd_print_memory(1); else lcd_print_station(1, ui_anim_chars[now()%3]); } return true; }