<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>光影猫知识库  - 最近更改 [zh-cn]</title>
		<link>https://wiki.photonicat.cn/%E7%89%B9%E6%AE%8A:%E6%9C%80%E8%BF%91%E6%9B%B4%E6%94%B9</link>
		<description>用这个订阅源跟踪本wiki的最近更改。</description>
		<language>zh-Hans-CN</language>
		<generator>MediaWiki 1.39.1</generator>
		<lastBuildDate>Mon, 31 Aug 2026 05:29:47 GMT</lastBuildDate>
		<item>
			<title>Photonicat 2 SOC Calculation</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_Calculation&amp;diff=260&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_Calculation&amp;diff=260&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“&amp;#039;&amp;#039;&amp;#039;Photonicat 2&amp;#039;&amp;#039;&amp;#039; does not guess the battery level from voltage. It runs a proper &amp;#039;&amp;#039;&amp;#039;coulomb counter&amp;#039;&amp;#039;&amp;#039; (also called a fuel gauge): think of it as a water meter on the battery, accounting for every milliamp-second in and out.  This page explains how that system works — from the measuring hardware, through the firmware&amp;#039;s integration, self-learning and temperature compensation, to the Linux kernel driver that turns it all into ordinary sysfs files.  For the in…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''Photonicat 2''' does not guess the battery level from voltage. It runs a&lt;br /&gt;
proper '''coulomb counter''' (also called a fuel gauge): think of it as a water&lt;br /&gt;
meter on the battery, accounting for every milliamp-second in and out.&lt;br /&gt;
&lt;br /&gt;
This page explains how that system works — from the measuring hardware, through&lt;br /&gt;
the firmware's integration, self-learning and temperature compensation, to the&lt;br /&gt;
Linux kernel driver that turns it all into ordinary sysfs files.&lt;br /&gt;
&lt;br /&gt;
For the indicator see [[Photonicat 2 LED Indicator]]; for sysfs paths see&lt;br /&gt;
[[Photonicat 2 sysfs]]. 中文版见 [[Photonicat 2 SOC 计算]]。&lt;br /&gt;
&lt;br /&gt;
== Voltage and charge level ==&lt;br /&gt;
&lt;br /&gt;
A lithium cell's voltage-vs-charge curve is very flat in the middle. The figures&lt;br /&gt;
below come from the firmware's '''discharge OCV table''' (IR-compensated pack&lt;br /&gt;
voltage):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Pack OCV (open-circuit voltage) !! Charge level&lt;br /&gt;
|-&lt;br /&gt;
| 7.58 V || 70 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.50 V || 60 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.44 V || 50 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.36 V || 40 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.28 V || 30 %&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Going from 70 % down to 30 % moves the voltage by just '''0.30 V''', about&lt;br /&gt;
'''6 mV per percent'''. Under load the IR drop across the internal resistance&lt;br /&gt;
reaches tens of millivolts, so voltage alone can be off by more than 10 %, and the&lt;br /&gt;
error grows with load.&lt;br /&gt;
&lt;br /&gt;
The two ends are steep: in this table 8.34 V is 100 % and 6.34 V is 0 %. The&lt;br /&gt;
firmware therefore '''anchors at the ends with voltage and advances through the&lt;br /&gt;
middle by current integration'''.&lt;br /&gt;
&lt;br /&gt;
== Overall structure ==&lt;br /&gt;
&lt;br /&gt;
  charge = starting charge − ∫(discharge current)dt + ∫(charge current)dt&lt;br /&gt;
&lt;br /&gt;
Integration needs a starting point, and its error accumulates over time, so it is&lt;br /&gt;
paired with a set of correction mechanisms. Photonicat 2 layers them as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Layer !! Job&lt;br /&gt;
|-&lt;br /&gt;
| Measurement hardware || TPA626 samples voltage/current every 100 ms&lt;br /&gt;
|-&lt;br /&gt;
| Coulomb integration || Accumulates current into a µAs ledger every 200 ms&lt;br /&gt;
|-&lt;br /&gt;
| OCV fusion || At rest, looks up charge from voltage and gently pulls the integral back&lt;br /&gt;
|-&lt;br /&gt;
| Anchors || At full/empty, pins the value directly to 100 % / 0 %&lt;br /&gt;
|-&lt;br /&gt;
| Self-learning || Capacity, resistance, empty point and charge gain — learned per unit&lt;br /&gt;
|-&lt;br /&gt;
| Temperature || Cold raises resistance and shrinks usable capacity; both corrected&lt;br /&gt;
|-&lt;br /&gt;
| Display layer || Maps internal charge to the 1–100 % the user sees&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 1. Measurement hardware ==&lt;br /&gt;
&lt;br /&gt;
The measuring chip is a '''TPA626''' (an I²C current/voltage monitor, in the same&lt;br /&gt;
family as the INA226). It sits across a milliohm-class shunt resistor in the&lt;br /&gt;
battery path, deriving current from the voltage drop while also measuring bus&lt;br /&gt;
voltage.&lt;br /&gt;
&lt;br /&gt;
* '''Sampling''': roughly every 100 ms (&amp;lt;code&amp;gt;VD1_Collect&amp;lt;/code&amp;gt;)&lt;br /&gt;
* '''Median filtering''': voltage and current each pass through a median filter&lt;br /&gt;
  that rejects occasional I²C glitches and load spikes&lt;br /&gt;
* '''Raw values kept separately''': the median filter lags by about 3 s and would&lt;br /&gt;
  smear out the charger plug/unplug voltage step; internal-resistance learning&lt;br /&gt;
  needs that step, so unfiltered raw values are kept alongside&lt;br /&gt;
&lt;br /&gt;
=== Current calibration ===&lt;br /&gt;
&lt;br /&gt;
The shunt and amplifier have unit-to-unit variation, so each board is calibrated&lt;br /&gt;
against a precision multimeter and fitted to a quadratic:&lt;br /&gt;
&lt;br /&gt;
  I_true(mA) = C2·x² + C1·x + C0&lt;br /&gt;
&lt;br /&gt;
Current coefficients (second calibration round, 2026-07-24; residuals ≤3 mA&lt;br /&gt;
across four points):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Term !! Value !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| C2 || −4.444×10⁻⁵ || Quadratic term, corrects high-current nonlinearity&lt;br /&gt;
|-&lt;br /&gt;
| C1 || 1.0411 || Linear term (gain)&lt;br /&gt;
|-&lt;br /&gt;
| C0 || +20 mA (discharge) / 0 mA (charge) || Zero offset, per direction&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Implementation details:&lt;br /&gt;
&lt;br /&gt;
* '''Clamp before evaluating''': outside the calibrated range the parabola bends&lt;br /&gt;
  back on itself (vertex near +11.7 A), so the input is clamped to ±3 A and&lt;br /&gt;
  extended linearly by the endpoint slope beyond that.&lt;br /&gt;
* '''64-bit arithmetic''': x² reaches 9×10⁶, which overflows int32 once scaled.&lt;br /&gt;
* '''55 mA dead band''': anything smaller is treated as zero, keeping idle noise&lt;br /&gt;
  out of the accumulator.&lt;br /&gt;
&lt;br /&gt;
== 2. Coulomb integration ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;coulomb_counter_update()&amp;lt;/code&amp;gt; runs every '''200 ms''', multiplying current&lt;br /&gt;
by elapsed time into a 64-bit '''µAs (microamp-second)''' accumulator. Using µAs&lt;br /&gt;
rather than mAh avoids fixed-point rounding error accumulating over long runs.&lt;br /&gt;
&lt;br /&gt;
* Discharge subtracts, charge adds&lt;br /&gt;
* Currents under '''30 mA''' in magnitude are ignored (dead band, anti-drift)&lt;br /&gt;
* The charge direction carries its own learned '''gain''' — charging is not 100 %&lt;br /&gt;
  efficient&lt;br /&gt;
&lt;br /&gt;
== 3. OCV fusion ==&lt;br /&gt;
&lt;br /&gt;
Whenever the battery is '''near rest''', the firmware looks up charge from voltage&lt;br /&gt;
and applies a small correction to the integral. All of the following must hold:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Condition !! Threshold !! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Current small enough || &amp;amp;#124;I&amp;amp;#124; ≤ 340 mA (~0.05C) || IR-model error is amplified at higher current&lt;br /&gt;
|-&lt;br /&gt;
| Held long enough || ≥ 30 s || Lets polarisation and surface charge relax&lt;br /&gt;
|-&lt;br /&gt;
| Voltage slew || ≤ 20 mV/s || Still in a transient, so not really at rest&lt;br /&gt;
|-&lt;br /&gt;
| Current slew || ≤ 2000 mA/s || Likewise&lt;br /&gt;
|-&lt;br /&gt;
| Plug/unplug grace || 10 s || Voltage has not settled after a charger event&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The correction is '''blended''' rather than written over the integral:&lt;br /&gt;
&lt;br /&gt;
* Weight capped at '''α = 0.07''' (OCV contributes at most 7 %), ramping linearly&lt;br /&gt;
  from 0 over 8 s&lt;br /&gt;
* Any single correction is limited to '''0.20 %'''&lt;br /&gt;
&lt;br /&gt;
OCV therefore corrects the integral gradually, and the displayed reading does not&lt;br /&gt;
jump.&lt;br /&gt;
&lt;br /&gt;
=== Three OCV tables ===&lt;br /&gt;
&lt;br /&gt;
Lithium cells show '''hysteresis''': at the same charge level, terminal voltage&lt;br /&gt;
reads higher while charging and lower while discharging (about 30 mV per cell,&lt;br /&gt;
roughly ±60 mV for a 2S pack). The firmware carries three tables:&lt;br /&gt;
&lt;br /&gt;
* '''Discharge table''' — used in discharge mode (&amp;amp;#124;I&amp;amp;#124; &amp;gt; 900 mA)&lt;br /&gt;
* '''Charge table''' — used in charge mode&lt;br /&gt;
* '''Rest table''' — the average of the two, used at low current (&amp;amp;#124;I&amp;amp;#124; ≤ 600 mA)&lt;br /&gt;
&lt;br /&gt;
Mode switching is '''hysteretic''' (enter at 900 mA, leave at 600 mA) to avoid&lt;br /&gt;
chattering around the threshold.&lt;br /&gt;
&lt;br /&gt;
Before any lookup the reading is '''IR-compensated''': OCV = terminal voltage −&lt;br /&gt;
I×R_pack, using the learned resistance described below.&lt;br /&gt;
&lt;br /&gt;
== 4. Anchors ==&lt;br /&gt;
&lt;br /&gt;
The middle is carried by integration; the two ends are set directly by anchors:&lt;br /&gt;
&lt;br /&gt;
* '''Full anchor''': charger present, vbus ≥ 8 V, and current has fallen low →&lt;br /&gt;
  charge = 100 %. The charger requirement is necessary because '''resting OCV at&lt;br /&gt;
  95 % is about 8.16 V''', so a high resting pack is easily mistaken for full; a&lt;br /&gt;
  poor or under-voltage charger cannot reach true full and is refused.&lt;br /&gt;
* '''Empty anchor''': discharged to the cutoff point → charge = 0 %, which also&lt;br /&gt;
  triggers empty-point learning.&lt;br /&gt;
&lt;br /&gt;
== 5. Self-learning ==&lt;br /&gt;
&lt;br /&gt;
Unit-to-unit variation can exceed 10 % even within one batch of cells and boards,&lt;br /&gt;
so the firmware '''learns four quantities per unit''' and stores them in data&lt;br /&gt;
flash, where they survive power loss.&lt;br /&gt;
&lt;br /&gt;
=== 5.1 Full-capacity learning (ageing) ===&lt;br /&gt;
&lt;br /&gt;
A cell rated 6800 mAh may be down to 5500 mAh after two years. With capacity&lt;br /&gt;
hard-coded, an aged pack reads optimistically. Learning procedure:&lt;br /&gt;
&lt;br /&gt;
# The full anchor opens a window and zeroes the discharge accumulator&lt;br /&gt;
# The pack discharges all the way to the low-voltage cutoff&lt;br /&gt;
# Full capacity = accumulated discharge + '''700 mAh'''&lt;br /&gt;
# Detecting any charging mid-window voids that attempt&lt;br /&gt;
&lt;br /&gt;
The '''700 mAh''' is the cutoff reserve: the device never runs the pack down to&lt;br /&gt;
0 V, so at the cutoff (around 6.3–6.45 V) roughly 700 mAh remains inside and must&lt;br /&gt;
be added back.&lt;br /&gt;
&lt;br /&gt;
The learned value also yields '''health''':&lt;br /&gt;
&lt;br /&gt;
  health = learned capacity / 6800 mAh&lt;br /&gt;
&lt;br /&gt;
Health is folded in slowly via an EMA, so a single measurement does not move it&lt;br /&gt;
sharply.&lt;br /&gt;
&lt;br /&gt;
=== 5.2 Internal-resistance learning (voltage-step method) ===&lt;br /&gt;
&lt;br /&gt;
Resistance is measured from the voltage step at the '''instant a charger is&lt;br /&gt;
plugged or unplugged''': current steps by ΔI and voltage steps by ΔV, so&lt;br /&gt;
&lt;br /&gt;
  R = ΔV / ΔI&lt;br /&gt;
&lt;br /&gt;
Conditions: voltage &amp;gt; 7.8 V (near full, otherwise OCV itself drifts with charge&lt;br /&gt;
and spoils the measurement), current step ≥ 300 mA, voltage step ≥ 15 mV. Results&lt;br /&gt;
fold in by EMA at 3/10 weight, clamped to 10–200 mΩ, defaulting to 50 mΩ.&lt;br /&gt;
&lt;br /&gt;
This is the '''whole-loop''' resistance: cell body + wiring/connectors (20 mΩ) +&lt;br /&gt;
protection-board MOSFET (15 mΩ). IR compensation uses that series total with&lt;br /&gt;
nothing subtracted; the 35 mΩ of board parasitics is subtracted only when the host&lt;br /&gt;
displays &amp;quot;cell internal resistance&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== 5.3 Empty-point learning ===&lt;br /&gt;
&lt;br /&gt;
Each unit's current-sense gain and true capacity differ slightly, so the moment&lt;br /&gt;
internal SOC reaches zero and the moment the hardware actually cuts out do not line&lt;br /&gt;
up (observed as the device cutting out while still showing 20 %). Rather than&lt;br /&gt;
altering the current/mAh chain, the firmware applies a per-unit learned linear map&lt;br /&gt;
at the '''display layer''':&lt;br /&gt;
&lt;br /&gt;
  displayed = (internal SOC − empty) × 100 / (100 − empty)&lt;br /&gt;
&lt;br /&gt;
'''Empty''' is the internal SOC recorded the last time the battery genuinely ran&lt;br /&gt;
out. Learning events: a low-voltage shutdown command, an unexpected host death&lt;br /&gt;
while discharging at low voltage, or the empty anchor.&lt;br /&gt;
&lt;br /&gt;
It also applies '''downward self-correction''': if voltage is still healthy&lt;br /&gt;
(&amp;gt; 6.8 V) during discharge but internal SOC has already fallen below the empty&lt;br /&gt;
point, empty was learned too high and follows the reading down. A replaced battery,&lt;br /&gt;
or an overshoot, recovers within one discharge cycle.&lt;br /&gt;
&lt;br /&gt;
=== 5.4 Charge-gain learning ===&lt;br /&gt;
&lt;br /&gt;
Charging is not 100 % efficient, so charge pushed in differs from charge actually&lt;br /&gt;
stored. This gain is learned at the full anchor and written to flash when it moves&lt;br /&gt;
by ≥1 %.&lt;br /&gt;
&lt;br /&gt;
== 6. Temperature compensation ==&lt;br /&gt;
&lt;br /&gt;
An on-board NTC feeds temperature to the coulomb counter every 200 ms, driving two&lt;br /&gt;
corrections.&lt;br /&gt;
&lt;br /&gt;
=== 6.1 Resistance temperature factor k(T) ===&lt;br /&gt;
&lt;br /&gt;
Internal resistance varies with temperature, which directly affects IR&lt;br /&gt;
compensation. The factor is a piecewise-linear approximation of typical NCA&lt;br /&gt;
temperature behaviour:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Temperature !! Resistance factor k(T)&lt;br /&gt;
|-&lt;br /&gt;
| −20 °C || ×3.00&lt;br /&gt;
|-&lt;br /&gt;
| −10 °C || ×2.30&lt;br /&gt;
|-&lt;br /&gt;
| 0 °C || ×1.80&lt;br /&gt;
|-&lt;br /&gt;
| 10 °C || ×1.35&lt;br /&gt;
|-&lt;br /&gt;
| 25 °C || ×1.00 (reference)&lt;br /&gt;
|-&lt;br /&gt;
| 40 °C || ×0.85&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
At −20 °C the resistance is about '''three times''' its room-temperature value.&lt;br /&gt;
The learned resistance is normalised to 25 °C and multiplied by k(T) in use.&lt;br /&gt;
Values outside −20…40 °C are clamped to the endpoints.&lt;br /&gt;
&lt;br /&gt;
=== 6.2 Cold-weather capacity compensation ===&lt;br /&gt;
&lt;br /&gt;
Usable capacity falls in the cold (the energy is not gone, it just cannot be drawn&lt;br /&gt;
out). The firmware compensates by '''raising the display empty point''' so the&lt;br /&gt;
reading falls earlier:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Temperature !! Empty point raised by&lt;br /&gt;
|-&lt;br /&gt;
| ≥ 15 °C || 0 (no compensation)&lt;br /&gt;
|-&lt;br /&gt;
| 0 °C || about +4 %&lt;br /&gt;
|-&lt;br /&gt;
| −10 °C || about +8 %&lt;br /&gt;
|-&lt;br /&gt;
| ≤ −20 °C || +12 % (capped)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
An NTC reading outside −30…70 °C is treated as a fault, and the last valid&lt;br /&gt;
temperature is held (initially 25 °C).&lt;br /&gt;
&lt;br /&gt;
== 7. The display curve ==&lt;br /&gt;
&lt;br /&gt;
The internally computed SOC is not displayed directly. One more mapping sits in&lt;br /&gt;
between:&lt;br /&gt;
&lt;br /&gt;
* '''4 % → displays 1 %'''&lt;br /&gt;
* '''96 % → displays 100 %'''&lt;br /&gt;
* Linear in between (slope 99/92), clipped at both ends&lt;br /&gt;
&lt;br /&gt;
So '''when the display reads 0 %, roughly 4 % is still in the pack''' (plus the&lt;br /&gt;
hardware margin below the empty point), leaving time to save work and shut down&lt;br /&gt;
cleanly; 96 % shows as 100 %. Both are standard consumer-electronics practice.&lt;br /&gt;
&lt;br /&gt;
The reported percentage is '''clamped to a minimum of 1 %''': while the device is&lt;br /&gt;
running it will not show 0 %.&lt;br /&gt;
&lt;br /&gt;
== 8. Retaining charge across power-off ==&lt;br /&gt;
&lt;br /&gt;
There are three paths.&lt;br /&gt;
&lt;br /&gt;
=== 8.1 SOC snapshot ===&lt;br /&gt;
&lt;br /&gt;
While running, SOC is written to flash whenever it drifts by ≥5 %; shutdown, host&lt;br /&gt;
power-down, standby entry and OTA reset all force a write and refresh the&lt;br /&gt;
timestamp.&lt;br /&gt;
&lt;br /&gt;
On boot:&lt;br /&gt;
&lt;br /&gt;
* '''≤12 hours''': SOC = snapshot − 2.0 mA × Δt (standby current), and OCV&lt;br /&gt;
  re-estimation is '''blocked''' from overriding it.&lt;br /&gt;
* '''&amp;gt;12 hours''': the snapshot is stale, so a cold-start OCV estimate is used.&lt;br /&gt;
&lt;br /&gt;
=== 8.2 Deep-sleep discharge estimation ===&lt;br /&gt;
&lt;br /&gt;
In deep sleep the TPA626 is powered down and no current can be measured. The&lt;br /&gt;
firmware records an RTC minute stamp on entry and, on waking, subtracts the&lt;br /&gt;
whole-device standby draw of about '''2.0 mA'''.&lt;br /&gt;
&lt;br /&gt;
=== 8.3 Detecting a battery swap ===&lt;br /&gt;
&lt;br /&gt;
Removing the battery cuts power to the RTC, which resets, so its time runs&lt;br /&gt;
backwards. The firmware treats this as a battery swap, voids the snapshot and&lt;br /&gt;
re-estimates from cold. A 10-minute tolerance avoids discarding a valid snapshot&lt;br /&gt;
after an update reboot.&lt;br /&gt;
&lt;br /&gt;
== 9. How the data reaches Linux ==&lt;br /&gt;
&lt;br /&gt;
Once the MCU has computed everything, it sends status frames to the host&lt;br /&gt;
(RK3576) over '''UART'''. Two consumers sit on the host side.&lt;br /&gt;
&lt;br /&gt;
=== 9.1 Kernel driver: photonicat-pm ===&lt;br /&gt;
&lt;br /&gt;
This is a '''serdev''' driver (&amp;lt;code&amp;gt;990-photonicat-pm-add-driver.patch&amp;lt;/code&amp;gt;,&lt;br /&gt;
kernel 6.12) that attaches to the serial port, parses status frames, and&lt;br /&gt;
registers as standard Linux devices:&lt;br /&gt;
&lt;br /&gt;
* '''power_supply''' class → &amp;lt;code&amp;gt;/sys/class/power_supply/battery&amp;lt;/code&amp;gt;&lt;br /&gt;
* '''RTC''' class → &amp;lt;code&amp;gt;/dev/rtc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Because these are '''standard subsystems''', existing Linux tools work directly&lt;br /&gt;
without knowing the private protocol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# Charge level (%) — the final output of everything described above&lt;br /&gt;
cat /sys/class/power_supply/battery/capacity&lt;br /&gt;
&lt;br /&gt;
# Voltage µV / current µA / power µW&lt;br /&gt;
cat /sys/class/power_supply/battery/voltage_now&lt;br /&gt;
cat /sys/class/power_supply/battery/current_now&lt;br /&gt;
cat /sys/class/power_supply/battery/power_now&lt;br /&gt;
&lt;br /&gt;
# Energy µWh: energy_full is the learned capacity — compare against&lt;br /&gt;
# energy_full_design to see ageing&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_now&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_full&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_full_design&lt;br /&gt;
&lt;br /&gt;
# Charger online&lt;br /&gt;
cat /sys/class/power_supply/charger/online&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''The MCU is the hardware RTC.''' There is no separate RTC chip on the board; the&lt;br /&gt;
MCU is always powered, keeps time itself, and sends it up with the status frames.&lt;br /&gt;
The driver registers it through &amp;lt;code&amp;gt;rtc_class_ops&amp;lt;/code&amp;gt;, so standard tools work&lt;br /&gt;
directly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hwclock -r          # read the time from the MCU&lt;br /&gt;
hwclock -w          # write system time back to the MCU&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is why '''the clock is still right after days unplugged and offline'''. It is&lt;br /&gt;
also the mechanism behind the battery-swap detection in 8.3, since removing the&lt;br /&gt;
battery resets the RTC and time runs backwards.&lt;br /&gt;
&lt;br /&gt;
=== 9.2 Userspace daemon: pcat-manager ===&lt;br /&gt;
&lt;br /&gt;
The kernel driver only consumes the power-related part of the status frame.&lt;br /&gt;
'''The rest of the UART protocol is handled by pcat-manager''': modem management,&lt;br /&gt;
watchdog, power on/off policy, button events, pushing the charge threshold down,&lt;br /&gt;
MCU firmware updates and so on. The full protocol is documented at&lt;br /&gt;
[[Photonicat 2 MCU 通讯协议]].&lt;br /&gt;
&lt;br /&gt;
The division of labour:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Component !! Responsibility&lt;br /&gt;
|-&lt;br /&gt;
| MCU firmware || Measurement, integration, learning, compensation — all the algorithms&lt;br /&gt;
|-&lt;br /&gt;
| photonicat-pm (kernel) || Power/RTC data → standard sysfs interfaces&lt;br /&gt;
|-&lt;br /&gt;
| pcat-manager (userspace) || Everything else: modem, watchdog, power policy, OTA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
For example, the '''charge limit''': set 80 % in the web UI and pcat-manager sends&lt;br /&gt;
it to the MCU over UART; the MCU stores it in data flash and drives the charging&lt;br /&gt;
MOSFET directly. From firmware '''RA2E1260726005''' the setting persists on the MCU&lt;br /&gt;
side and survives resets and OTA updates, and pcat-manager keeps its own mirror,&lt;br /&gt;
re-sending it if it detects an MCU restart.&lt;br /&gt;
&lt;br /&gt;
== 10. FAQ ==&lt;br /&gt;
&lt;br /&gt;
;The reading occasionally moves slightly&lt;br /&gt;
:OCV fusion or an anchor is correcting integration drift. A single correction is&lt;br /&gt;
 capped at 0.20 %, so large jumps should not occur in normal use; a large one&lt;br /&gt;
 generally means a stale snapshot led to a cold-start re-estimate.&lt;br /&gt;
&lt;br /&gt;
;Charge drops faster in winter&lt;br /&gt;
:Usable capacity falls when cold, and the firmware also raises the display empty&lt;br /&gt;
 point (about +8 % at −10 °C). It recovers as things warm up.&lt;br /&gt;
&lt;br /&gt;
;96 % shows as 100 %&lt;br /&gt;
:This is the display curve, see section 7. Likewise there is still margin when it&lt;br /&gt;
 reads 0 %.&lt;br /&gt;
&lt;br /&gt;
;Does a new battery need calibration&lt;br /&gt;
:No specific procedure is needed. One full discharge (from full to automatic&lt;br /&gt;
 shutdown) lets the firmware learn true capacity and the empty point; ordinary use&lt;br /&gt;
 gets there gradually.&lt;br /&gt;
&lt;br /&gt;
;How often health updates&lt;br /&gt;
:It needs a complete discharge window (full anchor → cutoff), and charging&lt;br /&gt;
 mid-window voids that attempt, so it updates slowly and changes gradually by EMA.&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:35:12 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_SOC_Calculation</comments>
		</item>
		<item>
			<title>Photonicat 2 SOC 计算</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=259&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&amp;diff=259&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“&amp;#039;&amp;#039;&amp;#039;光影猫2&amp;#039;&amp;#039;&amp;#039; 不靠&amp;quot;看电压猜电量&amp;quot;，而是用一套完整的&amp;#039;&amp;#039;&amp;#039;库仑计&amp;#039;&amp;#039;&amp;#039;（Coulomb counter，又叫电量计 / fuel gauge）来算电量：像给电池装了一个水表， 进出的每一毫安秒都记账。  本页讲清楚这套系统怎么工作——从硬件怎么测，到固件怎么积分、怎么自学习、 怎么做温度补偿，再到 Linux 内核怎么把它变成 sysfs 文件。  指示灯说明见 &lt;a href=&quot;/Photonicat_2_LED_%E6%8C%87%E7%A4%BA%E7%81%AF&quot; title=&quot;Photonicat 2 LED 指示灯&quot;&gt;Photonicat 2 LED 指示灯&lt;/a&gt;，s…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''光影猫2''' 不靠&amp;quot;看电压猜电量&amp;quot;，而是用一套完整的'''库仑计'''（Coulomb&lt;br /&gt;
counter，又叫电量计 / fuel gauge）来算电量：像给电池装了一个水表，&lt;br /&gt;
进出的每一毫安秒都记账。&lt;br /&gt;
&lt;br /&gt;
本页讲清楚这套系统怎么工作——从硬件怎么测，到固件怎么积分、怎么自学习、&lt;br /&gt;
怎么做温度补偿，再到 Linux 内核怎么把它变成 sysfs 文件。&lt;br /&gt;
&lt;br /&gt;
指示灯说明见 [[Photonicat 2 LED 指示灯]]，sysfs 路径见 [[Photonicat 2 sysfs]]。&lt;br /&gt;
English: [[Photonicat 2 SOC Calculation]]。&lt;br /&gt;
&lt;br /&gt;
== 电压与电量的关系 ==&lt;br /&gt;
&lt;br /&gt;
锂电池的&amp;quot;电压—电量&amp;quot;曲线中段非常平。下面取固件里的'''放电 OCV 表'''&lt;br /&gt;
（去 IR 后的整包电压）：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 整包 OCV（开路电压） !! 对应电量&lt;br /&gt;
|-&lt;br /&gt;
| 7.58 V || 70 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.50 V || 60 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.44 V || 50 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.36 V || 40 %&lt;br /&gt;
|-&lt;br /&gt;
| 7.28 V || 30 %&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
从 70 % 掉到 30 %，电压只降了 '''0.30 V'''，平均每 1 % 电量约 '''6 mV'''；&lt;br /&gt;
而带负载时内阻压降（I×R）可达几十毫伏，误差会超过 10 %，负载越大偏差越大。&lt;br /&gt;
&lt;br /&gt;
两端则很陡：这张表里 8.34 V 是 100 %、6.34 V 是 0 %。因此固件'''两端用电压定位，&lt;br /&gt;
中间靠电流积分推进'''。&lt;br /&gt;
&lt;br /&gt;
== 总体结构 ==&lt;br /&gt;
&lt;br /&gt;
  电量 = 起点电量 − ∫(放电电流)dt + ∫(充电电流)dt&lt;br /&gt;
&lt;br /&gt;
积分需要一个起点，且误差会随时间累积，因此还要配合一套修正机制。&lt;br /&gt;
光影猫2 分为以下几层：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 层 !! 作用&lt;br /&gt;
|-&lt;br /&gt;
| 硬件测量 || TPA626 每 100 ms 测一次电压/电流&lt;br /&gt;
|-&lt;br /&gt;
| 库仑积分 || 每 200 ms 把电流累加进 µAs 账本&lt;br /&gt;
|-&lt;br /&gt;
| OCV 融合 || 静置时用电压表反查电量，轻轻拉回积分漂移&lt;br /&gt;
|-&lt;br /&gt;
| 锚点 || 充满 / 欠压时直接把电量钉死到 100 % / 0 %&lt;br /&gt;
|-&lt;br /&gt;
| 自学习 || 满容量、内阻、空点、充电增益，每台机器各学各的&lt;br /&gt;
|-&lt;br /&gt;
| 温度补偿 || 冷天内阻变大、可用容量变少，都要修正&lt;br /&gt;
|-&lt;br /&gt;
| 显示层 || 把内部电量映射成用户看到的 1–100 %&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== 一、硬件测量 ==&lt;br /&gt;
&lt;br /&gt;
测量芯片是 '''TPA626'''（I²C 电流/电压监测器，与 INA226 同类）。它串一个&lt;br /&gt;
毫欧级采样电阻在电池回路上，测电阻两端压降换算电流，同时测总线电压。&lt;br /&gt;
&lt;br /&gt;
* '''采样周期'''：约 100 ms 一次（&amp;lt;code&amp;gt;VD1_Collect&amp;lt;/code&amp;gt;）&lt;br /&gt;
* '''中值滤波'''：电压和电流各过一个中值滤波器，滤掉 I²C 偶发抖动和负载尖峰&lt;br /&gt;
* '''原始值另存一份'''：中值滤波有约 3 s 滞后，会抹平充电器插拔的电压台阶；&lt;br /&gt;
  内阻自学习需要该瞬间台阶，故固件同时保留未滤波的原始值&lt;br /&gt;
&lt;br /&gt;
=== 电流校准 ===&lt;br /&gt;
&lt;br /&gt;
采样电阻和运放都有个体误差，出厂靠精密万用表实测标定，拟合成二次多项式：&lt;br /&gt;
&lt;br /&gt;
  I_真实(mA) = C2·x² + C1·x + C0&lt;br /&gt;
&lt;br /&gt;
当前系数（2026-07-24 二轮标定，四点残差 ≤3 mA）：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 项 !! 值 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| C2 || −4.444×10⁻⁵ || 二次项，修大电流段的非线性&lt;br /&gt;
|-&lt;br /&gt;
| C1 || 1.0411 || 一次项（增益）&lt;br /&gt;
|-&lt;br /&gt;
| C0 || +20 mA（放电）/ 0 mA（充电） || 零点偏移，分方向&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
实现细节：&lt;br /&gt;
&lt;br /&gt;
* '''先夹再算'''：抛物线在标定范围外会反向弯（顶点约 +11.7 A），故先把输入夹到&lt;br /&gt;
  ±3 A，域外按端点斜率线性延伸。&lt;br /&gt;
