123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342 |
- // -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
- // Example of a clock. This is very similar to the text-example,
- // except that it shows the time :)
- //
- // This code is public domain
- // (but note, that the led-matrix library this depends on is GPL v2)
- #include "led-matrix.h"
- #include "graphics.h"
- #include <getopt.h>
- #include <signal.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <unistd.h>
- #include <vector>
- #include <string>
- // demure added
- #include <ctime>
- #include <iostream>
- #include "json.hpp" //<nlohmann/json.hpp>
- using json = nlohmann::json;
- using namespace rgb_matrix;
- volatile bool interrupt_received = false;
- static void InterruptHandler(int signo) {
- interrupt_received = true;
- }
- static int usage(const char *progname) {
- fprintf(stderr, "usage: %s [options]\n", progname);
- fprintf(stderr, "Reads text from stdin and displays it. "
- "Empty string: clear screen\n");
- fprintf(stderr, "Options:\n");
- fprintf(stderr,
- //"\t-f <font-file> : Use given font.\n"
- //"\t-C <r,g,b> : Color. Default 255,255,0\n"
- //"\t-B <r,g,b> : Background-Color. Default 0,0,0\n"
- "\tTest : Description\n"
- "\n"
- );
- rgb_matrix::PrintMatrixFlags(stderr);
- return 1;
- }
- //static bool parseColor( Color *c, const char *str) {
- //return sscanf(str, "%hhu,%hhu,%hhu", &c->r, &c->g, &c->b) == 3;
- //}
- // Initialize rgb_matrix color structs
- // Values here don't matter...
- Color ct_time(0, 0, 200);
- Color ct_week(0, 125, 125);
- Color ct_date(125, 0, 125);
- Color ct_utc(150, 0, 0);
- Color ct_epoch(0, 150, 0);
- Color ct_temp(125, 125, 125);
- Color ct_humid(125, 125, 0);
- Color ct_sun(150, 75, 0);
- Color ct_rand(150, 150, 150); //DEBUG
- int main(int argc, char *argv[]) {
- RGBMatrix::Options matrix_options;
- rgb_matrix::RuntimeOptions runtime_opt;
- if (!rgb_matrix::ParseOptionsFromFlags(&argc, &argv,
- &matrix_options, &runtime_opt)) {
- return usage(argv[0]);
- }
- // Set Default LED Matrix Conf
- matrix_options.rows = 64;
- matrix_options.cols = 64;
- matrix_options.hardware_mapping = "adafruit-hat";
- //int opt;
- //while ((opt = getopt(argc, argv, "f:C:")) != -1) {
- //switch (opt) {
- //case 'f': bdf_font_file = strdup(optarg); break;
- //case 'C':
- //if (!parseColor(&color, optarg)) {
- //fprintf(stderr, "Invalid color spec: %s\n", optarg);
- //return usage(argv[0]);
- //}
- //break;
- //default:
- //return usage(argv[0]);
- //}
- //}
- /// Font Loading /// {{{
- const char *ft_16x32_file = "/led_matrix/spleen/spleen-16x32.bdf";
- rgb_matrix::Font ft_16x32;
- if (!ft_16x32.LoadFont(ft_16x32_file)) {
- fprintf(stderr, "Couldn't load font '%s'\n", ft_16x32_file);
- return 1;
- }
- const char *ft_12x24_file = "/led_matrix/spleen/spleen-12x24.bdf";
- rgb_matrix::Font ft_12x24;
- if (!ft_12x24.LoadFont(ft_12x24_file)) {
- fprintf(stderr, "Couldn't load font '%s'\n", ft_12x24_file);
- return 1;
- }
- const char *ft_8x16_file = "/led_matrix/spleen/spleen-8x16.bdf";
- rgb_matrix::Font ft_8x16;
- if (!ft_8x16.LoadFont(ft_8x16_file)) {
- fprintf(stderr, "Couldn't load font '%s'\n", ft_8x16_file);
- return 1;
- }
- const char *ft_5x8_file = "/led_matrix/spleen/spleen-5x8.bdf";
- rgb_matrix::Font ft_5x8;
- if (!ft_5x8.LoadFont(ft_5x8_file)) {
- fprintf(stderr, "Couldn't load font '%s'\n", ft_5x8_file);
- return 1;
- }
- /// End Font Loading /// }}}
- RGBMatrix *matrix = RGBMatrix::CreateFromOptions(matrix_options, runtime_opt);
- if (matrix == NULL)
- return 1;
- FrameCanvas *offscreen = matrix->CreateFrameCanvas();
- struct timespec next_time;
- next_time.tv_sec = time(NULL);
- next_time.tv_nsec = 0;
- struct tm tm;
- signal(SIGTERM, InterruptHandler);
- signal(SIGINT, InterruptHandler);
- // Set Background Color
- Color bg_color(0, 0, 0);
- while (!interrupt_received) {
- // Clear screen by overwriting with background color
- offscreen->Fill(bg_color.r, bg_color.g, bg_color.b);
- localtime_r(&next_time.tv_sec, &tm);
- /// Set Time Vars /// {{{
- // Normal Time
- time_t rawtime;
- struct tm * timeinfo;
- time (&rawtime);
- timeinfo = localtime (&rawtime);
- // Declare Normal Time Vars
- char t_time [8];
- char t_time_late [8];
- char t_week [10];
- char t_week_late [8];
- char t_date [16];
- char t_epoch [16];
- char t_hour [8];
- // Format Normal Time
- strftime (t_time,8,"%R",timeinfo);
- strftime (t_time_late,8,"%H%M",timeinfo);
- strftime (t_week,10,"%a, %b",timeinfo);
- strftime (t_week_late,8,"%a",timeinfo);
- strftime (t_date,16,"%F",timeinfo);
- strftime (t_epoch,16,"%s",timeinfo);
- strftime (t_hour,8,"%H",timeinfo);
- // Normal Time Vars for Tests
- int now_h = atoi(t_hour);
- int now_s = atoi(t_epoch);
- // UTC Time
- time_t utc_time;
- struct tm * tm_gmt;
- utc_time = time(NULL);
- tm_gmt = gmtime(&utc_time);
- char t_utc [10];
- strftime (t_utc,10,"%R UTC",tm_gmt);
- /// End Set Time Vars /// }}}
- /// Weather ///
- // Weather Lookup
- auto weather = json::parse(R"({"coord": {"lon": -10.000, "lat": 10.0000}, "weather": [{"id": 800, "main": "Clear", "description": "clear sky", "icon": "01n"}], "base": "stations", "main": {"temp": 292.48, "feels_like": 292.22, "temp_min": 290.19, "temp_max": 295.2, "pressure": 1016, "humidity": 67}, "visibility": 10000, "wind": {"speed": 2.06, "deg": 340}, "clouds": {"all": 1}, "dt": 1625274979, "sys": {"type": 2, "id": 1000000, "country": "US", "sunrise": 1625220143, "sunset": 1625275865}, "timezone": -14400, "id": 0000000, "name": "CITY", "cod": 200})"); //DEBUG
- // Weather Vars
- // Weather Pull Status
- int wi_cod = weather["cod"].get<int>();
- // Get K temp, Math K to F, and store as char
- char wc_temp_f [8];
- std::sprintf(wc_temp_f, "%dF", (int)round((weather["main"]["temp"].get<int>() - 273.15) * 9/5 + 32));
- // Humidity
- char wc_humid [8];
- std::sprintf(wc_humid, "%d%%H", weather["main"]["humidity"].get<int>());
- // Sunrise
- // TODO: strftime and store char array %H%M version for LED display
- int wi_sunrise = weather["sys"]["sunrise"].get<int>();
- int wi_sunset = weather["sys"]["sunset"].get<int>();
- // Convert Weather Sun Times
- time_t tm_sunrise = wi_sunrise;
- char wc_sunrise [8];
- strftime (wc_sunrise,8,"%H%M*",localtime(&tm_sunrise));
- time_t tm_sunset = wi_sunset;
- char wc_sunset [8];
- strftime (wc_sunset,8,"%H%M*",localtime(&tm_sunset));
- // Store Last Weather Update Time
- int wi_up = weather["dt"].get<int>();
- /// End Weather ///
- /// Test for Night Mode /// {{{
- bool night_mode; // declare var
- if (wi_sunset != 0 and (now_s - wi_up) < 21600) {
- if (now_s > wi_sunset or now_s < wi_sunrise) {
- night_mode = true;
- }
- else {
- night_mode = false;
- }
- }
- else {
- if (now_h < 7 or now_h > 21) {
- night_mode = true;
- }
- else {
- night_mode = false;
- }
- }
- /// End Test for Night Mode /// }}}
- /// Set Output Colors /// {{{
- // Test for night mode
- //if (now_h < 7 or now_h > 21) {
- if (night_mode == true) {
- ct_time.r = 30; ct_time.g = 0; ct_time.b = 0;
- ct_week.r = 30; ct_week.g = 0; ct_week.b = 0;
- ct_date.r = 30; ct_date.g = 0; ct_date.b = 0;
- ct_utc.r = 30; ct_utc.g = 0; ct_utc.b = 0;
- ct_epoch.r = 30; ct_epoch.g = 0; ct_epoch.b = 0;
- ct_temp.r = 30; ct_temp.g = 0; ct_temp.b = 0;
- ct_humid.r = 30; ct_humid.g = 0; ct_humid.b = 0;
- ct_sun.r = 30; ct_sun.g = 0; ct_sun.b = 0;
- ct_rand.r = 30; ct_rand.g = 0; ct_rand.b = 0; //DEBUG
- }
- // Else Day mode
- else {
- ct_time.r = 0; ct_time.g = 0; ct_time.b = 200;
- ct_week.r = 0; ct_week.g = 125; ct_week.b = 125;
- ct_date.r = 125; ct_date.g = 0; ct_date.b = 125;
- ct_utc.r = 150; ct_utc.g = 0; ct_utc.b = 0;
- ct_epoch.r = 0; ct_epoch.g = 150; ct_epoch.b = 0;
- ct_temp.r = 125; ct_temp.g = 125; ct_temp.b = 125;
- ct_humid.r = 125; ct_humid.g = 125; ct_humid.b = 0;
- ct_sun.r = 150; ct_sun.g = 75; ct_sun.b = 0;
- //ct_rand.r = 30; ct_rand.g = 0; ct_rand.b = 0; //DEBUG
- ct_rand.r = rand() % 100; ct_rand.g = rand() % 100; ct_rand.b = rand() % 100; //DEBUG
- }
- ///End Set Output Colors /// }}}
- /// Display LED output ///
- if (now_h <= 6) {
- // Location, font, X, Y, Color, BG_Color, String, Char_Spacing;
- rgb_matrix::DrawText(offscreen, ft_16x32, 0, 20, ct_time, NULL, t_time_late, 0);
- rgb_matrix::DrawText(offscreen, ft_16x32, 0, 42, ct_week, NULL, t_week_late, 0);
- // Display Night Temp
- rgb_matrix::DrawText(offscreen, ft_16x32, 0, 64, ct_temp, NULL, wc_temp_f, 0);
- } else {
- // Location, font, X, Y, Color, BG_Color, String, Char_Spacing;
- rgb_matrix::DrawText(offscreen, ft_12x24, 2, 15, ct_time, NULL, t_time, 0);
- rgb_matrix::DrawText(offscreen, ft_5x8, 0, 43, ct_week, NULL, t_week, 0);
- rgb_matrix::DrawText(offscreen, ft_5x8, 0, 50, ct_date, NULL, t_date, 0);
- rgb_matrix::DrawText(offscreen, ft_5x8, 0, 57, ct_utc, NULL, t_utc, 0);
- rgb_matrix::DrawText(offscreen, ft_5x8, 0, 64, ct_epoch, NULL, t_epoch, 0);
- // Display Day Weather
- rgb_matrix::DrawText(offscreen, ft_8x16, 0, 27, ct_temp, NULL, wc_temp_f, 0);
- rgb_matrix::DrawText(offscreen, ft_5x8, 0, 35, ct_humid, NULL, wc_humid, 0);
- //rgb_matrix::DrawText(offscreen, ft_5x8, 25, 35, ct_sun, NULL, "XXXX*", 0);
- if (now_s < wi_sunrise) {
- //printf("Sunrise is next at %s.\n",wc_sunrise);
- //printf("Sunrise is next at %d.\n",wi_sunrise);
- rgb_matrix::DrawText(offscreen, ft_5x8, 25, 35, ct_sun, NULL, wc_sunrise, 0);
- }
- else if (now_s < wi_sunset) {
- //printf("Sunset is next at %s.\n",wc_sunset);
- //printf("Sunset is next at %d.\n",wi_sunset);
- rgb_matrix::DrawText(offscreen, ft_5x8, 25, 35, ct_sun, NULL, wc_sunset, 0);
- }
- }
- rgb_matrix::DrawText(offscreen, ft_5x8, 59, 64, ct_rand, NULL, "+", 0); //DEBUG
- /// End Display LED output ///
- // Wait until we're ready to show it.
- clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next_time, NULL);
- // Atomic swap with double buffer
- offscreen = matrix->SwapOnVSync(offscreen);
- next_time.tv_sec += 1;
- }
- // Finished. Shut down the RGB matrix.
- delete matrix;
- write(STDOUT_FILENO, "\n", 1); // Create a fresh new line after ^C on screen
- return 0;
- }
|