Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: gijzelaerr/python-snap7
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: QuakeString/python-snap7-optimized
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Checking mergeability… Don’t worry, you can still create the pull request.
  • 17 commits
  • 14 files changed
  • 2 contributors

Commits on Mar 13, 2026

  1. Optimize read_multi_vars with nodeS7-style sort/merge/packetize pipeline

    Adds a 3-stage optimization (sort → merge → packetize) that collapses
    scattered read requests into minimal PDU-packed multi-item S7 exchanges.
    The optimization is transparent — read_multi_vars() uses it automatically
    for PE/PA/MK/DB areas, with CT/TM falling back to individual reads.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    93e5bdb View commit details
    Browse the repository at this point in the history
  2. Update README with fork optimization documentation

    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    dc95adf View commit details
    Browse the repository at this point in the history
  3. Add parallel dispatch, auto-tuned max_parallel, plan caching, and saf…

    …e block splitting
    
    - Parallel dispatch: send multiple packets in-flight on a single TCP
      connection using select(), match responses by sequence number (sliding
      window of max_parallel).
    - Auto-tune max_parallel after connect() using PLC's reported
      MaxConnections (via SZL 0x0131), falling back to PDU-size heuristic
      for PLCs that don't support it (LOGO, S7-200).
    - Cache optimization plan (sort/merge/packetize) across read_multi_vars()
      calls — recomputed only when the item list changes.
    - Fix _split_block to never tear multi-byte items (WORD, DWORD, REAL,
      LREAL) across chunk boundaries.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    524be95 View commit details
    Browse the repository at this point in the history
  4. Remove MAX_VARS read limit — optimization pipeline handles any item c…

    …ount
    
    The MAX_VARS=20 limit was inherited from the original snap7 C library's
    fixed-size array. Our pure Python pipeline sorts, merges, and packetizes
    any number of items into PDU-sized packets automatically. The limit is
    retained for write_multi_vars where no optimization exists.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    80041d6 View commit details
    Browse the repository at this point in the history
  5. Rename package to python-snap7-optimized for PyPI publishing

    Avoids conflict with the upstream python-snap7 package name.
    Updates pyproject.toml, publish workflows, and homepage URL.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    7b618dd View commit details
    Browse the repository at this point in the history
  6. Rename PyPI package to snap7-optimized

    python-snap7-optimized was rejected by PyPI name similarity check.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    a816889 View commit details
    Browse the repository at this point in the history
  7. Disable uv cache in publish test jobs to fix missing cache key warning

    Test jobs don't checkout the repo, so there's no pyproject.toml for cache hashing.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    57f6396 View commit details
    Browse the repository at this point in the history
  8. Promote optimization logs to INFO level for visibility

    Auto-tune, PDU negotiation, and plan-built messages are now INFO
    so they appear in gateway logs without requiring DEBUG on snap7 logger.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    bb1637e View commit details
    Browse the repository at this point in the history
  9. Fix S7-300 connection reset: set max_parallel=1 for PDU 240

    S7-300 PLCs reset the TCP connection when multiple PDUs are sent
    back-to-back (parallel dispatch). Force sequential mode for small
    PDU PLCs to prevent connection reset by peer errors.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    QuakeString and claude committed Mar 13, 2026
    Configuration menu
    Copy the full SHA
    b51a496 View commit details
    Browse the repository at this point in the history

Commits on Mar 27, 2026

  1. feat: add TCP keepalive and heartbeat_read() for redundant PLC support

    - Enable SO_KEEPALIVE with aggressive probes (KEEPIDLE=2s, KEEPINTVL=1s,
      KEEPCNT=2) on all TCP connections for fast dead-peer detection (~4s)
    - Add Client.heartbeat_read(timeout_ms) for lightweight liveness checks
      reading 1 byte from M0 with independent short timeout
    - Update README with documentation for all optimization features:
      parallel dispatch, plan caching, TCP keepalive, heartbeat read,
      and model-specific tuning table
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    QuakeString and claude committed Mar 27, 2026
    Configuration menu
    Copy the full SHA
    0a9e8a3 View commit details
    Browse the repository at this point in the history