* '''int64 运算'''：x² 最大到 9×10⁶，乘系数后会溢出 int32。&lt;br /&gt;
* '''55 mA 死区'''：小于该值按 0 处理，避免待机时噪声累积到账本。&lt;br /&gt;
&lt;br /&gt;
== 二、库仑积分 ==&lt;br /&gt;
&lt;br /&gt;
每 '''200 ms''' 调一次 &amp;lt;code&amp;gt;coulomb_counter_update()&amp;lt;/code&amp;gt;，把电流乘以时间&lt;br /&gt;
累加进一个 '''µAs（微安秒）'''的 64 位累加器。使用 µAs 而非 mAh，可避免定点&lt;br /&gt;
除法的舍入误差长期累积。&lt;br /&gt;
&lt;br /&gt;
* 放电减、充电加&lt;br /&gt;
* 电流绝对值小于 '''30 mA''' 的部分不计入（死区，防噪声漂移）&lt;br /&gt;
* 充电方向另有一个自学习的'''增益系数'''（充电效率不是 100 %）&lt;br /&gt;
&lt;br /&gt;
== 三、OCV 融合 ==&lt;br /&gt;
&lt;br /&gt;
在'''电池接近静置'''时，用电压反查电量表对积分做小幅修正。触发条件如下，&lt;br /&gt;
全部满足才执行：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 条件 !! 阈值 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| 电流足够小 || &amp;amp;#124;I&amp;amp;#124; ≤ 340 mA（约 0.05C） || 电流大时内阻压降的模型误差会放大&lt;br /&gt;
|-&lt;br /&gt;
| 持续足够久 || ≥ 30 s || 让极化电压和表面电荷弛豫掉&lt;br /&gt;
|-&lt;br /&gt;
| 电压变化率 || ≤ 20 mV/s || 还在动态过程中就不算静置&lt;br /&gt;
|-&lt;br /&gt;
| 电流变化率 || ≤ 2000 mA/s || 同上&lt;br /&gt;
|-&lt;br /&gt;
| 插拔宽限期 || 10 s || 充电器刚插拔，电压还没稳&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
修正采用'''加权融合'''而非直接覆盖：&lt;br /&gt;
&lt;br /&gt;
* 权重上限 '''α = 0.07'''（OCV 最多只占 7 %），且在 8 s 内从 0 线性爬升&lt;br /&gt;
* 单次修正最多 '''0.20 %'''&lt;br /&gt;
&lt;br /&gt;
因此 OCV 只对积分做渐进修正，显示电量不会跳变。&lt;br /&gt;
&lt;br /&gt;
=== 三张 OCV 表 ===&lt;br /&gt;
&lt;br /&gt;
锂电池存在'''滞回'''：同一电量下充电时端电压偏高、放电时偏低（约 30 mV/芯，&lt;br /&gt;
2S 约 ±60 mV）。固件为此设三张表：&lt;br /&gt;
&lt;br /&gt;
* '''放电表'''：进入放电模式（&amp;amp;#124;I&amp;amp;#124; &amp;gt; 900 mA）时用&lt;br /&gt;
* '''充电表'''：进入充电模式时用&lt;br /&gt;
* '''静置表（REST）'''：充放两表的平均，小电流（&amp;amp;#124;I&amp;amp;#124; ≤ 600 mA）时用&lt;br /&gt;
&lt;br /&gt;
模式切换带'''滞回'''（进 900 mA / 出 600 mA），避免在阈值附近反复切换。&lt;br /&gt;
&lt;br /&gt;
查表前先'''去 IR'''：OCV = 端电压 − I×R_pack，其中内阻取自下面的自学习值。&lt;br /&gt;
&lt;br /&gt;
== 四、锚点 ==&lt;br /&gt;
&lt;br /&gt;
中段靠积分，两端由锚点直接置位：&lt;br /&gt;
&lt;br /&gt;
* '''满电锚点'''：充电器在位、vbus ≥ 8 V 且电流已很小 → 电量 = 100 %。&lt;br /&gt;
  必须要求充电器在位：'''95 % 的静置 OCV 约 8.16 V'''，高电量静置电池易被误判为满电；&lt;br /&gt;
  劣质或欠压充电器无法充到真满，同样不给锚。&lt;br /&gt;
* '''欠压锚点'''：放到欠压关机点 → 电量 = 0 %，同时触发空点学习。&lt;br /&gt;
&lt;br /&gt;
== 五、自学习 ==&lt;br /&gt;
&lt;br /&gt;
同一批电池和板子的个体差异可超过 10 %，因此固件'''为每台机器单独学习'''&lt;br /&gt;
四个量，结果存入 data flash，掉电不丢。&lt;br /&gt;
&lt;br /&gt;
=== 5.1 满容量学习（电池老化） ===&lt;br /&gt;
&lt;br /&gt;
标称 6800 mAh 的电池用两年可能只剩 5500 mAh。满容量若写死，老化后 SOC 会偏乐观。&lt;br /&gt;
学习流程：&lt;br /&gt;
&lt;br /&gt;
# 满电锚点触发时开窗口，累计放电清零&lt;br /&gt;
# 一路放电到欠压关机点&lt;br /&gt;
# 满容量 = 累计放出的电量 + '''700 mAh'''&lt;br /&gt;
# 中途检测到充电 → 本次窗口作废&lt;br /&gt;
&lt;br /&gt;
其中 '''700 mAh''' 是关机点余量：整机不会把电池放到 0 V，在关机点&lt;br /&gt;
（约 6.3–6.45 V）包内仍剩约 700 mAh，需补回。&lt;br /&gt;
&lt;br /&gt;
学到的值换算成'''健康度'''：&lt;br /&gt;
&lt;br /&gt;
  健康度 = 学习容量 / 6800 mAh&lt;br /&gt;
&lt;br /&gt;
健康度按 EMA 缓慢融入，单次测量不会使其大幅变化。&lt;br /&gt;
&lt;br /&gt;
=== 5.2 内阻学习（电压台阶法） ===&lt;br /&gt;
&lt;br /&gt;
内阻由'''充电器插拔瞬间'''的电压台阶测得：电流突变 ΔI，电压随之突变 ΔV，&lt;br /&gt;
&lt;br /&gt;
  R = ΔV / ΔI&lt;br /&gt;
&lt;br /&gt;
条件：电压 &amp;gt; 7.8 V（近满电区，否则 OCV 本身会随电量移动而测不准）、&lt;br /&gt;
电流台阶 ≥ 300 mA、电压台阶 ≥ 15 mV。测量结果按 3/10 的权重 EMA 融入，&lt;br /&gt;
范围限制在 10–200 mΩ，默认值 50 mΩ。&lt;br /&gt;
&lt;br /&gt;
该值是'''整包回路电阻''' = 电芯本体 + 线缆/接插件（20 mΩ）+ 保护板 MOSFET（15 mΩ）。&lt;br /&gt;
去 IR 使用整包串联值，不做扣减；上位机显示&amp;quot;电芯本体内阻&amp;quot;时才减去这 35 mΩ 板级寄生。&lt;br /&gt;
&lt;br /&gt;
=== 5.3 显示空点学习 ===&lt;br /&gt;
&lt;br /&gt;
每台机器的电流计增益与实际容量存在偏差，内部 SOC 归零的时刻与硬件实际断电的&lt;br /&gt;
时刻可能不一致（表现为显示尚有 20 % 时断电）。固件不修改电流链路，而是在'''显示层'''&lt;br /&gt;
套一个每台机器自学习的线性映射：&lt;br /&gt;
&lt;br /&gt;
  显示值 = (内部SOC − 空点) × 100 / (100 − 空点)&lt;br /&gt;
&lt;br /&gt;
'''空点'''（empty）= 上一次&amp;quot;电池真的没电了&amp;quot;时的内部 SOC。学习事件包括：&lt;br /&gt;
低压关机命令、低压下主机意外死机、欠压锚点。&lt;br /&gt;
&lt;br /&gt;
并带'''向下自纠'''：放电时电压仍健康（&amp;gt; 6.8 V）而内部 SOC 已低于空点，&lt;br /&gt;
说明空点偏高，空点随之下调。换电池或学习过头可在一个放电周期内恢复。&lt;br /&gt;
&lt;br /&gt;
=== 5.4 充电增益学习 ===&lt;br /&gt;
&lt;br /&gt;
充电效率不足 100 %，充入电荷与实际存入电荷存在差异。该增益在满电锚点学习，&lt;br /&gt;
变化 ≥1 % 时落盘。&lt;br /&gt;
&lt;br /&gt;
== 六、温度补偿 ==&lt;br /&gt;
&lt;br /&gt;
板载 NTC 每 200 ms 把温度送入库仑计，用于两项修正：&lt;br /&gt;
&lt;br /&gt;
=== 6.1 内阻温度倍率 k(T) ===&lt;br /&gt;
&lt;br /&gt;
内阻随温度变化，直接影响去 IR 的准确性。倍率取 NCA 典型温度特性的分段线性近似：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 温度 !! 内阻倍率 k(T)&lt;br /&gt;
|-&lt;br /&gt;
| −20 °C || ×3.00&lt;br /&gt;
|-&lt;br /&gt;
| −10 °C || ×2.30&lt;br /&gt;
|-&lt;br /&gt;
| 0 °C || ×1.80&lt;br /&gt;
|-&lt;br /&gt;
| 10 °C || ×1.35&lt;br /&gt;
|-&lt;br /&gt;
| 25 °C || ×1.00（基准）&lt;br /&gt;
|-&lt;br /&gt;
| 40 °C || ×0.85&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
即 −20 °C 时内阻约为常温的'''三倍'''。学习到的内阻归一到 25 °C，使用时再乘 k(T)。&lt;br /&gt;
超出 −20…40 °C 的部分按端点截断。&lt;br /&gt;
&lt;br /&gt;
=== 6.2 低温可用容量补偿 ===&lt;br /&gt;
&lt;br /&gt;
低温下电池可用容量下降（电量并未消失，只是低温下无法取出）。固件据此&lt;br /&gt;
'''把显示空点上移'''，使显示电量提前走低：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 温度 !! 空点上移&lt;br /&gt;
|-&lt;br /&gt;
| ≥ 15 °C || 0（不补偿）&lt;br /&gt;
|-&lt;br /&gt;
| 0 °C || 约 +4 %&lt;br /&gt;
|-&lt;br /&gt;
| −10 °C || 约 +8 %&lt;br /&gt;
|-&lt;br /&gt;
| ≤ −20 °C || +12 %（封顶）&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NTC 读数超出 −30…70 °C 视为故障，保持上一次有效温度（初值 25 °C）。&lt;br /&gt;
&lt;br /&gt;
== 七、显示曲线 ==&lt;br /&gt;
&lt;br /&gt;
内部 SOC 不直接显示，中间还有一层映射：&lt;br /&gt;
&lt;br /&gt;
* '''4 % → 显示 1 %'''&lt;br /&gt;
* '''96 % → 显示 100 %'''&lt;br /&gt;
* 中段线性（斜率 99/92），两端截断&lt;br /&gt;
&lt;br /&gt;
因此'''显示 0 % 时电池仍留有约 4 % 余量'''（另加空点以下的硬件余量），&lt;br /&gt;
可供保存工作并正常关机；充到 96 % 即显示 100 %。这是消费电子的常规做法。&lt;br /&gt;
&lt;br /&gt;
固件上报的百分比'''下限钳在 1 %'''：未关机时不显示 0 %。&lt;br /&gt;
&lt;br /&gt;
== 八、关机后的电量保持 ==&lt;br /&gt;
&lt;br /&gt;
共三条路径：&lt;br /&gt;
&lt;br /&gt;
=== 8.1 SOC 快照 ===&lt;br /&gt;
&lt;br /&gt;
运行时 SOC 每漂移 ≥5 % 就自动落盘；关机、主机断电、进待机、OTA 复位前&lt;br /&gt;
强制落盘并刷新时间戳。&lt;br /&gt;
&lt;br /&gt;
开机恢复策略：&lt;br /&gt;
&lt;br /&gt;
* '''≤12 小时'''：SOC = 快照 − 2.0 mA × Δt（按待机电流扣减），并'''禁止'''&lt;br /&gt;
  OCV 重估覆盖。&lt;br /&gt;
* '''&amp;gt;12 小时'''：快照过期，走冷启动 OCV 重估。&lt;br /&gt;
&lt;br /&gt;
=== 8.2 深睡放电估计 ===&lt;br /&gt;
&lt;br /&gt;
电池深睡时 TPA626 掉电，无法采集电流。固件进睡前记录 RTC 分钟戳，&lt;br /&gt;
唤醒后按整机待机约 '''2.0 mA''' 恒流扣减。&lt;br /&gt;
&lt;br /&gt;
=== 8.3 换电池识别 ===&lt;br /&gt;
&lt;br /&gt;
电池拔出后 RTC 掉电重置，时间倒退。固件据此判定为换电池，快照作废并重新冷启动估计。&lt;br /&gt;
判定留有 10 分钟容差，避免升级重启时误判丢弃有效快照。&lt;br /&gt;
&lt;br /&gt;
== 九、数据如何到达 Linux ==&lt;br /&gt;
&lt;br /&gt;
MCU 算完，通过 '''UART''' 把状态帧发给主机（RK3576）。主机侧有两个消费者：&lt;br /&gt;
&lt;br /&gt;
=== 9.1 内核驱动：photonicat-pm ===&lt;br /&gt;
&lt;br /&gt;
这是一个 '''serdev''' 驱动（&amp;lt;code&amp;gt;990-photonicat-pm-add-driver.patch&amp;lt;/code&amp;gt;，&lt;br /&gt;
内核 6.12），直接挂在串口上解析状态帧，然后注册成标准 Linux 设备：&lt;br /&gt;
&lt;br /&gt;
* '''power_supply''' 类 → &amp;lt;code&amp;gt;/sys/class/power_supply/battery&amp;lt;/code&amp;gt;&lt;br /&gt;
* '''RTC''' 类 → &amp;lt;code&amp;gt;/dev/rtc&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
由于注册为'''标准子系统'''，现成 Linux 工具可直接使用，无需了解私有协议：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
# 电量（%），这就是上面整套算法的最终输出&lt;br /&gt;
cat /sys/class/power_supply/battery/capacity&lt;br /&gt;
&lt;br /&gt;
# 电压 µV / 电流 µA / 功率 µW&lt;br /&gt;
cat /sys/class/power_supply/battery/voltage_now&lt;br /&gt;
cat /sys/class/power_supply/battery/current_now&lt;br /&gt;
cat /sys/class/power_supply/battery/power_now&lt;br /&gt;
&lt;br /&gt;
# 能量 µWh：energy_full 是学习到的满容量，对比 energy_full_design 看老化&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_now&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_full&lt;br /&gt;
cat /sys/class/power_supply/battery/energy_full_design&lt;br /&gt;
&lt;br /&gt;
# 充电器在线&lt;br /&gt;
cat /sys/class/power_supply/charger/online&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''MCU 即硬件 RTC。'''板上没有独立 RTC 芯片，MCU 常供电并自行走时，&lt;br /&gt;
时间随状态帧上送。驱动将其注册为 &amp;lt;code&amp;gt;rtc_class_ops&amp;lt;/code&amp;gt;，标准工具可直接使用：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
hwclock -r          # 读 MCU 里的时间&lt;br /&gt;
hwclock -w          # 把系统时间写回 MCU&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
因此'''断网断电数日后开机时间仍准确'''。8.3 的换电池识别也依赖它：&lt;br /&gt;
RTC 掉电重置后时间会倒退。&lt;br /&gt;
&lt;br /&gt;
=== 9.2 用户态守护进程：pcat-manager ===&lt;br /&gt;
&lt;br /&gt;
内核驱动只处理状态帧中的电源部分。'''其余 UART 协议由 pcat-manager 处理'''：&lt;br /&gt;
调制解调器管理、看门狗、开关机策略、按键事件、充电阈值下发、MCU 固件升级等。&lt;br /&gt;
完整协议见 [[Photonicat 2 MCU 通讯协议]]。&lt;br /&gt;
&lt;br /&gt;
分工如下：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 组件 !! 负责&lt;br /&gt;
|-&lt;br /&gt;
| MCU 固件 || 测量、积分、学习、补偿——所有算法&lt;br /&gt;
|-&lt;br /&gt;
| photonicat-pm（内核） || 电源/RTC 数据 → 标准 sysfs 接口&lt;br /&gt;
|-&lt;br /&gt;
| pcat-manager（用户态） || 其余协议：调制解调器、看门狗、电源策略、OTA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
以'''充电上限'''为例：网页设置 80 % 后，pcat-manager 通过 UART 下发给 MCU，&lt;br /&gt;
MCU 存入 data flash 并直接控制充电 MOSFET。自固件 '''RA2E1260726005''' 起该设置在&lt;br /&gt;
MCU 侧持久化，复位或 OTA 后不丢失；pcat-manager 同时保留镜像，检测到 MCU 重启时重新下发。&lt;br /&gt;
&lt;br /&gt;
== 十、常见问题 ==&lt;br /&gt;
&lt;br /&gt;
;电量偶尔小幅跳动&lt;br /&gt;
:OCV 融合或锚点正在修正积分漂移。单次修正上限 0.20 %，正常情况下不会出现大跳变；&lt;br /&gt;
 若出现大跳变，通常是快照过期后走了冷启动重估。&lt;br /&gt;
&lt;br /&gt;
;冬天电量下降更快&lt;br /&gt;
:低温下可用容量下降，同时固件把显示空点上移（−10 °C 约 +8 %）。回暖后恢复。&lt;br /&gt;
&lt;br /&gt;
;充到 96 % 即显示 100 %&lt;br /&gt;
:显示曲线的设定，见第七节。同理显示 0 % 时电池仍有余量。&lt;br /&gt;
&lt;br /&gt;
;新电池是否需要校准&lt;br /&gt;
:不需要专门操作。完整放电一次（满电到自动关机）可让固件学到真实满容量和空点，&lt;br /&gt;
 日常使用也会逐步学到。&lt;br /&gt;
&lt;br /&gt;
;健康度的更新频率&lt;br /&gt;
:需要一次完整放电窗口（满电锚点 → 欠压），中途充电则本次作废，因此更新较慢，&lt;br /&gt;
 且按 EMA 缓变。&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:34:41 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_SOC_%E8%AE%A1%E7%AE%97</comments>
		</item>
		<item>
			<title>Photonicat 2 MCU 通讯协议</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_MCU_%E9%80%9A%E8%AE%AF%E5%8D%8F%E8%AE%AE&amp;diff=258&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_MCU_%E9%80%9A%E8%AE%AF%E5%8D%8F%E8%AE%AE&amp;diff=258&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“本页描述 &amp;#039;&amp;#039;&amp;#039;Photonicat 2&amp;#039;&amp;#039;&amp;#039; 主机（RK3576）与电源管理 MCU（Renesas RA2E1）之间的 串口通讯协议。协议同样适用于一代（RK3568），但一代的电压阈值是单节锂电语义， 详见下方&amp;quot;与一代的差异&amp;quot;。  相关页面：&lt;a href=&quot;/Photonicat_2_sysfs&quot; title=&quot;Photonicat 2 sysfs&quot;&gt;Photonicat 2 sysfs&lt;/a&gt;（内核已经把电源/RTC 数据导出成标准接口， 一般应用&amp;#039;&amp;#039;&amp;#039;不需要&amp;#039;&amp;#039;&amp;#039;自己解析本协议）、&lt;a href=&quot;/Photonicat_2_SOC_%E8%AE%A1%E7%AE%97&quot; title=&quot;Photonicat 2 SOC 计算&quot;&gt;Photonicat 2 SOC 计算&lt;/a&gt;（状态帧里的 电量是怎么算出…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;本页描述 '''Photonicat 2''' 主机（RK3576）与电源管理 MCU（Renesas RA2E1）之间的&lt;br /&gt;
串口通讯协议。协议同样适用于一代（RK3568），但一代的电压阈值是单节锂电语义，&lt;br /&gt;
详见下方&amp;quot;与一代的差异&amp;quot;。&lt;br /&gt;
&lt;br /&gt;
相关页面：[[Photonicat 2 sysfs]]（内核已经把电源/RTC 数据导出成标准接口，&lt;br /&gt;
一般应用'''不需要'''自己解析本协议）、[[Photonicat 2 SOC 计算]]（状态帧里的&lt;br /&gt;
电量是怎么算出来的）、[[Photonicat 2 LED 指示灯]]、[[Photonicat 2 提示音说明]]。&lt;br /&gt;
&lt;br /&gt;
== 先读这里：你可能不需要这个协议 ==&lt;br /&gt;
&lt;br /&gt;
绝大多数应用不应该直接收发本协议。主机侧已经有两层封装：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 你想做的事 !! 推荐用法&lt;br /&gt;
|-&lt;br /&gt;
| 读电量/电压/电流/充电器状态 || &amp;lt;code&amp;gt;/sys/class/power_supply/*&amp;lt;/code&amp;gt;，见 [[Photonicat 2 sysfs]]&lt;br /&gt;
|-&lt;br /&gt;
| 读写时间 || &amp;lt;code&amp;gt;hwclock&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;/dev/rtc&amp;lt;/code&amp;gt;（MCU 就是硬件 RTC）&lt;br /&gt;
|-&lt;br /&gt;
| 风扇转速、温度 || &amp;lt;code&amp;gt;/sys/class/hwmon/*&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;/sys/class/thermal/*&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 网页界面里的各种设置 || pcat-manager 的 REST API，见 [[Photonicat 2 开发者 API]]&lt;br /&gt;
|-&lt;br /&gt;
| 上面都覆盖不到的功能 || 才需要本页的协议&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
串口本身由内核驱动 &amp;lt;code&amp;gt;photonicat-pm&amp;lt;/code&amp;gt; 和用户态守护进程&lt;br /&gt;
'''pcat-manager''' 占用。第三方程序直接抢串口会和它们冲突。&lt;br /&gt;
&lt;br /&gt;
== 物理层 ==&lt;br /&gt;
&lt;br /&gt;
* 串口，'''115200''' 波特率，8 数据位，无校验，1 停止位（8N1）&lt;br /&gt;
* 主机侧设备：一代为 &amp;lt;code&amp;gt;/dev/ttyS4&amp;lt;/code&amp;gt;；二代由设备树绑定给&lt;br /&gt;
  &amp;lt;code&amp;gt;photonicat-pm&amp;lt;/code&amp;gt; 驱动（serdev），不再以裸 tty 暴露&lt;br /&gt;
&lt;br /&gt;
== 帧格式 ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 字节 !! 字段 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 起始位 || 固定 '''0xA5'''&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 源地址 || 见地址表&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 目的地址 || 见地址表&lt;br /&gt;
|-&lt;br /&gt;
| 3–4 || 帧序号 || 小端 uint16，主动发送方每发一帧加一，溢出回零；应答沿用请求的帧序号&lt;br /&gt;
|-&lt;br /&gt;
| 5–6 || 数据长度 || 小端 uint16，指&amp;quot;命令号 + 命令内容 + 是否需要回复&amp;quot;三段的总字节数&lt;br /&gt;
|-&lt;br /&gt;
| 7–8 || 命令号 || 小端 uint16&lt;br /&gt;
|-&lt;br /&gt;
| 9… || 命令内容 || 变长，见各命令说明&lt;br /&gt;
|-&lt;br /&gt;
| 倒数第 4 || 是否需要回复 || 1 = 需要应答，0 = 不需要&lt;br /&gt;
|-&lt;br /&gt;
| 倒数第 3、2 || CRC16 || 对'''从字节 1 到&amp;quot;是否需要回复&amp;quot;为止'''的所有字节计算，小端&lt;br /&gt;
|-&lt;br /&gt;
| 最后 1 || 结束位 || 固定 '''0x5A'''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
一帧总长 = 数据长度 + 10。接收方据此校验，长度对不上直接丢弃。&lt;br /&gt;
&lt;br /&gt;
=== 地址表 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 值 !! 含义&lt;br /&gt;
|-&lt;br /&gt;
| 0x01 || 第一块 CPU 板（目前只有一块，主机固定用 0x01）&lt;br /&gt;
|-&lt;br /&gt;
| 0x02 / 0x03 || 第二、三块 CPU 板（预留）&lt;br /&gt;
|-&lt;br /&gt;
| 0x80 || 广播给所有 CPU 板&lt;br /&gt;
|-&lt;br /&gt;
| 0x81 || 电源管理 MCU（RA2E1）&lt;br /&gt;
|-&lt;br /&gt;
| 0xFE || 广播给所有 RA2E1&lt;br /&gt;
|-&lt;br /&gt;
| 0xFF || 广播给系统内所有设备&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 命令号约定 ===&lt;br /&gt;
&lt;br /&gt;
'''奇数 = 请求，偶数 = 对应的应答'''（应答号 = 请求号 + 1）。这条规则贯穿整个&lt;br /&gt;
协议，MCU 内部就是按 &amp;lt;code&amp;gt;命令号 % 2&amp;lt;/code&amp;gt; 来分发的。&lt;br /&gt;
&lt;br /&gt;
== 命令一览 ==&lt;br /&gt;
&lt;br /&gt;
=== 基础与版本 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''1''' / 2 || CPU → MCU || 无 || 心跳。超过 1 分钟没有收到任何数据，MCU 会重启主机&lt;br /&gt;
|-&lt;br /&gt;
| '''3''' / 4 || CPU → MCU || 应答含 8 字节字符串 || 读硬件版本，例如 &amp;lt;code&amp;gt;NT2421A4&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''5''' / 6 || CPU → MCU || 应答含 14 字节字符串 || 读软件版本，例如 &amp;lt;code&amp;gt;RA2E1260726005&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| '''139''' / 140 || CPU → MCU || —— || 读硬件 ID&lt;br /&gt;
|-&lt;br /&gt;
| '''159''' / 160 || CPU → MCU || —— || 读 bootloader 版本号&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 状态上报（7） ===&lt;br /&gt;
&lt;br /&gt;
'''MCU → CPU'''，周期性主动上报，是整个协议里最重要的一帧。数据长度 56。&lt;br /&gt;
下表偏移量以'''命令内容'''首字节为 0（即整帧的字节 9）：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 偏移 !! 长度 !! 字段 !! 单位 / 说明&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 2 || 电池电压 || mV，小端&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 2 || 充电器接口电压 || mV，小端&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 2 || 输入 GPIO 状态 || 位域&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 2 || 输出 GPIO 状态 || 位域&lt;br /&gt;
|-&lt;br /&gt;
| 8 || 8 || 系统时间 || 年(2) 月 日 时 分 秒 星期，各 1 字节&lt;br /&gt;
|-&lt;br /&gt;
| 16 || 1 || RTC 状态 || 0 正常，1 初始化异常，2 无秒中断，3 无分钟中断&lt;br /&gt;
|-&lt;br /&gt;
| 17 || 1 || 板子温度 || '''实际温度 = 本字节 − 100'''（℃）&lt;br /&gt;
|-&lt;br /&gt;
| 18 || 2 || 电池电流 || mA，'''有符号'''小端。正 = 放电，负 = 充电&lt;br /&gt;
|-&lt;br /&gt;
| 20 || 2 || 剩余容量 || mAh&lt;br /&gt;
|-&lt;br /&gt;
| 22 || 1 || 电量 || %（1–100，算法见 [[Photonicat 2 SOC 计算]]）&lt;br /&gt;
|-&lt;br /&gt;
| 23 || 4 || 当前能量 || mWh，小端&lt;br /&gt;
|-&lt;br /&gt;
| 27 || 4 || 满电能量 || mWh，小端（学习值，可与标称对比看老化）&lt;br /&gt;
|-&lt;br /&gt;
| 31 || 4 || 累计开机时长 || 秒，小端&lt;br /&gt;
|-&lt;br /&gt;
| 35 || 4 || 加速度 X || 1/16384 g，有符号小端&lt;br /&gt;
|-&lt;br /&gt;
| 39 || 4 || 加速度 Y || 同上&lt;br /&gt;
|-&lt;br /&gt;
| 43 || 4 || 加速度 Z || 同上&lt;br /&gt;
|-&lt;br /&gt;
| 47 || 1 || 加速度数据就绪 || 非 0 表示有效&lt;br /&gt;
|-&lt;br /&gt;
| 48 || 4 || 风扇转速 || RPM，小端&lt;br /&gt;
|-&lt;br /&gt;
| 52 || 1 || 充电状态 || 0 未充电，1 小电流充电，2 大电流充电，3 已充满&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''向后兼容''':这一帧只在尾部追加字段，从不改动已有偏移。解析时应按&lt;br /&gt;
&amp;quot;长度至少为 N 才读第 N 个字段&amp;quot;的方式写，不要假设固定总长。&lt;br /&gt;
&lt;br /&gt;
=== 时间与定时开机 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''9''' / 10 || CPU → MCU || 年(2) 月 日 时 分 秒，共 7 字节 || 设置 MCU 时间&lt;br /&gt;
|-&lt;br /&gt;
| '''11''' / 12 || CPU → MCU || 见下 || 设置定时开机&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
定时开机每条 8 字节：年(2) 月 日 时 分 星期，再加 1 字节匹配掩码。&lt;br /&gt;
掩码 bit0 年、bit1 月、bit2 日、bit3 时、bit4 分、bit5 星期，&lt;br /&gt;
置 1 表示该项参与匹配。'''分匹配必须为 1'''，否则该条被忽略。&lt;br /&gt;
星期按位匹配，例如 &amp;lt;code&amp;gt;0b00000101&amp;lt;/code&amp;gt; 表示周日和周二。&lt;br /&gt;
一次最多 6 条，覆盖之前的设置，故该段最长 48 字节。&lt;br /&gt;
&lt;br /&gt;
=== 关机与复位 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''13''' / 14 || MCU → CPU || 1 字节关机事件 || MCU 通知主机即将关机&lt;br /&gt;
|-&lt;br /&gt;
| '''15''' / 16 || CPU → MCU || 无 || 主机请求关机&lt;br /&gt;
|-&lt;br /&gt;
| '''17''' / 18 || MCU → CPU || 无 || MCU 通知主机复位&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
关机事件取值：0 按键强制关机，1 电池低电压关机，2 升级前关机，3 其他。&lt;br /&gt;
&lt;br /&gt;
=== 开机原因（27） ===&lt;br /&gt;
&lt;br /&gt;
CPU → MCU 查询，应答 1 字节：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 值 !! 含义&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 按键开机&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 定时开机&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 车载模式：插入充电器开机&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 低电压关机后，插入充电器且电压满足条件开机&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 无电池开机&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 家庭模式：充电器电压满足条件开机&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 看门狗与电源策略 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''19''' / 20 || CPU → MCU || 3 字节：开机超时、关机超时、喂狗超时（秒） || 设置软件看门狗时间&lt;br /&gt;
|-&lt;br /&gt;
| '''21''' / 22 || CPU → MCU || 1 字节 || 0 = 插充电器不自动开机，1 = 插充电器开机。（低电压关机的机器即使设 0 也会开机）&lt;br /&gt;
|-&lt;br /&gt;
| '''157''' / 158 || CPU → MCU || 1 字节 || 硬件看门狗开关&lt;br /&gt;
|-&lt;br /&gt;
| '''161''' / 162 || CPU → MCU || 1 字节 || 设置设备模式（车载 / 家庭等）&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 电压阈值（23） ===&lt;br /&gt;
&lt;br /&gt;
CPU → MCU，'''18 字节'''，9 个 uint16 小端。二代为 2S 电池组，单位 mV，&lt;br /&gt;
数值是'''整包'''电压：&lt;br /&gt;
&lt;br /&gt;
# 电压高指示阈值&lt;br /&gt;
# 电压中指示阈值&lt;br /&gt;
# 电压低指示阈值&lt;br /&gt;
# 插充电器开机电压&lt;br /&gt;
# 充电器在位判定电压&lt;br /&gt;
# 充电器不在时关机电池阈值&lt;br /&gt;
# 工作中低电压提示阈值&lt;br /&gt;
# 大电流充电电压阈值&lt;br /&gt;
# 开机后持续 15 分钟判定满电的电压阈值&lt;br /&gt;
&lt;br /&gt;
超出默认值 ±1000 mV 的设置视为无效，MCU 会退回默认值。&lt;br /&gt;
&lt;br /&gt;
'''注意''':一代文档里的 3850 / 3700 / 3600 等是'''单节'''数值。二代是 2S，&lt;br /&gt;
默认值不同（例如低电告警 6500、强制关机 6300），不要照搬一代的数字。&lt;br /&gt;
各阈值的实际效果见 [[Photonicat 2 LED 指示灯]]。&lt;br /&gt;
&lt;br /&gt;
=== 温度阈值（145） ===&lt;br /&gt;
&lt;br /&gt;
CPU → MCU，2 字节：&lt;br /&gt;
&lt;br /&gt;
* 第 1 字节：主机断电温度（℃），有效范围 '''55–80'''，默认 75&lt;br /&gt;
* 第 2 字节：充电指示灯关闭温度（℃），有效范围 '''50–60'''，默认 53&lt;br /&gt;
&lt;br /&gt;
超范围返回错误，不生效。温度过高触发断电时会播放提示音，&lt;br /&gt;
见 [[Photonicat 2 提示音说明]]。&lt;br /&gt;
&lt;br /&gt;
=== 风扇 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''147''' / 148 || CPU → MCU || 1 字节占空比（0–100） || 主机直接接管风扇。'''一旦下发，MCU 内部的温控 PID 不再控制风扇'''；超过 100 返回错误&lt;br /&gt;
|-&lt;br /&gt;
| '''151''' / 152 || CPU → MCU || 目标温度 || 设置风扇 PID 的目标温度，默认 47 ℃&lt;br /&gt;
|-&lt;br /&gt;
| '''153''' / 154 || CPU → MCU || —— || 读取当前目标温度&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
未被主机接管时，MCU 用增量式 PID 控制风扇：目标温度 47 ℃，&lt;br /&gt;
充电时占空比上限 85 %，纯电池运行时上限 40 %。&lt;br /&gt;
&lt;br /&gt;
=== 指示灯与声音 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''25''' / 26 || CPU → MCU || 6 字节 || 设置网络指示灯：高电平时长(2)、低电平时长(2)、变换次数(2)，时长单位 10 ms，次数 0 表示一直闪&lt;br /&gt;
|-&lt;br /&gt;
| '''155''' / 156 || CPU → MCU || 1 字节 || 声光模式：0x00 全关，0x01 关声音开灯光，0x02 开声音关灯光，0x03 全开；传 '''0xFF''' 为查询当前值&lt;br /&gt;
|-&lt;br /&gt;
| '''163''' / 164 || CPU → MCU || 见下 || 播放自定义蜂鸣器序列&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''自定义蜂鸣器序列（163）'''载荷格式：&lt;br /&gt;
&lt;br /&gt;
  [步进 1][步进 2]…[步进 N][循环模式 1 字节]&lt;br /&gt;
