Skip to content

Commit

Permalink
Merge pull request #1 from vladkorotnev/develop
Browse files Browse the repository at this point in the history
Release 1.1
  • Loading branch information
vladkorotnev authored May 31, 2024
2 parents a48d814 + 6767966 commit a752baf
Show file tree
Hide file tree
Showing 19 changed files with 702 additions and 13 deletions.
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ ADMIN_PASS=\"plasma\"
# OpenWeatherMap configuration
WEATHER_LAT=\"43.0642\"
WEATHER_LON=\"141.3469\"
WEATHER_API_KEY=\"your OpenWeatherMap API Key\"
WEATHER_API_KEY=\"your OpenWeatherMap API Key\"

# Wordnik configuration
WORDNIK_API_KEY=\"your Wordnik API key\"
15 changes: 15 additions & 0 deletions include/service/foo_client.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once
#include <freertos/FreeRTOS.h>

// Output option for foo_controlserver:
// %artist%|%title%
// Also set the main delimiter to |

#define FOO_SEPARATOR '|'

void foo_client_begin();

bool foo_is_playing();
void foo_get_title(char *, size_t);
void foo_get_artist(char *, size_t);
TickType_t foo_last_recv();
10 changes: 10 additions & 0 deletions include/service/prefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ static constexpr prefs_key_t PREFS_KEY_WIFI_PASS = "pass";

static constexpr prefs_key_t PREFS_KEY_FPS_COUNTER = "fps_c";

static constexpr prefs_key_t PREFS_KEY_BLINK_SEPARATORS = "blink_separator";
static constexpr prefs_key_t PREFS_KEY_TICKING_SOUND = "ticking_sound";
static constexpr prefs_key_t PREFS_KEY_NO_SOUND_WHEN_OFF = "no_tick_off";

Expand All @@ -22,11 +23,17 @@ static constexpr prefs_key_t PREFS_KEY_WEATHER_LON = "w_lon";
static constexpr prefs_key_t PREFS_KEY_WEATHER_APIKEY = "w_apikey";
static constexpr prefs_key_t PREFS_KEY_WEATHER_INTERVAL_MINUTES = "w_interval_m";

static constexpr prefs_key_t PREFS_KEY_WORDNIK_APIKEY = "wd_apikey";
static constexpr prefs_key_t PREFS_KEY_WORDNIK_INTERVAL_MINUTES = "wd_interval_m";

static constexpr prefs_key_t PREFS_KEY_TRANSITION_TYPE = "s_transition";
static constexpr prefs_key_t PREFS_KEY_DISP_SCROLL_SPEED = "s_scrl_spd";

static constexpr prefs_key_t PREFS_KEY_SCRN_TIME_CLOCK_SECONDS = "s_clock_s";
static constexpr prefs_key_t PREFS_KEY_SCRN_TIME_INDOOR_SECONDS = "s_inside_s";
static constexpr prefs_key_t PREFS_KEY_SCRN_TIME_OUTDOOR_SECONDS = "s_outside_s";
static constexpr prefs_key_t PREFS_KEY_SCRN_TIME_WORD_OF_THE_DAY_SECONDS = "s_wotd_s";
static constexpr prefs_key_t PREFS_KEY_SCRN_TIME_FOOBAR_SECONDS = "s_foo_s";

static constexpr prefs_key_t PREFS_KEY_HOURLY_CHIME_ON = "h_chime_on";
static constexpr prefs_key_t PREFS_KEY_HOURLY_CHIME_START_HOUR = "h_chime_start";
Expand All @@ -38,6 +45,9 @@ static constexpr prefs_key_t PREFS_KEY_TIMEZONE = "tk_tz";
static constexpr prefs_key_t PREFS_KEY_TIMESERVER = "tk_ntp_serv";
static constexpr prefs_key_t PREFS_KEY_TIME_SYNC_INTERVAL_SEC = "tk_intv_s";

static constexpr prefs_key_t PREFS_KEY_FOOBAR_SERVER = "foo_svr";
static constexpr prefs_key_t PREFS_KEY_FOOBAR_PORT = "foo_prt";

void prefs_force_save();

String prefs_get_string(prefs_key_t, String def = String());
Expand Down
6 changes: 6 additions & 0 deletions include/service/wordnik.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once
#include <freertos/FreeRTOS.h>

void wotd_start();
bool wotd_get_current(char * word, size_t word_sz, char * definition, size_t def_sz);
TickType_t wotd_get_last_update();
21 changes: 21 additions & 0 deletions include/views/fb2k.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include "view.h"
#include <plasma/fanta_manipulator.h>
#include <views/string_scroll.h>

