first commit

This commit is contained in:
douboer@gmail.com
2026-03-15 09:30:40 +08:00
commit 3d19c4d34f
145 changed files with 11623 additions and 0 deletions

View File

@@ -0,0 +1,122 @@
#!/usr/bin/env sh
DEBUG=${DEBUG:-false}
[ "$DEBUG" = true ] && set -x
DIR="$(dirname "$0")"
DASH_PNG="$DIR/dash.png"
FETCH_DASHBOARD_CMD="$DIR/local/fetch-dashboard.sh"
LOW_BATTERY_CMD="$DIR/local/low-battery.sh"
REFRESH_SCHEDULE=${REFRESH_SCHEDULE:-"2,32 8-17 * * MON-FRI"}
FULL_DISPLAY_REFRESH_RATE=${FULL_DISPLAY_REFRESH_RATE:-0}
SLEEP_SCREEN_INTERVAL=${SLEEP_SCREEN_INTERVAL:-3600}
RTC=/sys/devices/platform/mxc_rtc.0/wakeup_enable
LOW_BATTERY_REPORTING=${LOW_BATTERY_REPORTING:-false}
LOW_BATTERY_THRESHOLD_PERCENT=${LOW_BATTERY_THRESHOLD_PERCENT:-10}
num_refresh=0
init() {
if [ -z "$TIMEZONE" ] || [ -z "$REFRESH_SCHEDULE" ]; then
echo "Missing required configuration."
echo "Timezone: ${TIMEZONE:-(not set)}."
echo "Schedule: ${REFRESH_SCHEDULE:-(not set)}."
exit 1
fi
echo "Starting dashboard with $REFRESH_SCHEDULE refresh..."
/etc/init.d/framework stop
initctl stop webreader >/dev/null 2>&1
echo powersave >/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
lipc-set-prop com.lab126.powerd preventScreenSaver 1
}
prepare_sleep() {
echo "Preparing sleep"
/usr/sbin/eips -f -g "$DIR/sleeping.png"
# Give screen time to refresh
sleep 2
# Ensure a full screen refresh is triggered after wake from sleep
num_refresh=$FULL_DISPLAY_REFRESH_RATE
}
refresh_dashboard() {
echo "Refreshing dashboard"
"$DIR/wait-for-wifi.sh" "$WIFI_TEST_IP"
"$FETCH_DASHBOARD_CMD" "$DASH_PNG"
fetch_status=$?
if [ "$fetch_status" -ne 0 ]; then
echo "Not updating screen, fetch-dashboard returned $fetch_status"
return 1
fi
if [ "$num_refresh" -eq "$FULL_DISPLAY_REFRESH_RATE" ]; then
num_refresh=0
# trigger a full refresh once in every 4 refreshes, to keep the screen clean
echo "Full screen refresh"
/usr/sbin/eips -f -g "$DASH_PNG"
else
echo "Partial screen refresh"
/usr/sbin/eips -g "$DASH_PNG"
fi
num_refresh=$((num_refresh + 1))
}
log_battery_stats() {
battery_level=$(gasgauge-info -c)
echo "$(date) Battery level: $battery_level."
if [ "$LOW_BATTERY_REPORTING" = true ]; then
battery_level_numeric=${battery_level%?}
if [ "$battery_level_numeric" -le "$LOW_BATTERY_THRESHOLD_PERCENT" ]; then
"$LOW_BATTERY_CMD" "$battery_level_numeric"
fi
fi
}
rtc_sleep() {
duration=$1
if [ "$DEBUG" = true ]; then
sleep "$duration"
else
# shellcheck disable=SC2039
[ "$(cat "$RTC")" -eq 0 ] && echo -n "$duration" >"$RTC"
echo "mem" >/sys/power/state
fi
}
main_loop() {
while true; do
log_battery_stats
next_wakeup_secs=$("$DIR/next-wakeup" --schedule="$REFRESH_SCHEDULE" --timezone="$TIMEZONE")
if [ "$next_wakeup_secs" -gt "$SLEEP_SCREEN_INTERVAL" ]; then
action="sleep"
prepare_sleep
else
action="suspend"
refresh_dashboard
fi
# take a bit of time before going to sleep, so this process can be aborted
sleep 10
echo "Going to $action, next wakeup in ${next_wakeup_secs}s"
rtc_sleep "$next_wakeup_secs"
done
}
init
main_loop

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env sh
# Export environment variables here
export WIFI_TEST_IP=${WIFI_TEST_IP:-1.1.1.1}
# 测试配置:全天每分钟刷新一次,便于验证图片拉取与屏幕刷新是否正常。
export REFRESH_SCHEDULE=${REFRESH_SCHEDULE:-"* * * * *"}
export TIMEZONE=${TIMEZONE:-"Asia/Shanghai"}
# By default, partial screen updates are used to update the screen,
# to prevent the screen from flashing. After a few partial updates,
# the screen will start to look a bit distorted (due to e-ink ghosting).
# 测试阶段强制每次都做一次全刷,避免首页残影和局部刷新的旧内容干扰验证。
# 等图片尺寸与刷新逻辑确认无误后,再改回 4 之类的值以节省功耗。
export FULL_DISPLAY_REFRESH_RATE=${FULL_DISPLAY_REFRESH_RATE:-0}
# When the time until the next wakeup is greater or equal to this number,
# the dashboard will not be refreshed anymore, but instead show a
# 'kindle is sleeping' screen. This can be useful if your schedule only runs
# during the day, for example.
export SLEEP_SCREEN_INTERVAL=3600
export LOW_BATTERY_REPORTING=${LOW_BATTERY_REPORTING:-false}
export LOW_BATTERY_THRESHOLD_PERCENT=10