&lt;br /&gt;
每个步进 4 字节：频率 uint16 小端（Hz，0 = 休止）+ 时长 uint16 小端（ms）。&lt;br /&gt;
循环模式 0 = 播放一次，1 = 循环。时长为 0 会被当作 1 ms。&lt;br /&gt;
声音被关闭时该命令不执行。内置提示音见 [[Photonicat 2 提示音说明]]。&lt;br /&gt;
&lt;br /&gt;
=== 电池与充电 ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 方向 !! 内容 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''165''' / 166 || CPU → MCU || 1 字节百分比 || 设置充电上限，有效范围 '''50–100'''，100 = 不限制。超范围返回错误&lt;br /&gt;
|-&lt;br /&gt;
| '''167''' / 168 || CPU → MCU || 应答 1 字节 || 读取当前充电上限&lt;br /&gt;
|-&lt;br /&gt;
| '''169''' / 170 || CPU → MCU || 应答见下 || 读取电池详细信息&lt;br /&gt;
|-&lt;br /&gt;
| '''141''' / 142 || CPU → MCU || 1 字节 || '''已废弃'''，保留解析以兼容老主机，行为等同空操作&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
充电上限自固件 '''RA2E1260726005''' 起持久化在 MCU 侧，复位和 OTA 后不丢失。&lt;br /&gt;
到达上限后 MCU 断开充电 MOSFET，回落约 2 % 后恢复充电。&lt;br /&gt;
&lt;br /&gt;
==== 电池信息（169）应答格式 ====&lt;br /&gt;
&lt;br /&gt;
应答是'''逐版本向尾部追加'''的结构，当前长度 59 字节。偏移以应答的命令内容&lt;br /&gt;
首字节为 0，全部小端：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 偏移 !! 长度 !! 字段 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 2 || 学习到的满容量 || mAh&lt;br /&gt;
|-&lt;br /&gt;
| 2 || 2 || 循环次数 || ——&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 2 || 标称满容量 || mAh&lt;br /&gt;
|-&lt;br /&gt;
| 6 || 1 || 标志位 || bit0 = 容量为学习值，bit1 = 学习窗口进行中&lt;br /&gt;
|-&lt;br /&gt;
| 7 || 2 || 内阻 || mΩ，整包串联值，归一到 25 ℃&lt;br /&gt;
|-&lt;br /&gt;
| 9 || 4 || 累计开机秒数 || ——&lt;br /&gt;
|-&lt;br /&gt;
| 13 || 2 || 电池中点电压 || mV（2P2S 中心抽头）&lt;br /&gt;
|-&lt;br /&gt;
| 15 || 2 || 内部 SOC || ×10，显示修饰前&lt;br /&gt;
|-&lt;br /&gt;
| 17 || 1 || 学习到的显示空点 || %，0 = 未学习&lt;br /&gt;
|-&lt;br /&gt;
| 18 || 2 || 显示变换 a || ×1000&lt;br /&gt;
|-&lt;br /&gt;
| 20 || 2 || 显示变换 b || ×100，有符号&lt;br /&gt;
|-&lt;br /&gt;
| 22 || 2 || 充电电流增益 || ×1000&lt;br /&gt;
|-&lt;br /&gt;
| 24 || 2 || 电流微调 a || ×1000&lt;br /&gt;
|-&lt;br /&gt;
| 26 || 2 || 电流微调 b || mA，有符号&lt;br /&gt;
|-&lt;br /&gt;
| 28 || 2 || 估算剩余容量 || mAh&lt;br /&gt;
|-&lt;br /&gt;
| 30 || 4 || 累计消耗能量 || mWh&lt;br /&gt;
|-&lt;br /&gt;
| 34 || 4 || 累计充入能量 || mWh&lt;br /&gt;
|-&lt;br /&gt;
| 38 || 1 || '''协议版本号''' || 当前 9&lt;br /&gt;
|-&lt;br /&gt;
| 39 || 1 || 电池健康度 || %，0xFF = 尚未学习&lt;br /&gt;
|-&lt;br /&gt;
| 40 || 2 || 预计可用时间 || 分钟，0xFFFF = 非稳定放电&lt;br /&gt;
|-&lt;br /&gt;
| 42 || 2 || 预计充满时间 || 分钟，0xFFFF = 非稳定充电&lt;br /&gt;
|-&lt;br /&gt;
| 44 || 1 || 库仑计在用温度 || ℃，有符号&lt;br /&gt;
|-&lt;br /&gt;
| 45 || 1 || 低温空点上移 || ×10 %，常温 = 0&lt;br /&gt;
|-&lt;br /&gt;
| 46 || 2 || 内阻温度倍率 k(T) || ×1000，25 ℃ = 1000&lt;br /&gt;
|-&lt;br /&gt;
| 48 || 1 || 回路寄生电阻 || mΩ（线缆+接插件+MOSFET）。电芯本体内阻 = 偏移 7 的值 − 本值&lt;br /&gt;
|-&lt;br /&gt;
| 49 || 4 || MCU 总运行秒数 || 自 MCU 复位起，看门狗/异常复位会清零&lt;br /&gt;
|-&lt;br /&gt;
| 53 || 4 || 距上次休眠唤醒秒数 || 从未休眠则等于总运行秒数&lt;br /&gt;
|-&lt;br /&gt;
| 57 || 2 || 进入待机次数 || 饱和计数&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
偏移 38 之前的版本靠'''应答长度'''区分（≥7、≥13、≥15、≥28、≥38…）；&lt;br /&gt;
从版本 9 起有显式版本号字段，建议新代码优先读它。这些字段的物理含义见&lt;br /&gt;
[[Photonicat 2 SOC 计算]]。&lt;br /&gt;
&lt;br /&gt;
=== 抬腕唤醒（149） ===&lt;br /&gt;
&lt;br /&gt;
MCU → CPU 主动上报抬腕/移动事件。对应 sysfs 的&lt;br /&gt;
&amp;lt;code&amp;gt;/sys/kernel/photonicat-pm/movement_trigger&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
=== MCU 固件升级 ===&lt;br /&gt;
&lt;br /&gt;
这一组命令由 pcat-manager 的升级工具使用，'''不建议手工调用'''——&lt;br /&gt;
中断升级流程可能使 MCU 无法启动。正常升级方式见&lt;br /&gt;
[[Photonicat 2 MCU 手动更新]]。&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 命令 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| '''129''' / 130 || 请求进入升级模式&lt;br /&gt;
|-&lt;br /&gt;
| '''203''' / 204 || 开始 OTA&lt;br /&gt;
|-&lt;br /&gt;
| '''205''' / 206 || 传送版本号&lt;br /&gt;
|-&lt;br /&gt;
| '''207''' / 208 || OTA 结束&lt;br /&gt;
|-&lt;br /&gt;
| '''209''' / 210 || 回报&amp;quot;已收到结束&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| '''211''' / 212 || 传输 OTA 数据&lt;br /&gt;
|-&lt;br /&gt;
| '''213''' / 214 || 接收就绪&lt;br /&gt;
|-&lt;br /&gt;
| '''215''' / 216 || 长度校验正确&lt;br /&gt;
|-&lt;br /&gt;
| '''217''' / 218、'''219''' / 220 || 新区域拷贝到备份区 / 拷贝完成&lt;br /&gt;
|-&lt;br /&gt;
| '''221''' / 222、'''223''' / 224 || 擦除 SPI 最新区 / 备份区&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 错误上报（201） ===&lt;br /&gt;
&lt;br /&gt;
MCU → CPU，用于上报解析或执行错误。&lt;br /&gt;
&lt;br /&gt;
== 与一代的差异 ==&lt;br /&gt;
&lt;br /&gt;
* 一代主机是 RK3568，二代是 RK3576&lt;br /&gt;
* 一代是单节锂电，命令 23 的阈值是单节电压（3850 / 3700 / 3600 等）；&lt;br /&gt;
  二代是 2S 电池组，同样的字段是整包电压（约为一代的两倍）&lt;br /&gt;
* 一代只有命令 1–28；二代在 129 以上扩展了 ID、风扇、温度、声光、&lt;br /&gt;
  电池信息、充电上限等&lt;br /&gt;
* 一代靠 pcat-manager 的 socket 对外提供数据；二代已集成进内核，&lt;br /&gt;
  推荐直接读 sysfs，见 [[Photonicat 2 sysfs]]&lt;br /&gt;
&lt;br /&gt;
== 参考实现 ==&lt;br /&gt;
&lt;br /&gt;
* 主机侧用户态：pcat-manager &amp;lt;code&amp;gt;src/pmu-manager.c&amp;lt;/code&amp;gt;&lt;br /&gt;
* 主机侧内核：&amp;lt;code&amp;gt;photonicat-pm&amp;lt;/code&amp;gt;（power_supply + RTC）&lt;br /&gt;
* 一代参考：[https://github.com/photonicat/rockchip_rk3568_pcat_manager/blob/master/src/pmu-manager.c rockchip_rk3568_pcat_manager]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:34:25 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_MCU_%E9%80%9A%E8%AE%AF%E5%8D%8F%E8%AE%AE</comments>
		</item>
		<item>
			<title>Photonicat 2 Docker 使用指南</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_Docker_%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97&amp;diff=257&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_Docker_%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97&amp;diff=257&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2, photonicatWrt 26.04.x（Docker 27.0.2, docker-compose v2.28, LuCI dockerman） / Photonicat 2, photonicatWrt 26.04.x (Docker 27.0.2, docker-compose v2.28, LuCI dockerman) |}  photonicatWrt 26.04 出厂即带完整 Docker 环境：&amp;#039;&amp;#039;&amp;#039;Docker Engine 27.0.2 + docker-compose v2 + LuCI 图形管理（dockerman）&amp;#039;&amp;#039;&amp;#039;。本页覆盖日常使用、存储位置、防火墙行为，以及一个&amp;#039;&amp;#039;&amp;#039;影响全网 I…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2, photonicatWrt 26.04.x（Docker 27.0.2, docker-compose v2.28, LuCI dockerman） / Photonicat 2, photonicatWrt 26.04.x (Docker 27.0.2, docker-compose v2.28, LuCI dockerman)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
photonicatWrt 26.04 出厂即带完整 Docker 环境：'''Docker Engine 27.0.2 + docker-compose v2 + LuCI 图形管理（dockerman）'''。本页覆盖日常使用、存储位置、防火墙行为，以及一个'''影响全网 IPv6 的重要坑'''及其正确修复方式。1 代用户请参考 [[Photonicat Openwrt Docker/istore]]。&lt;br /&gt;
&lt;br /&gt;
photonicatWrt 26.04 ships a complete Docker stack: '''Docker Engine 27.0.2 + docker-compose v2 + the LuCI dockerman GUI'''. This page covers daily use, storage, firewall behavior, and one '''important pitfall that breaks IPv6 for the whole LAN''' plus its correct fix. Gen-1 users see [[Photonicat Openwrt Docker/istore]].&lt;br /&gt;
&lt;br /&gt;
== 中文说明 ==&lt;br /&gt;
&lt;br /&gt;
=== 使用入口 ===&lt;br /&gt;
* '''图形界面'''：LuCI → Docker（dockerman），可管理镜像、容器、网络、卷。&lt;br /&gt;
* '''命令行'''（SSH）：&amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt; 与 &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt; 均可直接使用：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
docker info | grep -E 'Server Version|Root Dir'&lt;br /&gt;
docker run -d --name uptime-kuma -p 3001:3001 louislam/uptime-kuma&lt;br /&gt;
docker compose up -d        # 在含 docker-compose.yml 的目录下&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 存储位置 ===&lt;br /&gt;
* 镜像/容器数据目录（data-root）由出厂的 &amp;lt;code&amp;gt;/etc/docker/daemon.json&amp;lt;/code&amp;gt; 指定为 '''/opt'''，位于系统 overlay 分区（约 3.7 GB）。&lt;br /&gt;
* 跑多个容器建议把大数据挂到 '''NVMe/SD''' 上：优先用 &amp;lt;code&amp;gt;-v /mnt/nvme/...:/data&amp;lt;/code&amp;gt; 挂卷，而不是搬移 data-root。&lt;br /&gt;
* '''不要随意改 data-root'''：改了之后已有镜像会&amp;quot;消失&amp;quot;（其实还在旧目录占着空间）。&lt;br /&gt;
&lt;br /&gt;
=== 防火墙行为（wan_mode） ===&lt;br /&gt;
Docker 由 &amp;lt;code&amp;gt;/etc/init.d/docker&amp;lt;/code&amp;gt; 启动，行为由 UCI 选项控制：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci show docker            # docker.@docker[0].wan_mode&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;wan_mode='0'&amp;lt;/code&amp;gt;（默认）：以 &amp;lt;code&amp;gt;--iptables=false&amp;lt;/code&amp;gt; 启动——Docker '''不改动 IPv4 防火墙'''，规则完全由 fw4 掌管，端口发布经用户态代理转发。最干净、推荐。&lt;br /&gt;
* &amp;lt;code&amp;gt;wan_mode='1'&amp;lt;/code&amp;gt;：允许 Docker 自行管理 iptables（容器间隔离、DNAT 端口映射由 Docker 负责）。需要复杂容器网络时才用。&lt;br /&gt;
&lt;br /&gt;
=== ⚠ 重要坑：Docker 27 默认接管 IPv6 防火墙 ===&lt;br /&gt;
即使 &amp;lt;code&amp;gt;wan_mode='0'&amp;lt;/code&amp;gt;（IPv4 不接管），'''Docker 27 起 ip6tables 是独立开关且默认开启'''：启动时会创建 &amp;lt;code&amp;gt;ip6 filter FORWARD&amp;lt;/code&amp;gt; 链并置 '''policy drop''' —— 结果是'''路由器不再转发任何 IPv6'''，内网设备拿到公网 IPv6 地址却上不了网（fw4 放行也无效，因为两条链是&amp;quot;与&amp;quot;关系）。&lt;br /&gt;
&lt;br /&gt;
检查是否中招：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nft list chain ip6 filter FORWARD&lt;br /&gt;
# 看到 &amp;quot;policy drop&amp;quot; 且计数增长 = 中招&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''正确修复'''：在出厂 daemon.json 基础上'''追加'''一行 &amp;lt;code&amp;gt;&amp;quot;ip6tables&amp;quot;: false&amp;lt;/code&amp;gt;：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat &amp;gt; /etc/docker/daemon.json &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;data-root&amp;quot;: &amp;quot;/opt/&amp;quot;,&lt;br /&gt;
&amp;quot;log-level&amp;quot;: &amp;quot;warn&amp;quot;,&lt;br /&gt;
&amp;quot;ip6tables&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
/etc/init.d/docker restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''三个不要'''：&lt;br /&gt;
# 不要删除/改动出厂的 &amp;lt;code&amp;gt;data-root&amp;lt;/code&amp;gt;（镜像会&amp;quot;消失&amp;quot;，见上）；&lt;br /&gt;
# 不要往 daemon.json 添加 &amp;lt;code&amp;gt;&amp;quot;iptables&amp;quot;&amp;lt;/code&amp;gt; 键——它与启动参数 &amp;lt;code&amp;gt;--iptables=false&amp;lt;/code&amp;gt; 冲突，'''Docker 会在下次开机拒绝启动'''（dockerd 对&amp;quot;同一项既是命令行参数又在配置文件&amp;quot;直接报错退出）；&lt;br /&gt;
# 不要用 &amp;lt;code&amp;gt;ip6tables -P FORWARD ACCEPT&amp;lt;/code&amp;gt; 之类的手工命令当永久方案——重启后 Docker 会重建 drop 链。&lt;br /&gt;
&lt;br /&gt;
=== 两个启动脚本的说明 ===&lt;br /&gt;
系统里同时存在两个 Docker 启动脚本，实际生效的是前者：&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/init.d/docker&amp;lt;/code&amp;gt;（S25，luci-app-docker 提供）：开机先启动，读取 UCI &amp;lt;code&amp;gt;docker.wan_mode&amp;lt;/code&amp;gt;，'''真正拉起 dockerd'''。dockerd 会自动读取默认配置文件 &amp;lt;code&amp;gt;/etc/docker/daemon.json&amp;lt;/code&amp;gt;——这就是上面修复生效的原因。&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/init.d/dockerd&amp;lt;/code&amp;gt;（S99，OpenWrt 标准包）：开机时 dockerd 已在运行，它的实例不会生效；其 UCI 配置（/etc/config/dockerd）对实际运行的 Docker '''基本无效'''。排障时别被它误导。&lt;br /&gt;
&lt;br /&gt;
== English ==&lt;br /&gt;
&lt;br /&gt;
=== Entry points ===&lt;br /&gt;
* '''GUI''': LuCI → Docker (dockerman) — images, containers, networks, volumes.&lt;br /&gt;
* '''CLI''' (SSH): both &amp;lt;code&amp;gt;docker&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;docker compose&amp;lt;/code&amp;gt; work out of the box (see examples above).&lt;br /&gt;
&lt;br /&gt;
=== Storage ===&lt;br /&gt;
* The data-root is set by the factory &amp;lt;code&amp;gt;/etc/docker/daemon.json&amp;lt;/code&amp;gt; to '''/opt''' on the system overlay (~3.7 GB).&lt;br /&gt;
* For heavy use, keep bulky data on '''NVMe/SD''' via bind mounts (&amp;lt;code&amp;gt;-v /mnt/nvme/...:/data&amp;lt;/code&amp;gt;) rather than moving the data-root.&lt;br /&gt;
* '''Don't casually change data-root''' — existing images &amp;quot;disappear&amp;quot; (while still consuming space in the old location).&lt;br /&gt;
&lt;br /&gt;
=== Firewall behavior (wan_mode) ===&lt;br /&gt;
Docker is launched by &amp;lt;code&amp;gt;/etc/init.d/docker&amp;lt;/code&amp;gt;, controlled by UCI:&lt;br /&gt;
* &amp;lt;code&amp;gt;wan_mode='0'&amp;lt;/code&amp;gt; (default): started with &amp;lt;code&amp;gt;--iptables=false&amp;lt;/code&amp;gt; — Docker '''never touches the IPv4 firewall'''; fw4 owns all rules and published ports go through the userland proxy. Cleanest, recommended.&lt;br /&gt;
* &amp;lt;code&amp;gt;wan_mode='1'&amp;lt;/code&amp;gt;: Docker manages iptables itself (container isolation, DNAT port mapping). Only for complex container networking.&lt;br /&gt;
&lt;br /&gt;
=== ⚠ The big pitfall: Docker 27 hijacks the IPv6 firewall by default ===&lt;br /&gt;
Even with &amp;lt;code&amp;gt;wan_mode='0'&amp;lt;/code&amp;gt;, '''ip6tables is a separate switch, enabled by default since Docker 27''': at startup it creates an &amp;lt;code&amp;gt;ip6 filter FORWARD&amp;lt;/code&amp;gt; chain with '''policy drop''' — the router '''stops forwarding all IPv6'''. LAN clients hold global IPv6 addresses but can't reach the internet, and fw4's accepts don't help (the chains AND together).&lt;br /&gt;
&lt;br /&gt;
Check: &amp;lt;code&amp;gt;nft list chain ip6 filter FORWARD&amp;lt;/code&amp;gt; — &amp;quot;policy drop&amp;quot; with a growing counter means you're hit.&lt;br /&gt;
&lt;br /&gt;
'''Correct fix''': '''append''' &amp;lt;code&amp;gt;&amp;quot;ip6tables&amp;quot;: false&amp;lt;/code&amp;gt; to the factory daemon.json (full file above), then &amp;lt;code&amp;gt;/etc/init.d/docker restart&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Three don'ts''':&lt;br /&gt;
# Don't remove/alter the factory &amp;lt;code&amp;gt;data-root&amp;lt;/code&amp;gt; (images &amp;quot;disappear&amp;quot;, see above);&lt;br /&gt;
# Don't add an &amp;lt;code&amp;gt;&amp;quot;iptables&amp;quot;&amp;lt;/code&amp;gt; key — it conflicts with the launch flag &amp;lt;code&amp;gt;--iptables=false&amp;lt;/code&amp;gt; and '''dockerd refuses to start at next boot''' (it hard-errors when the same directive is both a flag and in the config file);&lt;br /&gt;
# Don't rely on manual &amp;lt;code&amp;gt;ip6tables -P FORWARD ACCEPT&amp;lt;/code&amp;gt; — Docker recreates the drop chain after a reboot.&lt;br /&gt;
&lt;br /&gt;
=== About the two init scripts ===&lt;br /&gt;
Two Docker init scripts coexist; the first one wins:&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/init.d/docker&amp;lt;/code&amp;gt; (S25, from luci-app-docker): starts first at boot, reads UCI &amp;lt;code&amp;gt;docker.wan_mode&amp;lt;/code&amp;gt;, and '''actually launches dockerd'''. dockerd reads the default config file &amp;lt;code&amp;gt;/etc/docker/daemon.json&amp;lt;/code&amp;gt; — which is why the fix above works.&lt;br /&gt;
* &amp;lt;code&amp;gt;/etc/init.d/dockerd&amp;lt;/code&amp;gt; (S99, the standard OpenWrt package): by the time it runs, dockerd is already up, so its instance never takes effect; its UCI config (/etc/config/dockerd) is '''effectively inert''' on this firmware. Don't let it mislead you while debugging.&lt;br /&gt;
&lt;br /&gt;
[[Photoincat 2 IPv6 PPPoE]] ｜ [[Photonicat Openwrt Docker/istore]] ｜ [[Photonicat 2 管理界面新功能 (2026)]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:33:53 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_Docker_%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97</comments>
		</item>
		<item>
			<title>Photonicat 2 开发者 API</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%BC%80%E5%8F%91%E8%80%85_API&amp;diff=256&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%BC%80%E5%8F%91%E8%80%85_API&amp;diff=256&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2, pcat-manager-web（2026-07 起所有接口强制鉴权） / Photonicat 2, pcat-manager-web (auth enforced on all endpoints since 2026-07) |}  pcat-manager-web 管理界面的所有功能都基于一套 &amp;#039;&amp;#039;&amp;#039;REST + WebSocket API&amp;#039;&amp;#039;&amp;#039;，可用于脚本自动化和第三方集成（Home Assistant、监控面板、短信转发等）。本页是面向开发者的概览。&amp;#039;&amp;#039;&amp;#039;注意&amp;#039;&amp;#039;&amp;#039;：这是设备内部 API…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2, pcat-manager-web（2026-07 起所有接口强制鉴权） / Photonicat 2, pcat-manager-web (auth enforced on all endpoints since 2026-07)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
pcat-manager-web 管理界面的所有功能都基于一套 '''REST + WebSocket API'''，可用于脚本自动化和第三方集成（Home Assistant、监控面板、短信转发等）。本页是面向开发者的概览。'''注意'''：这是设备内部 API，版本间可能变动，升级固件后请回归测试你的集成。&lt;br /&gt;
&lt;br /&gt;
Everything in the pcat-manager-web UI is driven by a '''REST + WebSocket API''' you can use for scripting and integrations (Home Assistant, monitoring dashboards, SMS forwarding…). This page is a developer-oriented overview. '''Note''': this is the device's internal API and may change between releases — retest integrations after firmware updates.&lt;br /&gt;
&lt;br /&gt;
== 基础 Basics ==&lt;br /&gt;
&lt;br /&gt;
* '''Base URL'''：设备地址，如 &amp;lt;code&amp;gt;http://172.16.0.1/&amp;lt;/code&amp;gt; / your device address, e.g. &amp;lt;code&amp;gt;http://172.16.0.1/&amp;lt;/code&amp;gt;&lt;br /&gt;
* '''认证 Authentication'''：先 POST &amp;lt;code&amp;gt;/login&amp;lt;/code&amp;gt; 建立会话（Cookie）；2026-07 起所有 API 强制登录校验。 / Establish a session via &amp;lt;code&amp;gt;/login&amp;lt;/code&amp;gt; first; since 2026-07 every endpoint requires it.&lt;br /&gt;
* '''格式 Content type'''：POST 一律 &amp;lt;code&amp;gt;application/json&amp;lt;/code&amp;gt;，并携带有效 '''CSRF token'''（登录页面/会话中获取）。所有'''改变状态的操作只接受 POST'''。 / POSTs use &amp;lt;code&amp;gt;application/json&amp;lt;/code&amp;gt; with a valid '''CSRF token'''; all state-changing operations are POST-only.&lt;br /&gt;
* '''错误格式 Error shape'''（统一 / uniform）：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ &amp;quot;status&amp;quot;: &amp;quot;error&amp;quot;, &amp;quot;message&amp;quot;: &amp;quot;Descriptive error message&amp;quot;, &amp;quot;error_code&amp;quot;: &amp;quot;SPECIFIC_ERROR_CODE&amp;quot; }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
: HTTP 状态码：200 成功，400 参数错误，401 未登录，403 无权限/CSRF 失败，404 不存在。 / 200 OK, 400 bad request, 401 login required, 403 forbidden/CSRF, 404 not found.&lt;br /&gt;
&lt;br /&gt;
== 接口分组 Endpoint groups ==&lt;br /&gt;
&lt;br /&gt;
以下为主要分组及代表接口（完整字段见设备仓库 docs/api.md）。 / Major groups with representative endpoints (full schemas in the repo's docs/api.md).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width:100%&amp;quot;&lt;br /&gt;
! style=&amp;quot;width:22%&amp;quot; | 分组 Group !! 代表接口 Representative endpoints !! 说明 Notes&lt;br /&gt;
|-&lt;br /&gt;
| '''系统 System''' || &amp;lt;code&amp;gt;GET /api/v1/system/board.json&amp;lt;/code&amp;gt;（设备信息 device info）、系统信息 system info、重启/关机 reboot &amp;amp; poweroff || 型号、序列号、固件版本、运行时间 / model, serial, firmware, uptime&lt;br /&gt;
|-&lt;br /&gt;
| '''网络 Network''' || 无线配置 wireless config、接口状态 interfaces、&amp;lt;code&amp;gt;GET&amp;lt;/code&amp;gt; 已连接设备 connected devices || WiFi SSID/密码、DHCP 客户端列表 / WiFi credentials, DHCP client list&lt;br /&gt;
|-&lt;br /&gt;
| '''蜂窝 Mobile''' || APN 设置、调制解调器信息/配置 modem info &amp;amp; config || 运营商、信号、IMEI、网络模式 / carrier, signal, IMEI, network mode&lt;br /&gt;
|-&lt;br /&gt;
| '''短信 SMS''' || 列表 list、发送 send（v1/v2）、标记已读 mark-read、删除 delete、清空 clear || 收发短信自动化的主要入口 / the main hook for SMS automation&lt;br /&gt;
|-&lt;br /&gt;
| '''语音通话 Voice call''' || 拨打 make、接听 answer、挂断 hangup、状态 status、通话记录 history、音频通道 audio path || 蜂窝版专属 / cellular models only&lt;br /&gt;
|-&lt;br /&gt;
| '''设备控制 Device control''' || 电源 LED、蜂鸣器 beeper、设备设置 device settings || 灯光/提示音策略 / LED &amp;amp; beeper policies&lt;br /&gt;
|-&lt;br /&gt;
| '''定时 Timer''' || 时间信息、定时任务管理、车载模式 car boot mode || 对应 /timer 页面的三种电源模式 / powers the /timer page modes&lt;br /&gt;
|-&lt;br /&gt;
| '''统计 Statistics''' || 仪表盘数据 dashboard、状态 status、流量统计 data statistics || 监控集成最常用 / most used for monitoring integrations&lt;br /&gt;
|-&lt;br /&gt;
| '''屏幕 Screen''' || &amp;lt;code&amp;gt;GET/POST /api/v1/screen/user_config.json&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;GET /api/v1/screen/data.json&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;GET /api/v1/screen/frame.png&amp;lt;/code&amp;gt;、custom_metrics 状态/执行 || 布局、数据、'''实时截屏''' / layout, data, '''live frame capture'''&lt;br /&gt;
|-&lt;br /&gt;
| '''系统配置 System config''' || CPU 调度 CPU scheduling、风扇转速 fan speed、屏幕短信条数限制 SMS screen limit || 性能与散热调优 / performance &amp;amp; thermals&lt;br /&gt;
|-&lt;br /&gt;
| '''维护 Maintenance''' || 固件管理 firmware management、软件包管理 package management、SMS Hook 管理 || 升级与短信钩子（转发脚本）/ upgrades &amp;amp; SMS hooks (forwarding scripts)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== WebSocket（SocketIO）==&lt;br /&gt;
&lt;br /&gt;
实时事件走 SocketIO（连接根路径）。 / Real-time events use SocketIO at the root URL.&lt;br /&gt;
&lt;br /&gt;
* '''客户端 → 服务器 Client → server'''：&amp;lt;code&amp;gt;request_install&amp;lt;/code&amp;gt;（本地 IPK 安装 / local IPK install）、&amp;lt;code&amp;gt;request_install_package&amp;lt;/code&amp;gt;（仓库安装 / repo install）、&amp;lt;code&amp;gt;request_firmware_upgrade&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;get_firmware_upgrade_status_socket&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;cancel_firmware_upgrade&amp;lt;/code&amp;gt;（仅下载阶段可取消 / cancellable during download only）&lt;br /&gt;
* '''服务器 → 客户端 Server → client'''：&amp;lt;code&amp;gt;log_response&amp;lt;/code&amp;gt;（实时日志 / live logs）、&amp;lt;code&amp;gt;firmware_upgrade_status&amp;lt;/code&amp;gt;（含进度百分比 / with progress percentage）：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
{ &amp;quot;status&amp;quot;: &amp;quot;downloading&amp;quot;, &amp;quot;progress&amp;quot;: 45, &amp;quot;message&amp;quot;: &amp;quot;Downloading firmware (45%)&amp;quot; }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 2026-07 起 WebSocket 连接同样需要已登录会话。 / Since 2026-07 the socket also requires an authenticated session.&lt;br /&gt;
&lt;br /&gt;
== 快速上手示例 Quick example ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# 登录拿会话 / log in for a session cookie&lt;br /&gt;
curl -c jar.txt -X POST http://172.16.0.1/login -d 'password=YOUR_PASSWORD'&lt;br /&gt;
&lt;br /&gt;
# 读取设备信息 / read device info&lt;br /&gt;
curl -b jar.txt http://172.16.0.1/api/v1/system/board.json&lt;br /&gt;
&lt;br /&gt;
# 抓一帧屏幕画面 / grab a live screen frame&lt;br /&gt;
curl -b jar.txt -o frame.png http://172.16.0.1/api/v1/screen/frame.png&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; 提示 Tips&lt;br /&gt;
* 写操作需附带 CSRF token；具体字段名以当前固件版本为准。 / State-changing calls need the CSRF token; field names follow your firmware version.&lt;br /&gt;
* 不要在公网直接暴露管理端口；如需远程访问请走 VPN。 / Never expose the manager port to the internet; use a VPN for remote access.&lt;br /&gt;
&lt;br /&gt;
[[Photonicat 2 管理界面新功能 (2026)]] ｜ [[Photonicat 2 小屏幕自定义]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:32:34 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E5%BC%80%E5%8F%91%E8%80%85_API</comments>
		</item>
		<item>
			<title>Photonicat 2 spec</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_spec&amp;diff=255&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_spec&amp;diff=255&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; !colspan=&amp;quot;5&amp;quot;|Photonicat2光影猫 配置表 |- |align=&amp;quot;center&amp;quot; width=&amp;quot;150px&amp;quot; | 规格 || align=&amp;quot;center&amp;quot; width=&amp;quot;200px&amp;quot; | 不安装电池 || align=&amp;quot;center&amp;quot;  width=&amp;quot;200px&amp;quot;| 移动版 Cell|| align=&amp;quot;center&amp;quot;  width=&amp;quot;200px&amp;quot;| 4G版 || align=&amp;quot;center&amp;quot;  width=&amp;quot;200px&amp;quot;| 5G版 |- | CPU || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|瑞芯微 RK3568（8核 Cortex®-A72 + A53 @ 2.2GHz), ARM Mali G52 MC3, NPU 6Tops |- | 内存 || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|标配：4GB LPDD…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;|Photonicat2光影猫 配置表&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; width=&amp;quot;150px&amp;quot; | 规格 || align=&amp;quot;center&amp;quot; width=&amp;quot;200px&amp;quot; | 不安装电池 || align=&amp;quot;center&amp;quot;  width=&amp;quot;200px&amp;quot;| 移动版 Cell|| align=&amp;quot;center&amp;quot;  width=&amp;quot;200px&amp;quot;| 4G版 || align=&amp;quot;center&amp;quot;  width=&amp;quot;200px&amp;quot;| 5G版&lt;br /&gt;
|-&lt;br /&gt;
| CPU || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|瑞芯微 RK3568（8核 Cortex®-A72 + A53 @ 2.2GHz), ARM Mali G52 MC3, NPU 6Tops&lt;br /&gt;
|-&lt;br /&gt;
| 内存 || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|标配：4GB LPDDR5, 高配：16GB LPDDR5&lt;br /&gt;
|-&lt;br /&gt;
| eMMC || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|标配：8GB eMMC, 高配：128GB eMMC&lt;br /&gt;
|-&lt;br /&gt;
| 网络 || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;| 原生 PHY x 2&lt;br /&gt;
|-&lt;br /&gt;
| 顶部I/O ||align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|USB 3.0, HDMI 4K, 1Gbps RJ45 x 2&lt;br /&gt;
|-&lt;br /&gt;
| 侧面I/O || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|NanoSIM（家庭版无） 全系标配 MicroSD&lt;br /&gt;
|-&lt;br /&gt;
| 内置WIFI || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;| 全系标配 USB WiFi B/G/N/AC (2.4G/5G)&lt;br /&gt;
|-&lt;br /&gt;
| 内置WiFi天线 || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;| 标配： 4/5G x 4，WiFi天线 x3&lt;br /&gt;
|-&lt;br /&gt;
| 内置M.2 B-key || align=&amp;quot;center&amp;quot; | 无 ||  align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;| M.2 B-Key(用于扩展其他WWAN设备)&lt;br /&gt;
|-&lt;br /&gt;
| 内置M.2 E-key || align=&amp;quot;center&amp;quot; | 无 ||  align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;| M.2 E-Key(用于扩展其他Wifi模块等设备)&lt;br /&gt;
|-&lt;br /&gt;
| 内置M.2 M-key || align=&amp;quot;center&amp;quot; | 无 ||  align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;| M.2 M-Key(用于扩展其他NVME 设备)&lt;br /&gt;
|-&lt;br /&gt;
| 供电/工作功耗  || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|DC20V @ 2.5A(Max),  无WWAN, NVME,  1.0~2.0W, 4G 2.5~6W, 5G 2.5~10W&lt;br /&gt;
|-&lt;br /&gt;
| 电池 ||align=&amp;quot;center&amp;quot; | 无 || align=&amp;quot;center&amp;quot; colspan=&amp;quot;3&amp;quot;| 移动版配 7000mAh @ 7.4v, 50Wh (18650 * 4) &lt;br /&gt;
|-&lt;br /&gt;
| 4G 模块 ||align=&amp;quot;center&amp;quot; | 无 || align=&amp;quot;center&amp;quot; | 无 || align=&amp;quot;center&amp;quot; | 全网通（占用M.2 B-key接口） || align=&amp;quot;center&amp;quot; | 无&lt;br /&gt;
|-&lt;br /&gt;
| 5G 模块 || align=&amp;quot;center&amp;quot; | 无 || align=&amp;quot;center&amp;quot; | 无 || align=&amp;quot;center&amp;quot; | 无 || align=&amp;quot;center&amp;quot; | 全网/球通，（占用M.2 B-key接口）&lt;br /&gt;
|-&lt;br /&gt;
| 最佳电池续航时间 || align=&amp;quot;center&amp;quot; | N/A  || align=&amp;quot;center&amp;quot; | 6小时 || align=&amp;quot;center&amp;quot; | 5小时 || align=&amp;quot;center&amp;quot; | 4小时，RM520N-GL 5小时&lt;br /&gt;
|-&lt;br /&gt;
| 关机充满电时间 || align=&amp;quot;center&amp;quot; | N/A  || align=&amp;quot;center&amp;quot; | 3小时 || align=&amp;quot;center&amp;quot; | 3小时 || align=&amp;quot;center&amp;quot; | 3小时&lt;br /&gt;
|-&lt;br /&gt;
| 开机充满电时间 || align=&amp;quot;center&amp;quot; | N/A || align=&amp;quot;center&amp;quot; | 3-4小时 || align=&amp;quot;center&amp;quot; | 4-5小时 || align=&amp;quot;center&amp;quot; | 4-6小时&lt;br /&gt;
|-&lt;br /&gt;
| 重量 || align=&amp;quot;center&amp;quot; | 260克（无电池）|| align=&amp;quot;center&amp;quot; |470克|| align=&amp;quot;center&amp;quot; |480克 || align=&amp;quot;center&amp;quot; |485克&lt;br /&gt;
|-&lt;br /&gt;
| 尺寸 || align=&amp;quot;center&amp;quot; colspan=&amp;quot;4&amp;quot;|154mm x 78mm x 32mm&lt;br /&gt;
|}&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:31:41 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_spec</comments>
		</item>
		<item>
			<title>Photonicat 2 Wifi/WWAN/NVME M2 兼容模块</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_Wifi/WWAN/NVME_M2_%E5%85%BC%E5%AE%B9%E6%A8%A1%E5%9D%97&amp;diff=254&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_Wifi/WWAN/NVME_M2_%E5%85%BC%E5%AE%B9%E6%A8%A1%E5%9D%97&amp;diff=254&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“Photonicat 2 的 M.2 插槽使用 &amp;#039;&amp;#039;&amp;#039;USB 3.0&amp;#039;&amp;#039;&amp;#039; 接口，模块以 USB 设备方式工作。  ==WWAN 蜂窝模块 (4G/5G)== {| class=&amp;quot;wikitable&amp;quot; ! 模块 !! 制式 !! 方案 !! GPS/GNSS !! 电话语音 !! 备注 |- | RM500U-CN-AB || 5G || 紫光展锐 Unisoc || ❌ 不支持 || ✅ 支持 || 实测固件无任何 GNSS AT 指令 |- | RM500U-CNV || 5G || 紫光展锐 Unisoc || ❌ 不支持 || ✅ 支持（已实测） || 实测固件无任何 GNSS AT 指令 |- |…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Photonicat 2 的 M.2 插槽使用 '''USB 3.0''' 接口，模块以 USB 设备方式工作。&lt;br /&gt;
