Repository navigation
Expand file tree
/
Copy pathThemeParkModule.hpp
More file actions
139 lines (117 loc) · 5.21 KB
/
Copy pathThemeParkModule.hpp
File metadata and controls
139 lines (117 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#ifndef THEMEPARKMODULE_HPP
#define THEMEPARKMODULE_HPP
#include "DrawableModule.hpp"
#include <U8g2_for_Adafruit_GFX.h>
#include "PsramUtils.hpp"
#include <functional>
#include "PixelScroller.hpp"
class WebClientModule;
struct DeviceConfig;
struct Attraction {
PsramString name;
int waitTime; // in minutes
bool isOpen;
Attraction() : waitTime(0), isOpen(false) {}
};
struct ThemeParkData {
PsramString id;
PsramString name;
PsramString country;
float crowdLevel; // 0-100 scale from API (was int 0-10)
PsramVector<Attraction> attractions;
time_t lastUpdate;
bool isOpen;
PsramString openingTime; // e.g. "09:00"
PsramString closingTime; // e.g. "18:00"
int attractionPages; // Number of pages needed to show all attractions
ThemeParkData() : crowdLevel(0.0f), lastUpdate(0), isOpen(false), attractionPages(1) {}
};
struct AvailablePark {
PsramString id;
PsramString name;
PsramString country;
AvailablePark() {}
AvailablePark(const PsramString& parkId, const PsramString& parkName)
: id(parkId), name(parkName) {}
AvailablePark(const PsramString& parkId, const PsramString& parkName, const PsramString& parkCountry)
: id(parkId), name(parkName), country(parkCountry) {}
};
class ThemeParkModule : public DrawableModule {
public:
ThemeParkModule(U8G2_FOR_ADAFRUIT_GFX& u8g2, GFXcanvas16& canvas, WebClientModule* webClient);
~ThemeParkModule();
void begin();
void setConfig(const DeviceConfig* config);
void queueData();
void processData();
void onUpdate(std::function<void()> callback);
// DrawableModule Interface
const char* getModuleName() const override { return "ThemeParkModule"; }
const char* getModuleDisplayName() const override { return "Freizeitparks"; }
void draw() override;
void tick() override;
void logicTick() override;
void resetPaging() override;
bool isEnabled() override;
unsigned long getDisplayDuration() override;
int getCurrentPage() const override { return _currentPage; }
int getTotalPages() const override { return _totalPages; }
void configure(const ModuleConfig& config) override;
void onActivate() override;
// Public methods for web configuration
PsramVector<AvailablePark> getAvailableParks();
void parseAvailableParks(const char* jsonBuffer, size_t size);
void checkAndUpdateParksList(); // Check if parks list needs daily update
private:
U8G2_FOR_ADAFRUIT_GFX& _u8g2;
GFXcanvas16& _canvas;
WebClientModule* _webClient;
const DeviceConfig* _config;
SemaphoreHandle_t _dataMutex;
ModuleConfig _modConfig;
PsramVector<ThemeParkData> _parkData;
PsramVector<AvailablePark> _availableParks;
PsramVector<PsramString> _parkIds; // Configured park IDs
// Track last processed update time for each park to avoid reprocessing same data
// Using PsramVector of pairs instead of std::map for PSRAM allocation
struct ProcessedTimeEntry {
PsramString parkId;
time_t timestamp;
ProcessedTimeEntry() : timestamp(0) {}
ProcessedTimeEntry(const PsramString& id, time_t ts) : parkId(id), timestamp(ts) {}
};
PsramVector<ProcessedTimeEntry> _lastProcessedWaitTimes;
PsramVector<ProcessedTimeEntry> _lastProcessedOpeningTimes;
PsramVector<ProcessedTimeEntry> _lastProcessedCrowdLevel;
int _currentPage;
int _currentParkIndex; // Index of current park being displayed
int _currentAttractionPage; // Current attraction page within park
int _totalPages;
uint32_t _logicTicksSincePageSwitch;
unsigned long _pageDisplayDuration;
time_t _lastUpdate;
time_t _lastParksListUpdate; // Track when parks list was last updated
time_t _lastParkDetailsUpdate; // Track when park details (name, hours) were updated
std::function<void()> _updateCallback;
// PixelScroller für pixelweises Scrolling
PixelScroller* _parkNameScroller = nullptr; // Scroller für Parknamen
PixelScroller* _attractionScroller = nullptr; // Scroller für Attraktionsnamen
void parseWaitTimes(const char* jsonBuffer, size_t size, const PsramString& parkId);
void parseCrowdLevel(const char* jsonBuffer, size_t size, const PsramString& parkId);
void parseOpeningTimes(const char* jsonBuffer, size_t size, const PsramString& parkId);
bool shouldDisplayPark(const ThemeParkData& park) const;
bool parkHasOpenAttractions(const ThemeParkData& park) const; // Check if park has at least one open attraction
int calculateTotalPages() const; // Calculate total pages considering closed/open parks
void drawParkPage(int parkIndex, int attractionPage);
void drawNoDataPage();
uint16_t getCrowdLevelColor(float level);
uint16_t calcColor(float value, float low, float high); // Calculate color gradient
uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b); // Convert RGB to RGB565
PsramString truncateString(const PsramString& text, int maxWidth);
// Cache management
void loadParkCache();
void saveParkCache();
PsramString getParkNameFromCache(const PsramString& parkId);
PsramString getParkCountryFromCache(const PsramString& parkId);
};
#endif // THEMEPARKMODULE_HPP