#include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef DMALLOC #include #endif void ppp_status(char *buf, int bufsize) { const char *STATFILE="/tmp/ppp0_status"; FILE *file = fopen(STATFILE, "r"); if (!file) { *buf = '\0'; return; } fgets(buf, bufsize, file); fclose(file); } void wlan_getparam(const char *param, char *buf, int buflen) { FILE *pipe; char linebuf[128]; char *p1, *p2 = buf, *endp = buf + buflen - 1; snprintf(linebuf, 127, "/bin/uci get wireless.cfg2.%s", param); pipe = popen(linebuf, "r"); fgets(linebuf, 128, pipe); p1 = linebuf; while (!isspace(*p1) && p2 < endp) *(p2++) = *(p1++); *p2 = '\0'; pclose(pipe); return; } int wlan_clients() { FILE *pipe; char linebuf[32] = {0}; pipe = popen("/usr/sbin/wl assoclist | /usr/bin/wc -l", "r"); fgets(linebuf, 32, pipe); pclose(pipe); return atoi(linebuf); } /* Public functions */ static char *weekdays[7] = {"ma", "ti", "ke", "to", "pe", "la", "su"}; int infoscreen_clock(unsigned char screen[LCD_H][LCD_W]) { char buf[32], tbuf[32]; time_t t = time(NULL); struct tm *ts = localtime(&t);; strftime(buf, 32, "%H:%M:%S", ts); dh_malign(buf, screen[2], LCD_W); int wday; strftime(buf, 32, "%u", ts); wday = atoi(buf); strftime(tbuf, 32, "%d.%m.%Y", ts); snprintf(buf, 32, "%s %s", weekdays[wday - 1], tbuf); fr_malign(buf, screen[5], LCD_W); return 1; } int infoscreen_tv(unsigned char screen[LCD_H][LCD_W]) { #define nl 32 const int max_interval = 1800; static int next_update = 0; static char tv1[nl] = {0}, tv2[nl] = {0}, mtv3[nl] = {0}, nel[nl] = {0}, sub[nl] = {0}; int status, timestamp = 0; if (next_update <= time(NULL)) { char pagedata[512] = {0}; char update[32] = {0}; status = http_getpage_async("http://kapsi.fi/~jpa/stuff/other/tvohjelmat.cgi", pagedata, 512, ×tamp); if (status > 0) { get_value(pagedata, "tv1", tv1, nl) || (tv1[0] = '\0'); get_value(pagedata, "tv2", tv2, nl) || (tv2[0] = '\0'); get_value(pagedata, "mtv", mtv3, nl) || (mtv3[0] = '\0'); get_value(pagedata, "nel", nel, nl) || (nel[0] = '\0'); get_value(pagedata, "sub", sub, nl) || (sub[0] = '\0'); get_value(pagedata, "Update", update, 32); next_update = atoi(update); if (next_update < 60) next_update = 60; next_update += timestamp; } else if (status != HTTP_ASYNCWAIT) { next_update = time(NULL) + 60; // Some error occurred, wait and retry } } if (next_update + max_interval < time(NULL)) { tv1[0] = tv2[0] = mtv3[0] = nel[0] = sub[0] = '\0'; } // Render titles int mpos = fr_textwidth("MTV3:"); fr_ralign("TV1:", screen[1], mpos); fr_ralign("TV2:", screen[2], mpos); fr_ralign("MTV3:", screen[3], mpos); fr_ralign("Nel.:", screen[4], mpos); fr_ralign("Sub.:", screen[5], mpos); mpos += 2; // Space int maxw = LCD_W - mpos; fr_render(tv1, screen[1] + mpos, maxw); fr_render(tv2, screen[2] + mpos, maxw); fr_render(mtv3, screen[3] + mpos, maxw); fr_render(nel, screen[4] + mpos, maxw); fr_render(sub, screen[5] + mpos, maxw); return next_update; } int infoscreen_poytya(unsigned char screen[LCD_H][LCD_W]) { const int update_interval = 600; const int max_interval = 7200; static int lastupdate = 0; static char pagedata[256]; int status, timestamp = 0; if (lastupdate + update_interval <= time(NULL)) { status = http_getpage_async("http://warri1.dyndns.org/lampotila/remtemp.txt", pagedata, 256, ×tamp); if (status > 0 || status != HTTP_ASYNCWAIT) lastupdate = timestamp; } if (lastupdate + max_interval < time(NULL)) { pagedata[0] = '\0'; // Clear data } char textbuf[64], valuebuf[32]; /* Get updated time */ if (get_value(pagedata, "Updated", valuebuf, 32)) { snprintf(textbuf, 64, "@ %s", valuebuf); fr_render(textbuf, screen[1], LCD_W); } /* Sikala */ if (get_value(pagedata, "Ylasikala", valuebuf, 32)) { snprintf(textbuf, 64, "Ylä-s. %s", valuebuf); fr_render(textbuf, screen[3], LCD_W); } /* Ulkoilma */ if (get_value(pagedata, "Ulkoilma", valuebuf, 32)) { snprintf(textbuf, 64, "Ulkoilma %s", valuebuf); fr_render(textbuf, screen[4], LCD_W); } /* Yläkerta */ if (get_value(pagedata, "Ylakerta", valuebuf, 32)) { snprintf(textbuf, 64, "Yläkerta %s", valuebuf); fr_render(textbuf, screen[5], LCD_W); } return lastupdate + update_interval; } int infoscreen_wlan(unsigned char screen[LCD_H][LCD_W]) { char enckey[64], essid[32]; char linebuf[32]; int clients; wlan_getparam("key", enckey, 64); clients = wlan_clients(); wlan_getparam("ssid", essid, 32); str_trimchars(essid, "\""); snprintf(linebuf, 32, "ESSID: %s", essid); fr_render(linebuf, screen[1], LCD_W); snprintf(linebuf, 32, "WEP: %.4s-%.4s-", enckey, enckey + 4); fr_render(linebuf, screen[2], LCD_W); int pos = fr_textwidth("WEP: "); snprintf(linebuf, 32, "%.4s-%.4s-", enckey + 8, enckey + 12); fr_render(linebuf, screen[3] + pos, LCD_W - pos); snprintf(linebuf, 32, "%.4s-%.4s-%.2s", enckey + 16, enckey + 20, enckey + 24); fr_render(linebuf, screen[4] + pos, LCD_W - pos); snprintf(linebuf, 32, "Yhteyksiä: %d kpl", clients); fr_render(linebuf, screen[5], LCD_W); return time(NULL) + 10; } typedef struct repacontext { char *url; int lastupdate; char pagedata[512]; } repacontext; int infoscreen_repa(repacontext* ctx, unsigned char screen[LCD_H][LCD_W]) { const int update_interval = 600; const int max_interval = 7200; int status, timestamp = 0; if (ctx->lastupdate + update_interval <= time(NULL)) { status = http_getpage_async(ctx->url, ctx->pagedata, 512, ×tamp); if (status > 0 || status != HTTP_ASYNCWAIT) ctx->lastupdate = timestamp; } if (ctx->lastupdate + max_interval < time(NULL)) { ctx->pagedata[0] = '\0'; } char buf[32]; int colw = fr_textwidth("88:88 "); char *line = ctx->pagedata; fr_render("Pysäk", screen[1], colw); fr_render("Peril", screen[1] + colw, colw); fr_render("Linja", screen[1] + colw * 2, LCD_W - 2 * colw); int i = 2; while (line != NULL && *line != 0 && i < LCD_H) { get_str_field(line, 0, buf, 32); fr_render(buf, screen[i], colw); get_str_field(line, 1, buf, 32); fr_render(buf, screen[i] + colw, colw); get_str_field(line, 2, buf, 32); fr_render(buf, screen[i] + colw * 2, LCD_W - 2 * colw); line = strchr(line + 1, '\n'); i += 1; } return ctx->lastupdate + update_interval; } int infoscreen_repa_tamk(unsigned char screen[LCD_H][LCD_W]) { static repacontext ctx = { "http://koti.kapsi.fi/jpa/stuff/other/reittiopas/tamk.cgi", 0, {0}}; return infoscreen_repa(&ctx, screen); } int infoscreen_repa_rautatieasema(unsigned char screen[LCD_H][LCD_W]) { static repacontext ctx = { "http://koti.kapsi.fi/jpa/stuff/other/reittiopas/rautatieasema.cgi", 0, {0}}; return infoscreen_repa(&ctx, screen); } int infoscreen_repa_sorila(unsigned char screen[LCD_H][LCD_W]) { static repacontext ctx = { "http://koti.kapsi.fi/jpa/stuff/other/reittiopas/sorila.cgi", 0, {0}}; return infoscreen_repa(&ctx, screen); } int infoscreen_forecast(unsigned char screen[LCD_H][LCD_W]) { const int update_interval = 3600; const int max_interval = 6 * 3600; static int lastupdate = 0; static char pagedata[256]; int status, timestamp = 0; if (lastupdate + update_interval <= time(NULL)) { status = http_getpage_async("http://koti.kapsi.fi/~jpa/stuff/other/saatiedote/saatiedote.cgi", pagedata, 256, ×tamp); if (status > 0 || status != HTTP_ASYNCWAIT) lastupdate = timestamp; } if (lastupdate + max_interval < time(NULL)) { pagedata[0] = '\0'; // Clear data } int x = 16; char *line = pagedata; char buf[32]; char textbuf[LCD_W] = {0}; fr_render("Klo", textbuf, LCD_W); while (line != NULL && *line != 0 && x < LCD_W - 16) { get_str_field(line, 0, buf, 32); fr_malign(buf, textbuf + x, 16); get_str_field(line, 1, buf, 32); if (strcmp(buf, "cloud") == 0) ws_render(&ws_cloud, screen[1] + x); else if (strcmp(buf, "sun") == 0) ws_render(&ws_sun, screen[1] + x); else if (strcmp(buf, "suncloud") == 0) ws_render(&ws_suncloud, screen[1] + x); else if (strcmp(buf, "storm") == 0) ws_render(&ws_storm, screen[1] + x); else if (strcmp(buf, "fog") == 0) ws_render(&ws_fog, screen[1] + x); else if (strcmp(buf, "rain") == 0) ws_render(&ws_rain, screen[1] + x); else if (strcmp(buf, "snow") == 0) ws_render(&ws_snow, screen[1] + x); line = strchr(line + 1, '\n'); x += 17; } // Put the text close to the symbols for (x = 0; x < LCD_W; x++) { *(screen[3] + x) = textbuf[x] >> 1; } return lastupdate + update_interval; } int infoscreen_lampotila(unsigned char screen[LCD_H][LCD_W]) { float sisa, sisa_hum, ulko; sisa = rpc_temperature_sisa(); sisa_hum = rpc_humidity_sisa(); ulko = rpc_temperature_ulko(); char linebuf[32]; snprintf(linebuf, 32, "Sisä: %0.1f°C %0.0f%%", sisa, sisa_hum); fr_render(linebuf, screen[4], LCD_W); snprintf(linebuf, 32, "Ulkoilma: %0.1f°C", ulko); fr_render(linebuf, screen[5], LCD_W); int forecast_update = infoscreen_forecast(screen); int my_update = time(NULL) + 60; if (forecast_update < my_update) return forecast_update; else return my_update; }