&lt;br /&gt;
==WWAN 蜂窝模块 (4G/5G)==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 模块 !! 制式 !! 方案 !! GPS/GNSS !! 电话语音 !! 备注&lt;br /&gt;
|-&lt;br /&gt;
| RM500U-CN-AB || 5G || 紫光展锐 Unisoc || ❌ 不支持 || ✅ 支持 || 实测固件无任何 GNSS AT 指令&lt;br /&gt;
|-&lt;br /&gt;
| RM500U-CNV || 5G || 紫光展锐 Unisoc || ❌ 不支持 || ✅ 支持（已实测） || 实测固件无任何 GNSS AT 指令&lt;br /&gt;
|-&lt;br /&gt;
| RM520N-GL-AA || 5G || 高通 Qualcomm || ✅ 支持 || ❌ 不支持 || 与 RM500Q 相同的 AT+QGPS 指令集（GPS 未单独实测）&lt;br /&gt;
|-&lt;br /&gt;
| RM500Q-GL-AB || 5G || 高通 Qualcomm || ✅ 支持（已实测） || ✅ 支持（USB 声卡方式，已实测） || 测试可用，功能可能不全；标准 AT+QGPS 指令集，NMEA 输出&lt;br /&gt;
|-&lt;br /&gt;
| FM350-GL || 5G || 联发科 MediaTek || ❌ 不支持 || ❌ 不支持 || USB 版固件不提供 GNSS 接口（已实测）&lt;br /&gt;
|-&lt;br /&gt;
| EM05-CN-FD || 4G || 高通 Qualcomm || ✅ 支持（已实测） || ❌ 不支持 || 标准 AT+QGPS 指令集，NMEA 输出&lt;br /&gt;
|-&lt;br /&gt;
| EM05-CE-FC || 4G || 高通 Qualcomm || ✅ 支持 || ❌ 不支持 || EM05 系列同指令集（GPS 未单独实测）&lt;br /&gt;
|}&lt;br /&gt;
GPS 定位需外接 GNSS 天线。&lt;br /&gt;
&lt;br /&gt;
==Wifi 模块==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 型号 !! 类别 !! 备注&lt;br /&gt;
|-&lt;br /&gt;
| Mediatek MT7921 || Wifi 6 ||&lt;br /&gt;
|-&lt;br /&gt;
| Mediatek MT7921K || Wifi 6 ||&lt;br /&gt;
|-&lt;br /&gt;
| Mediatek MT7922 || Wifi 6 ||&lt;br /&gt;
|-&lt;br /&gt;
| Qualcomm NFA765 || Wifi 6 ||&lt;br /&gt;
|-&lt;br /&gt;
| MediaTek MT7925B || Wifi 7 || 需 '''2026-06''' 或更新版本固件&lt;br /&gt;
|-&lt;br /&gt;
| Qualcomm WCN7851 || Wifi 7 || 需 '''2026-06''' 或更新版本固件&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==NVME SSD==&lt;br /&gt;
2230基本全系支持。&lt;br /&gt;
&lt;br /&gt;
==注意事项==&lt;br /&gt;
注意自行加装的模块，可能工作异常，不兼容等问题，可以咨询对应模块卖家，无法提供客户自行加装部分的支持，自行承担风险。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
其他可能支持，或不支持，符合标准接口协议的模块。⚠️注意插拔插需要断开USB-PD供电，以及电池供电。&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:31:03 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_Wifi/WWAN/NVME_M2_%E5%85%BC%E5%AE%B9%E6%A8%A1%E5%9D%97</comments>
		</item>
		<item>
			<title>Photoincat 2 IPv6 PPPoE</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photoincat_2_IPv6_PPPoE&amp;diff=253&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photoincat_2_IPv6_PPPoE&amp;diff=253&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用版本 / Applies to | photonicatWrt &amp;#039;&amp;#039;&amp;#039;26.04.1&amp;#039;&amp;#039;&amp;#039; (r7720, OpenWrt 24+ base, fw4/nftables, odhcpd) — 更新于 2026-07 / Updated 2026-07 |- ! 旧版指南 / Older firmware | 2023–2024 固件请参考本页面历史版本 / For 2023–2024 firmware see the page history |}  * 本文说明如何在 photonicat (photonicatWrt 26.04.x) 上配置基于 &amp;#039;&amp;#039;&amp;#039;PPPoE 的原生 IPv6&amp;#039;&amp;#039;&amp;#039;，让内网设备通过 &amp;#039;&amp;#039;&amp;#039;SLAAC / DHCPv6&amp;#039;&amp;#039;&amp;#039; 获得公…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用版本 / Applies to&lt;br /&gt;