View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
# Fetch a new dashboard image, make sure to output it to "$1".
# For example:
"$(dirname "$0")/../xh" -d -q -o "$1" get https://raw.githubusercontent.com/pascalw/kindle-dash/master/example/example.png

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env sh
battery_level_percentage=$1
last_battery_report_state="$(dirname "$0")/state/last_battery_report"
previous_report_timestamp=$(cat "$last_battery_report_state" 2>/dev/null || echo '-1')
now=$(date +%s)
# Implement desired logic here. The example below for example only reports low
# battery every 24 hours.
if [ "$previous_report_timestamp" -eq -1 ] ||
[ $((now - previous_report_timestamp)) -gt 86400 ]; then
# Replace this with for example an HTTP call via curl, or xh
echo "Reporting low battery: $battery_level_percentage%"
echo "$now" >"$last_battery_report_state"
fi

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env sh
DEBUG=${DEBUG:-false}
[ "$DEBUG" = true ] && set -x
DIR="$(dirname "$0")"
ENV_FILE="$DIR/local/env.sh"
LOG_FILE="$DIR/logs/dash.log"
mkdir -p "$(dirname "$LOG_FILE")"
# shellcheck disable=SC1090
[ -f "$ENV_FILE" ] && . "$ENV_FILE"
if [ "$DEBUG" = true ]; then
"$DIR/dash.sh"
else
"$DIR/dash.sh" >>"$LOG_FILE" 2>&1 &
fi

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env sh
pkill -f dash.sh

View File

@@ -0,0 +1,26 @@
#!/usr/bin/env sh
test_ip=$1
if [ -z "$test_ip" ]; then
echo "No test ip specified"
exit 1
fi
wait_for_wifi() {
max_retry=30
counter=0
ping -c 1 "$test_ip" >/dev/null 2>&1
# shellcheck disable=SC2181
while [ $? -ne 0 ]; do
[ $counter -eq $max_retry ] && echo "Couldn't connect to Wi-Fi" && exit 1
counter=$((counter + 1))
sleep 1
ping -c 1 "$test_ip" >/dev/null 2>&1
done
}
wait_for_wifi
echo "Wi-Fi connected"

Binary file not shown.

View File

