mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-06 23:57:39 +03:00
Add auto-sleep timeout setting and handle it in loop
Incremented settings count, added autoSleepMinutes to CrossPointSettings, updated save/load functions, and integrated auto-sleep logic based on the new setting.
This commit is contained in:
parent
490ae79ede
commit
9ab27f848c
1
docs/Upload_EPUBs_to_CrossPoint.macro
Normal file
1
docs/Upload_EPUBs_to_CrossPoint.macro
Normal file
File diff suppressed because one or more lines are too long
174
docs/Upload_EPUBs_to_CrossPoint.tsk.xml
Normal file
174
docs/Upload_EPUBs_to_CrossPoint.tsk.xml
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
<TaskerData sr="" dvi="1" tv="6.5.11">
|
||||||
|
<Task sr="task6">
|
||||||
|
<cdate>1767235270638</cdate>
|
||||||
|
<edate>1767236697913</edate>
|
||||||
|
<id>6</id>
|
||||||
|
<nme>Upload EPUBs to CrossPoint</nme>
|
||||||
|
<Action sr="act0" ve="7">
|
||||||
|
<code>398</code>
|
||||||
|
<Str sr="arg0" ve="3">CrossPoint-Reader</Str>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act1" ve="7">
|
||||||
|
<code>547</code>
|
||||||
|
<Str sr="arg0" ve="3">%READER_IP</Str>
|
||||||
|
<Str sr="arg1" ve="3">192.168.4.1</Str>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
<Int sr="arg5" val="3"/>
|
||||||
|
<Int sr="arg6" val="1"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act10" ve="7">
|
||||||
|
<code>37</code>
|
||||||
|
<ConditionList sr="if">
|
||||||
|
<Condition sr="c0" ve="3">
|
||||||
|
<lhs>%file_list</lhs>
|
||||||
|
<op>13</op>
|
||||||
|
<rhs>"%filename"</rhs>
|
||||||
|
</Condition>
|
||||||
|
</ConditionList>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act11" ve="7">
|
||||||
|
<code>339</code>
|
||||||
|
<se>false</se>
|
||||||
|
<Bundle sr="arg0">
|
||||||
|
<Vals sr="val">
|
||||||
|
<file>%epub_file:file</file>
|
||||||
|
<file-type>java.lang.String</file-type>
|
||||||
|
</Vals>
|
||||||
|
</Bundle>
|
||||||
|
<Int sr="arg1" val="1"/>
|
||||||
|
<Int sr="arg10" val="0"/>
|
||||||
|
<Int sr="arg11" val="0"/>
|
||||||
|
<Int sr="arg12" val="1"/>
|
||||||
|
<Str sr="arg2" ve="3">http://%READER_IP/upload?path=%TARGET_DIR</Str>
|
||||||
|
<Str sr="arg3" ve="3"/>
|
||||||
|
<Str sr="arg4" ve="3"/>
|
||||||
|
<Str sr="arg5" ve="3"/>
|
||||||
|
<Str sr="arg6" ve="3"/>
|
||||||
|
<Str sr="arg7" ve="3">%upload_response</Str>
|
||||||
|
<Int sr="arg8" val="60"/>
|
||||||
|
<Int sr="arg9" val="0"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act12" ve="7">
|
||||||
|
<code>548</code>
|
||||||
|
<Str sr="arg0" ve="3">✓ %filename</Str>
|
||||||
|
<Int sr="arg1" val="0"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act13" ve="7">
|
||||||
|
<code>43</code>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act14" ve="7">
|
||||||
|
<code>40</code>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act15" ve="7">
|
||||||
|
<code>523</code>
|
||||||
|
<Str sr="arg0" ve="3">Upload Complete</Str>
|
||||||
|
<Str sr="arg1" ve="3">Processed %EPUB_FILES(#) files</Str>
|
||||||
|
<Str sr="arg10" ve="3"/>
|
||||||
|
<Str sr="arg11" ve="3"/>
|
||||||
|
<Str sr="arg12" ve="3"/>
|
||||||
|
<Img sr="arg2" ve="2"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
<Int sr="arg5" val="3"/>
|
||||||
|
<Int sr="arg6" val="0"/>
|
||||||
|
<Int sr="arg7" val="0"/>
|
||||||
|
<Int sr="arg8" val="0"/>
|
||||||
|
<Str sr="arg9" ve="3"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act2" ve="7">
|
||||||
|
<code>30</code>
|
||||||
|
<Int sr="arg0" val="0"/>
|
||||||
|
<Int sr="arg1" val="5"/>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act3" ve="7">
|
||||||
|
<code>547</code>
|
||||||
|
<Str sr="arg0" ve="3">%SOURCE_DIR</Str>
|
||||||
|
<Str sr="arg1" ve="3">/storage/emulated/0/Documents/ereader</Str>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
<Int sr="arg5" val="3"/>
|
||||||
|
<Int sr="arg6" val="1"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act4" ve="7">
|
||||||
|
<code>547</code>
|
||||||
|
<Str sr="arg0" ve="3">%TARGET_DIR</Str>
|
||||||
|
<Str sr="arg1" ve="3">/books</Str>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
<Int sr="arg5" val="3"/>
|
||||||
|
<Int sr="arg6" val="1"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act5" ve="7">
|
||||||
|
<code>412</code>
|
||||||
|
<Str sr="arg0" ve="3">%SOURCE_DIR</Str>
|
||||||
|
<Str sr="arg1" ve="3">*.epub</Str>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
<Str sr="arg5" ve="3">%EPUB_FILES</Str>
|
||||||
|
<Int sr="arg6" val="1"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act6" ve="7">
|
||||||
|
<code>39</code>
|
||||||
|
<Str sr="arg0" ve="3">%epub_file</Str>
|
||||||
|
<Str sr="arg1" ve="3">%EPUB_FILES()</Str>
|
||||||
|
<Int sr="arg2" val="1"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act7" ve="7">
|
||||||
|
<code>590</code>
|
||||||
|
<Str sr="arg0" ve="3">%epub_file</Str>
|
||||||
|
<Str sr="arg1" ve="3">/</Str>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act8" ve="7">
|
||||||
|
<code>547</code>
|
||||||
|
<Str sr="arg0" ve="3">%filename</Str>
|
||||||
|
<Str sr="arg1" ve="3">%epub_file(#)</Str>
|
||||||
|
<Int sr="arg2" val="0"/>
|
||||||
|
<Int sr="arg3" val="0"/>
|
||||||
|
<Int sr="arg4" val="0"/>
|
||||||
|
<Int sr="arg5" val="3"/>
|
||||||
|
<Int sr="arg6" val="1"/>
|
||||||
|
</Action>
|
||||||
|
<Action sr="act9" ve="7">
|
||||||
|
<code>339</code>
|
||||||
|
<se>false</se>
|
||||||
|
<Bundle sr="arg0">
|
||||||
|
<Vals sr="val">
|
||||||
|
<net.dinglisch.android.tasker.RELEVANT_VARIABLES><StringArray sr=""><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0>%http_cookies
|
||||||
|
Cookies
|
||||||
|
The cookies the server sent in the response in the Cookie:COOKIE_VALUE format. You can use this directly in the 'Headers' field of the HTTP Request action</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES0><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1>%http_file_output
|
||||||
|
File Output
|
||||||
|
Will always contain the file's full path even if you specified a directory as the File to save.</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES1><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2>%http_response_code
|
||||||
|
Response Code
|
||||||
|
The HTTP Code the server responded</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES2><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3>%http_headers()
|
||||||
|
Response Headers
|
||||||
|
The HTTP Headers the server sent in the response. Each header is in the 'key:value' format</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES3><_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4>%http_response_length
|
||||||
|
Response Length
|
||||||
|
The size of the response in bytes</_array_net.dinglisch.android.tasker.RELEVANT_VARIABLES4></StringArray></net.dinglisch.android.tasker.RELEVANT_VARIABLES>
|
||||||
|
<net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>[Ljava.lang.String;</net.dinglisch.android.tasker.RELEVANT_VARIABLES-type>
|
||||||
|
</Vals>
|
||||||
|
</Bundle>
|
||||||
|
<Int sr="arg1" val="0"/>
|
||||||
|
<Int sr="arg10" val="0"/>
|
||||||
|
<Int sr="arg11" val="0"/>
|
||||||
|
<Int sr="arg12" val="1"/>
|
||||||
|
<Str sr="arg2" ve="3">http://%READER_IP/api/files?path=%TARGET_DIR</Str>
|
||||||
|
<Str sr="arg3" ve="3"/>
|
||||||
|
<Str sr="arg4" ve="3"/>
|
||||||
|
<Str sr="arg5" ve="3"/>
|
||||||
|
<Str sr="arg6" ve="3"/>
|
||||||
|
<Str sr="arg7" ve="3">%file_list</Str>
|
||||||
|
<Int sr="arg8" val="10"/>
|
||||||
|
<Int sr="arg9" val="0"/>
|
||||||
|
</Action>
|
||||||
|
</Task>
|
||||||
|
</TaskerData>
|
||||||
10
docs/test.sh
Normal file
10
docs/test.sh
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# Test 1: Check if curl exists
|
||||||
|
which curl
|
||||||
|
echo "---"
|
||||||
|
# Test 2: Try simple HTTP request
|
||||||
|
curl -v "http://192.168.4.1/" 2>&1
|
||||||
|
echo "---"
|
||||||
|
# Test 3: Try file upload with simple filename (no spaces)
|
||||||
|
echo "test" > /sdcard/test.txt
|
||||||
|
curl -v -X POST -F "file=@/sdcard/test.txt" "http://192.168.4.1/upload?path=/" 2>&1
|
||||||
|
|
||||||
32
flake.nix
32
flake.nix
@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
description = "CrossPoint Reader - ESP32 E-Paper Firmware";
|
|
||||||
|
|
||||||
inputs = {
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = { self, nixpkgs, flake-utils }:
|
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
|
||||||
let
|
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
platformio
|
|
||||||
python3
|
|
||||||
git
|
|
||||||
];
|
|
||||||
|
|
||||||
shellHook = ''
|
|
||||||
echo "CrossPoint Reader development environment"
|
|
||||||
echo "Commands:"
|
|
||||||
echo " pio run - Build firmware"
|
|
||||||
echo " pio run -t upload - Build and flash to device"
|
|
||||||
echo " pio run -t clean - Clean build artifacts"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
15
shell.nix
15
shell.nix
@ -1,15 +0,0 @@
|
|||||||
{ pkgs ? import <nixpkgs> {} }:
|
|
||||||
|
|
||||||
pkgs.mkShell {
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
platformio
|
|
||||||
python3
|
|
||||||
git
|
|
||||||
];
|
|
||||||
|
|
||||||
shellHook = ''
|
|
||||||
echo "PlatformIO development environment loaded"
|
|
||||||
echo "Run 'pio run' to build the firmware"
|
|
||||||
echo "Run 'pio run -t upload' to build and flash"
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
@ -12,7 +12,7 @@ CrossPointSettings CrossPointSettings::instance;
|
|||||||
namespace {
|
namespace {
|
||||||
constexpr uint8_t SETTINGS_FILE_VERSION = 1;
|
constexpr uint8_t SETTINGS_FILE_VERSION = 1;
|
||||||
// Increment this when adding new persisted settings fields
|
// Increment this when adding new persisted settings fields
|
||||||
constexpr uint8_t SETTINGS_COUNT = 12;
|
constexpr uint8_t SETTINGS_COUNT = 13;
|
||||||
constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
|
constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin";
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@ -39,6 +39,7 @@ bool CrossPointSettings::saveToFile() const {
|
|||||||
serialization::writePod(outputFile, lineSpacing);
|
serialization::writePod(outputFile, lineSpacing);
|
||||||
serialization::writePod(outputFile, bluetoothEnabled);
|
serialization::writePod(outputFile, bluetoothEnabled);
|
||||||
serialization::writePod(outputFile, useCoverArtPicker);
|
serialization::writePod(outputFile, useCoverArtPicker);
|
||||||
|
serialization::writePod(outputFile, autoSleepMinutes);
|
||||||
outputFile.close();
|
outputFile.close();
|
||||||
|
|
||||||
Serial.printf("[%lu] [CPS] Settings saved to file\n", millis());
|
Serial.printf("[%lu] [CPS] Settings saved to file\n", millis());
|
||||||
@ -89,6 +90,8 @@ bool CrossPointSettings::loadFromFile() {
|
|||||||
if (++settingsRead >= fileSettingsCount) break;
|
if (++settingsRead >= fileSettingsCount) break;
|
||||||
serialization::readPod(inputFile, useCoverArtPicker);
|
serialization::readPod(inputFile, useCoverArtPicker);
|
||||||
if (++settingsRead >= fileSettingsCount) break;
|
if (++settingsRead >= fileSettingsCount) break;
|
||||||
|
serialization::readPod(inputFile, autoSleepMinutes);
|
||||||
|
if (++settingsRead >= fileSettingsCount) break;
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
inputFile.close();
|
inputFile.close();
|
||||||
|
|||||||
@ -66,6 +66,8 @@ class CrossPointSettings {
|
|||||||
uint8_t bluetoothEnabled = 0;
|
uint8_t bluetoothEnabled = 0;
|
||||||
// File browser settings
|
// File browser settings
|
||||||
uint8_t useCoverArtPicker = 0;
|
uint8_t useCoverArtPicker = 0;
|
||||||
|
// Auto-sleep timeout (enum index: 0=5min, 1=10min, 2=15min, 3=20min, 4=30min, 5=60min, 6=Never)
|
||||||
|
uint8_t autoSleepMinutes = 1; // Default to 10 minutes
|
||||||
|
|
||||||
~CrossPointSettings() = default;
|
~CrossPointSettings() = default;
|
||||||
|
|
||||||
@ -74,6 +76,19 @@ class CrossPointSettings {
|
|||||||
|
|
||||||
uint16_t getPowerButtonDuration() const { return shortPwrBtn ? 10 : 400; }
|
uint16_t getPowerButtonDuration() const { return shortPwrBtn ? 10 : 400; }
|
||||||
int getReaderFontId() const;
|
int getReaderFontId() const;
|
||||||
|
unsigned long getAutoSleepTimeoutMs() const {
|
||||||
|
// Map enum index to milliseconds: 0=5min, 1=10min, 2=15min, 3=20min, 4=30min, 5=60min, 6=Never(0)
|
||||||
|
constexpr unsigned long timeouts[] = {
|
||||||
|
5UL * 60UL * 1000UL, // 0: 5 minutes
|
||||||
|
10UL * 60UL * 1000UL, // 1: 10 minutes (default)
|
||||||
|
15UL * 60UL * 1000UL, // 2: 15 minutes
|
||||||
|
20UL * 60UL * 1000UL, // 3: 20 minutes
|
||||||
|
30UL * 60UL * 1000UL, // 4: 30 minutes
|
||||||
|
60UL * 60UL * 1000UL, // 5: 60 minutes
|
||||||
|
0UL // 6: Never (disabled)
|
||||||
|
};
|
||||||
|
return (autoSleepMinutes < 7) ? timeouts[autoSleepMinutes] : timeouts[1];
|
||||||
|
}
|
||||||
|
|
||||||
bool saveToFile() const;
|
bool saveToFile() const;
|
||||||
bool loadFromFile();
|
bool loadFromFile();
|
||||||
|
|||||||
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
// Define the static settings list
|
// Define the static settings list
|
||||||
namespace {
|
namespace {
|
||||||
constexpr int settingsCount = 13;
|
constexpr int settingsCount = 14;
|
||||||
const SettingInfo settingsList[settingsCount] = {
|
const SettingInfo settingsList[settingsCount] = {
|
||||||
// Should match with SLEEP_SCREEN_MODE
|
// Should match with SLEEP_SCREEN_MODE
|
||||||
{"Sleep Screen", SettingType::ENUM, &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover"}},
|
{"Sleep Screen", SettingType::ENUM, &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover"}},
|
||||||
@ -35,6 +35,10 @@ const SettingInfo settingsList[settingsCount] = {
|
|||||||
{"Reader Font Size", SettingType::ENUM, &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}},
|
{"Reader Font Size", SettingType::ENUM, &CrossPointSettings::fontSize, {"Small", "Medium", "Large", "X Large"}},
|
||||||
{"Reader Line Spacing", SettingType::ENUM, &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}},
|
{"Reader Line Spacing", SettingType::ENUM, &CrossPointSettings::lineSpacing, {"Tight", "Normal", "Wide"}},
|
||||||
{"Cover Art Picker", SettingType::TOGGLE, &CrossPointSettings::useCoverArtPicker, {}},
|
{"Cover Art Picker", SettingType::TOGGLE, &CrossPointSettings::useCoverArtPicker, {}},
|
||||||
|
{"Auto Sleep Timeout",
|
||||||
|
SettingType::ENUM,
|
||||||
|
&CrossPointSettings::autoSleepMinutes,
|
||||||
|
{"5 min", "10 min", "15 min", "20 min", "30 min", "60 min", "Never"}},
|
||||||
{"Bluetooth", SettingType::TOGGLE, &CrossPointSettings::bluetoothEnabled, {}},
|
{"Bluetooth", SettingType::TOGGLE, &CrossPointSettings::bluetoothEnabled, {}},
|
||||||
{"Check for updates", SettingType::ACTION, nullptr, {}},
|
{"Check for updates", SettingType::ACTION, nullptr, {}},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -127,8 +127,6 @@ EpdFont ui12RegularFont(&ubuntu_12_regular);
|
|||||||
EpdFont ui12BoldFont(&ubuntu_12_bold);
|
EpdFont ui12BoldFont(&ubuntu_12_bold);
|
||||||
EpdFontFamily ui12FontFamily(&ui12RegularFont, &ui12BoldFont);
|
EpdFontFamily ui12FontFamily(&ui12RegularFont, &ui12BoldFont);
|
||||||
|
|
||||||
// Auto-sleep timeout (10 minutes of inactivity)
|
|
||||||
constexpr unsigned long AUTO_SLEEP_TIMEOUT_MS = 10 * 60 * 1000;
|
|
||||||
// measurement of power button press duration calibration value
|
// measurement of power button press duration calibration value
|
||||||
unsigned long t1 = 0;
|
unsigned long t1 = 0;
|
||||||
unsigned long t2 = 0;
|
unsigned long t2 = 0;
|
||||||
@ -330,8 +328,10 @@ void loop() {
|
|||||||
lastActivityTime = millis(); // Reset inactivity timer
|
lastActivityTime = millis(); // Reset inactivity timer
|
||||||
}
|
}
|
||||||
|
|
||||||
if (millis() - lastActivityTime >= AUTO_SLEEP_TIMEOUT_MS) {
|
// Check auto-sleep timeout (if enabled - 0 means never sleep)
|
||||||
Serial.printf("[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", millis(), AUTO_SLEEP_TIMEOUT_MS);
|
const unsigned long autoSleepTimeout = SETTINGS.getAutoSleepTimeoutMs();
|
||||||
|
if (autoSleepTimeout > 0 && millis() - lastActivityTime >= autoSleepTimeout) {
|
||||||
|
Serial.printf("[%lu] [SLP] Auto-sleep triggered after %lu ms of inactivity\n", millis(), autoSleepTimeout);
|
||||||
enterDeepSleep();
|
enterDeepSleep();
|
||||||
// This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start
|
// This should never be hit as `enterDeepSleep` calls esp_deep_sleep_start
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user