| photonicatWrt '''26.04.1''' (r7720, OpenWrt 24+ base, fw4/nftables, odhcpd) — 更新于 2026-07 / Updated 2026-07&lt;br /&gt;
|-&lt;br /&gt;
! 旧版指南 / Older firmware&lt;br /&gt;
| 2023–2024 固件请参考本页面历史版本 / For 2023–2024 firmware see the page history&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* 本文说明如何在 photonicat (photonicatWrt 26.04.x) 上配置基于 '''PPPoE 的原生 IPv6'''，让内网设备通过 '''SLAAC / DHCPv6''' 获得公网 (GUA) 地址，全球直连、无需 NAT6。&lt;br /&gt;
* This document explains how to configure '''native IPv6 over PPPoE''' on photonicat (photonicatWrt 26.04.x), so LAN clients get global (GUA) addresses via '''SLAAC / DHCPv6''' — direct global connectivity, no NAT6 required.&lt;br /&gt;
&lt;br /&gt;
== 一键配置脚本 / Automatic setup script ==&lt;br /&gt;
无需手动执行下面的步骤，可以直接运行一键脚本自动完成全部配置（自动备份、应用、验证）。 / Instead of the manual steps below, you can run a one-shot script that applies all of them for you (backup, apply, verify).&lt;br /&gt;
&lt;br /&gt;
SSH 登录路由器后运行 / SSH into the router and run:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cd /tmp&lt;br /&gt;
wget -O pcat2_pppoe_ipv6.sh https://gist.githubusercontent.com/c2h2/ae07a4c818457b4cf3f087bf164059f8/raw/pcat2_pppoe_ipv6.sh&lt;br /&gt;
sh pcat2_pppoe_ipv6.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* 脚本会先把当前配置备份到 &amp;lt;code&amp;gt;/tmp&amp;lt;/code&amp;gt;，应用时 PPPoE 会短暂断线重连几秒，随后自动等待前缀下发并测试 IPv6 连通性。 / The script backs up your config to &amp;lt;code&amp;gt;/tmp&amp;lt;/code&amp;gt; first, briefly restarts the PPPoE session, then waits for the delegated prefix and tests IPv6 connectivity.&lt;br /&gt;
* 可选参数 / Options: &amp;lt;code&amp;gt;--ra-high&amp;lt;/code&amp;gt;（多路由/多 RA 环境，见下文第 3 节 / multi-router LANs, see section 3）、&amp;lt;code&amp;gt;--force&amp;lt;/code&amp;gt;（非 PPPoE WAN / non-PPPoE WAN）、&amp;lt;code&amp;gt;--no-ping&amp;lt;/code&amp;gt;（跳过连通性测试 / skip the connectivity test）。运行 / Run &amp;lt;code&amp;gt;sh pcat2_pppoe_ipv6.sh --help&amp;lt;/code&amp;gt; 查看帮助。&lt;br /&gt;
* 脚本源码 / Script source: [https://gist.github.com/c2h2/ae07a4c818457b4cf3f087bf164059f8 GitHub Gist]。中国大陆用户如无法访问 gist，请按下文手动配置。 / If the gist is unreachable from mainland China, follow the manual steps below.&lt;br /&gt;
&lt;br /&gt;
== 中文指南 ==&lt;br /&gt;
&lt;br /&gt;
=== 1. WAN 接口（PPPoE） ===&lt;br /&gt;
新版固件下 '''不需要手动创建绑定 eth0 的 WAN6 接口'''。只要 WAN 口开启 IPv6 协商，netifd 会自动在 PPPoE 逻辑口上创建动态别名接口 &amp;lt;code&amp;gt;wan_6&amp;lt;/code&amp;gt;（注意是下划线），负责 DHCPv6 / 前缀委托。&lt;br /&gt;
&lt;br /&gt;
LuCI: '''网络 → 接口 → WAN → 高级设置'''&lt;br /&gt;
* 获取 IPv6 地址 → '''自动'''&lt;br /&gt;
* 委托 IPv6 前缀 → '''启用'''&lt;br /&gt;
&lt;br /&gt;
或使用 UCI：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set network.wan.ipv6='auto'&lt;br /&gt;
uci commit network&lt;br /&gt;
ifup wan&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; 注意 如果系统里遗留了一个绑定 &amp;lt;code&amp;gt;eth0&amp;lt;/code&amp;gt; 的 WAN6 接口（老指南的做法），它在 PPPoE 线路上会一直处于 pending 状态。建议直接禁用：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set network.wan6.auto='0'&lt;br /&gt;
uci commit network&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. LAN 接口 ===&lt;br /&gt;
LuCI: '''网络 → 接口 → LAN'''&lt;br /&gt;
* IPv6 分配长度 (ip6assign) → '''60'''（运营商一般下发 /56 或 /60）&lt;br /&gt;
* '''IPv6 前缀过滤器 (ip6class) → 必须留空！'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set network.lan.ip6assign='60'&lt;br /&gt;
uci -q delete network.lan.ip6class&lt;br /&gt;
uci commit network&lt;br /&gt;
ifup lan&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; ⚠ 最常见故障 如果 &amp;lt;code&amp;gt;ip6class&amp;lt;/code&amp;gt; 被设为 &amp;lt;code&amp;gt;local&amp;lt;/code&amp;gt;，LAN 只会分配 ULA（fd00::/8 私有前缀），运营商委托的公网前缀'''永远不会'''下发到 br-lan，内网设备就只有 fdxx 地址、无法访问 IPv6 互联网。删除该选项即可恢复。&lt;br /&gt;
&lt;br /&gt;
=== 3. RA / DHCPv6（SLAAC） ===&lt;br /&gt;
LuCI: '''网络 → 接口 → LAN → DHCP 服务器 → IPv6 设置'''&lt;br /&gt;
* RA 服务：'''混合模式''' （SLAAC 默认开启，即 RA 前缀带 A 标志）&lt;br /&gt;
* DHCPv6 服务：'''混合模式'''&lt;br /&gt;
* NDP 代理：'''混合模式'''（旁路由/中继场景才需要）&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set dhcp.lan.ra='hybrid'&lt;br /&gt;
uci set dhcp.lan.dhcpv6='hybrid'&lt;br /&gt;
uci commit dhcp&lt;br /&gt;
/etc/init.d/odhcpd reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; 提示 若局域网内还有其它设备也在发 RA（多路由/多线路环境），把 photonicat 的路由优先级调高，客户端会优先选它作为默认网关：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set dhcp.lan.ra_preference='high'&lt;br /&gt;
uci commit dhcp &amp;amp;&amp;amp; /etc/init.d/odhcpd reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4. Docker 与 IPv6 转发（26.04 版重要坑） ===&lt;br /&gt;
photonicatWrt 自带 Docker（27.x）。Docker 27+ 默认启用 ip6tables，会创建 &amp;lt;code&amp;gt;ip6 filter FORWARD&amp;lt;/code&amp;gt; 链且'''策略为 drop''' —— 它会丢弃'''所有'''转发的 IPv6 流量，即使 fw4 防火墙已放行 lan→wan。症状：路由器本机 &amp;lt;code&amp;gt;ping6&amp;lt;/code&amp;gt; 正常，内网设备拿到了公网 IPv6 却 ping 不通外网。&lt;br /&gt;
&lt;br /&gt;
检查：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nft list chain ip6 filter FORWARD&lt;br /&gt;
# 如果看到 policy drop 且计数一直增长，即中招&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
永久修复：在 &amp;lt;code&amp;gt;/etc/docker/daemon.json&amp;lt;/code&amp;gt; 的'''出厂内容基础上'''加一行 &amp;lt;code&amp;gt;&amp;quot;ip6tables&amp;quot;: false&amp;lt;/code&amp;gt;（不影响 IPv4 容器网络）：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat &amp;gt; /etc/docker/daemon.json &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;data-root&amp;quot;: &amp;quot;/opt/&amp;quot;,&lt;br /&gt;
&amp;quot;log-level&amp;quot;: &amp;quot;warn&amp;quot;,&lt;br /&gt;
&amp;quot;ip6tables&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
/etc/init.d/docker restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
; ⚠ 注意 photonicatWrt 实际由 &amp;lt;code&amp;gt;/etc/init.d/docker&amp;lt;/code&amp;gt;（而非 dockerd）以 &amp;lt;code&amp;gt;--iptables=false&amp;lt;/code&amp;gt; 参数启动 Docker。'''不要'''在 daemon.json 里添加 &amp;lt;code&amp;gt;&amp;quot;iptables&amp;quot;&amp;lt;/code&amp;gt; 键，也不要改动出厂的 &amp;lt;code&amp;gt;data-root&amp;lt;/code&amp;gt; —— 与启动参数冲突会导致 Docker 开机无法启动，改 data-root 会导致已有镜像&amp;quot;消失&amp;quot;。详见 [[Photonicat 2 Docker 使用指南]]。&lt;br /&gt;
&lt;br /&gt;
=== 5. 防火墙 ===&lt;br /&gt;
fw4 默认已放行 lan→wan 的 IPv6 转发和必要的 ICMPv6，'''出站上网无需额外规则'''。只有当你需要'''从公网主动访问内网设备'''（自建服务器/NAS）时才添加入站规则，且建议按端口精确放行，不要整段 ACCEPT 全部入站 IPv6。&lt;br /&gt;
&lt;br /&gt;
=== 6. 验证 ===&lt;br /&gt;
路由器上：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ifstatus wan_6 | grep -A6 ipv6-prefix     # 应看到运营商委托的 /56 或 /60&lt;br /&gt;
ifstatus lan | grep -A8 ipv6-prefix-assignment   # 应看到公网前缀已分配给 br-lan&lt;br /&gt;
ping -6 -c3 photonicat.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
内网设备上：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ip -6 addr show   # 应有公网 (如 240e:/2408:/2409: 等) SLAAC 地址&lt;br /&gt;
ping -6 -c3 photonicat.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 7. 多出口/多 RA 环境排障 ===&lt;br /&gt;
如果局域网里有多台设备宣告 RA（例如另一台 5G 网关、Proxmox 虚拟机等），Linux 客户端会把多个默认网关做 ECMP 负载均衡，流量可能被分到没有 IPv6 上行的网关而'''间歇性丢包'''；或者源地址选择与网关不匹配（photonicat 的默认路由是按源前缀限定的 &amp;lt;code&amp;gt;from 240e:xxxx::/56&amp;lt;/code&amp;gt;），返回 &amp;quot;Destination unreachable: No route&amp;quot;。&lt;br /&gt;
&lt;br /&gt;
* 首选：让没有上行的设备停止宣告默认路由（router lifetime 设为 0）。&lt;br /&gt;
* 客户端（systemd-networkd）也可固定网关并用地址标签固定源地址选择：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf&lt;br /&gt;
[IPv6AcceptRA]&lt;br /&gt;
UseGateway=false&lt;br /&gt;
&lt;br /&gt;
[Route]&lt;br /&gt;
Gateway=fe80::xxxx:xxxx:xxxx:xxxx   # photonicat br-lan 的链路本地地址&lt;br /&gt;
&lt;br /&gt;
[IPv6AddressLabel]&lt;br /&gt;
Label=99&lt;br /&gt;
Prefix=2409::/16    # 不希望选为源地址的运营商前缀&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== English Guide ==&lt;br /&gt;
&lt;br /&gt;
=== 1. WAN interface (PPPoE) ===&lt;br /&gt;
On current firmware you '''no longer need a manual WAN6 interface bound to eth0'''. With IPv6 negotiation enabled on WAN, netifd automatically spawns a dynamic alias interface &amp;lt;code&amp;gt;wan_6&amp;lt;/code&amp;gt; (with an underscore) on the PPPoE logical interface, which handles DHCPv6 and prefix delegation.&lt;br /&gt;
&lt;br /&gt;
LuCI: '''Network → Interfaces → WAN → Advanced'''&lt;br /&gt;
* Obtain IPv6 address → '''Automatic'''&lt;br /&gt;
* Delegate IPv6 prefix → '''Enabled'''&lt;br /&gt;
&lt;br /&gt;
Or via UCI:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set network.wan.ipv6='auto'&lt;br /&gt;
uci commit network&lt;br /&gt;
ifup wan&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Note If a legacy WAN6 interface bound to &amp;lt;code&amp;gt;eth0&amp;lt;/code&amp;gt; exists (as older guides suggested), it will sit in &amp;quot;pending&amp;quot; forever on a PPPoE line. Disable it:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set network.wan6.auto='0'&lt;br /&gt;
uci commit network&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 2. LAN interface ===&lt;br /&gt;
* IPv6 assignment length (ip6assign) → '''60''' (ISPs typically delegate a /56 or /60)&lt;br /&gt;
* '''IPv6 prefix filter (ip6class) → must be left EMPTY!'''&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set network.lan.ip6assign='60'&lt;br /&gt;
uci -q delete network.lan.ip6class&lt;br /&gt;
uci commit network&lt;br /&gt;
ifup lan&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; ⚠ Most common failure If &amp;lt;code&amp;gt;ip6class&amp;lt;/code&amp;gt; is set to &amp;lt;code&amp;gt;local&amp;lt;/code&amp;gt;, the LAN only gets ULA (fd00::/8) prefixes — the ISP-delegated global prefix is '''never''' assigned to br-lan, so clients only get fdxx addresses and cannot reach the IPv6 internet. Deleting this option fixes it.&lt;br /&gt;
&lt;br /&gt;
=== 3. RA / DHCPv6 (SLAAC) ===&lt;br /&gt;
* RA-Service: '''hybrid''' (SLAAC is on by default — RA prefixes carry the A flag)&lt;br /&gt;
* DHCPv6-Service: '''hybrid'''&lt;br /&gt;
* NDP-Proxy: '''hybrid''' (only needed for relay/bridge setups)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set dhcp.lan.ra='hybrid'&lt;br /&gt;
uci set dhcp.lan.dhcpv6='hybrid'&lt;br /&gt;
uci commit dhcp&lt;br /&gt;
/etc/init.d/odhcpd reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; Tip If other devices on the LAN also send RAs (multi-router / multi-uplink environments), raise the photonicat's router preference so clients prefer it as default gateway:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
uci set dhcp.lan.ra_preference='high'&lt;br /&gt;
uci commit dhcp &amp;amp;&amp;amp; /etc/init.d/odhcpd reload&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 4. Docker vs IPv6 forwarding (important 26.04 pitfall) ===&lt;br /&gt;
photonicatWrt ships Docker (27.x). Docker 27+ enables ip6tables by default and creates an &amp;lt;code&amp;gt;ip6 filter FORWARD&amp;lt;/code&amp;gt; chain with '''policy drop''' — it silently drops '''all''' forwarded IPv6, even though fw4 correctly allows lan→wan. Symptom: &amp;lt;code&amp;gt;ping6&amp;lt;/code&amp;gt; works from the router itself, LAN clients get global IPv6 addresses but cannot reach the internet.&lt;br /&gt;
&lt;br /&gt;
Check:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
nft list chain ip6 filter FORWARD&lt;br /&gt;
# if you see &amp;quot;policy drop&amp;quot; and a growing counter, this is your problem&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Permanent fix: add &amp;lt;code&amp;gt;&amp;quot;ip6tables&amp;quot;: false&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;/etc/docker/daemon.json&amp;lt;/code&amp;gt; '''while keeping the factory keys''' (IPv4 container networking is unaffected):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
cat &amp;gt; /etc/docker/daemon.json &amp;lt;&amp;lt;'EOF'&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;data-root&amp;quot;: &amp;quot;/opt/&amp;quot;,&lt;br /&gt;
&amp;quot;log-level&amp;quot;: &amp;quot;warn&amp;quot;,&lt;br /&gt;
&amp;quot;ip6tables&amp;quot;: false&lt;br /&gt;
}&lt;br /&gt;
EOF&lt;br /&gt;
/etc/init.d/docker restart&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
; ⚠ Note On photonicatWrt, Docker is actually launched by &amp;lt;code&amp;gt;/etc/init.d/docker&amp;lt;/code&amp;gt; (not dockerd) with &amp;lt;code&amp;gt;--iptables=false&amp;lt;/code&amp;gt;. Do '''not''' add an &amp;lt;code&amp;gt;&amp;quot;iptables&amp;quot;&amp;lt;/code&amp;gt; key to daemon.json and do not change the factory &amp;lt;code&amp;gt;data-root&amp;lt;/code&amp;gt; — a flag/config conflict prevents Docker from starting at boot, and a changed data-root makes existing images &amp;quot;disappear&amp;quot;. See [[Photonicat 2 Docker 使用指南]].&lt;br /&gt;
&lt;br /&gt;
=== 5. Firewall ===&lt;br /&gt;
fw4 already allows IPv6 lan→wan forwarding and the required ICMPv6 by default — '''no extra rules are needed for outbound connectivity'''. Only add inbound rules when you need to reach LAN devices from the internet (self-hosted servers/NAS), and prefer precise per-port rules over a blanket ACCEPT of all inbound IPv6.&lt;br /&gt;
&lt;br /&gt;
=== 6. Verification ===&lt;br /&gt;
On the router:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ifstatus wan_6 | grep -A6 ipv6-prefix     # ISP-delegated /56 or /60 should appear&lt;br /&gt;
ifstatus lan | grep -A8 ipv6-prefix-assignment   # the global prefix should be assigned to br-lan&lt;br /&gt;
ping -6 -c3 photonicat.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
On a LAN client:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ip -6 addr show   # expect a global (e.g. 240e:/2408:/2409:) SLAAC address&lt;br /&gt;
ping -6 -c3 photonicat.com&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 7. Troubleshooting multi-uplink / multi-RA LANs ===&lt;br /&gt;
If several devices advertise RAs on the LAN (another 5G gateway, Proxmox VMs, …), Linux clients install an ECMP default route across all of them; flows hashed to a gateway without IPv6 upstream '''blackhole intermittently'''. Source-address selection can also mismatch the gateway (the photonicat's upstream default route is source-restricted, e.g. &amp;lt;code&amp;gt;from 240e:xxxx::/56&amp;lt;/code&amp;gt;), yielding &amp;quot;Destination unreachable: No route&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* Preferred fix: make routers without upstream stop advertising a default route (router lifetime 0).&lt;br /&gt;
* On a systemd-networkd client you can pin the gateway and steer source selection:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# /etc/systemd/network/eth0.network.d/50-ipv6-gateway.conf&lt;br /&gt;
[IPv6AcceptRA]&lt;br /&gt;
UseGateway=false&lt;br /&gt;
&lt;br /&gt;
[Route]&lt;br /&gt;
Gateway=fe80::xxxx:xxxx:xxxx:xxxx   # photonicat br-lan link-local address&lt;br /&gt;
&lt;br /&gt;
[IPv6AddressLabel]&lt;br /&gt;
Label=99&lt;br /&gt;
Prefix=2409::/16    # ISP prefix you do NOT want chosen as source&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== IPv6 地址说明 / Understanding the addresses ==&lt;br /&gt;
一个接口同时拥有多个 IPv6 地址是正常现象 / Multiple IPv6 addresses on one interface is normal:&lt;br /&gt;
* &amp;lt;code&amp;gt;240e:xxxx:xxxx:xx00:xxxx:xxff:fexx:xxxx/64&amp;lt;/code&amp;gt; → 公网地址，SLAAC 由 RA 前缀+接口标识自动生成 / global address, auto-generated via SLAAC&lt;br /&gt;
* &amp;lt;code&amp;gt;240e:xxxx:xxxx:xx00::2e9/128&amp;lt;/code&amp;gt; → DHCPv6 下发的公网地址 / global address assigned by stateful DHCPv6&lt;br /&gt;
* &amp;lt;code&amp;gt;fdxx:....../64&amp;lt;/code&amp;gt; → ULA 私有地址，仅内网使用，不上公网 / ULA private address, LAN-only&lt;br /&gt;
* &amp;lt;code&amp;gt;fe80::/64&amp;lt;/code&amp;gt; → 链路本地地址，用于邻居发现/网关 / link-local, used for NDP and as gateway&lt;br /&gt;
只有 global (GUA) 地址可用于公网通信；“全球直连”意味着设备在公网可见，请合理配置防火墙。 / Only GUA addresses reach the internet; being globally reachable means you should keep the firewall sensible.&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:28:20 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photoincat_2_IPv6_PPPoE</comments>
		</item>
		<item>
			<title>Photonicat 2 访客门户 Captive Portal</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E8%AE%BF%E5%AE%A2%E9%97%A8%E6%88%B7_Captive_Portal&amp;diff=252&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E8%AE%BF%E5%AE%A2%E9%97%A8%E6%88%B7_Captive_Portal&amp;diff=252&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2, photonicatWrt &amp;#039;&amp;#039;&amp;#039;26.04+&amp;#039;&amp;#039;&amp;#039;（含 OpenNDS、fw4/nftables 的固件）与 pcat-manager-web 2026-06 及以后版本 / Photonicat 2, photonicatWrt 26.04+ images (with OpenNDS on fw4/nftables) and pcat-manager-web builds from 2026-06 onward |}  &amp;#039;&amp;#039;&amp;#039;访客门户（Captive Portal）&amp;#039;&amp;#039;&amp;#039;功能让 photonicat 2 成为一台&amp;#039;&amp;#039;&amp;#039;强制门户网关&amp;#039;&amp;#039;&amp;#039;：连接它 WiFi/LAN 的访客必须先看到 Photonicat 品牌…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2, photonicatWrt '''26.04+'''（含 OpenNDS、fw4/nftables 的固件）与 pcat-manager-web 2026-06 及以后版本 / Photonicat 2, photonicatWrt 26.04+ images (with OpenNDS on fw4/nftables) and pcat-manager-web builds from 2026-06 onward&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''访客门户（Captive Portal）'''功能让 photonicat 2 成为一台'''强制门户网关'''：连接它 WiFi/LAN 的访客必须先看到 Photonicat 品牌的欢迎页并点击&amp;quot;同意并连接&amp;quot;，才能访问互联网——就像酒店、机场的 WiFi 登录页。这与 [[Photonicat 2 Smart WAN 智能上网|Smart WAN]] 正好相反：Smart WAN 是让设备'''通过'''别人的门户上网，本功能是让设备'''发布'''自己的门户。&lt;br /&gt;
&lt;br /&gt;
The '''Captive Portal''' feature turns the photonicat 2 into a '''captive gateway''': guests joining its WiFi/LAN must pass a Photonicat-branded splash page (&amp;quot;Agree &amp;amp; Connect&amp;quot;) before reaching the internet — like hotel or airport WiFi. It is the inverse of [[Photonicat 2 Smart WAN 智能上网|Smart WAN]]: Smart WAN gets the device '''through''' someone else's portal; this feature '''serves''' your own.&lt;br /&gt;
&lt;br /&gt;
== 中文说明 ==&lt;br /&gt;
&lt;br /&gt;
=== 工作原理 ===&lt;br /&gt;
* 基于 '''OpenNDS'''（nodogsplash 的持续维护继任者），原生运行在 fw4/nftables 防火墙上。&lt;br /&gt;
* 访客设备（iPhone/Android/Windows）连上 WiFi 后，操作系统的联网探测会'''自动弹出'''登录页；点击'''同意并连接'''即放行该设备的 MAC。&lt;br /&gt;
* 当前为'''一键点击直连'''模式（无需账号密码）；门户页为 Photonicat 品牌定制版，'''首次点击即完成授权'''，不会卡在中间页。&lt;br /&gt;
* 会话按 MAC 记录，超过 &amp;lt;code&amp;gt;sessiontimeout&amp;lt;/code&amp;gt; 后需重新点击。&lt;br /&gt;
&lt;br /&gt;
=== 开启方法 ===&lt;br /&gt;
# 打开管理界面 → '''设置（/settings）'''页面。&lt;br /&gt;
# 找到'''访客门户 Captive Portal''' 开关，打开即可；关闭同理。启停结果和失败原因都会在页面上提示。&lt;br /&gt;
# 开启后约 10–15 秒内防火墙规则重建，新客户端可能短暂无法弹页，属正常现象，稍候重试即可。&lt;br /&gt;
&lt;br /&gt;
=== 注意事项 ===&lt;br /&gt;
* '''访客必须通过 DHCP 获取地址'''：手动配置静态 IP 的客户端会被 OpenNDS 拒绝（403 &amp;quot;IP not allocated by dhcp&amp;quot;）。&lt;br /&gt;
* '''HTTPS 无法被拦截重定向'''：弹页依赖操作系统的 HTTP 探测。若没自动弹出，请手动访问任意 http:// 网站。&lt;br /&gt;
* 门户默认作用于 '''br-lan'''（含有线口）；生产环境建议为访客单独建一个 SSID/网络再启用。&lt;br /&gt;
* 与 Smart WAN 可'''同时使用'''：上行做别人门户的客户端、下行发布自己的门户，互不冲突。&lt;br /&gt;
* 管理页面、DNS 与系统更新域名（如 dl.photonicat.com）已加入'''白名单（walled garden）'''，认证前也可访问，避免把自己锁在门外。&lt;br /&gt;
&lt;br /&gt;
=== 命令行验证（SSH） ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ndsctl status          # 守护进程状态&lt;br /&gt;
ndsctl json            # 客户端及认证状态（authenticated / preauthenticated）&lt;br /&gt;
nft list ruleset | grep -i nds    # 查看门户防火墙规则&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
反向验证：第二台'''未点击同意'''的设备应无法访问互联网（https 站点超时），直到它也完成点击。&lt;br /&gt;
&lt;br /&gt;
== English ==&lt;br /&gt;
&lt;br /&gt;
=== How it works ===&lt;br /&gt;
* Built on '''OpenNDS''' (the maintained successor of nodogsplash), running natively on the fw4/nftables firewall.&lt;br /&gt;
* When a guest device (iPhone/Android/Windows) joins, the OS's connectivity probe '''auto-pops''' the login sheet; tapping '''Agree &amp;amp; Connect''' authorizes that device's MAC.&lt;br /&gt;
* Current mode is '''click-through''' (no credentials); the splash is Photonicat-branded and '''authorizes on the first tap''' — no stranded intermediate pages.&lt;br /&gt;
* Sessions are per-MAC and expire after &amp;lt;code&amp;gt;sessiontimeout&amp;lt;/code&amp;gt;, requiring a fresh tap.&lt;br /&gt;
&lt;br /&gt;
=== Enabling ===&lt;br /&gt;
# Open the manager UI → '''Settings (/settings)'''.&lt;br /&gt;
# Toggle '''Captive Portal''' on or off; the page reports success and surfaces start/stop failures with reasons.&lt;br /&gt;
# For ~10–15 s after enabling, nftables rules are rebuilding and new clients may briefly fail to get the splash — normal, just retry.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* '''Guests must use DHCP''': static-IP clients are rejected by OpenNDS (403 &amp;quot;IP not allocated by dhcp&amp;quot;).&lt;br /&gt;
* '''HTTPS cannot be intercepted''': the popup relies on the OS HTTP probe. If no sheet appears, browse any http:// site manually.&lt;br /&gt;
* The portal gates '''br-lan''' by default (including wired ports); for production, prefer a dedicated guest SSID/network.&lt;br /&gt;
* '''Coexists with Smart WAN''': captive client upstream, captive gateway downstream at the same time.&lt;br /&gt;
* The admin UI, DNS and update domains (e.g. dl.photonicat.com) are '''walled-garden allowed''' pre-auth, so you can't lock yourself out.&lt;br /&gt;
&lt;br /&gt;
=== CLI verification (SSH) ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ndsctl status          # daemon state&lt;br /&gt;
ndsctl json            # clients and auth state (authenticated / preauthenticated)&lt;br /&gt;
nft list ruleset | grep -i nds    # portal firewall rules&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Negative test: a second device that has '''not''' tapped Agree must fail to reach the internet (https times out) until it does.&lt;br /&gt;
&lt;br /&gt;
[[Photonicat 2 Smart WAN 智能上网]] ｜ [[Photonicat 2 管理界面新功能 (2026)]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:27:44 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E8%AE%BF%E5%AE%A2%E9%97%A8%E6%88%B7_Captive_Portal</comments>
		</item>
		<item>
			<title>Photonicat 2 管理界面新功能 (2026)</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2%E6%96%B0%E5%8A%9F%E8%83%BD_(2026)&amp;diff=251&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2%E6%96%B0%E5%8A%9F%E8%83%BD_(2026)&amp;diff=251&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2, pcat-manager-web 2026-06/07 更新（随 photonicatWrt 26.04.x OTA 或 pcat- 系列 IPK 分发） / Photonicat 2, pcat-manager-web 2026-06/07 updates (shipped via photonicatWrt 26.04.x OTA or pcat- IPK packages) |}  本页汇总 photonicat 2 &amp;#039;&amp;#039;&amp;#039;Web 管理界面（pcat-manager-web）&amp;#039;&amp;#039;&amp;#039;2026 年上半年的新功能与改进。两大重点功能有独立页面：&lt;a href=&quot;/Photonicat_2_Smart_WAN_%E6%99%BA%E8%83%BD%E4%B8%8A%E7%BD%91&quot; title=&quot;Photonicat 2 Smart WAN 智能上网&quot;&gt;Photonicat 2 Smart WAN 智能上网&lt;/a&gt;…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2, pcat-manager-web 2026-06/07 更新（随 photonicatWrt 26.04.x OTA 或 pcat- 系列 IPK 分发） / Photonicat 2, pcat-manager-web 2026-06/07 updates (shipped via photonicatWrt 26.04.x OTA or pcat- IPK packages)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
本页汇总 photonicat 2 '''Web 管理界面（pcat-manager-web）'''2026 年上半年的新功能与改进。两大重点功能有独立页面：[[Photonicat 2 Smart WAN 智能上网]] 与 [[Photonicat 2 访客门户 Captive Portal]]。&lt;br /&gt;
&lt;br /&gt;
This page rounds up the H1-2026 features and improvements of the photonicat 2 '''web manager (pcat-manager-web)'''. The two headline features have dedicated pages: [[Photonicat 2 Smart WAN 智能上网|Smart WAN]] and [[Photonicat 2 访客门户 Captive Portal|Captive Portal]].&lt;br /&gt;
&lt;br /&gt;
== 中文说明 ==&lt;br /&gt;
&lt;br /&gt;
=== 仪表盘 Dashboard ===&lt;br /&gt;
* '''真实出口指示'''：首页拓扑图只点亮'''当前实际使用的出口'''（有线/WiFi 中继/蜂窝），WiFi 中继状态正确显示；LAN 绿点仅在真的有出口可用时点亮。&lt;br /&gt;
* 新增显示 '''WiFi 信号强度'''、'''当前网络模式'''，WAN 图标按多出口组合显示。&lt;br /&gt;
* '''限速统计更准'''：修复 NAT 转发吞吐统计与 FM350 模组计数器清零导致的速度显示错误。&lt;br /&gt;
* 性能优化：仪表盘数据缓存与轮询对齐，页面响应更快；前端框架升级至 Alpine.js 3.15。&lt;br /&gt;
&lt;br /&gt;
=== 公网 IP 自定义查询（含小屏显示） ===&lt;br /&gt;
解决&amp;quot;photonicat.com 被墙时 LCD 无法显示公网 IP&amp;quot;的问题：&lt;br /&gt;
* '''小屏页面（/screen）新增 &amp;quot;Public IP&amp;quot; 标签页'''，可自定义公网 IP 查询：&lt;br /&gt;
** 多个查询 URL 按顺序尝试（自动校验返回的是合法 IPv4/IPv6）；&lt;br /&gt;
** 每个源可配解析方式：&amp;lt;code&amp;gt;json:字段&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;regex:正则&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;line:行号&amp;lt;/code&amp;gt; 或纯文本；&lt;br /&gt;
** 可自定义 User-Agent；页面内附完整配置示例。&lt;br /&gt;
* 配置同时写入 Web 后端与 Go 小屏程序，网页和 LCD 屏使用同一套查询源。&lt;br /&gt;
* 小屏 BTC 价格示例已切换到 Photonicat 官方 API。&lt;br /&gt;
&lt;br /&gt;
=== 电话与短信（蜂窝版） ===&lt;br /&gt;
* '''通话记录'''：类 iPhone 的通话历史（/phone 页面）——来电/去电/未接分类、接通状态、通话时长、时间戳；支持一键回拨、单条删除与清空。记录保存在本机 SQLite（/etc/pc_phone.db）。&lt;br /&gt;
* '''拨号界面'''：实时通话状态显示，音频通道可切换（扬声器/听筒/耳机/蓝牙）。&lt;br /&gt;
* '''SIM 卡号可编辑'''：/modem 页面 SIM 卡号旁新增铅笔图标，点击即可内联编辑并保存（运营商不下发号码时可手工标注），支持回车保存/Esc 取消。&lt;br /&gt;
* 短信列表自动刷新修复：新短信到达后无需手动刷新页面。&lt;br /&gt;
&lt;br /&gt;
=== 电源与电池 ===&lt;br /&gt;
* '''Type-C 反向供电状态修正'''：用 photonicat 2 当充电宝给外设供电时，电池状态正确显示&amp;quot;放电中&amp;quot;（此前误显示充电）。&lt;br /&gt;
* '''开关机策略（/timer）'''三种模式：&lt;br /&gt;
** 手动模式：仅按键/软件控制开关机；&lt;br /&gt;
** 车载/UPS 模式：插电自动开机，断电后可设 0–600 分钟延迟安全关机（车载点火联动、UPS 场景）；&lt;br /&gt;
** 定时模式：最多 6 条按星期+时间（HH:MM）的定时开/关机计划。&lt;br /&gt;
&lt;br /&gt;
=== 设置与维护 ===&lt;br /&gt;
* '''WiFi 恢复出厂'''：/settings 新增一键恢复 WiFi 默认配置按钮——WiFi 配置改乱连不上时的自救手段。&lt;br /&gt;
* '''系统更新更安全'''：升级过程中显著提示&amp;quot;'''请勿断电'''&amp;quot;，升级确认流程简化；正式固件源为 dl.photonicat.com（系统镜像与 MCU 固件均自动检测新版本）。&lt;br /&gt;
* 修复新版 OpenWrt 下 WLAN 启用状态检测（wifi-iface 与 wifi-device 需同时启用）。&lt;br /&gt;
&lt;br /&gt;
=== 安全加固 ===&lt;br /&gt;
2026-07 起的版本完成了一轮安全加固，建议所有用户升级：&lt;br /&gt;
* 所有 API 接口强制登录校验，WebSocket 连接增加鉴权；&lt;br /&gt;
* 全面启用 CSRF 防护；所有改变状态的操作仅接受 POST；&lt;br /&gt;
* 不再向前端泄露 LuCI 密码；登录 PIN 页面不再依赖外部 CDN；&lt;br /&gt;
* 配置写入原子化，异常断电不再损坏配置文件；修复开放重定向等问题。&lt;br /&gt;
&lt;br /&gt;
== English ==&lt;br /&gt;
&lt;br /&gt;
=== Dashboard ===&lt;br /&gt;
* '''True egress indication''': the topology only lights the '''actually active egress''' (ethernet / WiFi relay / cellular); relaying WiFi shows correctly; the LAN green dot requires a live egress.&lt;br /&gt;
* Added '''WiFi signal strength''' and '''current network mode'''; WAN icons composite across multiple uplinks.&lt;br /&gt;
* '''Accurate throughput''': fixed NAT-forwarding speed accounting and FM350 modem counter resets.&lt;br /&gt;
* Performance: dashboard caching aligned to the display poll; frontend upgraded to Alpine.js 3.15.&lt;br /&gt;
&lt;br /&gt;
=== Configurable public-IP lookup (incl. mini screen) ===&lt;br /&gt;
Fixes &amp;quot;the LCD can't show the public IP when photonicat.com is blocked&amp;quot;:&lt;br /&gt;
* The '''Mini Screen page (/screen) gains a &amp;quot;Public IP&amp;quot; tab''' to customize lookups:&lt;br /&gt;
** multiple URLs tried in order (responses validated as real IPv4/IPv6);&lt;br /&gt;
** per-source parsers: &amp;lt;code&amp;gt;json:field&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;regex:pattern&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;line:N&amp;lt;/code&amp;gt; or plain text;&lt;br /&gt;
** custom User-Agent; a worked example is embedded in the page.&lt;br /&gt;
* The config feeds both the web backend and the Go screen daemon — web UI and LCD share the same sources.&lt;br /&gt;
* The screen's BTC price example now uses the official Photonicat API.&lt;br /&gt;
&lt;br /&gt;
=== Phone &amp;amp; SMS (cellular models) ===&lt;br /&gt;
* '''Call history''': iPhone-like history on /phone — incoming/outgoing/missed, status, duration, timestamps; one-tap callback, per-record delete and clear-all. Stored locally in SQLite (/etc/pc_phone.db).&lt;br /&gt;
* '''Dialer''': live call status, switchable audio path (speaker/earpiece/headset/bluetooth).&lt;br /&gt;
* '''Editable SIM number''': a pencil icon next to the SIM number on /modem enables inline editing (useful when the carrier doesn't provision the number); Enter saves, Esc cancels.&lt;br /&gt;
* SMS list auto-refresh fixed — new messages appear without a manual reload.&lt;br /&gt;
&lt;br /&gt;
=== Power &amp;amp; battery ===&lt;br /&gt;
* '''Type-C reverse-power status fixed''': when the photonicat 2 powers other devices as a power bank, the battery correctly shows &amp;quot;discharging&amp;quot; (previously showed charging).&lt;br /&gt;
* '''Power policies (/timer)''', three modes:&lt;br /&gt;
** Manual: power button / software only;&lt;br /&gt;
** Car/UPS: auto power-on when external power connects; graceful shutdown 0–600 minutes after it disconnects (car ignition, UPS scenarios);&lt;br /&gt;
** Timer: up to 6 scheduled on/off events by day-of-week + time (HH:MM).&lt;br /&gt;
&lt;br /&gt;
=== Settings &amp;amp; maintenance ===&lt;br /&gt;
* '''WiFi reset-to-defaults''': one-click button on /settings restoring factory WiFi config — the escape hatch when WiFi settings get wedged.&lt;br /&gt;
* '''Safer updates''': a prominent &amp;quot;'''do not power off'''&amp;quot; notice during upgrades and a simplified confirmation flow; official sources at dl.photonicat.com (system image and MCU firmware both auto-checked).&lt;br /&gt;
* Fixed WLAN enabled-state detection on newer OpenWrt (both wifi-iface and wifi-device must be enabled).&lt;br /&gt;
&lt;br /&gt;
=== Security hardening ===&lt;br /&gt;
Builds since 2026-07 include a security hardening pass — all users should update:&lt;br /&gt;
* Authentication enforced on all API routes; WebSocket connections authenticated;&lt;br /&gt;
* CSRF protection across the board; state-changing operations are POST-only;&lt;br /&gt;
* The LuCI password is no longer exposed to the frontend; the PIN page no longer loads from an external CDN;&lt;br /&gt;
* Atomic config writes (power loss can't corrupt configs); open-redirect and socket-framing fixes.&lt;br /&gt;
&lt;br /&gt;
[[Photonicat 2 Smart WAN 智能上网]] ｜ [[Photonicat 2 访客门户 Captive Portal]] ｜ [[Photoincat 2 IPv6 PPPoE]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:27:31 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E7%AE%A1%E7%90%86%E7%95%8C%E9%9D%A2%E6%96%B0%E5%8A%9F%E8%83%BD_(2026)</comments>
		</item>
		<item>
			<title>Photonicat 2 多出口与故障切换</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%A4%9A%E5%87%BA%E5%8F%A3%E4%B8%8E%E6%95%85%E9%9A%9C%E5%88%87%E6%8D%A2&amp;diff=250&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%A4%9A%E5%87%BA%E5%8F%A3%E4%B8%8E%E6%95%85%E9%9A%9C%E5%88%87%E6%8D%A2&amp;diff=250&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2, photonicatWrt 26.04.x + pcat-manager-web 2026-06 及以后版本 / Photonicat 2, photonicatWrt 26.04.x with pcat-manager-web builds from 2026-06 onward |}  Photonicat 2 同时拥有&amp;#039;&amp;#039;&amp;#039;有线 WAN、WiFi 中继（Smart WAN）和 4G/5G 蜂窝&amp;#039;&amp;#039;&amp;#039;三类出口。本页解释它们如何排定优先级、断线时如何自动切换、仪表盘指示灯的含义，以及排障方法。  The photonicat 2 has…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2, photonicatWrt 26.04.x + pcat-manager-web 2026-06 及以后版本 / Photonicat 2, photonicatWrt 26.04.x with pcat-manager-web builds from 2026-06 onward&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Photonicat 2 同时拥有'''有线 WAN、WiFi 中继（Smart WAN）和 4G/5G 蜂窝'''三类出口。本页解释它们如何排定优先级、断线时如何自动切换、仪表盘指示灯的含义，以及排障方法。&lt;br /&gt;
&lt;br /&gt;
The photonicat 2 has three egress classes at once: '''wired WAN, WiFi relay (Smart WAN), and 4G/5G cellular'''. This page explains how they're prioritized, how failover works, what the dashboard indicators mean, and how to debug it.&lt;br /&gt;
&lt;br /&gt;
== 中文说明 ==&lt;br /&gt;
&lt;br /&gt;
=== 优先级：路由 metric 链 ===&lt;br /&gt;
故障切换完全由'''路由 metric'''（数值越小优先级越高）决定——所有出口可以同时在线，流量始终走 metric 最小的可用出口：&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 出口 !! 接口 !! metric !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| 有线宽带 || wan (eth0 / pppoe-wan) || '''1'''（IPv6 别名 wan_6 随主接口） || 最高优先级&lt;br /&gt;
|-&lt;br /&gt;
| WiFi 中继 (Smart WAN) || wan_wifi / wan_wifi_v6 || '''5 / 6''' || 次优先&lt;br /&gt;
|-&lt;br /&gt;
| 5G 蜂窝 || wwan_5g / wwan_5g_v6 || '''10 / 11''' || 兜底&lt;br /&gt;
|-&lt;br /&gt;
| LTE 蜂窝 || wwan_lte / wwan_lte_v6 || '''12 / 13''' || 兜底（LTE 模组）&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* '''插上网线''' → 有线立即接管（metric 1 最小）。&lt;br /&gt;
* '''拔掉网线''' → 有线路由消失，流量自动落到 WiFi 中继；WiFi 也没有 → 蜂窝。全程无需人工干预。&lt;br /&gt;
* '''WiFi 连上了但没有互联网'''（如未登录的酒店门户）：Smart WAN 的联网探测会把 wan_wifi 的 metric '''临时调到蜂窝之后'''——上网流量走蜂窝，WiFi 链路保持连接供你登录；探测恢复后自动还原。详见 [[Photonicat 2 Smart WAN 智能上网]]。&lt;br /&gt;
&lt;br /&gt;
=== 与 pcat-manager 的关系 ===&lt;br /&gt;
固件自带的 pcat-manager 默认只跟踪有线 wan（eth0）：有线一断，pcat-manager 的策略会自动开启蜂窝网络，'''跳过 WiFi 中继'''，破坏上面的 metric 切换链。因此启用 Smart WAN 时，管理程序会自动把 pcat-manager 的规则切换为系统默认；关闭 Smart WAN 时自动还原。&lt;br /&gt;
&lt;br /&gt;
=== 仪表盘指示 ===&lt;br /&gt;
* 首页拓扑图'''只点亮当前真正承载流量的出口'''（而不是&amp;quot;接口在线&amp;quot;）——有线/WiFi 中继/蜂窝一目了然。&lt;br /&gt;
* 同时显示 WiFi 信号强度与当前网络模式；多出口在线时 WAN 图标为组合图标。&lt;br /&gt;
* LAN 绿点只在存在可用出口时点亮。&lt;br /&gt;
&lt;br /&gt;
=== 排障 ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ip route show default          # IPv4 默认路由及 metric（可能有多条，走 metric 最小者）&lt;br /&gt;
ip -6 route show default       # IPv6 同理&lt;br /&gt;
ip route get 1.1.1.1           # 当前实际选择的出口&lt;br /&gt;
ifstatus wan_wifi | head       # Smart WAN 接口状态&lt;br /&gt;
logread | grep -i wifi_wan     # Smart WAN 巡检/切换日志&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* 流量走了蜂窝但 WiFi 明明在线 → 查 &amp;lt;code&amp;gt;ip route show default&amp;lt;/code&amp;gt;：若 wan_wifi 的 metric 被调高，说明门户探测判定该 WiFi 无法上网。&lt;br /&gt;
* 切换后个别应用卡住 → 长连接（VPN、SSH）绑定旧出口地址是正常现象，重连即可。&lt;br /&gt;
&lt;br /&gt;
== English ==&lt;br /&gt;
&lt;br /&gt;
=== Priority: the route-metric chain ===&lt;br /&gt;
Failover is driven purely by '''route metrics''' (lower wins). All uplinks can be up simultaneously; traffic always takes the lowest-metric available route:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Egress !! Interface !! Metric !! Role&lt;br /&gt;
|-&lt;br /&gt;
| Wired broadband || wan (eth0 / pppoe-wan) || '''1''' (IPv6 alias wan_6 follows) || top priority&lt;br /&gt;
|-&lt;br /&gt;
| WiFi relay (Smart WAN) || wan_wifi / wan_wifi_v6 || '''5 / 6''' || second&lt;br /&gt;
|-&lt;br /&gt;
| 5G cellular || wwan_5g / wwan_5g_v6 || '''10 / 11''' || fallback&lt;br /&gt;
|-&lt;br /&gt;
| LTE cellular || wwan_lte / wwan_lte_v6 || '''12 / 13''' || fallback (LTE modems)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* '''Plug in ethernet''' → wired takes over instantly (metric 1).&lt;br /&gt;
* '''Unplug it''' → the wired route vanishes; traffic falls to WiFi relay, then to cellular if no saved WiFi is reachable. No manual action.&lt;br /&gt;
* '''WiFi associated but no internet''' (e.g. an unauthenticated hotel portal): Smart WAN's connectivity probe '''temporarily demotes''' wan_wifi below cellular — internet traffic uses cellular while the WiFi stays associated for you to log in; the metric is restored on recovery. See [[Photonicat 2 Smart WAN 智能上网|Smart WAN]].&lt;br /&gt;
&lt;br /&gt;
=== Interaction with pcat-manager ===&lt;br /&gt;
Stock pcat-manager only tracks the wired wan (eth0): when it drops, pcat-manager policies would enable cellular network, '''skipping WiFi relay''' and defeating the metric chain. So while Smart WAN is enabled, the manager automatically switches pcat-manager rules to default routing rule and restores them when Smart WAN is turned off.&lt;br /&gt;
&lt;br /&gt;
=== Dashboard indicators ===&lt;br /&gt;
* The topology lights '''only the egress actually carrying traffic''' (not merely &amp;quot;interface up&amp;quot;) — wired / WiFi relay / cellular at a glance.&lt;br /&gt;
* WiFi signal strength and the current network mode are shown; WAN icons composite when several uplinks are up.&lt;br /&gt;
* The LAN green dot requires a live egress.&lt;br /&gt;
&lt;br /&gt;
=== Debugging ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ip route show default          # IPv4 default routes and metrics (lowest wins)&lt;br /&gt;
ip -6 route show default       # same for IPv6&lt;br /&gt;
ip route get 1.1.1.1           # which egress is actually selected right now&lt;br /&gt;
ifstatus wan_wifi | head       # Smart WAN interface state&lt;br /&gt;
logread | grep -i wifi_wan     # Smart WAN reconcile/failover logs&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Traffic on cellular while WiFi looks fine → check &amp;lt;code&amp;gt;ip route show default&amp;lt;/code&amp;gt;: a raised wan_wifi metric means the portal probe judged that WiFi offline.&lt;br /&gt;
* An app hangs right after failover → long-lived connections (VPN, SSH) pinned to the old egress address must reconnect; that's expected.&lt;br /&gt;
&lt;br /&gt;
[[Photonicat 2 Smart WAN 智能上网]] ｜ [[Photonicat 4G/5G 家庭网络备份]] ｜ [[Photoincat 2 IPv6 PPPoE]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:27:10 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E5%A4%9A%E5%87%BA%E5%8F%A3%E4%B8%8E%E6%95%85%E9%9A%9C%E5%88%87%E6%8D%A2</comments>
		</item>
		<item>
			<title>Photonicat2 无线桥接</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat2_%E6%97%A0%E7%BA%BF%E6%A1%A5%E6%8E%A5&amp;diff=249&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat2_%E6%97%A0%E7%BA%BF%E6%A1%A5%E6%8E%A5&amp;diff=249&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“本文将介绍在photonicat2使用双无线网卡时，将其中一个网卡作为公网接入使用的步骤。  ==方法==  * 在PC上访问http://172.16.0.1:8080，点击网络-&amp;gt;无线网络，打开无线网络配置页面。 * 在准备作为公网接入的无线网卡对应的radio设备上点击 扫描 按钮。 &lt;a href=&quot;/index.php?title=%E6%96%87%E4%BB%B6:Pcat2_wifi_bridge_img1.jpg&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;文件:Pcat2 wifi bridge img1.jpg（页面不存在）&quot;&gt;file:Pcat2 wifi bridge img1.jpg&lt;/a&gt;  * 扫描完成后会显示热点扫描结果，在想要加入的热点上点击 加入网络。 file:Pc…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;本文将介绍在photonicat2使用双无线网卡时，将其中一个网卡作为公网接入使用的步骤。&lt;br /&gt;
&lt;br /&gt;
==方法==&lt;br /&gt;
&lt;br /&gt;
* 在PC上访问http://172.16.0.1:8080，点击网络-&amp;gt;无线网络，打开无线网络配置页面。&lt;br /&gt;
* 在准备作为公网接入的无线网卡对应的radio设备上点击 扫描 按钮。&lt;br /&gt;
[[file:Pcat2 wifi bridge img1.jpg]]&lt;br /&gt;
&lt;br /&gt;
* 扫描完成后会显示热点扫描结果，在想要加入的热点上点击 加入网络。&lt;br /&gt;
[[file:Pcat2 wifi bridge img2.jpg]]&lt;br /&gt;
&lt;br /&gt;
* 在打开的配置页面中，启用 重置无线配置，设定新网络的名称为wwan_wifi，输入热点的WPA密钥。然后点击 提交。&lt;br /&gt;
[[file:Pcat2 wifi bridge img6.jpg]]&lt;br /&gt;
&lt;br /&gt;
* 在接口配置页面上，点击 保存。&lt;br /&gt;
[[file:Pcat2 wifi bridge img4.jpg]]&lt;br /&gt;
&lt;br /&gt;
* 在无线网络配置主页面上，点击 保存并应用。&lt;br /&gt;
[[file:Pcat2 wifi bridge img5.jpg]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:26:28 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat2_%E6%97%A0%E7%BA%BF%E6%A1%A5%E6%8E%A5</comments>
		</item>
		<item>
			<title>Photonicat 2 Smart WAN 智能上网</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_Smart_WAN_%E6%99%BA%E8%83%BD%E4%B8%8A%E7%BD%91&amp;diff=248&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_Smart_WAN_%E6%99%BA%E8%83%BD%E4%B8%8A%E7%BD%91&amp;diff=248&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2, photonicatWrt &amp;#039;&amp;#039;&amp;#039;26.04.1+&amp;#039;&amp;#039;&amp;#039; 与 pcat-manager-web 2026-06 及以后版本 / Photonicat 2 with photonicatWrt 26.04.1+ and pcat-manager-web builds from 2026-06 onward |}  &amp;#039;&amp;#039;&amp;#039;Smart WAN（智能上网）&amp;#039;&amp;#039;&amp;#039;让 photonicat 2 像手机一样使用上游 WiFi：保存多个热点、自动回连信号最强的已知网络、识别强制门户（酒店/机场登录页）、支持企业级 802.1x 网络，并…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2, photonicatWrt '''26.04.1+''' 与 pcat-manager-web 2026-06 及以后版本 / Photonicat 2 with photonicatWrt 26.04.1+ and pcat-manager-web builds from 2026-06 onward&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''Smart WAN（智能上网）'''让 photonicat 2 像手机一样使用上游 WiFi：保存多个热点、自动回连信号最强的已知网络、识别强制门户（酒店/机场登录页）、支持企业级 802.1x 网络，并在 WiFi 不可用时自动切换回有线/蜂窝网络。&lt;br /&gt;
&lt;br /&gt;
'''Smart WAN''' makes the photonicat 2 treat upstream WiFi like a phone does: save multiple hotspots, auto-reconnect to the strongest known network, detect captive portals (hotel/airport login pages), join enterprise 802.1x networks, and fail over to ethernet/cellular automatically when WiFi is unusable.&lt;br /&gt;
&lt;br /&gt;
== 中文说明 ==&lt;br /&gt;
&lt;br /&gt;
=== 功能总览 ===&lt;br /&gt;
* '''已保存网络 + 自动回连'''：像手机一样保存多个上游 WiFi。设备每 60 秒巡检一次：已连接则保持；掉线则扫描并自动加入'''信号最强'''的已保存网络；周围没有已知网络时让无线待机，流量自动回落到有线/蜂窝。&lt;br /&gt;
* '''强制门户检测'''：优先用 HTTPS 探测（证书有效的 200 响应不可能被门户伪造），HTTPS 失败再用 HTTP 区分&amp;quot;被门户劫持&amp;quot;和&amp;quot;链路彻底没网&amp;quot;。检测到门户后界面会显示'''门户徽标'''。&lt;br /&gt;
* '''检测到无网时自动降级'''：把 WiFi 上行的路由 metric 调低优先级，出口流量立即切换到有线/蜂窝，'''WiFi 链路保持连接'''以便你完成门户登录；恢复联网后自动还原优先级。&lt;br /&gt;
* '''自动登录命令'''：可为每个已保存网络配置一条登录命令（如 curl 提交门户表单）。检测到门户时自动执行，环境变量 &amp;lt;code&amp;gt;$WIFI_WAN_IFACE&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;$WIFI_WAN_GATEWAY&amp;lt;/code&amp;gt; 可用。常连的酒店/公司门户可实现全自动上网。&lt;br /&gt;
* '''企业级 802.1x（PEAP/TTLS）'''：支持连接需要用户名+密码的企业/校园网（eduroam 类）。设备会自动探测 wpad 是否具备 EAP 能力，具备时界面才显示相关字段。&lt;br /&gt;
* '''每 SSID 固定私有 MAC'''：仿 iPhone 的&amp;quot;私有地址&amp;quot;——对每个 SSID 使用一个稳定的随机 MAC。既不暴露硬件地址，又保证重连后门户授权和 DHCP 租约仍然有效。&lt;br /&gt;
&lt;br /&gt;
=== 使用方法 ===&lt;br /&gt;
# 打开管理界面（默认 &amp;lt;code&amp;gt;http://172.16.0.1&amp;lt;/code&amp;gt;）→ '''设备控制'''页面，网络模式选择 '''Smart WAN'''。&lt;br /&gt;
# 点击扫描，选择目标热点输入密码即可保存并连接；企业网络会出现 EAP 身份/密码字段。&lt;br /&gt;
# 可选项：&lt;br /&gt;
#* '''私有 MAC''' 开关（默认建议开启）；&lt;br /&gt;
#* '''自动登录命令'''（连接需要网页登录的热点时填写）。&lt;br /&gt;
# 之后设备会自动维护连接，无需人工干预。&lt;br /&gt;
&lt;br /&gt;
=== 排障 ===&lt;br /&gt;
* 界面显示门户徽标但没弹登录页 → 用手机/电脑连到 photonicat 的下游 WiFi，浏览任意 http:// 网站即可触发门户。&lt;br /&gt;
* WiFi 已连接但流量走了蜂窝 → 说明门户探测判定该 WiFi 无法上网（可能需要登录）；完成登录后约一分钟内自动切回。&lt;br /&gt;
* 企业网络字段不出现 → 固件的 wpad 不支持 EAP，需要更新到 26.04.1 及以上官方固件。&lt;br /&gt;
&lt;br /&gt;
== English ==&lt;br /&gt;
&lt;br /&gt;
=== Feature overview ===&lt;br /&gt;
* '''Saved networks + auto-reconnect''': save multiple upstream hotspots, phone-style. A reconciler runs every 60 s: stay put if associated; otherwise scan and join the '''strongest''' saved network in range; if none is reachable the radio idles and traffic falls back to ethernet/cellular via route metrics.&lt;br /&gt;
* '''Captive-portal detection''': HTTPS-first probing (a valid-TLS 200 cannot be spoofed by a portal), falling back to HTTP to distinguish &amp;quot;hijacked by a portal&amp;quot; from &amp;quot;dead uplink&amp;quot;. A '''portal badge''' appears in the UI when one is detected.&lt;br /&gt;
* '''Automatic demotion when offline''': the WiFi uplink's route metric is demoted so egress instantly fails over to ethernet/cellular, while the WiFi link '''stays associated''' so you can complete the portal login; the metric is restored on recovery.&lt;br /&gt;
* '''Per-network auto-login command''': attach a login command (e.g. a curl form submission) to any saved network; it runs automatically on portal detection with &amp;lt;code&amp;gt;$WIFI_WAN_IFACE&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;$WIFI_WAN_GATEWAY&amp;lt;/code&amp;gt; exported. Frequent hotel/office portals become fully hands-free.&lt;br /&gt;
* '''Enterprise 802.1x (PEAP/TTLS)''': join username+password enterprise/campus networks (eduroam-style). The device probes wpad for EAP capability and only then offers the fields.&lt;br /&gt;
* '''Stable per-SSID private MAC''': iPhone-style private addressing — one stable random MAC per SSID, hiding the hardware address while keeping portal authorizations and DHCP leases valid across reconnects.&lt;br /&gt;
&lt;br /&gt;
=== How to use ===&lt;br /&gt;
# Open the manager UI (default &amp;lt;code&amp;gt;http://172.16.0.1&amp;lt;/code&amp;gt;) → '''Device Control''', select network mode '''Smart WAN'''.&lt;br /&gt;
# Scan, pick the hotspot, enter the password to save &amp;amp; connect; enterprise networks expose EAP identity/password fields.&lt;br /&gt;
# Optional: the '''private MAC''' toggle (recommended on) and the '''auto-login command''' for web-login hotspots.&lt;br /&gt;
# The device maintains the connection autonomously from then on.&lt;br /&gt;
&lt;br /&gt;
=== Troubleshooting ===&lt;br /&gt;
* Portal badge shown but no login page → connect a phone/laptop to the photonicat's downstream WiFi and browse any http:// site to trigger it.&lt;br /&gt;
* WiFi associated but traffic uses cellular → the probe judged that WiFi offline (login likely required); after logging in it switches back within a minute.&lt;br /&gt;
* No enterprise fields → the firmware's wpad lacks EAP support; update to official 26.04.1+.&lt;br /&gt;
&lt;br /&gt;
[[Photonicat 2 访客门户 Captive Portal|相关：让 photonicat 自己发布访客登录页 / Related: serving a guest splash page yourself]] ｜ [[IPv6 术语表 Glossary]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:26:13 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_Smart_WAN_%E6%99%BA%E8%83%BD%E4%B8%8A%E7%BD%91</comments>
		</item>
		<item>
			<title>Photonicat 2 固件 Changelog</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%9B%BA%E4%BB%B6_Changelog&amp;diff=247&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%9B%BA%E4%BB%B6_Changelog&amp;diff=247&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“中文版见 &lt;a href=&quot;/Photonicat_2_%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97&quot; title=&quot;Photonicat 2 固件更新日志&quot;&gt;Photonicat 2 固件更新日志&lt;/a&gt;.  ==2025-08-22== * initial release  ==2025-09-19 r7612== * Simplified multi-WAN routing, disabled &amp;lt;code&amp;gt;mwan3&amp;lt;/code&amp;gt;.   * Built-in Docker packages by default.   * Bumped kernel version to 6.12.45.   * Applied PCIe patches from upstream.   * Added USB hub reset timing and watchdog.   * Status LED and beeper can be disabled by the user.   * Improved mini display performance.   * Added LED, beeper, and fan control w…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;中文版见 [[Photonicat 2 固件更新日志]].&lt;br /&gt;
&lt;br /&gt;
==2025-08-22==&lt;br /&gt;
* initial release&lt;br /&gt;
&lt;br /&gt;
==2025-09-19 r7612==&lt;br /&gt;
* Simplified multi-WAN routing, disabled &amp;lt;code&amp;gt;mwan3&amp;lt;/code&amp;gt;.  &lt;br /&gt;
* Built-in Docker packages by default.  &lt;br /&gt;
* Bumped kernel version to 6.12.45.  &lt;br /&gt;
* Applied PCIe patches from upstream.  &lt;br /&gt;
* Added USB hub reset timing and watchdog.  &lt;br /&gt;
* Status LED and beeper can be disabled by the user.  &lt;br /&gt;
* Improved mini display performance.  &lt;br /&gt;
* Added LED, beeper, and fan control with over-temperature protection algorithm.  &lt;br /&gt;
* Simplified network WAN interface selection: &amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;eth_only&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cell_only&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;all_off&amp;lt;/code&amp;gt;.  &lt;br /&gt;
* Added /update management interface.&lt;br /&gt;
* MCU: Optimized coulomb counting algorithm.  &lt;br /&gt;
* MCU: Fixed occasional issue where charging indicator light did not display.&lt;br /&gt;
&lt;br /&gt;
== 2025-12-12 r7618 ==&lt;br /&gt;
* Improved bootup speed by removing unnecessary network resets.&lt;br /&gt;
* Updated OpenWrt &amp;lt;code&amp;gt;netifd&amp;lt;/code&amp;gt; to improve NFA765 wifi module compatibility.&lt;br /&gt;
* Improved fan control strategy and overall thermal behavior.&lt;br /&gt;
* Improved intelligent fan speed adjustment logic. &amp;lt;code&amp;gt;smart_quiet&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;smart_cool&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;manual&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Fixed UI crash when network mode was set to '''Cellular Only'''.&lt;br /&gt;
* Fixed an issue where 4G/5G band information was not displayed in the UI.&lt;br /&gt;
* Fixed missing information in the with some 5G module information page. &lt;br /&gt;
* Fixed 5G Signal not displaying error.&lt;br /&gt;
* Fixed the '''Remember Me''' login option not working after a system restart.&lt;br /&gt;
&lt;br /&gt;
== 2026-03-06 r7660 ==&lt;br /&gt;
* '''Kernel &amp;amp; system updates''' — Updated kernel to 6.12.74, mac80211 to 6.12.61, python3 to 3.13.9 with related packages (PAM-based auth replacing deprecated &amp;lt;code&amp;gt;spwd&amp;lt;/code&amp;gt;), and system version to 26.04, fixed several CVEs.&lt;br /&gt;
* '''Fibocom FM350-GL 5G modem support''' — Full support including signal strength, temperature monitoring, IMEI, carrier/operator display, serving cell info, roaming preference, 4G/5G network mode and band selection, WWAN power off toggle via rfkill, network stats tracking, and hex-encoded operator name decoding.&lt;br /&gt;
* '''SMS reliability''' — Switched to PDU mode for all modems, fixed FM350-GL serial port handling, prompt detection, and response timeouts.&lt;br /&gt;
* '''Web terminal''' — Added web-based terminal (&amp;lt;code&amp;gt;/terminal&amp;lt;/code&amp;gt;) with persistent PTY sessions, fullscreen toggle, disconnect/reconnect, JetBrains Mono font, and mobile viewport optimization.&lt;br /&gt;
* '''Direct Power Mode &amp;amp; TCP BBR v3''' — Added power-on mode options for battery-free and quick-response applications (auto power-on when adapter connected, no battery required). Added TCP BBR v3 support with congestion control configuration in General Settings.&lt;br /&gt;
* '''Battery history &amp;amp; power event logging''' — Battery history chart with SQLite storage, fixed voltage scale, area fill, watt display, and power on/off event timeline. Persistent power event logging with voltage, current, SOC data, and DC plug/unplug tracking.&lt;br /&gt;
* '''Idle &amp;amp; low battery shutdown''' — Live idle shutdown countdown timer, low battery shutdown support, WiFi client idle monitoring (OR mode), battery-only auto-shutdown option, and 2% SOC tolerance for SOC estimation jumps.&lt;br /&gt;
* '''General Settings &amp;amp; timer page redesign''' — New General Settings page with language, timezone, hostname, and LuCI sync. Redesigned timer page with modern split-panel layout, compact full-width panes, and clarified Car/UPS mode descriptions.&lt;br /&gt;
* '''Dashboard &amp;amp; header improvements''' — Active WAN shown first, public IPv6 detection, modem temperature display, 5G/4G indicator in network icon row, status-aware rendering, gateway underline, and optimized mobile header layout.&lt;br /&gt;
* '''Performance &amp;amp; UI/UX polish''' — Native Python ubus/uci wrappers, non-blocking IO caching, CPU powersave disabling big cores (A72), 3-month static asset caching, temperature and wattage charts, tab state preserved across refresh, single-language notifications, improved icons, Wiki and Community footer buttons, smart phone formatting, and verbose firmware upgrade progress.&lt;br /&gt;
&lt;br /&gt;
== 2026-06-15 r7714 ==&lt;br /&gt;
* '''Kernel &amp;amp; system updates''' — Updated kernel to 6.12.91, fixed some recent critical security problems. Updated mac80211 to 6.18.26. fixed several CVEs.&lt;br /&gt;
* '''OpenWRT base system''' - Updated base system and LuCI to 25.12. Added IEEE80211.BE support (Allow to enable 6GHz channels on QCNCM865 and MT7925).&lt;br /&gt;
* '''Smart WAN (WiFi-as-WAN)''' — New Smart WAN mode turns the onboard radio into an upstream WiFi client with automatic Ethernet → WiFi → Cellular failover. Phone-like auto-reconnect to known upstream WiFi, robust scan-device resolution, and a confirmation dialog before switching. The disabled STA radio is shown correctly with a dedicated &amp;quot;WAN (WiFi)&amp;quot; status.&lt;br /&gt;
* '''WiFi 7 (802.11be) &amp;amp; WPA3''' — Added WiFi 7 (BE) and WPA3-SAE support for PCIe cards, with correct htmode/channel handling for 5GHz BE and 6GHz BE, PCIe card-name detection, and normalized encryption values in the UI.&lt;br /&gt;
* '''Dashboard &amp;amp; header improvements''' — Active egress is now highlighted live (only the active WAN row lights up); exposes WiFisignal, active egress, and network mode; status-aware network icons with gateway underline, accurate WAN underline, red-cross for disabled links, and tooltips. Added public IPv6 / public-IP aliases.&lt;br /&gt;
* '''Battery &amp;amp; charge control''' — Added a battery charge-limit slider (80–100%) on the Device Control page, made charge-limit the single source of truth, fixed the battery icon to show the true charge percentage, and robustly default to 100% when never set.&lt;br /&gt;
** '''Hardware requirement:''' the battery charge limit is only supported on '''PCB revision A3''' boards. Earlier board revisions do not support it.&lt;br /&gt;
* '''Screen visual editor''' — New Figma-style visual layout editor for the device display, merged with the JSON view into a single Editor tab. Add/remove pages, per-element position reset, center &amp;amp; snap tools, reset-layout, live JSON diff, label/data-key canvas toggle, and a coordinate fix mapping editor coords to the device content region. Fixed the graph element type rendering on device.&lt;br /&gt;
* '''Screen custom data sources''' — Added custom metrics (command / uci / env / json_file / HTTPS) in the editor with on-device examples, one-click Save &amp;amp; Restart, live value preview on Refresh, duplicate-key warnings, clearer data_key guidance, Gold/AAPL examples via the official Photonicat market API, and flicker-free live preview.&lt;br /&gt;
* '''Device Control &amp;amp; network modes''' — Reordered network modes with composite WAN icons; consolidated the charge-limit setting onto the Device Control page.&lt;br /&gt;
* '''FM350-GL roaming''' — Enabled automatic roaming via &amp;lt;code&amp;gt;AT+COPS=0&amp;lt;/code&amp;gt; and hid the unenforceable &amp;quot;no roaming&amp;quot; option; fixed band selection being overwritten by polling refresh; removed the USB 3.12 10Gbps option that caused LAN/WAN failures.&lt;br /&gt;
* '''Security hardening''' — Added a &amp;lt;code&amp;gt;socketio_auth_required&amp;lt;/code&amp;gt; decorator for WebSocket endpoints, added auth to &amp;lt;code&amp;gt;/switch_locale&amp;lt;/code&amp;gt; and low-battery-shutdown routes, and removed unused/over-permissioned API endpoints.&lt;br /&gt;
* '''Performance''' — Reduced idle CPU usage (file-only logging by default, fewer select wakeups and uci forks), cached &amp;lt;code&amp;gt;data_stats.json&amp;lt;/code&amp;gt; and aligned dashboard caching to the display poll, dropped a no-op screen thread, and read WWAN rfkill state directly from sysfs.&lt;br /&gt;
* '''Mini-display performance''' — Major CPU reduction on the display loop (static-page CPU ~3.2% → ~1.4%, roughly 55% less): skip re-render/SPI blit on unchanged frames via a data-epoch gate, byte-compare before transferring pixels, and halve polling cadences. Fonts (incl. the ~37MB CJK collection) are now parsed once and cached/preloaded, and network lookups (wireless SSID, iwinfo client enumeration, public IP) are cached to cut process forks (~3.8/s → ~1.7/s).&lt;br /&gt;
&lt;br /&gt;
== 2026-06-16 r7715 ==&lt;br /&gt;
* '''Mini-display SPI clock reliability''' — Lowered the display SPI clock from 120 MHz to 50 MHz to eliminate visual glitches or display problems at the higher rate; the conservative timing trades a negligible refresh-latency increase for a stable, artifact-free image.&lt;br /&gt;
* '''Serial-number validation fix''' — Valid device serials were incorrectly shown as &amp;lt;code&amp;gt;(invalid)&amp;lt;/code&amp;gt; on-device because the signature check depended on the &amp;lt;code&amp;gt;cryptography&amp;lt;/code&amp;gt; module, which is not installed on the target OpenWrt image.&lt;br /&gt;
&lt;br /&gt;
== 2026-06-23 r7720 ==&lt;br /&gt;
* '''OpenWRT base system''' — Updated routing and telephony packages to OpenWRT 25.12 branch. Switch default firewall to fw4.&lt;br /&gt;
&lt;br /&gt;
== 2026-07-31 r7853 ==&lt;br /&gt;
* '''Boot time cut by 59% — 17.4 s → 7.2 s''' — A full reboot cycle is now 16.6 s instead of 28.0 s. The biggest single cause was a phantom &amp;lt;code&amp;gt;fstab&amp;lt;/code&amp;gt; entry that made every unit wait each boot for a disk that was never fitted. Also: root filesystem recompressed from &amp;lt;code&amp;gt;xz&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;zstd&amp;lt;/code&amp;gt;, squashfs re-tuned to 256 KiB blocks with direct reads, U-Boot no longer scans USB and the network for boot media, the boot logo is painted in one SPI transfer instead of 110,080 one-byte ones, and the failsafe window is 300 ms instead of 1 s.&lt;br /&gt;
* '''Optional services now ship idle''' — Docker, Samba, collectd, aria2, nlbwmon, watchcat, frp, filebrowser, rclone, adbyby, OpenAppFilter, Tailscale and ZeroTier are still installed but no longer autostart (73 → 59 running services); enable any of them with one click in '''System → Startup'''. &amp;lt;code&amp;gt;vnstat&amp;lt;/code&amp;gt; and the web terminal are deliberately left running.&lt;br /&gt;
* '''WAN priority table replaces Smart WAN mode''' — The '''Smart WAN''' switch from r7714 is now a single metric-based '''priority table''' listing every enabled uplink — Ethernet, upstream WiFi, PPPoE and Cellular — in a fixed slot order, falling back down the list. It replaces &amp;lt;code&amp;gt;mwan3&amp;lt;/code&amp;gt; entirely. Wired WAN now fails over immediately on carrier loss instead of waiting for a probe to time out, and PPPoE is correctly reported as the active egress.&lt;br /&gt;
* '''Upstream WiFi (WiFi-as-WAN)''' — Joins the stronger band automatically when one SSID is broadcast on both 2.4 and 5 GHz; roams to a saved network that comes back into range while still associated; rejoins known networks faster after roaming away; reports live association and standby state with per-radio icons; and scans less aggressively when no saved network is nearby.&lt;br /&gt;
* '''New /dev diagnostics page''' — A live 3D model of the device driven by the built-in G-sensor, with guided orientation calibration; a 2S2P 18650 pack diagram showing per-stage voltages; the MCU fuel-gauge log; and a modem dial log viewer. Tone tests and MIDI playback for the internal beeper.&lt;br /&gt;
* '''Fibocom FM350-GL 5G modem''' — The dialer is rewritten from Python to native C for reliability. It now honours the network-mode preference set in the web UI, locks to 4G when asked and climbs back to 5G when available, falls back to LTE if a 5G dial fails, and watches the data plane to catch a connection that is up but not passing traffic. Fixed a 4G-only SIM causing an endless modem power-cycle, and automatic mode being reported as 5G when it was not. Modem firmware version is now shown, with a firmware-update dialog.&lt;br /&gt;
* '''Modem dial log''' — The last 16 MB of dialling activity is kept in memory and viewable from the web UI, so an intermittent connection problem can be diagnosed after the fact.&lt;br /&gt;
* '''Battery charge limit''' — 1% resolution slider, synchronised to the MCU with debounced saves and re-read live so the UI always reflects what the hardware is enforcing. The limit now survives an MCU restart.&lt;br /&gt;
** '''Hardware requirement:''' the battery charge limit is only supported on '''PCB revision A3''' boards. Earlier board revisions do not support it.&lt;br /&gt;
* '''Firmware and MCU update flow''' — Version dropdowns with per-version changelogs and downgrade support; MCU and firmware updates can no longer run at the same time; no update is offered when the installed MCU is newer than the server's; and OTA now defaults to &amp;lt;code&amp;gt;sysupgrade -c -p&amp;lt;/code&amp;gt;, with the individual flags exposed as tick boxes.&lt;br /&gt;
* '''PhotonDNS''' — A new high-performance DNS forwarder written in Rust: sharded LRU cache, serve-stale, prefetching, cache persistence, UDP/TCP/DoT/DoH upstreams and hedged-racing failover with per-upstream health tracking, plus China-list and ad-list helpers. Ships with its own LuCI page but '''disabled by default'''.&lt;br /&gt;
* '''Security hardening''' — CSRF is now enforced, the LuCI password is no longer leaked to the page, all API routes require authentication, state changes are POST-only, developer endpoints are gated, an open-redirect was closed, and '''Remember Me''' now uses proper SQLite-backed tokens.&lt;br /&gt;
* '''Captive portal''' — One-tap accept, portal URLs that work without DNS, branded error pages, serialised enable/disable so rapid toggling cannot leave it half-configured, and failures are surfaced instead of silently ignored.&lt;br /&gt;
* '''Lower idle CPU and less flash wear''' — Heavy modem AT queries only run when the modem page is open, usage statistics are batched to flash with retention and indexing, PMU settings poll every 60 s instead of continuously, public-IP probes back off, and hidden browser tabs stop polling altogether.&lt;br /&gt;
* '''Mini display''' — New cat wake-up boot animation. Per-page refresh rates (2 Hz on the clock and CPU pages, 1 Hz while pinging) instead of one fixed rate. Per-core CPU bars, a memory bar with the value inside, per-disk usage bars and a scrolling SSID ticker. iStat-style bars with supersampled anti-aliasing and softer text. Battery remaining-time slot, WAN mode line, configurable public-IP lookup, true physical-zero backlight at brightness 0, and standby when the upstream link is not associated.&lt;br /&gt;
* '''WiFi fixes''' — Fixed the intermittent failure where the access point came up but did not broadcast its SSID after boot, and WLAN-enabled detection under the new OpenWrt, where a radio only works if both the interface and the device are enabled. Added a '''reset WiFi to defaults''' button to recover from a bad configuration.&lt;br /&gt;
* '''eMMC compatibility''' — Internal storage is now pinned to HS200 at 52 MHz in both the bootloader and the kernel, eliminating a class of intermittent storage errors.&lt;br /&gt;
* '''Assorted fixes''' — CPU powersave setting now persists across reboot; manual fan speed survives a page refresh; the battery correctly shows as discharging while powering an external device over USB Type-C; PPPoE keepalive relaxed to &amp;lt;code&amp;gt;5 5&amp;lt;/code&amp;gt; to stop spurious drops; &amp;lt;code&amp;gt;irqbalance&amp;lt;/code&amp;gt; removed in favour of static Ethernet IRQ pinning after it was found parking both NIC interrupts on one core; missing English strings added; Alpine.js updated to 3.15.12.&lt;br /&gt;
&lt;br /&gt;
=== MCU Changes ===&lt;br /&gt;
* '''Less standby power''' — Standby current drops from about 2.6 mA to 1.1 mA, so a charged pack holds its charge for weeks rather than days when the device is off. The current monitor, accelerometer and flash now power down properly, and the fan actually stops when the main board is off.&lt;br /&gt;
* '''A more accurate battery percentage''' — The fuel gauge has been reworked end to end with temperature compensation, self-learned internal resistance and periodic re-anchoring. The reading no longer jumps (for example 40% to 80% after a firmware update), survives reboots and firmware updates, and reports true learned capacity and cycle count. Behaviour is now much closer to a phone's.&lt;br /&gt;
* '''New LED behaviour''' — MacBook-style indicator: the colour tells you the charge state and the motion tells you what the device is doing, with smooth gamma-corrected breathing while charging and a continuous red flash when the battery is low. Several false pure-red flashes at power-on and when the pack was full have been fixed.&lt;br /&gt;
* '''Raise-to-wake improved''' — Rebuilt as proper gesture detection, like a phone's. It no longer wakes by itself when the device is stood upright and left alone, and responds faster when you do pick it up.&lt;br /&gt;
* '''Stability and power-on speed''' — Fixed the random freeze after extended running and the rarer permanent lockup that could only be cleared by removing the battery. Power-on is quicker: the main board powers as soon as the button has been held 200 ms, overlapping the long-press window. Beeper timing is corrected, including the charger-plugged beep that could arrive 40–50 s late, and reset and update operations now play a short confirmation melody.&lt;br /&gt;
&lt;br /&gt;
== 2026-08-11 r7897 ==&lt;br /&gt;
&lt;br /&gt;
=== GPS ===&lt;br /&gt;
&lt;br /&gt;
* '''New GPS page''' — position on a map, accuracy, speed, heading and per-satellite signal. Off by default; enable in General Settings.&lt;br /&gt;
* '''Offline maps and track logging''' — a world map pack ships built in, regions can be downloaded, and routes can be recorded and replayed.&lt;br /&gt;
* '''GLONASS, BeiDou and Galileo''' can now be added to GPS.&lt;br /&gt;
&lt;br /&gt;
=== Cellular ===&lt;br /&gt;
&lt;br /&gt;
* '''A 5G connection that stops passing traffic now recovers on its own''', instead of looking connected until you reboot.&lt;br /&gt;
* '''Fixed a startup race that could leave cellular dead''', and cellular no longer overrides your routing priority.&lt;br /&gt;
* '''Devices with no modem fitted no longer show &amp;quot;No Service&amp;quot;.'''&lt;br /&gt;
&lt;br /&gt;
=== Network and Wi-Fi ===&lt;br /&gt;
&lt;br /&gt;
* '''Failover now works on the default setting''' — most devices had never migrated to the current routing system.&lt;br /&gt;
* '''Improved upstream Wi-Fi — more stable''' — your own network name and password are kept across a reboot and restored when you turn the relay off.&lt;br /&gt;
* '''Add-on PCIe Wi-Fi cards work straight after a flash''', with no extra reboots or manual enabling.&lt;br /&gt;
* '''Fixed per-client traffic statistics on AIC8800 Wi-Fi''', now also visible in the web UI.&lt;br /&gt;
&lt;br /&gt;
=== Phone (in development) ===&lt;br /&gt;
&lt;br /&gt;
* '''Early support for calls from the web interface''', with audio, dialer, contacts and voicemail. Off by default. ONLY support RM500U and RM500Q. EM05 pending.&lt;br /&gt;
&lt;br /&gt;
=== Battery and MCU ===&lt;br /&gt;
&lt;br /&gt;
* '''Improved battery percentage and health estimates''' — both now settle before they are shown, instead of jumping after you plug in or after a single discharge.&lt;br /&gt;
* '''The charge limit survives an MCU restart''', and LED and beeper schedules keep running while the device sleeps.&lt;br /&gt;
* '''New readings''' — internal resistance, MCU uptime and board revision.&lt;br /&gt;
&lt;br /&gt;
=== Web interface ===&lt;br /&gt;
&lt;br /&gt;
* '''Switched from the werkzeug development server to granian''', which parses HTTP in Rust — pages and files load several times faster, and static files are served without entering Python at all.&lt;br /&gt;
* '''Language and light/dark are now device-wide''', not per browser, with a reset button.&lt;br /&gt;
* '''Colour picker for display themes''', and the reboot screen now reloads itself when the device is back.&lt;br /&gt;
&lt;br /&gt;
=== Mini display ===&lt;br /&gt;
&lt;br /&gt;
* '''New GPS page''', shown only on GPS-capable modems.&lt;br /&gt;
* '''Storage page rebuilt''' — separate eMMC, NVMe and SD bars and a clearer layout.&lt;br /&gt;
* '''Smarter refresh, colour themes and live public IP''' — the clock and battery are no longer stale on wake.&lt;br /&gt;
&lt;br /&gt;
=== NAS and sharing ===&lt;br /&gt;
&lt;br /&gt;
* '''You can now mount an SMB share''', and the NFS server can actually export one.&lt;br /&gt;
* '''Fixed eMMC partitioning failures''', and NTFS drives now mount correctly.&lt;br /&gt;
&lt;br /&gt;
== 2026-08-14 r7907 ==&lt;br /&gt;
&lt;br /&gt;
* '''LXC containers''' — containers now survive a firmware upgrade; added container backup/restore, image downloads that recover from a flaky CDN, self-healing of the network bridge on start, and a Proxmox-style resizable console popup; fixed CPU/memory bars showing empty.&lt;br /&gt;
* '''GPS''' — trip odometer on the web GPS page and the mini display, and map tiles fall back to mirror servers when the main tile server is blocked.&lt;br /&gt;
* '''Web terminal''' — /terminal is now a real WebSocket console (via granian ASGI) instead of polling, with a cleaner full-screen console popup.&lt;br /&gt;
* '''Safer firmware updates''' — the web UI can no longer reboot the device mid-flash, the update screen shows a realistic 3–5 minute estimate with a restarting overlay, and power-off is available from the user menu.&lt;br /&gt;
* '''Networking fixes''' — upstream WiFi gets a boot grace period so one failed probe right after boot no longer bounces the egress; the connectivity probe now works behind transparent proxies (e.g. OpenClash); cellular interfaces dialled manually through netifd are left alone; hotspot settings survive the firmware regenerating the config.&lt;br /&gt;
* '''Smaller root filesystem''' — multimedia applications, Realtek wireless drivers and other rarely-used packages are now optional modules instead of preinstalled, more kernel modules are available to install, and the BPF traffic scheduler (&amp;lt;code&amp;gt;kmod-sched-bpf&amp;lt;/code&amp;gt;) is enabled.&lt;br /&gt;
* '''RK3576 platform fixes''' — backported upstream device-tree fixes for Photonicat 2 and added the missing CPU cache-hierarchy description.&lt;br /&gt;
* '''LED/beeper schedules''' — schedule delivery to the MCU is now verified end-to-end, degrading gracefully instead of failing silently.&lt;br /&gt;
* '''Mini display and screen''' — a proxy's fake-IP DNS answers no longer fail both LCD ping rows; auto-dim delays can be edited in seconds, minutes or hours; the live screen preview refreshes at 1 Hz and can no longer freeze; car mode shows the configured timeout instead of a made-up 10 minutes.&lt;br /&gt;
* '''Bluetooth''' — the AIC8800's Bluetooth is now built in BlueZ mode so a standard HCI adapter appears, and a new Bluetooth panel on the /dev page can diagnose the adapter and scan for nearby devices.&lt;br /&gt;
=== MCU Changes ===&lt;br /&gt;
Latest MCU firmware version: &amp;lt;code&amp;gt;RA2E1260813002&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* '''Raise-to-wake now responds in 1–2 seconds''' — confirmation uses a leaky integrator, so hand tremor no longer restarts the detection pipeline; a knock on the desk no longer fakes a pick-up.&lt;br /&gt;
* '''Car mode''' — a manual shutdown with DC power still plugged in no longer bounces straight back on.&lt;br /&gt;
* '''Battery groundwork''' — added a coulomb-meter test harness and machine-learned LFP state-of-charge work, groundwork for further battery-percentage accuracy improvements.&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:25:18 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E5%9B%BA%E4%BB%B6_Changelog</comments>
		</item>
		<item>
			<title>Photonicat 2 固件更新日志</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97&amp;diff=246&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97&amp;diff=246&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“English version: &lt;a href=&quot;/Photonicat_2_%E5%9B%BA%E4%BB%B6_Changelog&quot; title=&quot;Photonicat 2 固件 Changelog&quot;&gt;Photonicat 2 固件 Changelog&lt;/a&gt;.  ==2025-08-22== * 首个正式版本。  ==2025-09-19 r7612== * 简化多 WAN 路由，停用 &amp;lt;code&amp;gt;mwan3&amp;lt;/code&amp;gt;。 * 默认内置 Docker 相关软件包。 * 内核升级至 6.12.45。 * 合入上游 PCIe 补丁。 * 增加 USB Hub 复位时序与看门狗。 * 状态指示灯与蜂鸣器可由用户关闭。 * 提升小屏幕显示性能。 * 增加 LED、蜂鸣器与风扇控制，并加入过温保护算…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;English version: [[Photonicat 2 固件 Changelog]].&lt;br /&gt;
&lt;br /&gt;
==2025-08-22==&lt;br /&gt;
* 首个正式版本。&lt;br /&gt;
&lt;br /&gt;
==2025-09-19 r7612==&lt;br /&gt;
* 简化多 WAN 路由，停用 &amp;lt;code&amp;gt;mwan3&amp;lt;/code&amp;gt;。&lt;br /&gt;
* 默认内置 Docker 相关软件包。&lt;br /&gt;
* 内核升级至 6.12.45。&lt;br /&gt;
* 合入上游 PCIe 补丁。&lt;br /&gt;
* 增加 USB Hub 复位时序与看门狗。&lt;br /&gt;
* 状态指示灯与蜂鸣器可由用户关闭。&lt;br /&gt;
* 提升小屏幕显示性能。&lt;br /&gt;
* 增加 LED、蜂鸣器与风扇控制，并加入过温保护算法。&lt;br /&gt;
* 简化网络 WAN 接口选择：&amp;lt;code&amp;gt;auto&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;eth_only&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;cell_only&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;all_off&amp;lt;/code&amp;gt;。&lt;br /&gt;
* 新增 /update 管理界面。&lt;br /&gt;
* MCU：优化库仑计算法。&lt;br /&gt;
* MCU：修复充电指示灯偶尔不亮的问题。&lt;br /&gt;
&lt;br /&gt;
== 2025-12-12 r7618 ==&lt;br /&gt;
* 去掉不必要的网络复位，加快开机速度。&lt;br /&gt;
* 更新 OpenWrt &amp;lt;code&amp;gt;netifd&amp;lt;/code&amp;gt;，改善 NFA765 无线模块兼容性。&lt;br /&gt;
* 改进风扇控制策略与整体散热表现。&lt;br /&gt;
* 优化智能调速逻辑：&amp;lt;code&amp;gt;smart_quiet&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;smart_cool&amp;lt;/code&amp;gt;、&amp;lt;code&amp;gt;manual&amp;lt;/code&amp;gt;。&lt;br /&gt;
* 修复网络模式设为 '''仅蜂窝网络''' 时界面崩溃的问题。&lt;br /&gt;
* 修复界面不显示 4G/5G 频段信息的问题。&lt;br /&gt;
* 修复部分 5G 模块信息页面内容缺失的问题。&lt;br /&gt;
* 修复 5G 信号不显示的问题。&lt;br /&gt;
* 修复重启后 '''记住我''' 登录选项失效的问题。&lt;br /&gt;
&lt;br /&gt;
== 2026-03-06 r7660 ==&lt;br /&gt;
* '''内核与系统更新''' —— 内核升级至 6.12.74，mac80211 升级至 6.12.61，python3 升级至 3.13.9 并同步更新相关软件包（改用基于 PAM 的认证，替代已废弃的 &amp;lt;code&amp;gt;spwd&amp;lt;/code&amp;gt;），系统版本升级至 26.04，修复多个 CVE。&lt;br /&gt;
* '''支持广和通 FM350-GL 5G 模块''' —— 完整支持信号强度、温度监控、IMEI、运营商显示、服务小区信息、漫游偏好、4G/5G 网络模式与频段选择、通过 rfkill 关闭 WWAN 供电、流量统计，以及十六进制编码运营商名称的解码。&lt;br /&gt;
* '''短信可靠性''' —— 所有模块统一改用 PDU 模式，修复 FM350-GL 的串口处理、提示符检测与响应超时问题。&lt;br /&gt;
* '''网页终端''' —— 新增网页终端（&amp;lt;code&amp;gt;/terminal&amp;lt;/code&amp;gt;），支持持久 PTY 会话、全屏切换、断开/重连、JetBrains Mono 字体与移动端视口优化。&lt;br /&gt;
* '''直流供电模式与 TCP BBR v3''' —— 新增开机模式选项，适用于无电池及需要快速响应的场景（接入适配器即自动开机，无需电池）。新增 TCP BBR v3 支持，可在常规设置中配置拥塞控制算法。&lt;br /&gt;
* '''电池历史与电源事件记录''' —— 新增基于 SQLite 存储的电池历史曲线，固定电压刻度、区域填充、功率显示，以及开关机事件时间轴。持久记录电源事件，包含电压、电流、电量数据与 DC 插拔跟踪。&lt;br /&gt;
* '''空闲与低电量关机''' —— 空闲关机倒计时实时显示、低电量自动关机、WiFi 客户端空闲监测（OR 模式）、仅电池供电时自动关机选项，以及电量估算跳变 2% 的容差处理。&lt;br /&gt;
* '''常规设置与定时页面重做''' —— 新增常规设置页面，可设置语言、时区、主机名并与 LuCI 同步。定时页面改为现代化的左右分栏布局，面板更紧凑并占满宽度，车载/UPS 模式说明更清晰。&lt;br /&gt;
* '''仪表盘与顶栏改进''' —— 优先显示当前活动 WAN、公网 IPv6 检测、模块温度显示、网络图标行中的 5G/4G 标识、按状态渲染、网关下划线，以及移动端顶栏布局优化。&lt;br /&gt;
* '''性能与界面细节打磨''' —— 原生 Python ubus/uci 封装、非阻塞 IO 缓存、CPU 省电模式下关闭大核（A72）、静态资源缓存 3 个月、温度与功率曲线图、刷新后保留标签页状态、通知只用单一语言、图标改进、页脚新增 Wiki 与社区按钮、智能手机号格式化，以及更详细的固件升级进度显示。&lt;br /&gt;
&lt;br /&gt;
== 2026-06-15 r7714 ==&lt;br /&gt;
* '''内核与系统更新''' —— 内核升级至 6.12.91，修复近期若干严重安全问题。mac80211 升级至 6.18.26，修复多个 CVE。&lt;br /&gt;
* '''OpenWRT 基础系统''' —— 基础系统与 LuCI 升级至 25.12。新增 IEEE 802.11be 支持（可在 QCNCM865 与 MT7925 上启用 6GHz 信道）。&lt;br /&gt;
* '''Smart WAN（WiFi 当作 WAN）''' —— 新增 Smart WAN 模式，把板载无线变成上级 WiFi 客户端，并在以太网 → WiFi → 蜂窝之间自动故障切换。像手机一样自动重连已知的上级 WiFi，扫描设备解析更稳健，切换前会有确认对话框。被停用的 STA 射频现在会正确显示为独立的 &amp;quot;WAN (WiFi)&amp;quot; 状态。&lt;br /&gt;
* '''WiFi 7（802.11be）与 WPA3''' —— PCIe 网卡新增 WiFi 7（BE）与 WPA3-SAE 支持，正确处理 5GHz BE 与 6GHz BE 的 htmode/信道，支持 PCIe 卡型号识别，并统一了界面中的加密方式取值。&lt;br /&gt;
* '''仪表盘与顶栏改进''' —— 当前出口实时高亮（只有正在使用的 WAN 行会亮起）；显示 WiFi 信号、当前出口与网络模式；网络图标随状态变化，带网关下划线、准确的 WAN 下划线、被禁用链路的红叉与提示文字。新增公网 IPv6 / 公网 IP 别名。&lt;br /&gt;
* '''电池与充电控制''' —— 在设备控制页面新增电池充电限制滑块（80–100%），以充电限制作为唯一数据源，修正电池图标显示真实电量百分比，并在从未设置过时稳妥地默认为 100%。&lt;br /&gt;
** '''硬件要求：'''充电限制功能仅 '''A3 版本 PCB''' 的机器支持，更早的 PCB 版本不支持该功能。&lt;br /&gt;
* '''小屏幕可视化编辑器''' —— 新增 Figma 风格的屏幕布局可视化编辑器，与 JSON 视图合并为同一个&amp;quot;编辑器&amp;quot;标签页。支持增删页面、单个元素位置重置、居中与吸附工具、恢复默认布局、JSON 实时差异对比、标签/数据键画布切换，并修正了编辑器坐标到设备显示区域的映射。修复设备端 graph 元素类型的渲染问题。&lt;br /&gt;
* '''小屏幕自定义数据源''' —— 编辑器中新增自定义指标（command / uci / env / json_file / HTTPS），附带设备端示例、一键保存并重启、刷新时实时预览取值、重复键名警告、更清晰的 data_key 说明、通过官方 Photonicat 行情 API 提供的黄金/AAPL 示例，以及无闪烁的实时预览。&lt;br /&gt;
* '''设备控制与网络模式''' —— 重新排列网络模式并使用组合式 WAN 图标；把充电限制设置统一收纳到设备控制页面。&lt;br /&gt;
* '''FM350-GL 漫游''' —— 通过 &amp;lt;code&amp;gt;AT+COPS=0&amp;lt;/code&amp;gt; 启用自动漫游，并隐藏了实际无法生效的&amp;quot;禁止漫游&amp;quot;选项；修复轮询刷新会覆盖频段选择的问题；移除会导致 LAN/WAN 失效的 USB 3.12 10Gbps 选项。&lt;br /&gt;
* '''安全加固''' —— 为 WebSocket 端点增加 &amp;lt;code&amp;gt;socketio_auth_required&amp;lt;/code&amp;gt; 装饰器，为 &amp;lt;code&amp;gt;/switch_locale&amp;lt;/code&amp;gt; 与低电量关机相关路由增加鉴权，并移除未使用或权限过高的 API 端点。&lt;br /&gt;
* '''性能''' —— 降低空闲 CPU 占用（默认只写文件日志、减少 select 唤醒与 uci 进程调用），缓存 &amp;lt;code&amp;gt;data_stats.json&amp;lt;/code&amp;gt; 并让仪表盘缓存与屏幕轮询对齐，去掉一个空转的屏幕线程，改为直接从 sysfs 读取 WWAN rfkill 状态。&lt;br /&gt;
* '''小屏幕性能''' —— 显示循环 CPU 占用大幅下降（静态页面约 3.2% → 约 1.4%，降低约 55%）：通过数据版本门控跳过画面无变化时的重绘与 SPI 传输，传输前先做字节比较，并把各类轮询频率减半。字体（包括约 37MB 的中日韩字体集）改为只解析一次并缓存预加载，网络信息查询（无线 SSID、iwinfo 客户端枚举、公网 IP）也做了缓存，进程调用从约 3.8 次/秒降到约 1.7 次/秒。&lt;br /&gt;
&lt;br /&gt;
== 2026-06-16 r7715 ==&lt;br /&gt;
* '''小屏幕 SPI 时钟可靠性''' —— 将屏幕 SPI 时钟从 120 MHz 降到 50 MHz，消除高频率下的画面异常或显示问题；保守的时序只带来可忽略的刷新延迟，换来稳定无杂点的画面。&lt;br /&gt;
* '''序列号校验修复''' —— 有效的设备序列号在设备上被错误显示为 &amp;lt;code&amp;gt;(invalid)&amp;lt;/code&amp;gt;，原因是签名校验依赖 &amp;lt;code&amp;gt;cryptography&amp;lt;/code&amp;gt; 模块，而目标 OpenWrt 固件中并未安装该模块。&lt;br /&gt;
&lt;br /&gt;
== 2026-06-23 r7720 ==&lt;br /&gt;
* '''OpenWRT 基础系统''' —— 路由与电话相关软件包更新至 OpenWRT 25.12 分支。默认防火墙切换为 fw4。&lt;br /&gt;
&lt;br /&gt;
== 2026-07-31 r7854 ==&lt;br /&gt;
* '''开机时间缩短 59% —— 17.4 秒 → 7.2 秒''' —— 完整重启一次现在只需 16.6 秒，之前是 28.0 秒。最大的单一原因是一条多余的 &amp;lt;code&amp;gt;fstab&amp;lt;/code&amp;gt; 条目，导致每次开机所有服务都要等待一块根本没有装的硬盘。此外：根文件系统压缩从 &amp;lt;code&amp;gt;xz&amp;lt;/code&amp;gt; 改为 &amp;lt;code&amp;gt;zstd&amp;lt;/code&amp;gt;，squashfs 重新调整为 256 KiB 块并启用直接读取，U-Boot 不再扫描 USB 与网络寻找启动介质，开机 Logo 改为一次 SPI 传输完成（此前是 110,080 次单字节传输），failsafe 等待窗口从 1 秒缩短到 300 毫秒。&lt;br /&gt;
* '''可选服务出厂不再自启''' —— Docker、Samba、collectd、aria2、nlbwmon、watchcat、frp、filebrowser、rclone、adbyby、OpenAppFilter、Tailscale 与 ZeroTier 仍然预装，但不再开机自启（运行中的服务从 73 个降到 59 个）；需要时在 '''系统 → 启动项''' 中一键启用即可。&amp;lt;code&amp;gt;vnstat&amp;lt;/code&amp;gt; 与网页终端有意保持运行。&lt;br /&gt;
* '''WAN 优先级表取代 Smart WAN 模式''' —— r7714 的 '''Smart WAN''' 开关改为基于路由 metric 的'''优先级表'''，按固定槽位顺序列出所有已启用的上行链路 —— 以太网、上级 WiFi、PPPoE 与蜂窝 —— 并逐级向下切换。它完全取代了 &amp;lt;code&amp;gt;mwan3&amp;lt;/code&amp;gt;。有线 WAN 现在在链路断开时立即切换，而不用等探测超时；PPPoE 也能被正确识别为当前出口。&lt;br /&gt;
* '''上级 WiFi（WiFi 当作 WAN）''' —— 同一 SSID 同时广播 2.4G 与 5G 时自动接入信号更强的频段；已连接状态下也会漫游到重新进入范围的已保存网络；漫游离开后能更快重新接入已知网络；实时显示关联与待机状态并带有各射频的图标；附近没有已保存网络时降低扫描频率。&lt;br /&gt;
* '''全新 /dev 诊断页面''' —— 由内置 G-sensor 驱动的实时 3D 设备模型，并提供引导式姿态校准；显示各段电压的 2S2P 18650 电池组示意图；MCU 电量计日志；以及模块拨号日志查看器。还有内置蜂鸣器的音调测试与 MIDI 播放。&lt;br /&gt;
* '''广和通 FM350-GL 5G 模块''' —— 拨号程序由 Python 重写为原生 C 实现，可靠性更高。现在会遵循网页界面中设置的网络模式偏好，需要时锁定 4G 并在 5G 可用时自动回到 5G，5G 拨号失败会回退到 LTE，并监控数据面以发现&amp;quot;连接已建立但不通流量&amp;quot;的情况。修复了仅支持 4G 的 SIM 卡导致模块无限重启上电的问题，以及自动模式被误报为 5G 的问题。现在会显示模块固件版本，并提供固件更新对话框。&lt;br /&gt;
* '''模块拨号日志''' —— 最近 16 MB 的拨号活动会保存在内存中并可在网页界面查看，便于事后排查间歇性的连接问题。&lt;br /&gt;
* '''电池充电限制''' —— 1% 精度的滑块，带防抖保存并同步给 MCU，同时实时回读，界面始终反映硬件实际执行的限制值。该限制现在在 MCU 重启后依然保留。&lt;br /&gt;
** '''硬件要求：'''充电限制功能仅 '''A3 版本 PCB''' 的机器支持，更早的 PCB 版本不支持该功能。&lt;br /&gt;
* '''固件与 MCU 更新流程''' —— 版本下拉框中可查看各版本更新说明并支持降级；MCU 与固件更新不能再同时进行；当已安装的 MCU 版本比服务器上的更新时不再提示更新；OTA 默认使用 &amp;lt;code&amp;gt;sysupgrade -c -p&amp;lt;/code&amp;gt;，各个参数以勾选框形式开放。&lt;br /&gt;
* '''PhotonDNS''' —— 全新的高性能 DNS 转发器，使用 Rust 编写：分片 LRU 缓存、过期仍可用（serve-stale）、预取、缓存持久化，支持 UDP/TCP/DoT/DoH 上游与并发竞速故障切换，并对每个上游做健康跟踪，另附国内域名列表与广告列表辅助功能。自带 LuCI 页面，但'''默认关闭'''。&lt;br /&gt;
* '''安全加固''' —— 强制启用 CSRF 校验，LuCI 密码不再泄露到页面中，所有 API 路由都需要鉴权，状态变更只允许 POST，开发者端点受到限制，修复了一处开放重定向，'''记住我''' 改用基于 SQLite 的正规令牌实现。&lt;br /&gt;
* '''访客门户（Captive Portal）''' —— 一键接受、无需 DNS 也能打开的门户地址、带品牌样式的错误页、启用/停用操作串行化（快速反复切换不会留下半配置状态），失败会明确提示而不是静默忽略。&lt;br /&gt;
* '''更低空闲 CPU 与更少闪存写入''' —— 只有打开模块页面时才执行较重的 AT 查询，使用统计批量写入闪存并带保留期与索引，PMU 设置改为每 60 秒轮询一次而非持续轮询，公网 IP 探测采用退避策略，浏览器标签页隐藏时完全停止轮询。&lt;br /&gt;
* '''小屏幕''' —— 全新的猫咪苏醒开机动画。改为按页面设置刷新率（时钟与 CPU 页面 2 Hz，ping 时 1 Hz），不再是统一固定刷新率。新增每核心 CPU 条、数值内嵌的内存条、各磁盘占用条与滚动的 SSID 跑马灯。iStat 风格的进度条采用超采样抗锯齿，文字更柔和。新增电池剩余时间栏位、WAN 模式行、可配置的公网 IP 查询、亮度为 0 时真正的物理全黑背光，以及上级链路未关联时进入待机。&lt;br /&gt;
* '''WiFi 修复''' —— 修复开机后 AP 已启动却不广播 SSID 的间歇性问题，以及新版 OpenWrt 下的 WLAN 启用状态判断（射频需要接口与设备同时启用才会工作）。新增 '''恢复 WiFi 默认设置''' 按钮，便于从错误配置中恢复。&lt;br /&gt;
* '''eMMC 兼容性''' —— 内部存储在 bootloader 与内核中都固定为 HS200 @ 52 MHz，消除了一类间歇性存储错误。&lt;br /&gt;
* '''其他修复''' —— CPU 省电设置重启后保持生效；手动风扇转速在页面刷新后保留；通过 USB Type-C 为外部设备供电时电池能正确显示为放电状态；PPPoE keepalive 放宽为 &amp;lt;code&amp;gt;5 5&amp;lt;/code&amp;gt;，避免误断线；移除 &amp;lt;code&amp;gt;irqbalance&amp;lt;/code&amp;gt;，改为静态绑定以太网中断（此前发现它会把两个网口中断都放到同一个核心上）；补齐缺失的英文字符串；Alpine.js 升级至 3.15.12。&lt;br /&gt;
&lt;br /&gt;
=== MCU 更新 ===&lt;br /&gt;
* '''待机功耗更低''' —— 待机电流从约 2.6 mA 降到 1.1 mA，关机状态下充满电的电池组可以保持数周而不是几天。电流监测芯片、加速度计与闪存现在会正确断电，主板关闭时风扇也会真正停转。&lt;br /&gt;
* '''更准确的电量百分比''' —— 电量计从头到尾重做，加入温度补偿、内阻自学习与周期性重新锚定。读数不再跳变（例如固件更新后从 40% 跳到 80%），能在重启与固件更新后保持，并可上报学习到的真实容量与循环次数。整体表现已经非常接近手机。&lt;br /&gt;
* '''全新指示灯行为''' —— MacBook 式指示灯：颜色表示充电状态，动态表示设备状态，充电时为平滑的伽马校正呼吸效果，低电量时持续红色闪烁。修复了开机时以及电池充满时出现的多次误报纯红闪烁。&lt;br /&gt;
* '''抬起唤醒改进''' —— 重写为真正的手势识别，和手机一样。设备竖立静置时不会再自行唤醒，而真正拿起时响应更快。&lt;br /&gt;
* '''稳定性与开机速度''' —— 修复长时间运行后的随机死机，以及较少见的、只能通过取出电池才能恢复的永久性死锁。开机更快：按键按住 200 毫秒后主板即上电，与长按判定窗口重叠进行。修正蜂鸣器时序，包括插入充电器后可能延迟 40–50 秒才响的提示音；复位与更新操作现在会播放一小段确认旋律。&lt;br /&gt;
&lt;br /&gt;
== 2026-08-11 r7897 ==&lt;br /&gt;
&lt;br /&gt;
=== GPS ===&lt;br /&gt;
&lt;br /&gt;
* '''新增 GPS 页面''' —— 地图定位、精度、速度、航向和各卫星信号。默认关闭,可在&amp;quot;通用设置&amp;quot;中开启。&lt;br /&gt;
* '''离线地图与轨迹记录''' —— 内置世界地图包,可下载区域地图,并可记录和回放行驶轨迹。&lt;br /&gt;
* '''可在 GPS 之外启用 GLONASS、北斗和伽利略。'''&lt;br /&gt;
&lt;br /&gt;
=== 蜂窝网络 ===&lt;br /&gt;
&lt;br /&gt;
* '''5G 连接中断后可自行恢复''',不再出现显示已连接、实际不通、必须重启的情况。&lt;br /&gt;
* '''修复可能导致蜂窝网络完全不通的启动时序问题''',且不再覆盖您的路由优先级。&lt;br /&gt;
* '''未安装模块的设备不再显示&amp;quot;无服务&amp;quot;。'''&lt;br /&gt;
&lt;br /&gt;
=== 网络与 WiFi ===&lt;br /&gt;
&lt;br /&gt;
* '''默认设置下故障切换现在真正生效''' —— 此前大部分设备从未迁移到当前的路由机制。&lt;br /&gt;
* '''上游 WiFi 功能改进,更加稳定''' —— 重启后仍保留您自己的网络名称和密码,关闭中继后也会自动恢复。&lt;br /&gt;
* '''刷机后外接 PCIe WiFi 网卡即可使用''',无需额外重启或手动开启。&lt;br /&gt;
* '''修复 AIC8800 WiFi 的单客户端流量统计''',并可在网页界面查看。&lt;br /&gt;
&lt;br /&gt;
=== 电话功能（开发中） ===&lt;br /&gt;
&lt;br /&gt;
* '''初步支持在网页界面拨打和接听电话''',包含通话音频、拨号盘、联系人和语音信箱。默认关闭。仅支持 RM500U 和 RM500Q,EM05 待支持。&lt;br /&gt;
&lt;br /&gt;
=== 电池与 MCU ===&lt;br /&gt;
&lt;br /&gt;
* '''电量百分比与健康度估算改进''' —— 读数稳定后才显示,不再在插电后或首次放电后跳变。&lt;br /&gt;
* '''充电上限在 MCU 重启后保留''',休眠期间 LED 与蜂鸣器定时计划继续运行。&lt;br /&gt;
* '''新增读数''' —— 电池内阻、MCU 运行时长和主板版本。&lt;br /&gt;
&lt;br /&gt;
=== 网页界面 ===&lt;br /&gt;
&lt;br /&gt;
* '''网页服务器由 werkzeug 开发服务器改为 granian''',其 HTTP 解析由 Rust 实现 —— 页面和文件加载速度提升数倍,静态文件无需进入 Python 即可直接返回。&lt;br /&gt;
* '''语言与浅色/深色改为设备级设置''',不再随浏览器变化,并新增恢复默认按钮。&lt;br /&gt;
* '''显示屏主题新增取色器''',重启页面在设备恢复后自动刷新。&lt;br /&gt;
&lt;br /&gt;
=== 迷你显示屏 ===&lt;br /&gt;
&lt;br /&gt;
* '''新增 GPS 页面''',仅在支持 GPS 的模块上显示。&lt;br /&gt;
* '''存储页面重新设计''' —— eMMC、NVMe 和 SD 各自独立的进度条,布局更清晰。&lt;br /&gt;
* '''刷新更智能,新增配色主题与公网 IP 实时跟踪''',唤醒后时钟和电量不再是旧值。&lt;br /&gt;
&lt;br /&gt;
=== NAS 与共享 ===&lt;br /&gt;
&lt;br /&gt;
* '''现在可以挂载 SMB 共享''',NFS 服务器也能真正导出共享。&lt;br /&gt;
* '''修复 eMMC 分区失败问题''',NTFS 磁盘现在也能正常挂载。&lt;br /&gt;
&lt;br /&gt;
== 2026-08-17 r7908 ==&lt;br /&gt;
&lt;br /&gt;
* '''LXC 容器''' —— 容器现在可以在固件升级后保留；新增容器备份/恢复，下载镜像时可从不稳定的 CDN 自动恢复，容器启动时自动修复网络桥接，并提供 Proxmox 风格、可调整大小的控制台弹窗；修复 CPU/内存占用条一直显示为空的问题。&lt;br /&gt;
* '''GPS''' —— 网页 GPS 页面与迷你显示屏新增行程里程表；主地图瓦片服务器被屏蔽时自动切换到镜像服务器。&lt;br /&gt;
* '''网页终端''' —— /terminal 改为基于 granian ASGI 的真正 WebSocket 控制台，不再使用轮询，控制台弹窗界面也更简洁。&lt;br /&gt;
* '''更安全的固件更新''' —— 网页界面不会再在刷写过程中重启设备；更新页面给出更真实的 3–5 分钟预估并显示重启中遮罩；用户菜单中新增关机选项。&lt;br /&gt;
* '''网络修复''' —— 上级 WiFi 增加开机宽限期，开机后第一次探测失败不再导致出口切换；连通性探测在透明代理（如 OpenClash）环境下也能正常工作；不再干预用户通过 netifd 手动拨号的蜂窝接口；热点设置在固件重新生成配置后依然保留。&lt;br /&gt;
* '''更小的根文件系统''' —— 多媒体应用、Realtek 无线驱动等不常用软件包改为可选模块，不再预装；提供更多可安装的内核模块；默认启用 BPF 流量调度器（&amp;lt;code&amp;gt;kmod-sched-bpf&amp;lt;/code&amp;gt;）。&lt;br /&gt;
* '''RK3576 平台修复''' —— 合入上游针对 Photonicat 2 的设备树修复，并补上缺失的 CPU 缓存层级描述。&lt;br /&gt;
* '''LED/蜂鸣器定时计划''' —— 定时计划下发到 MCU 现在有端到端校验，失败时逐级降级而不是静默失败。&lt;br /&gt;
* '''迷你显示屏与屏幕设置''' —— 代理的 fake-IP DNS 应答不再导致 LCD 两行 ping 同时失败；自动熄屏延时可按秒、分钟或小时设置；屏幕实时预览以 1 Hz 刷新且不再卡死；车载模式显示实际配置的超时时间，而不是虚构的 10 分钟。&lt;br /&gt;
* '''蓝牙''' —— AIC8800 的蓝牙现在以 BlueZ 模式构建，系统中会出现标准 HCI 适配器；/dev 页面新增蓝牙面板，可诊断适配器并扫描附近设备。&lt;br /&gt;
&lt;br /&gt;
=== MCU 更新 ===&lt;br /&gt;
最新 MCU 固件版本：&amp;lt;code&amp;gt;RA2E1260813002&amp;lt;/code&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
* '''抬起唤醒响应缩短到 1–2 秒''' —— 确认逻辑改用漏积分器，手部抖动不再重置检测流程；敲桌子也不会再被误判为拿起。&lt;br /&gt;
* '''车载模式''' —— DC 电源仍插着时手动关机，设备不会再自动重新开机。&lt;br /&gt;
* '''电池基础工作''' —— 新增库仑计测试工具与基于机器学习的磷酸铁锂（LFP）电量估算研究，为进一步提升电量百分比精度打基础。&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:24:45 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97</comments>
		</item>
		<item>
			<title>Photoincat 2 第三方固件更新</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photoincat_2_%E7%AC%AC%E4%B8%89%E6%96%B9%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0&amp;diff=245&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photoincat_2_%E7%AC%AC%E4%B8%89%E6%96%B9%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0&amp;diff=245&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“==光影猫第三方固件== ==photonicat 2 == *Lean大QWRT：https://github.com/coolsnowwolf/lede/releases/tag/20251001 *immortalwrt：尽请期待  ==photonicat 1 == *Lean编译QWRT：https://github.com/coolsnowwolf/lede/releases/tag/20251001 *ZagLu编译immortalwrt：https://pcat.qsim.top/zagwrt/immortalwrt/releases/24.10.2/targets/rockchip/armv8/   ===注：使用第三方的固件或插件，我们不对版权问题或软件兼容承担任何责任，不…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==光影猫第三方固件==&lt;br /&gt;
==photonicat 2 ==&lt;br /&gt;
*Lean大QWRT：https://github.com/coolsnowwolf/lede/releases/tag/20251001&lt;br /&gt;
*immortalwrt：尽请期待&lt;br /&gt;
&lt;br /&gt;
==photonicat 1 ==&lt;br /&gt;
*Lean编译QWRT：https://github.com/coolsnowwolf/lede/releases/tag/20251001&lt;br /&gt;
*ZagLu编译immortalwrt：https://pcat.qsim.top/zagwrt/immortalwrt/releases/24.10.2/targets/rockchip/armv8/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===注：使用第三方的固件或插件，我们不对版权问题或软件兼容承担任何责任，不同固件之间更新需要用USB线进行烧录,参见：[[Photonicat 2 固件USB线刷更新教程]]===&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:24:15 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photoincat_2_%E7%AC%AC%E4%B8%89%E6%96%B9%E5%9B%BA%E4%BB%B6%E6%9B%B4%E6%96%B0</comments>
		</item>
		<item>
			<title>Photonicat 2 MCU 手动更新</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_MCU_%E6%89%8B%E5%8A%A8%E6%9B%B4%E6%96%B0&amp;diff=244&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_MCU_%E6%89%8B%E5%8A%A8%E6%9B%B4%E6%96%B0&amp;diff=244&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“= 获取pcat-pmu-updater =  若系统中没有安装 pcat-pmu-updater，下载MCU更新用程序： &amp;lt;pre&amp;gt; wget http://dl.photonicat.com/firmware/pcat2_mcu/pcat-pmu-updater-bin-arm64.tar.gz &amp;lt;/pre&amp;gt;  解压： &amp;lt;pre&amp;gt; tar -xf pcat-pmu-updater-bin-arm64.tar.gz cd pcat-pmu-updater &amp;lt;/pre&amp;gt;  = 获取最新MCU固件：= &amp;lt;pre&amp;gt; wget https://dl.photonicat.com/firmware/pcat2_mcu/ota.bin &amp;lt;/pre&amp;gt;  = 更新MCU固件：= &amp;lt;pre&amp;gt; sudo ./pcat-pmu-updater -F ota.bin &amp;lt;/pre&amp;gt;  更新完…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= 获取pcat-pmu-updater =&lt;br /&gt;
&lt;br /&gt;
若系统中没有安装 pcat-pmu-updater，下载MCU更新用程序：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget http://dl.photonicat.com/firmware/pcat2_mcu/pcat-pmu-updater-bin-arm64.tar.gz&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
解压：&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
tar -xf pcat-pmu-updater-bin-arm64.tar.gz&lt;br /&gt;
cd pcat-pmu-updater&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= 获取最新MCU固件：=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget https://dl.photonicat.com/firmware/pcat2_mcu/ota.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= 更新MCU固件：=&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo ./pcat-pmu-updater -F ota.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
更新完成后会自动关机完成MCU固件更新。&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:23:31 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_MCU_%E6%89%8B%E5%8A%A8%E6%9B%B4%E6%96%B0</comments>
		</item>
		<item>
			<title>Photonicat 2 OTA更新</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_OTA%E6%9B%B4%E6%96%B0&amp;diff=243&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_OTA%E6%9B%B4%E6%96%B0&amp;diff=243&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“Photonicat 2 提供了Web的OTA更新功能，支持web更新固件/MCU程序, http://172.16.0.1/update 中查看固件以及更新。”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;Photonicat 2 提供了Web的OTA更新功能，支持web更新固件/MCU程序, http://172.16.0.1/update 中查看固件以及更新。&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:22:51 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_OTA%E6%9B%B4%E6%96%B0</comments>
		</item>
		<item>
			<title>Photonicat 2 小屏幕自定义</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%B0%8F%E5%B1%8F%E5%B9%95%E8%87%AA%E5%AE%9A%E4%B9%89&amp;diff=242&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E5%B0%8F%E5%B1%8F%E5%B9%95%E8%87%AA%E5%AE%9A%E4%B9%89&amp;diff=242&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“{| class=&amp;quot;wikitable&amp;quot; |- ! 适用 / Applies to | Photonicat 2（内置 LCD 小屏）, pcat-manager-web 2026-06 及以后版本 / Photonicat 2 (built-in LCD), pcat-manager-web builds from 2026-06 onward |}  Photonicat 2 的&amp;#039;&amp;#039;&amp;#039;内置小屏幕&amp;#039;&amp;#039;&amp;#039;不只是状态显示器——通过管理界面的 &amp;#039;&amp;#039;&amp;#039;/screen&amp;#039;&amp;#039;&amp;#039; 页面可以调整亮度息屏策略、&amp;#039;&amp;#039;&amp;#039;可视化编辑屏幕布局&amp;#039;&amp;#039;&amp;#039;，甚至接入&amp;#039;&amp;#039;&amp;#039;自定义数据源&amp;#039;&amp;#039;&amp;#039;（HTTP 接口 / Shell 命令 / UCI 配置值…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 适用 / Applies to&lt;br /&gt;
| Photonicat 2（内置 LCD 小屏）, pcat-manager-web 2026-06 及以后版本 / Photonicat 2 (built-in LCD), pcat-manager-web builds from 2026-06 onward&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Photonicat 2 的'''内置小屏幕'''不只是状态显示器——通过管理界面的 '''/screen''' 页面可以调整亮度息屏策略、'''可视化编辑屏幕布局'''，甚至接入'''自定义数据源'''（HTTP 接口 / Shell 命令 / UCI 配置值），把任何你关心的数据显示到屏幕上（公网 IP、BTC 价格、家里的温度传感器……）。&lt;br /&gt;
&lt;br /&gt;
The photonicat 2's '''built-in mini screen''' is more than a status display — the manager UI's '''/screen''' page lets you tune brightness/dimming, '''visually edit the screen layout''', and attach '''custom data sources''' (HTTP endpoints / shell commands / UCI values) to render any data you care about (public IP, BTC price, a home temperature sensor…).&lt;br /&gt;
&lt;br /&gt;
== 中文说明 ==&lt;br /&gt;
&lt;br /&gt;
页面地址：管理界面 → '''小屏幕（/screen）'''，共三个标签页。&lt;br /&gt;
&lt;br /&gt;
=== 1. 屏幕设置 ===&lt;br /&gt;
* '''最大 / 最小亮度'''：设定屏幕亮度范围。&lt;br /&gt;
* '''自动降低亮度时间'''：电池供电与充电两种状态'''分别'''设定息屏/降亮延迟——插电时可以常亮，用电池时尽快变暗省电。&lt;br /&gt;
* '''短信显示开关及条数限制'''：控制屏幕上是否显示短信以及最多显示多少条（隐私考虑可关闭）。&lt;br /&gt;
* '''实时预览'''：页面内嵌当前屏幕画面的实时预览（后端接口 &amp;lt;code&amp;gt;/api/v1/screen/frame.png&amp;lt;/code&amp;gt;），不用低头看设备就能确认显示效果。&lt;br /&gt;
&lt;br /&gt;
=== 2. 屏幕编辑器 ===&lt;br /&gt;
可视化布局编辑器，在网页上的'''画布'''中直接编辑屏幕内容：&lt;br /&gt;
* 添加/移动/删除显示元素，绑定'''数据键（data key）'''——既可用内置数据（电量、信号、速率、公网 IP 等），也可用下述自定义数据源产生的键。&lt;br /&gt;
* 编辑结果保存到 &amp;lt;code&amp;gt;user_config&amp;lt;/code&amp;gt;，Web 后端与屏幕守护进程（Go 程序）读取'''同一份配置'''，保存后屏幕立即生效。&lt;br /&gt;
* 恢复默认：默认布局可随时通过 &amp;lt;code&amp;gt;/api/v1/screen/default_config.json&amp;lt;/code&amp;gt; 找回，改坏了不用怕。&lt;br /&gt;
&lt;br /&gt;
=== 3. 自定义数据源（custom_metrics） ===&lt;br /&gt;
编辑器下方的'''数据源'''区域可添加三种类型的数据源，产生的 data key 供屏幕元素引用：&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 类型 !! 说明 !! 典型用途&lt;br /&gt;
|-&lt;br /&gt;
| '''HTTP/HTTPS 轮询''' || 周期性请求一个 URL，按配置的解析器提取数值 || 公网 IP、加密货币价格（BTC 示例用 Photonicat 官方 API）、天气、家庭传感器接口&lt;br /&gt;
|-&lt;br /&gt;
| '''命令 Command''' || 周期性执行一条 shell 命令，取其输出 || CPU 温度、磁盘剩余、连接数、任意脚本&lt;br /&gt;
|-&lt;br /&gt;
| '''UCI 值''' || 读取一项 OpenWrt UCI 配置 || 显示当前 SSID、APN 等配置项&lt;br /&gt;
|}&lt;br /&gt;
* 每个数据源有'''启用开关'''、独立的采集周期与解析设置。&lt;br /&gt;
* '''状态与测试'''：每个源显示最近一次取值/错误信息与成功次数，并有&amp;quot;立即执行&amp;quot;按钮（&amp;lt;code&amp;gt;/api/v1/screen/custom_metrics/&amp;amp;lt;源名&amp;amp;gt;/execute&amp;lt;/code&amp;gt;）方便调试，不用等下一个周期。&lt;br /&gt;
&lt;br /&gt;
=== 4. Public IP 标签页 ===&lt;br /&gt;
自定义公网 IP 查询（网页与 LCD 共用）：多个 URL 按顺序尝试、每源可配 &amp;lt;code&amp;gt;json:字段&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;regex:正则&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;line:行号&amp;lt;/code&amp;gt; 解析器、自定义 User-Agent，返回值自动校验为合法 IPv4/IPv6。photonicat.com 被墙时换成任意可达的 IP 查询源即可恢复屏幕公网 IP 显示。页面内有完整示例。&lt;br /&gt;
&lt;br /&gt;
== English ==&lt;br /&gt;
&lt;br /&gt;
Location: manager UI → '''Mini Screen (/screen)''', three tabs.&lt;br /&gt;
&lt;br /&gt;
=== 1. Screen settings ===&lt;br /&gt;
* '''Max / min brightness''' range.&lt;br /&gt;
* '''Auto-dim delays''' set '''separately''' for on-battery and on-charger — stay bright when plugged in, dim fast on battery.&lt;br /&gt;
* '''SMS display toggle and count limit''' — hide messages from the screen entirely for privacy, or cap how many show.&lt;br /&gt;
* '''Live preview''' embedded in the page (backed by &amp;lt;code&amp;gt;/api/v1/screen/frame.png&amp;lt;/code&amp;gt;) so you can verify the layout without looking at the device.&lt;br /&gt;
&lt;br /&gt;
=== 2. Screen editor ===&lt;br /&gt;
A visual canvas editor for the screen layout:&lt;br /&gt;
* Add/move/remove display elements and bind them to '''data keys''' — built-ins (battery, signal, throughput, public IP…) or keys produced by the custom data sources below.&lt;br /&gt;
* Layouts persist to &amp;lt;code&amp;gt;user_config&amp;lt;/code&amp;gt;, read by both the web backend and the Go screen daemon — one config, applied immediately on save.&lt;br /&gt;
* The factory layout is always recoverable via &amp;lt;code&amp;gt;/api/v1/screen/default_config.json&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== 3. Custom data sources (custom_metrics) ===&lt;br /&gt;
Three source types feed data keys for screen elements:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Type !! What it does !! Typical uses&lt;br /&gt;
|-&lt;br /&gt;
| '''HTTP/HTTPS poll''' || Periodically fetch a URL and extract a value with a configured parser || public IP, crypto prices (the BTC example uses the official Photonicat API), weather, home sensor endpoints&lt;br /&gt;
|-&lt;br /&gt;
| '''Command''' || Periodically run a shell command and take its output || CPU temperature, disk free, connection counts, any script&lt;br /&gt;
|-&lt;br /&gt;
| '''UCI value''' || Read an OpenWrt UCI config value || current SSID, APN, any config item&lt;br /&gt;
|}&lt;br /&gt;
* Each source has an '''enable toggle''', its own poll interval and parser settings.&lt;br /&gt;
* '''Status &amp;amp; testing''': per-source last value/error and success count, plus an execute-now button (&amp;lt;code&amp;gt;/api/v1/screen/custom_metrics/&amp;amp;lt;name&amp;amp;gt;/execute&amp;lt;/code&amp;gt;) for debugging without waiting a cycle.&lt;br /&gt;
&lt;br /&gt;
=== 4. Public IP tab ===&lt;br /&gt;
Configurable public-IP lookup shared by the web UI and the LCD: ordered URLs, per-source &amp;lt;code&amp;gt;json:field&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;regex:pattern&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;line:N&amp;lt;/code&amp;gt; parsers, custom User-Agent, responses validated as real IPv4/IPv6. If photonicat.com is blocked in your region, point it at any reachable IP echo service and the LCD shows your public IP again. A worked example is embedded in the page.&lt;br /&gt;
&lt;br /&gt;
[[Photonicat 2 管理界面新功能 (2026)]] ｜ [[Photonicat 2 开发者 API]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:15:44 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E5%B0%8F%E5%B1%8F%E5%B9%95%E8%87%AA%E5%AE%9A%E4%B9%89</comments>
		</item>
		<item>
			<title>Photonicat 2 提示音说明</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E6%8F%90%E7%A4%BA%E9%9F%B3%E8%AF%B4%E6%98%8E&amp;diff=241&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E6%8F%90%E7%A4%BA%E9%9F%B3%E8%AF%B4%E6%98%8E&amp;diff=241&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“&amp;#039;&amp;#039;&amp;#039;光影猫2&amp;#039;&amp;#039;&amp;#039; 用一颗蜂鸣器提示工作状态。本页列出全部提示音的音高、时长与触发条件，并可直接在线试听。  指示灯说明见 &lt;a href=&quot;/Photonicat_2_LED_%E6%8C%87%E7%A4%BA%E7%81%AF&quot; title=&quot;Photonicat 2 LED 指示灯&quot;&gt;Photonicat 2 LED 指示灯&lt;/a&gt;。English: &lt;a href=&quot;/index.php?title=Photonicat_2_Sound_Guide&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Photonicat 2 Sound Guide（页面不存在）&quot;&gt;Photonicat 2 Sound Guide&lt;/a&gt;。  蜂鸣器可通过上位机协议关闭（与指示灯共用一个开关设置，可分别控制声音与灯光）。关闭后所有提示音均不发声。  ==速查==  {| class=&amp;quot;wikitable&amp;quot; ! 提示音 !! 听感 !! 含义…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''光影猫2''' 用一颗蜂鸣器提示工作状态。本页列出全部提示音的音高、时长与触发条件，并可直接在线试听。&lt;br /&gt;
&lt;br /&gt;
指示灯说明见 [[Photonicat 2 LED 指示灯]]。English: [[Photonicat 2 Sound Guide]]。&lt;br /&gt;
&lt;br /&gt;
蜂鸣器可通过上位机协议关闭（与指示灯共用一个开关设置，可分别控制声音与灯光）。关闭后所有提示音均不发声。&lt;br /&gt;
&lt;br /&gt;
==速查==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 提示音 !! 听感 !! 含义&lt;br /&gt;
|-&lt;br /&gt;
| 🔔 两声短促上行 || 嘀-嘀 || 开机&lt;br /&gt;
|-&lt;br /&gt;
| 🔕 三声下行 || 嘀-嘟-哆 || 关机&lt;br /&gt;
|-&lt;br /&gt;
| 🔌 两声上行 || 嘀-嘀（低起） || 插入充电器&lt;br /&gt;
|-&lt;br /&gt;
| ⚡ 明亮三连音 || 嘀-嘀-嘀（上行） || 正在给外接设备供电&lt;br /&gt;
|-&lt;br /&gt;
| 🔊 单声短促 || 嘀 || 充电电流达到标准&lt;br /&gt;
|-&lt;br /&gt;
| 🚨 四组高低交替 || 嘀-嘟 ×4 || 温度过高，已关闭主机&lt;br /&gt;
|-&lt;br /&gt;
| 🛠 高低交替两轮 || 嘟-嘀 ×2 || 进入固件烧录模式&lt;br /&gt;
|-&lt;br /&gt;
| ♻ 八声高低交替 || 长串高低音 || 进入恢复出厂设置模式&lt;br /&gt;
|-&lt;br /&gt;
| 🎵 上行琶音 3 秒 || 由低到高一串 || 数据擦除成功，即将重启&lt;br /&gt;
|-&lt;br /&gt;
| 🎵 下行低音 2 秒 || 由高到低，低沉 || 数据擦除失败，即将重启&lt;br /&gt;
|-&lt;br /&gt;
| 🎵 明亮上行 2 秒 || 短促上行动机 || 固件升级成功，即将重启&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==完整提示音表==&lt;br /&gt;
&lt;br /&gt;
频率单位 Hz，时长单位 ms。“静音”表示该步不发声只等待。&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 提示音 !! 试听 !! 序列（频率 Hz / 时长 ms） !! 总时长 !! 触发条件&lt;br /&gt;
|-&lt;br /&gt;
| 开机 || [[File:Pcat2-boot.mp3|noicon]] || 1300/75 → 1500/75 || 0.15 s || 长按电源键开机&lt;br /&gt;
|-&lt;br /&gt;
| 关机 || [[File:Pcat2-shutdown.mp3|noicon]] || 2000/150 → 1500/150 → 1000/150 || 0.45 s || 长按电源键关机，或低电量自动关机&lt;br /&gt;
|-&lt;br /&gt;
| 插入充电器 || [[File:Pcat2-charger-in.mp3|noicon]] || 432/150 → 528/75 || 0.23 s || 检测到充电器接入&lt;br /&gt;
|-&lt;br /&gt;
| 对外供电 || [[File:Pcat2-powering-device.mp3|noicon]] || 523/55 → 659/55 → 784/80 || 0.19 s || DC 在位且电池在放电，即正在给外接设备供电（需持续 4 秒才提示）&lt;br /&gt;
|-&lt;br /&gt;
| 充电电流达标 || [[File:Pcat2-charge-current-ok.mp3|noicon]] || 2500/100 || 0.10 s || 充电电流达到设定标准。'''每次插入充电器只响一声'''（拔掉后重新武装）；'''RA2E1260805003''' 之前的固件在每个充电开始沿都响，弱充电器电流在门限附近徘徊时会反复响&lt;br /&gt;
|-&lt;br /&gt;
| 温度过高 || [[File:Pcat2-over-temperature.mp3|noicon]] || (2500/100 → 500/100) ×4 || 0.80 s || 温度超过门限，已关闭主机&lt;br /&gt;
|-&lt;br /&gt;
| 烧录模式 || [[File:Pcat2-download-mode.mp3|noicon]] || (3000/300 → 2000/300) ×2 || 1.20 s || 关机状态下短按 3 下再长按 10 秒以上&lt;br /&gt;
|-&lt;br /&gt;
| 恢复出厂 || [[File:Pcat2-factory-reset.mp3|noicon]] || 4000/300 → 1000/300 → 2000/300 → 3000/300 → 2000/300 → 4000/300 → 3000/300 → 1000/300 || 2.40 s || 关机状态下短按 1 下再长按 17 秒以上&lt;br /&gt;
|-&lt;br /&gt;
| MCU 上电（新 bootloader） || [[File:Pcat2-mcu-boot-new.mp3|noicon]] || 4000/30 → 静音 1000 → 4000/200 || 1.23 s || MCU 上电自检&lt;br /&gt;
|-&lt;br /&gt;
| MCU 上电（旧 bootloader） || [[File:Pcat2-mcu-boot-old.mp3|noicon]] || 4000/200 || 0.20 s || MCU 上电自检&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==重启前提示音==&lt;br /&gt;
&lt;br /&gt;
以下三段为'''阻塞播放'''：播完整段才会执行复位，因此时长即为复位前的等待时间。&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 提示音 !! 试听 !! 序列（频率 Hz / 时长 ms） !! 总时长 !! 触发条件&lt;br /&gt;
|-&lt;br /&gt;
| 🎵 擦除成功 || [[File:Pcat2-wipe-ok.mp3|noicon]]&amp;lt;br/&amp;gt;[[:File:Pcat2-wipe-ok.mid|MIDI]] || 523/160 → 659/160 → 784/160 → 1047/160 → 1319/160 → 1568/160 → 2093/258 → 静音 74 → 1568/135 → 2093/135 → 2637/429 → 静音 92 → 2093/184 → 2637/184 → 3136/552 || 3.00 s || 出厂数据擦除成功，随即重启&lt;br /&gt;
|-&lt;br /&gt;
| 🎵 擦除失败 || [[File:Pcat2-wipe-fail.mp3|noicon]]&amp;lt;br/&amp;gt;[[:File:Pcat2-wipe-fail.mid|MIDI]] || 440/357 → 静音 51 → 415/357 → 静音 51 → 392/357 → 静音 51 → 330/765 || 1.99 s || 出厂数据擦除失败，随即重启&lt;br /&gt;
|-&lt;br /&gt;
| 🎵 升级成功 || [[File:Pcat2-update-ok.mp3|noicon]]&amp;lt;br/&amp;gt;[[:File:Pcat2-update-ok.mid|MIDI]] || 784/170 → 1047/170 → 1319/170 → 1568/382 → 静音 102 → 1319/170 → 1568/170 → 2093/638 || 1.97 s || MCU 固件升级成功，随即重启&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''注：'''自固件 RA2E1260726002 起，这三段整体加快（擦除成功由 4.89 s 压到 3.00 s，另两段各加快约 15 %），音型不变，只是节奏更紧凑，重启等待更短。&lt;br /&gt;
&lt;br /&gt;
==关于试听文件==&lt;br /&gt;
&lt;br /&gt;
试听用的 mp3 由固件里的实际音符表（频率+时长）直接合成，采用方波，与蜂鸣器的听感一致；实际设备上的音色会因蜂鸣器与腔体而略有差别。三段重启前旋律另附 MIDI 文件，方便二次编辑。&lt;br /&gt;
&lt;br /&gt;
==说明==&lt;br /&gt;
&lt;br /&gt;
* 提示音与指示灯可分别开关：声音关闭后指示灯仍正常工作，反之亦然。&lt;br /&gt;
* “对外供电”提示需放电条件连续保持 4 秒才触发，避免插拔充电器的瞬态误报。&lt;br /&gt;
* 重启前的三段提示音播放期间会正常喂看门狗，不会因为播放时间长而触发意外复位。&lt;br /&gt;
&lt;br /&gt;
[[Category:Photonicat 2]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:15:16 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E6%8F%90%E7%A4%BA%E9%9F%B3%E8%AF%B4%E6%98%8E</comments>
		</item>
		<item>
			<title>文件:Pcat2-led-orange-breathing-v3.gif</title>
			<link>https://wiki.photonicat.cn/index.php?title=%E6%96%87%E4%BB%B6:Pcat2-led-orange-breathing-v3.gif&amp;diff=240&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=%E6%96%87%E4%BB%B6:Pcat2-led-orange-breathing-v3.gif&amp;diff=240&amp;oldid=0</guid>
			<description>&lt;p&gt;&lt;a href=&quot;/index.php?title=%E7%94%A8%E6%88%B7:Guangyingmao&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new mw-userlink&quot; title=&quot;用户:Guangyingmao（页面不存在）&quot;&gt;&lt;bdi&gt;Guangyingmao&lt;/bdi&gt;&lt;/a&gt;上传&lt;a href=&quot;/%E6%96%87%E4%BB%B6:Pcat2-led-orange-breathing-v3.gif&quot; title=&quot;文件:Pcat2-led-orange-breathing-v3.gif&quot;&gt;文件:Pcat2-led-orange-breathing-v3.gif&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:11:45 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E6%96%87%E4%BB%B6%E8%AE%A8%E8%AE%BA:Pcat2-led-orange-breathing-v3.gif</comments>
		</item>
		<item>
			<title>Photonicat 2 LED 指示灯</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_LED_%E6%8C%87%E7%A4%BA%E7%81%AF&amp;diff=239&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_LED_%E6%8C%87%E7%A4%BA%E7%81%AF&amp;diff=239&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“&amp;#039;&amp;#039;&amp;#039;光影猫2&amp;#039;&amp;#039;&amp;#039; 只有一颗双色指示灯（红 + 绿）。黄色（橙色）由红绿同时点亮合成，没有蓝色。  指示灯采用 MacBook 式的表示方式： * &amp;#039;&amp;#039;&amp;#039;颜色表示充电状态&amp;#039;&amp;#039;&amp;#039; —— 🟠 黄色 = 正在充电，🟢 绿色 = 已充满。 * &amp;#039;&amp;#039;&amp;#039;呼吸与否表示主机状态&amp;#039;&amp;#039;&amp;#039; —— 呼吸 = 系统运行中，常亮 = 系统已关机。  适用于固件 &amp;#039;&amp;#039;&amp;#039;RA2E1260726001&amp;#039;&amp;#039;&amp;#039; 及之后版本。较早的固件在充电和充满时不…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;'''光影猫2''' 只有一颗双色指示灯（红 + 绿）。黄色（橙色）由红绿同时点亮合成，没有蓝色。&lt;br /&gt;
&lt;br /&gt;
指示灯采用 MacBook 式的表示方式：&lt;br /&gt;
* '''颜色表示充电状态''' —— 🟠 黄色 = 正在充电，🟢 绿色 = 已充满。&lt;br /&gt;
* '''呼吸与否表示主机状态''' —— 呼吸 = 系统运行中，常亮 = 系统已关机。&lt;br /&gt;
&lt;br /&gt;
适用于固件 '''RA2E1260726001''' 及之后版本。较早的固件在充电和充满时不区分开关机状态。&lt;br /&gt;
&lt;br /&gt;
自 '''RA2E1260731011''' 起：充电橙色更暖（红 60 % / 绿 24 %，原为 55 %/35 %）；呼吸只降到约峰值 1/12 的暗橙再进入谷底熄灭——旧固件呼吸首尾极暗处会显得像纯红——谷底熄灭保持由 0.24 s 加长到 0.5 s（周期约 6.1 s）。&lt;br /&gt;
&lt;br /&gt;
自 '''RA2E1260802000''' 起：电池耗尽或电压过低时尝试开机，会立刻红灯'''闪 3 次'''（更早的固件此时什么都不显示，空电设备看起来像变砖）；关机状态下短按遇到低电同样闪 3 次。持续红闪仅在系统运行中使用。长按开关机时长改为 1.5 秒。&lt;br /&gt;
&lt;br /&gt;
'''RA2E1260805000''' 修复：RA2E1260802000–RA2E1260802001 存在缺陷——设备关机待机时短按电源键，'''即使电池满电'''也可能红灯闪 3 次。原因是待机唤醒瞬间电压传感器短暂读到 0 mV，被误判为低电量。现在只有真实的低电压读数才会触发红灯。&lt;br /&gt;
&lt;br /&gt;
自 '''RA2E1260808001''' 起：关机状态下电池低于最低开机电压（6600 mV）时，'''任何'''按键都会在按下约 0.1 秒时立即红灯闪 3 次——判定发生在给主机供电之前，主机电源轨完全不动——闪完后设备回到深度睡眠，把最后的电量留给内置时钟走时。RA2E1260802000–RA2E1260808000 上，开机被拒的红闪要按满 1.5 秒长按并松手后才出现，短按在松手前没有任何提示。本版本同时修复：若系统关机（包括 6300 mV 自动关机）时持续低电红闪正在进行，旧固件不会将其停掉——系统已关机红灯却一直闪个不停，还挡住控制器进入休眠，白白耗尽剩余电量。现在关机即停。&lt;br /&gt;
&lt;br /&gt;
英文版见 [[Photonicat 2 LED Indicator]]。提示音说明见 [[Photonicat 2 提示音说明]]。&lt;br /&gt;
&lt;br /&gt;
==速查==&lt;br /&gt;
&lt;br /&gt;
以下动画为示意，节奏与实际固件一致（呼吸周期约 6.1 秒、心跳周期 2 秒）。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 动画 !! 指示灯 !! 含义&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-orange-breathing-v3.gif|52px|link=]] || 🟠 黄色呼吸 || 正在充电，系统运行中&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-orange-solid-v3.gif|52px|link=]] || 🟠 黄色常亮 || 正在充电，系统已关机&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-green-breathing-v3.gif|52px|link=]] || 🟢 绿色呼吸 || 已充满（或已达充电上限），系统运行中&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-green-solid-v2.gif|52px|link=]] || 🟢 绿色常亮 || 已充满（或已达充电上限），系统已关机&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-green-heartbeat-v2.gif|52px|link=]] || 🟢 绿色心跳脉冲 || 电池供电运行中，电量正常&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-red-lowbatt-v2.gif|52px|link=]] || 🔴 红色持续闪烁 || 电量低（低于 6500 mV，详见下方[[#低电量红灯|低电量红灯]]）&lt;br /&gt;
|-&lt;br /&gt;
| [[File:Pcat2-led-off-v2.gif|52px|link=]] || ⚫ 熄灭 || 电池供电待机，系统已关机&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==完整状态表==&lt;br /&gt;
&lt;br /&gt;
电压门限为固件默认值，可由上位机覆盖。以下为 2S 电池组数值：满电 8280 mV、低电告警 6500 mV、最低开机 6600 mV、强制关机 6300 mV。&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 电量 !! 充电器 !! 动画 !! 颜色 !! 形态 !! 节奏&lt;br /&gt;
|-&lt;br /&gt;
| 充电中，任意电量 || 已插入 || [[File:Pcat2-led-orange-breathing-v3.gif|44px|link=]] || 🟠 黄色 || 呼吸（开机） || 渐亮 2.8 s / 渐暗 2.8 s / 熄灭 0.5 s，周期约 6.1 s；谷底降到约峰值 1/12 的暗橙，不会出现纯红&lt;br /&gt;
|-&lt;br /&gt;
| 充电中，任意电量 || 已插入 || [[File:Pcat2-led-orange-solid-v3.gif|44px|link=]] || 🟠 黄色 || 常亮（关机） || 持续&lt;br /&gt;
|-&lt;br /&gt;
| 已充满或达充电上限 || 已插入 || [[File:Pcat2-led-green-breathing-v3.gif|44px|link=]] || 🟢 绿色 || 呼吸（开机） || 同为约 6.1 s 周期，延迟 10 s 后生效&lt;br /&gt;
|-&lt;br /&gt;
| 已充满或达充电上限 || 已插入 || [[File:Pcat2-led-green-solid-v2.gif|44px|link=]] || 🟢 绿色 || 常亮（关机） || 持续，延迟 10 s 后生效&lt;br /&gt;
|-&lt;br /&gt;
| 低于 6600 mV，DC ≥ 8 V 且无充电电流 || 已插入 || [[File:Pcat2-led-orange-solid-v3.gif|44px|link=]] || 🟠 黄色 || 常亮 || 持续&lt;br /&gt;
|-&lt;br /&gt;
| 高于 6500 mV，开机 || 未插入 || [[File:Pcat2-led-green-heartbeat-v2.gif|44px|link=]] || 🟢 绿色 || 心跳脉冲 || 周期 2 s&lt;br /&gt;
|-&lt;br /&gt;
| 高于 6500 mV，正在开机 || 未插入 || [[File:Pcat2-led-green-solid-v2.gif|44px|link=]] || 🟢 绿色 || 常亮 || 持续&lt;br /&gt;
|-&lt;br /&gt;
| 高于 6600 mV，关机 || 未插入 || [[File:Pcat2-led-green-solid-v2.gif|44px|link=]] || 🟢 绿色 || 常亮 || 持续&lt;br /&gt;
|-&lt;br /&gt;
| 低于 6500 mV，开机 || 未插入 || [[File:Pcat2-led-red-lowbatt-v2.gif|44px|link=]] || 🔴 红色 || 持续闪烁 || 亮 1 s / 灭 1 s，60 s 后开始，持续到电压回升&lt;br /&gt;
|-&lt;br /&gt;
| 低于 6500 mV（有效读数），关机短按一次 || 未插入 || [[File:Pcat2-led-red-lowbatt-v2.gif|44px|link=]] || 🔴 红色 || 闪烁 || 亮 1 s / 灭 1 s，'''闪 3 次'''，首次立即亮（约 0.5 s 防抖）&lt;br /&gt;
|-&lt;br /&gt;
| 低于 6600 mV，关机时按下任意按键 || 未插入 || [[File:Pcat2-led-red-lowbatt-v2.gif|44px|link=]] || 🔴 红色 || 闪烁 || '''闪 3 次'''，按下约 0.1 s 即开始（'''RA2E1260808001''' 起；旧固件要按满 1.5 s 长按并松手才闪）。主机电源轨不会上电，闪完后设备回到深度睡眠&lt;br /&gt;
|-&lt;br /&gt;
| 拔出充电器且关机 || 未插入 || [[File:Pcat2-led-off-v2.gif|44px|link=]] || colspan=&amp;quot;2&amp;quot; | ⚫ 熄灭&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==服务与过渡状态==&lt;br /&gt;
&lt;br /&gt;
以下状态优先级高于上表。&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 状态 !! 动画 !! 颜色 !! 形态 !! 节奏&lt;br /&gt;
|-&lt;br /&gt;
| 正在关机 || [[File:Pcat2-led-green-blink-shutdown-v2.gif|44px|link=]] || 🟢 绿色 || 闪烁 || 约亮 0.5 s / 灭 1.5 s&lt;br /&gt;
|-&lt;br /&gt;
| 固件烧录模式 || [[File:Pcat2-led-orange-blink-fast-v3.gif|44px|link=]] || 🟠 黄色 || 快闪 || 周期约 0.5 s&lt;br /&gt;
|-&lt;br /&gt;
| 复位 / 恢复出厂模式 || [[File:Pcat2-led-orange-blink-slow-v3.gif|44px|link=]] || 🟠 黄色 || 慢闪 || 周期约 1 s&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==低电量红灯==&lt;br /&gt;
&lt;br /&gt;
电量过低时指示灯会变为 🔴 '''红色闪烁'''，这是唯一使用红色的场合。&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! 项目 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
| 触发条件 || 电池电压低于 '''6500 mV'''（2S 电池组，约 3.25 V/节），且'''未插充电器'''&lt;br /&gt;
|-&lt;br /&gt;
| 闪烁节奏 || 亮 1 秒 / 灭 1 秒&lt;br /&gt;
|-&lt;br /&gt;
| 闪烁次数 || '''开机状态：'''持续闪烁，直到电压回升或插上充电器。'''关机状态'''（按下任意按键）：只'''闪 3 次'''，随后设备回到深度睡眠&lt;br /&gt;
|-&lt;br /&gt;
| 开机状态下 || 电压持续低于门限 '''60 秒'''后才开始闪&lt;br /&gt;
|-&lt;br /&gt;
| 关机时按任意键 || 电池低于开机门限时，任何按键都会在按下约 0.1 秒时红灯闪 3 次（'''RA2E1260808001''' 起），闪完后设备回到深度睡眠。待机唤醒瞬间传感器的 0 mV 预热读数不会触发——固件会先补采一次真实电压再判定（'''RA2E1260805000''' 起）&lt;br /&gt;
|-&lt;br /&gt;
| 绿灯会怎样 || 红灯期间绿色心跳会停止，两者不会同时亮&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''⚠️ 重要提醒'''&lt;br /&gt;
&lt;br /&gt;
* 系统运行中，红灯会'''一直闪到电压回升或接入充电器'''，不会自行停止。（RA2E1260726003 之前的固件只闪 3 次就不再提示。）系统关机时，短按或开机被拒只闪 3 次，随后 MCU 回到待机。&lt;br /&gt;
* 红灯触发点（6500 mV）与'''强制关机点（6300 mV）只差 200 mV'''，在 2S 锂电的放电末端属于很陡的一段，看到红灯应尽快接入充电器。&lt;br /&gt;
* 判据是'''电压不是百分比'''：大负载下电压会被拉低，可能在剩余电量还不算太少时就提前告警；负载减轻后电压回升，告警也会随之消失。&lt;br /&gt;
&lt;br /&gt;
==充电上限==&lt;br /&gt;
&lt;br /&gt;
若设置了充电上限（例如 80 %），电量达到上限后会断开充电，充电电流归零，设备据此按“已充满”处理并显示 🟢 '''绿色'''。此后由电池给负载供电并缓慢放电，低于恢复门限后重新开始充电，指示灯回到 🟠 黄色。每次切换约有 10 秒延迟。&lt;br /&gt;
&lt;br /&gt;
==说明==&lt;br /&gt;
&lt;br /&gt;
* 绿色呼吸峰值 25 % 占空、绿色常亮 50 %，所以绿色呼吸比常亮更暗；橙色呼吸峰值与橙色常亮相同（红 60 % / 绿 24 %）。&lt;br /&gt;
* 🔴 红色仅用于低电量提示：系统运行中持续闪烁直到电压回升或接入充电器；系统关机时只闪 3 次。&lt;br /&gt;
* 指示灯可通过上位机协议关闭，关闭后绿色/黄色各状态均不亮灯。🔴 低电红色告警自 '''RA2E1260808001''' 起例外：它属于系统级告警，即使指示灯已关闭也照样闪红，保证亏电拒开机的设备不会看起来像坏了。（此前版本关灯连红色告警一起关掉。）&lt;br /&gt;
* 指示灯依据的电量是怎么算出来的，见 [[Photonicat 2 SOC 计算]]。&lt;br /&gt;
&lt;br /&gt;
[[Category:Photonicat 2]]&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:10:45 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_LED_%E6%8C%87%E7%A4%BA%E7%81%AF</comments>
		</item>
		<item>
			<title>Photonicat 2 新手入门指南</title>
			<link>https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97&amp;diff=238&amp;oldid=0</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=Photonicat_2_%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97&amp;diff=238&amp;oldid=0</guid>
			<description>&lt;p&gt;创建页面，内容为“==Photonicat 2 快速上手== #接入9V-20V电源USB-C PWR接口，接入sim卡或网线至WAN口。 #手机或电脑连接 WiFi或LAN网口 （默认WiFi 密码：photonicat) #等待机器屏幕亮起，内容加载完毕后找到屏幕显示的WiFi SSID进行连接或用有线连接LAN网口 （默认WiFi 密码：photonicat) #在浏览器中打开172.16.0.1，修改Photonicat配置 （例如Wifi密码、Wifi 频率） #在浏览器中打开172.16.0.1:8080或…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;==Photonicat 2 快速上手==&lt;br /&gt;
#接入9V-20V电源USB-C PWR接口，接入sim卡或网线至WAN口。&lt;br /&gt;
#手机或电脑连接 WiFi或LAN网口 （默认WiFi 密码：photonicat)&lt;br /&gt;
#等待机器屏幕亮起，内容加载完毕后找到屏幕显示的WiFi SSID进行连接或用有线连接LAN网口 （默认WiFi 密码：photonicat)&lt;br /&gt;
#在浏览器中打开172.16.0.1，修改Photonicat配置 （例如Wifi密码、Wifi 频率）&lt;br /&gt;
#在浏览器中打开172.16.0.1:8080或者在Web管理页面右上角点击OpenWRT，进入OpenWRT高级配置页面，可自主进行高级配置修改&lt;br /&gt;
&lt;br /&gt;
==更改管理员密码==&lt;br /&gt;
#进入OpenWRT配置页面&lt;br /&gt;
#选择&amp;lt;code&amp;gt;系统&amp;lt;/code&amp;gt; -&amp;gt; &amp;lt;code&amp;gt;管理权&amp;lt;/code&amp;gt; 页面&lt;br /&gt;
#在主机密码位置输入新密码，并点击 &amp;lt;code&amp;gt;保存&amp;amp;应用&amp;lt;/code&amp;gt;&lt;br /&gt;
[[File:openwrt-changpw-wiki-02.png|500px]]&lt;br /&gt;
&lt;br /&gt;
==出厂默认配置==&lt;br /&gt;
#LAN IP : &amp;lt;code&amp;gt;172.16.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
#管理界面地址(原厂）: &amp;lt;code&amp;gt;http://172.16.0.1&amp;lt;/code&amp;gt;&lt;br /&gt;
#OpenWRT原生界面 : &amp;lt;code&amp;gt;http://172.16.0.1:8080&amp;lt;/code&amp;gt;&lt;br /&gt;
#Wifi默认密码 : &amp;lt;code&amp;gt;photonicat&amp;lt;/code&amp;gt;&lt;br /&gt;
#登陆用户 : &amp;lt;code&amp;gt;root&amp;lt;/code&amp;gt;&lt;br /&gt;
#登录密码 : &amp;lt;code&amp;gt;photonicat&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Photonicat 2 按键配置==&lt;br /&gt;
Photonicat采用极简设计理念，外部只保留一个功能按键来实现所有功能，相关按键功能定义请参见以下'''按键功能定义表'''&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 功能   !! 进入方式 !! 状态提示&lt;br /&gt;
|-&lt;br /&gt;
|开机||关机状态下长按3秒||电源灯绿色常亮15S后绿色闪烁&lt;br /&gt;
|-&lt;br /&gt;
|开机进入烧录模式||关机状态下短按3下，再长按10秒以上||电源灯黄色闪烁（0.25秒亮，0.25秒暗）&lt;br /&gt;
|-&lt;br /&gt;
|开机恢复出厂设置||关机状态下短按1下，再长按17秒以上||电源灯黄色闪烁（0.5秒亮，0.5秒暗）&lt;br /&gt;
|-&lt;br /&gt;
|关机||开机状态下长按3秒||电源灯熄灭&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Photonicat 2 LED灯状态说明==&lt;br /&gt;
Photonicat 2 只有 1 颗 LED 灯来显示相关的工作状态。颜色表示充电状态（🟠 黄色 = 充电中，🟢 绿色 = 已充满），呼吸与否表示主机状态（呼吸 = 系统运行中，常亮 = 系统已关机）。&lt;br /&gt;
&lt;br /&gt;
'''完整说明（含全部状态、电压门限与节奏）见 [[Photonicat 2 LED 指示灯]]，English: [[Photonicat 2 LED Indicator]]。'''&lt;br /&gt;
&lt;br /&gt;
=== LED灯工作状态表 ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! LED灯   !! 状态 !! 相关工作状态&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=1|烧录模式||🟠 黄灯快闪||可进行固件烧录&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=1|恢复出厂模式||🟠 黄灯慢闪||可进行Reset设置&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=6|充电状态||🟠 黄灯呼吸||充电中，系统运行&lt;br /&gt;
|-&lt;br /&gt;
|🟠 黄灯常亮||充电中，系统已关机&lt;br /&gt;
|-&lt;br /&gt;
|🟢 绿灯呼吸||已充满（或已达充电上限），系统运行&lt;br /&gt;
|-&lt;br /&gt;
|🟢 绿灯常亮||已充满（或已达充电上限），系统已关机&lt;br /&gt;
|-&lt;br /&gt;
|⚫ 常暗||未插入充电器&lt;br /&gt;
|-&lt;br /&gt;
|🔴 红灯闪 3 次||低电量警示&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=1|电池供电||🟢 绿灯心跳脉冲||开机，电量正常&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=1|关机状态||⚫ 常暗||主板断电，关机&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
'''注：'''充电与充满的开关机区分需固件 RA2E1260726001 及以上；较早固件充电统一为黄灯呼吸、充满统一为绿灯常亮。&lt;br /&gt;
&lt;br /&gt;
==Photonicat 2 工作模式说明==&lt;br /&gt;
Photonicat 2 可以通过WEB管理页面配置不同工作模式,分别为普通模式、车载模式和定时模式,相关工作模式的说明请参加下表'''工作模式说明表'''。&lt;br /&gt;
=== 工作模式说明表 ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 工作模式 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
|普通模式||需手动开关机&lt;br /&gt;
|-&lt;br /&gt;
|车载模式||插入充电器开机，拔出充电器关机，具体细节请参见'''车载模式开关机逻辑表'''&lt;br /&gt;
|-&lt;br /&gt;
|定时模式||根据WEB管理页面设置的时间定时开关机（车载模式下，定时模式不生效）&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
=== 车载模式开关机逻辑表 ===&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 功能 !! 说明&lt;br /&gt;
|-&lt;br /&gt;
|开机 ||  插上充电器&lt;br /&gt;
|-&lt;br /&gt;
|关机 || 拔出充电器&lt;br /&gt;
|-&lt;br /&gt;
|无充电器状态下开机 || 长按3秒按键正常开机流程，开机后在充电器保持未插入的状态下不再主动关机，插入再拔出充电器后根据车载模式正常工作&lt;br /&gt;
|-&lt;br /&gt;
|-&lt;br /&gt;
|有充电器状态下关机 || 长按3秒按键正常关机流程，关机后在充电器保持现有状态的情况下不再主动开机，拔出再插入充电器后根据车载模式正常工作&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:10:02 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:Photonicat_2_%E6%96%B0%E6%89%8B%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97</comments>
		</item>
		<item>
			<title>首页</title>
			<link>https://wiki.photonicat.cn/index.php?title=%E9%A6%96%E9%A1%B5&amp;diff=237&amp;oldid=236</link>
			<guid isPermaLink="false">https://wiki.photonicat.cn/index.php?title=%E9%A6%96%E9%A1%B5&amp;diff=237&amp;oldid=236</guid>
			<description>&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2026年8月30日 (日) 14:09的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l72&quot;&gt;第72行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第72行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Photonicat 2代==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==Photonicat 2代 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;用户手册 User Manual==&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;===入门 Getting Started=&lt;/ins&gt;==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{|width=&amp;quot;90%&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;{|width=&amp;quot;90%&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|[[Photonicat 2 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;specs&lt;/del&gt;]]||[[Photonicat 2 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;sysfs&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&amp;quot;left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;/ins&gt;|[[Photonicat 2 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;新手入门指南&lt;/ins&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|&lt;/del&gt;[[&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Build system image for photonicat2&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;align=&amp;quot;left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;/ins&gt;|[[Photonicat 2 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;LED 指示灯&lt;/ins&gt;]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;（&lt;/ins&gt;[[&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Photonicat 2 LED Indicator|EN&lt;/ins&gt;]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;）&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|[[Photonicat 2 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Wifi/WWAN/NVME M2 兼容模块&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&amp;quot;left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;/ins&gt;|[[Photonicat 2 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;提示音说明&lt;/ins&gt;]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;（&lt;/ins&gt;[[Photonicat 2 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Sound Guide|EN&lt;/ins&gt;]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;）&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|&lt;/del&gt;[[Photonicat 2 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;固件USB线刷更新教程&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&amp;quot;left&amp;quot; width=&amp;quot;25%&amp;quot;&lt;/ins&gt;|[[Photonicat 2 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;小屏幕自定义&lt;/ins&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|[[Photonicat 2 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;固件在线升级更新&lt;/del&gt;]]&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|-&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;===固件更新 Firmware Update===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{|width=&quot;90%&quot;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 固件在线升级更新]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 OTA更新]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 固件USB线刷更新教程]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 MCU 手动更新]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|-&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photoincat 2 第三方固件更新]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 固件更新日志]]（[[Photonicat 2 固件 Changelog|EN]]）&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;===网络功能 Networking===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{|width=&quot;90%&quot;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 Smart WAN 智能上网]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 多出口与故障切换]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 访客门户 Captive Portal]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photoincat 2 IPv6 PPPoE]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|-&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat2 无线桥接]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 管理界面新功能 (2026)]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;===硬件扩展 Hardware===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{|width=&quot;90%&quot;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 Wifi/WWAN/NVME M2 兼容模块]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 spec|Photonicat 2 规格]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|}&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;===开发者 Developers===&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;{|width=&quot;90%&quot;&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 开发者 API]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 sysfs]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 Docker 使用指南]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Build system image for photonicat2]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|-&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 MCU 通讯协议]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|[[Photonicat 2 SOC 计算]]（[[Photonicat 2 SOC Calculation|EN]]）&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|align=&quot;left&quot; width=&quot;25%&quot;|&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;|}&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;!-- diff cache key gym_wiki:diff::1.12:old-236:rev-237 --&gt;
&lt;/table&gt;</description>
			<pubDate>Sun, 30 Aug 2026 06:09:25 GMT</pubDate>
			<dc:creator>Guangyingmao</dc:creator>
			<comments>https://wiki.photonicat.cn/%E8%AE%A8%E8%AE%BA:%E9%A6%96%E9%A1%B5</comments>
		</item>
</channel></rss>