class Fb2kView: public Renderable {
public:
Fb2kView();
void prepare();
void step();
void render(FantaManipulator*);

private:
void update_if_needed();
const font_definition_t * font;
char artist_buffer[128];
char title_buffer[128];
TickType_t last_update;
StringScroll * top_line;
StringScroll * bottom_line;
};
1 change: 1 addition & 0 deletions include/views/simple_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ class SimpleClock: public Renderable {
tk_time_of_day_t next_time;
int phase;
char separator;
bool blink_separator;
};
2 changes: 2 additions & 0 deletions include/views/string_scroll.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ class StringScroll: public Renderable {
private:
const font_definition_t * font;
const char * string;
bool scroll_only_if_not_fit;
int y_position;
int position;
int frame_divisor;
int increment;
int string_width;
int frame_counter;
};
21 changes: 21 additions & 0 deletions include/views/word_of_the_day.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once
#include "view.h"
#include <plasma/fanta_manipulator.h>
#include <views/string_scroll.h>

class WordOfTheDayView: public Renderable {
public:
WordOfTheDayView();
void prepare();
void step();
void render(FantaManipulator*);

private:
const font_definition_t * font;
char word_buffer[32];
char definition_buffer[256];
TickType_t last_update;
ani_sprite_state_t icon_state;
sprite_t current_icon_frame;
StringScroll * bottom_line;
};
38 changes: 35 additions & 3 deletions src/idle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,24 @@
#include <service/time.h>
#include <service/owm/weather.h>
#include <service/prefs.h>
#include <service/foo_client.h>
#include <views/simple_clock.h>
#include <views/rain_ovl.h>
#include <views/thunder_ovl.h>
#include <views/indoor_view.h>
#include <views/framework.h>
#include <views/current_weather.h>
#include <views/word_of_the_day.h>
#include <views/fb2k.h>

static char LOG_TAG[] = "APL_IDLE";

typedef enum MainViewId: uint16_t {
VIEW_CLOCK = 0,
VIEW_INDOOR_WEATHER,
VIEW_OUTDOOR_WEATHER,
VIEW_WORD_OF_THE_DAY,
VIEW_FB2K,

VIEW_MAX
} MainViewId_t;
Expand All @@ -26,6 +31,8 @@ static int screen_times_ms[VIEW_MAX] = {
30000, // VIEW_CLOCK
10000, // VIEW_INDOOR_WEATHER
25000, // VIEW_OUTDOOR_WEATHER
25000, // VIEW_WORD_OF_THE_DAY
0, // VIEW_FB2K
};

static bool did_prepare = false;
Expand All @@ -43,6 +50,8 @@ static ThunderOverlay * thunder;

static IndoorView * indoorView;
static CurrentWeatherView * weatherView;
static WordOfTheDayView * wotdView;
static Fb2kView *fb2kView;

static ViewMultiplexor * slideShow;