Commits on Mar 28, 2026

  1. ci: remove GitHub Pages deploy step from doc workflow

    The deploy job fails with 404 because GitHub Pages is not enabled on
    this fork. Keep the build job so documentation still gets validated
    on push, but remove the upload-pages-artifact and deploy-pages steps.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    QuakeString and claude committed Mar 28, 2026
    Configuration menu
    Copy the full SHA
    fd8848e View commit details
    Browse the repository at this point in the history
  2. chore: bump version to 3.1.0 for redundant PLC support release

    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    QuakeString and claude committed Mar 28, 2026
    Configuration menu
    Copy the full SHA
    e6ab7a3 View commit details
    Browse the repository at this point in the history
  3. fix: widen RST table columns to fix PyPI rendering validation

    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    QuakeString and claude committed Mar 28, 2026
    Configuration menu
    Copy the full SHA
    13b6dff View commit details
    Browse the repository at this point in the history

Commits on Apr 17, 2026

  1. fix(parser): correct GET_CLK byte offsets and stop masking errors

    parse_get_clock_response was reading year/month/day/hour/min/sec from
    bytes 1-6 of the USER_DATA GET_CLK response, but S7-300/400/1200/1500
    CPUs put those at bytes 2-7 (bytes 0 and 1 are reserved/version). On
    every real PLC the decoder therefore decoded month=26, fell into the
    ValueError branch, and silently returned datetime.now() — indistinguish-
    able from a real clock read.
    
    Two concrete problems:
    
    1. Wrong offsets: for the observed 10-byte response
         00 19 26 04 17 20 31 55 25 36
       the old code read year=19, month=26 (invalid) → ValueError → fallback.
       The correct decoding is year=26 (2026), month=04, ..., second=55.
    
    2. Silent fallback: both the truncated-response branch and the BCD
       parse-error branch returned datetime.now(). Callers had no way to
       distinguish "this CPU does not expose its clock" (S7-300 answering
       0xd402 "Information function unavailable") from "clock read
       succeeded and happens to equal host time". Gateway tooling using
       this to detect drift would always see ~0ms, including when the PLC's
       real clock was hours off.
    
    Changes:
      - Try year offsets 2 and 1 (handles minor per-CPU variation). Accept
        only results whose full year lands in 1990..2099.
      - Reject responses whose return_code != 0xFF (explicit PLC error).
      - Raise ValueError with diagnostic detail instead of returning
        datetime.now() when the response is truncated or unparsable.
    
    Consumers now get an accurate PLC time or a clear error — no fabricated
    fallback values.
    QuakeString committed Apr 17, 2026
    Configuration menu
    Copy the full SHA
    3cb4751 View commit details
    Browse the repository at this point in the history
  2. chore: bump version to 3.1.1 for clock-read bug fix

    Releases the fix in 3cb4751 (parse_get_clock_response correct byte
    offsets and no silent datetime.now() fallback). Adds CHANGES.md entries
    for 3.1.0 (redundant PLC) and 3.1.1 (this fix).
    QuakeString committed Apr 17, 2026
    Configuration menu
    Copy the full SHA
    729b4b8 View commit details
    Browse the repository at this point in the history
  3. style: apply ruff-format to clock-parser diagnostics

    Single-line the long f-string raises and switch the keepalive
    constants to double-quoted strings so pre-commit (ruff-format) is
    happy. No behavior change.
    QuakeString committed Apr 17, 2026
    Configuration menu
    Copy the full SHA
    5320f7d View commit details
    Browse the repository at this point in the history
  4. fix(client): narrow socket Optional before use to satisfy mypy

    heartbeat() already guarded self.connection but not self.connection.socket,
    so the settimeout() call tripped mypy's union-attr check. Cache the socket
    in a local after the None check and use it for both the gettimeout() read
    and the settimeout() write, eliminating the need for additional guards.
    QuakeString committed Apr 17, 2026
    Configuration menu
    Copy the full SHA
    c9c042a View commit details
    Browse the repository at this point in the history
Loading