Files
Vlad DolomanandClaude Sonnet 5.5 4d1ff0c7ea Fix dashboard bugs, verify register map against manual, harden scripts
- index.html: remove duplicated sections/IDs, restore card CSS, add fetch
  timeout and error handling, label relay and lithium type values
- app.py: close inverter connection in finally, socket timeout, lock plus
  2s cache, debug off, friendly missing-config error, HTTP 502 on failure
- app.py: fix register scaling per Deye Modbus V118 (battery temp +1000
  offset, charge efficiency 0.1%, block 5 off-by-one for 312-325)
- read_registers.py: drop hard-coded IP/serial (env or config.py), use
  argparse type validators, unify INVERTER_SLAVE_ID, document limits
- extract_pdf.py: main guard, argparse, output next to script, pypdf in
  docs/requirements.txt; pin requirements

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-06 19:14:33 +02:00

62 lines
2.0 KiB
Python

"""Search a Deye Modbus manual PDF for specific register numbers.
Usage:
python docs/extract_pdf.py [--pdf PATH] [--registers 94 245 320] [--output PATH]
Requires pypdf (pip install -r docs/requirements.txt). By default the first
*.pdf in this folder is used and pdf_output.txt is written next to this script.
"""
import argparse
import glob
import os
import re
import sys
try:
import pypdf
except ImportError:
sys.exit("ERROR: pypdf is required. Install with: pip install -r docs/requirements.txt")
HERE = os.path.dirname(os.path.abspath(__file__))
def extract_text_from_pdf(pdf_path):
reader = pypdf.PdfReader(pdf_path)
return "\n".join((page.extract_text() or "") for page in reader.pages)
def find_default_pdf():
pdfs = sorted(glob.glob(os.path.join(HERE, "*.pdf")))
return pdfs[0] if pdfs else None
def main():
parser = argparse.ArgumentParser(description=__doc__.split("\n")[0])
parser.add_argument("--pdf", default=find_default_pdf(), help="PDF manual (default: first *.pdf in docs/)")
parser.add_argument("--registers", nargs="+", type=int, default=[94, 245, 320], help="register numbers to find")
parser.add_argument("--output", default=os.path.join(HERE, "pdf_output.txt"), help="output file")
args = parser.parse_args()
if not args.pdf or not os.path.isfile(args.pdf):
sys.exit("ERROR: PDF not found. Pass --pdf PATH or place a PDF in docs/.")
print("Searching for registers...")
lines = extract_text_from_pdf(args.pdf).split("\n")
with open(args.output, "w", encoding="utf-8") as f:
for i, line in enumerate(lines):
for reg in args.registers:
if re.search(r"\b" + str(reg) + r"\b", line):
f.write(f"MATCH {reg}: {line.strip()}\n")
for j in range(max(0, i - 5), min(len(lines), i + 6)):
if j != i:
f.write(f" CTX: {lines[j].strip()}\n")
f.write("-" * 20 + "\n")
print(f"Done. Check {args.output}")
if __name__ == "__main__":
main()