Expand Down Expand Up @@ -150,15 +159,30 @@ void app_idle_prepare(SensorPool* s, Beeper* b) {
tick_tock_enable = prefs_get_bool(PREFS_KEY_TICKING_SOUND);
hourly_chime_on = prefs_get_bool(PREFS_KEY_HOURLY_CHIME_ON);

screen_times_ms[VIEW_CLOCK] = std::max(prefs_get_int(PREFS_KEY_SCRN_TIME_CLOCK_SECONDS) * 1000, 1000);
screen_times_ms[VIEW_INDOOR_WEATHER] = std::max(prefs_get_int(PREFS_KEY_SCRN_TIME_INDOOR_SECONDS) * 1000, 1000);
screen_times_ms[VIEW_OUTDOOR_WEATHER] = std::max(prefs_get_int(PREFS_KEY_SCRN_TIME_OUTDOOR_SECONDS) * 1000, 1000);
screen_times_ms[VIEW_CLOCK] = prefs_get_int(PREFS_KEY_SCRN_TIME_CLOCK_SECONDS) * 1000;
screen_times_ms[VIEW_INDOOR_WEATHER] = prefs_get_int(PREFS_KEY_SCRN_TIME_INDOOR_SECONDS) * 1000;
screen_times_ms[VIEW_OUTDOOR_WEATHER] = prefs_get_int(PREFS_KEY_SCRN_TIME_OUTDOOR_SECONDS) * 1000;
screen_times_ms[VIEW_WORD_OF_THE_DAY] = prefs_get_int(PREFS_KEY_SCRN_TIME_WORD_OF_THE_DAY_SECONDS) * 1000;
// VIEW_FB2K gets set dynamically in processing()

bool has_at_least_one_screen = false;
for(int i = 0; i < VIEW_MAX; i++) {
if(screen_times_ms[i] != 0) {
has_at_least_one_screen = true;
break;
}
}
if(!has_at_least_one_screen) {
screen_times_ms[VIEW_CLOCK] = 3600000;
}

clockView = new SimpleClock();
indoorView = new IndoorView(sensors);
rain = new RainOverlay(101, 16);
thunder = new ThunderOverlay(101, 16);
weatherView = new CurrentWeatherView();
wotdView = new WordOfTheDayView();
fb2kView = new Fb2kView();

// thunder hurts readability on other views, so keep it on clock only
ViewCompositor * thunderClock = new ViewCompositor();
Expand All @@ -169,6 +193,8 @@ void app_idle_prepare(SensorPool* s, Beeper* b) {
slideShow->add_view(thunderClock, VIEW_CLOCK);
slideShow->add_view(indoorView, VIEW_INDOOR_WEATHER);
slideShow->add_view(weatherView, VIEW_OUTDOOR_WEATHER);
slideShow->add_view(wotdView, VIEW_WORD_OF_THE_DAY);
slideShow->add_view(fb2kView, VIEW_FB2K);

lastScreenSwitch = xTaskGetTickCount();

Expand All @@ -185,6 +211,10 @@ void change_screen_if_needed() {
if(now - lastScreenSwitch >= pdMS_TO_TICKS(screen_times_ms[curScreen])) {
curScreen = (MainViewId_t) (((uint16_t) curScreen) + 1);
if(curScreen == VIEW_MAX) curScreen = VIEW_CLOCK;
while(screen_times_ms[curScreen] == 0) {
curScreen = (MainViewId_t) (((uint16_t) curScreen) + 1);
if(curScreen == VIEW_MAX) curScreen = VIEW_CLOCK;
}
slideShow->switch_to(curScreen, (transition_type_t) prefs_get_int(PREFS_KEY_TRANSITION_TYPE));
lastScreenSwitch = now;
}
Expand Down Expand Up @@ -214,4 +244,6 @@ void app_idle_process() {

tick_tock_enable = prefs_get_bool(PREFS_KEY_TICKING_SOUND);
hourly_chime_on = prefs_get_bool(PREFS_KEY_HOURLY_CHIME_ON);
screen_times_ms[VIEW_FB2K] =
foo_is_playing() ? (prefs_get_int(PREFS_KEY_SCRN_TIME_FOOBAR_SECONDS) * 1000) : 0;
}
6 changes: 5 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include <service/owm/weather.h>
#include <service/time.h>
#include <service/prefs.h>
#include <service/wordnik.h>
#include <service/foo_client.h>
#include <network/admin_panel.h>
#include <utils.h>
#include <state.h>
Expand Down Expand Up @@ -75,7 +77,7 @@ void setup() {
con->set_cursor(true);

// Plasma Information System OS (not DOS, there's no disk in it!)
con->print("PIS-OS v1.0\n");
con->print("PIS-OS v1.1\n");
delay(500);

beepola = new Beeper(HWCONF_BEEPER_GPIO, HWCONF_BEEPER_PWM_CHANNEL);
Expand Down Expand Up @@ -130,6 +132,8 @@ void setup() {

timekeeping_begin();
weather_start();
wotd_start();
foo_client_begin();
power_mgmt_start(sensors, &plasma, beepola);
admin_panel_prepare(sensors, beepola);
fps_counter = prefs_get_bool(PREFS_KEY_FPS_COUNTER);
Expand Down
46 changes: 43 additions & 3 deletions src/network/admin_panel.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "network/admin_panel.h"
#include <service/prefs.h>
#include <service/owm/weather.h>
#include <service/wordnik.h>
#include <views/transitions.h>
#include <sound/melodies.h>
#include <GyverPortal.h>
Expand Down Expand Up @@ -112,6 +113,7 @@ void build() {
GP.BREAK();

GP.SPOILER_BEGIN("Clock", GP_BLUE);
render_bool("Blink separators:", PREFS_KEY_BLINK_SEPARATORS);
render_bool("Ticking sound:", PREFS_KEY_TICKING_SOUND);
render_bool("Only when screen is on:", PREFS_KEY_NO_SOUND_WHEN_OFF);
GP.HR();
Expand All @@ -138,9 +140,16 @@ void build() {
render_int("Show temperature for [s]:", PREFS_KEY_SCRN_TIME_INDOOR_SECONDS);
GP.BREAK();
render_int("Show current weather for [s]:", PREFS_KEY_SCRN_TIME_OUTDOOR_SECONDS);
GP.BREAK();
render_int("Show word of the day for [s]:", PREFS_KEY_SCRN_TIME_WORD_OF_THE_DAY_SECONDS);
GP.BREAK();
render_int("Show Fb2k for [s]:", PREFS_KEY_SCRN_TIME_FOOBAR_SECONDS);
GP.HR();
GP.LABEL("Screen transition:");
GP.SELECT(PREFS_KEY_TRANSITION_TYPE, "Off,Wipe,Horizontal Slide,Vertical Slide,Random", prefs_get_int(PREFS_KEY_TRANSITION_TYPE));
GP.HR();
GP.LABEL("Scroll speed:");
GP.SELECT(PREFS_KEY_DISP_SCROLL_SPEED, "Slow,Medium,Fast,Sonic", prefs_get_int(PREFS_KEY_DISP_SCROLL_SPEED));
GP.SPOILER_END();
GP.BREAK();

Expand Down Expand Up @@ -211,6 +220,29 @@ void build() {
GP.NUMBER("demo_weather", "Demo weather code", 200);
#endif
GP.SPOILER_END();
GP.BREAK();

GP.SPOILER_BEGIN("Wordnik", GP_BLUE);
render_string("API Key", PREFS_KEY_WORDNIK_APIKEY, true);
render_int("Update interval [m]:", PREFS_KEY_WORDNIK_INTERVAL_MINUTES);

char wotd[32];
char definition[256];
if(wotd_get_current(wotd, 32, definition, 256)) {
GP.HR();
GP.LABEL("Today's word:");
GP.LABEL(wotd);
GP.BREAK();
GP.SPAN(definition);
}
GP.SPOILER_END();
GP.BREAK();

GP.SPOILER_BEGIN("Foobar2000", GP_BLUE);
render_string("Control Server IP", PREFS_KEY_FOOBAR_SERVER);
render_int("Control Server Port:", PREFS_KEY_FOOBAR_PORT);
GP.SPAN("Please set the format in foo_controlserver to: %artist%|%title%, and main delimiter to: |");
GP.SPOILER_END();

GP.HR();
#if defined(PDFB_PERF_LOGS)
Expand All @@ -224,6 +256,7 @@ void action() {
if(ui.click()) {
save_string(PREFS_KEY_WIFI_SSID);
save_string(PREFS_KEY_WIFI_PASS);
save_bool(PREFS_KEY_BLINK_SEPARATORS);
save_bool(PREFS_KEY_TICKING_SOUND);
save_bool(PREFS_KEY_HOURLY_CHIME_ON);
save_int(PREFS_KEY_HOURLY_CHIME_START_HOUR, 0, 23);
Expand All @@ -233,11 +266,14 @@ void action() {
save_string(PREFS_KEY_TIMESERVER);
save_string(PREFS_KEY_TIMEZONE);
save_int(PREFS_KEY_TIME_SYNC_INTERVAL_SEC, 600, 21600);
save_int(PREFS_KEY_SCRN_TIME_CLOCK_SECONDS, 1, 3600);
save_int(PREFS_KEY_SCRN_TIME_INDOOR_SECONDS, 1, 3600);
save_int(PREFS_KEY_SCRN_TIME_OUTDOOR_SECONDS, 1, 3600);
save_int(PREFS_KEY_SCRN_TIME_CLOCK_SECONDS, 0, 3600);
save_int(PREFS_KEY_SCRN_TIME_INDOOR_SECONDS, 0, 3600);
save_int(PREFS_KEY_SCRN_TIME_OUTDOOR_SECONDS, 0, 3600);
save_int(PREFS_KEY_SCRN_TIME_WORD_OF_THE_DAY_SECONDS, 0, 3600);
save_int(PREFS_KEY_SCRN_TIME_FOOBAR_SECONDS, 0, 3600);
save_bool(PREFS_KEY_NO_SOUND_WHEN_OFF);
save_int(PREFS_KEY_TRANSITION_TYPE, TRANSITION_NONE, TRANSITION_RANDOM);
save_int(PREFS_KEY_DISP_SCROLL_SPEED, 0, 4);
save_int(PREFS_KEY_LIGHTNESS_THRESH_UP, 0, 4096);
save_int(PREFS_KEY_LIGHTNESS_THRESH_DOWN, 0, 4096);
save_int(PREFS_KEY_MOTIONLESS_TIME_OFF_SECONDS, 60, 21600);
Expand All @@ -246,6 +282,10 @@ void action() {
save_string(PREFS_KEY_WEATHER_LAT);
save_string(PREFS_KEY_WEATHER_LON);
save_int(PREFS_KEY_WEATHER_INTERVAL_MINUTES, 30, 24 * 60);
save_string(PREFS_KEY_WORDNIK_APIKEY);
save_int(PREFS_KEY_WORDNIK_INTERVAL_MINUTES, 60, 3600);
save_string(PREFS_KEY_FOOBAR_SERVER);
save_int(PREFS_KEY_FOOBAR_PORT, 1000, 9999);
save_bool(PREFS_KEY_FPS_COUNTER);

#ifdef DEMO_WEATHER_WEBADMIN
Expand Down
Loading

0 comments on commit a752baf

Please sign in to comment.