@@ -0,0 +1,27 @@
kindletool: KindleTool, Copyright (C) 2011-2015 Yifan Lu, licensed under the GNU General Public License version 3+ (http://www.gnu.org/licenses/gpl.html).
(https://github.com/NiLuJe/KindleTool/)
|
|-> libarchive, Copyright (C) Tim Kientzle, licensed under the New BSD License (http://www.opensource.org/licenses/bsd-license.php)
| (http://libarchive.github.com/)
|
|-> GMP, GNU MP Library, Copyright 1991-2013 Free Software Foundation, Inc.,
| licensed under the GNU Lesser General Public License version 3+ (http://www.gnu.org/licenses/lgpl.html).
| (http://gmplib.org/)
|
`-> nettle, Copyright (C) 2001-2013 Niels Möller,
licensed under the GNU Lesser General Public License version 2.1+ (https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html).
(http://www.lysator.liu.se/~nisse/nettle)
libz: zlib, Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler,
Licensed under the zlib license (http://zlib.net/zlib_license.html)
(http://zlib.net/)
fbink: FBInk (FrameBuffer eInker), Copyright (C) 2018-2019 NiLuJe <ninuje@gmail.com>,
Released under the GNU General Public License version 3+ (https://www.gnu.org/licenses/gpl.html)
(https://github.com/NiLuJe/FBInk)
BigBlue_Terminal.ttf: BigBlue Terminal +, Copyright (C) VileR, <viler@int10h.org>,
Licensed under a Creative Commons Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0/)
(https://int10h.org/blog/2015/12/bigblue-terminal-oldschool-fixed-width-font/).
Patched with extra glyphs via https://github.com/ryanoasis/nerd-fonts/, see the WiKi for individual licenses.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension>
<information>
<name>MR Installer</name>
<version>1.6</version>
<author>NiLuJe</author>
<id>MRInstaller</id>
</information>
<menus>
<menu type="json" dynamic="true">menu.json</menu>
</menus>
</extension>

View File

@@ -0,0 +1,78 @@
#!/usr/bin/env python2
"""
Barebones example of FBInk usage through Python's cFFI module
"""
# To get a Py3k-like print function
from __future__ import print_function
import sys
# Load the wrapper module, it's linked against FBInk, so the dynamic loader will take care of pulling in the actual FBInk library
from _fbink import ffi, lib as FBInk
# Let's check which FBInk version we're using...
# NOTE: ffi.string() returns a bytes on Python 3, not a str, hence the extra decode
print("Loaded FBInk {}".format(ffi.string(FBInk.fbink_version()).decode("ascii")))
# And now we're good to go! Let's print "Hello World" in the center of the screen...
# Setup the config...
fbink_cfg = ffi.new("FBInkConfig *")
fbink_cfg.is_centered = False
fbink_cfg.is_halfway = True
fbink_cfg.is_cleared = True
fbink_cfg.is_verbose = True
fbink_ot_cfg = ffi.new("FBInkOTConfig *")
fbink_ot_cfg.size_pt = 24
"""
# Open the FB...
fbfd = FBInk.fbink_open()
if fbfd == -1:
raise SystemExit("Failed to open the framebuffer, aborting . . .")
# Initialize FBInk...
if FBInk.fbink_init(fbfd, fbink_cfg) < 0:
raise SystemExit("Failed to initialize FBInk, aborting . . .")
# Do stuff!
if FBInk.fbink_print(fbfd, b"Hello World", fbink_cfg) < 0:
print("Failed to print that string!", file=sys.stderr)
# And now we can wind things down...
if FBInk.fbink_close(fbfd) < 0:
raise SystemExit("Failed to close the framebuffer, aborting . . .")
"""
# Or, the same but in a slightly more Pythonic approach ;).
fbfd = FBInk.fbink_open()
try:
FBInk.fbink_init(fbfd, fbink_cfg)
FBInk.fbink_add_ot_font("BigBlue_Terminal.ttf", FBInk.FNT_REGULAR)
string = u"Success \uf632 or \ufadf or \ufae0 or \ufc8f or \uf633 or \uf4a1" // \uf633
string += u"\n"
string += u"Error \uf071 or \uf525 or \uf529 or \uf421 or \ufb8f" // \uf071
string += u"\n"
string += u"Wait \uf252 or \ufa1e or \uf49b" // \uf252
string += u"\n"
string += u"Python \ue73c or \ue235 or \uf81f or \ue606" // \ue73c
string += u"\n"
string += u"USBNet \ue795 or \uf68c or \ufcb5 or \uf489" // \uf68c
string += u"\n"
string += u"Bridge \uf270 or \uf52c or \ue286 or \uf5a6 or \ue214" // \ue286 (AMZ: \uf270)
string += u"\n"
string += u":( \uf119 or \uf6f7" // \uf119
string += u"\n"
string += u"Linux \uf17c or \uf31a or \uf83c" // \uf17c
string += u"\n"
string += u":) \uf118 or \uf6f4" // \uf118
string += u"\n"
string += u"Tools \ue20f or \ufbf6 or \uf992 or \ufab6 or \uf425" // \uf425
string += u"\n"
string += u"MRPI \ufcdd or \ufcde or \uf8d5 or \uf962 or \ufac3 or \uf487 or \uf427" // \uf8d5 (KUAL: \uf962)
string = string.encode("utf-8")
# NOTE: On Python 3, cFFI maps char to bytes, not str
FBInk.fbink_print_ot(fbfd, string, fbink_ot_cfg, fbink_cfg, ffi.NULL)
finally:
FBInk.fbink_free_ot_fonts()
FBInk.fbink_close(fbfd)

View File

@@ -0,0 +1,24 @@
{
"comment001": "MR Package Installer",
"comment002": "",
"comment003": "$Id: menu.json 11305 2014-12-23 14:56:54Z NiLuJe $",
"comment004": "",
"items": [
{
"name": "Helper",
"priority": -998,
"items": [
{
"name": "Install MR Packages",
"action": "./bin/mrinstaller.sh",
"params": "launch_installer",
"priority": -998,
"exitmenu": true,
"refresh": false,
"status": false,
"internal": "status Launching the MR Installer"
}
]
}
]
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension>
<information>
<name>Kindle dashboard</name>
<id>pascalw-kindle-dash</id>
</information>
<menus>
<menu type="json" dynamic="true">menu.json</menu>
</menus>
</extension>

View File

@@ -0,0 +1,5 @@
{
"items": [
{"name": "Kindle Dashboard", "action": "/mnt/us/dashboard/start.sh"}
]
}

View File

@@ -0,0 +1,8 @@
#!/bin/sh
mntroot rw
cd /usr/bin
mv otaupd otaupd.bck
mv otav3 otav3.bck
mntroot ro
reboot

View File

@@ -0,0 +1,8 @@
#!/bin/sh
mntroot rw
cd /usr/bin
mv otaupd.bck otaupd
mv otav3.bck otav3
mntroot ro
reboot

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension>
<information>
</information>
<menus>
<menu type="json" dynamic="true">menu.json</menu>
</menus>
</extension>

View File

@@ -0,0 +1,22 @@
{
"items": [
{
"name": "Rename OTA binaries",
"priority": -998,
"items": [
{
"name": "Rename",
"priority": 1,
"action": "bin/rename.sh",
"exitmenu": true
},
{
"name": "Restore",
"priority": 2,
"action": "bin/restore.sh",
"exitmenu": true
}
]
}
]
}