{"id":47698310,"url":"https://github.com/fa-yoshinobu/plc-comm-slmp-python","last_synced_at":"2026-06-12T05:01:19.824Z","repository":{"id":344201264,"uuid":"1180861934","full_name":"fa-yoshinobu/plc-comm-slmp-python","owner":"fa-yoshinobu","description":"High-performance, strictly typed Python client for Mitsubishi SLMP (Seamless Message Protocol). Supports Binary 3E/4E frames for iQ-R, iQ-F, and Q series PLCs.","archived":false,"fork":false,"pushed_at":"2026-06-11T19:57:22.000Z","size":2340,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T21:15:36.902Z","etag":null,"topics":["industrial-automation","iot","melsec","mitsubishi","plc","python","slmp"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fa-yoshinobu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-13T13:46:28.000Z","updated_at":"2026-06-11T19:57:05.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fa-yoshinobu/plc-comm-slmp-python","commit_stats":null,"previous_names":["fa-yoshinobu/slmp4e-connect-python","fa-yoshinobu/plc-comm-slmp-python"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/fa-yoshinobu/plc-comm-slmp-python","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fa-yoshinobu%2Fplc-comm-slmp-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fa-yoshinobu%2Fplc-comm-slmp-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fa-yoshinobu%2Fplc-comm-slmp-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fa-yoshinobu%2Fplc-comm-slmp-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fa-yoshinobu","download_url":"https://codeload.github.com/fa-yoshinobu/plc-comm-slmp-python/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fa-yoshinobu%2Fplc-comm-slmp-python/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34229624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["industrial-automation","iot","melsec","mitsubishi","plc","python","slmp"],"created_at":"2026-04-02T16:58:54.911Z","updated_at":"2026-06-12T05:01:19.818Z","avatar_url":"https://github.com/fa-yoshinobu.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![CI](https://github.com/fa-yoshinobu/plc-comm-slmp-python/actions/workflows/ci.yml/badge.svg)](https://github.com/fa-yoshinobu/plc-comm-slmp-python/actions/workflows/ci.yml)\n[![Documentation](https://img.shields.io/badge/docs-GitHub_Pages-blue.svg)](https://fa-yoshinobu.github.io/plc-comm-slmp-python/)\n[![PyPI](https://img.shields.io/pypi/v/slmp-connect-python.svg)](https://pypi.org/project/slmp-connect-python/)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Static Analysis: Ruff](https://img.shields.io/badge/Lint-Ruff-black.svg)](https://github.com/astral-sh/ruff)\n\n# SLMP Protocol for Python\n\n![Illustration](https://raw.githubusercontent.com/fa-yoshinobu/plc-comm-slmp-python/main/docsrc/assets/melsec.png)\n\n[![Automated Release](https://github.com/fa-yoshinobu/plc-comm-slmp-python/actions/workflows/automated-release.yml/badge.svg)](https://github.com/fa-yoshinobu/plc-comm-slmp-python/actions/workflows/automated-release.yml)\n[![Release](https://github.com/fa-yoshinobu/plc-comm-slmp-python/actions/workflows/release.yml/badge.svg)](https://github.com/fa-yoshinobu/plc-comm-slmp-python/actions/workflows/release.yml)\n\n[![Python](https://img.shields.io/badge/Python-3776AB?logo=python\u0026logoColor=white)](https://www.python.org/)\n[![MkDocs](https://img.shields.io/badge/MkDocs-526CFE?logo=materialformkdocs\u0026logoColor=white)](https://www.mkdocs.org/)\n[![GitHub Pages](https://img.shields.io/badge/GitHub%20Pages-222222?logo=githubpages\u0026logoColor=white)](https://pages.github.com/)\n\nHigh-level SLMP helpers for Mitsubishi PLC communication over Binary 3E and 4E frames.\n\nThis repository treats the high-level helper layer as the recommended user surface:\n\n- `SlmpConnectionOptions`\n- `open_and_connect` / `open_and_connect_sync`\n- `AsyncSlmpClient`\n- `QueuedAsyncSlmpClient`\n- `SlmpClient`\n- `normalize_address`\n- `parse_address` / `try_parse_address` / `format_address`\n- `read_typed` / `write_typed`\n- `read_words_single_request` / `read_dwords_single_request`\n- `read_words_chunked` / `read_dwords_chunked`\n- `write_bit_in_word`\n- `read_named` / `write_named`\n- `poll`\n\n## Installation\n\n```bash\npip install slmp-connect-python\n```\n\nThe latest release lives at \u003chttps://pypi.org/project/slmp-connect-python/\u003e, where wheel and tarball downloads and metadata are available.\n\n## Quick Start\n\nRecommended async path:\n\n```python\nimport asyncio\n\nfrom slmp import SlmpConnectionOptions, open_and_connect, read_named, write_typed\n\n\nasync def main() -\u003e None:\n    options = SlmpConnectionOptions(\n        host=\"192.168.250.100\",\n        plc_family=\"iq-f\",\n        port=1025,\n    )\n    async with await open_and_connect(options) as client:\n        before = await read_named(client, [\"D100\", \"D200:F\", \"D50.3\"])\n        print(\"before:\", before)\n\n        await write_typed(client, \"D100\", \"U\", 42)\n\n        after = await read_named(client, [\"D100\", \"D200:F\", \"D50.3\"])\n        print(\"after:\", after)\n\n\nasyncio.run(main())\n```\n\nChoose canonical `plc_family` explicitly.\nIn the recommended high-level helper layer, the only PLC selector is `plc_family`.\n\n## High-Level PLC Selection\n\nFor normal application code:\n\n- set `plc_family`\n- let the library derive the fixed frame type, access profile, `X` / `Y` text rule, and device-range family\n- do not pass raw `frame_type`, `plc_series`, or `device_family`\n\n| `plc_family` | Derived `frame_type` | Derived `access_profile` | `X` / `Y` text | Derived range family | Notes |\n| --- | --- | --- | --- | --- | --- |\n| `iq-f` | `3e` | `ql` | octal | `iq-f` | live-validated |\n| `iq-r` | `4e` | `iqr` | hexadecimal | `iq-r` | live-validated |\n| `iq-l` | `4e` | `iqr` | hexadecimal | `iq-l` | live-validated on `L16HCPU` |\n| `mx-f` | `4e` | `iqr` | hexadecimal | `mx-f` | fixed family mapping |\n| `mx-r` | `4e` | `iqr` | hexadecimal | `mx-r` | fixed family mapping |\n| `qcpu` | `3e` | `ql` | hexadecimal | `qcpu` | retained path |\n| `lcpu` | `3e` | `ql` | hexadecimal | `lcpu` | retained path |\n| `qnu` | `3e` | `ql` | hexadecimal | `qnu` | retained path |\n| `qnudv` | `3e` | `ql` | hexadecimal | `qnudv` | retained path |\n\nLow-level compatibility tools may still work with raw `frame_type` / `plc_series`, but that is not the normal public helper path.\n\nHigh-level accepted `plc_family` values:\n\n| Canonical | Typical target | Notes |\n| --- | --- | --- |\n| `iq-f` | FX5 / iQ-F | `X` / `Y` use manual octal text |\n| `iq-r` | iQ-R | `X` / `Y` use hexadecimal text |\n| `iq-l` | iQ-L | independent iQ-L range rules; live-validated on `L16HCPU` |\n| `mx-f` | MX-F | fixed high-level family mapping |\n| `mx-r` | MX-R | fixed high-level family mapping |\n| `qcpu` | QCPU | `3e/ql` fixed profile |\n| `lcpu` | LCPU | `3e/ql` fixed profile |\n| `qnu` | QnU | `3e/ql` fixed profile |\n| `qnudv` | QnUDV | `3e/ql` fixed profile |\n\nPractical rules:\n\n- non-`iQ-F` `X` / `Y`: text such as `X20` / `Y20` is interpreted as hexadecimal\n- `iQ-F` / FX5 `X` / `Y`: text such as `X100` / `Y100` is interpreted as manual octal notation and encoded to the binary numeric value\n- example: `X100` on `iQ-F` becomes binary device number `0x40`\n- if you pass a numeric `DeviceRef`, string notation is already resolved, so `plc_family` is not needed for that one address\n- short aliases such as `iqf`, `iqr`, `q`, `l`, and `qnudvcpu` are rejected\n\n## Supported PLC Registers\n\nStart with these public high-level families first:\n\n- word devices: `D`, `SD`, `R`, `ZR`, `TN`, `CN`\n- bit devices: `M`, `X`, `Y`, `SM`, `B`\n- typed forms: `D200:F`, `D300:L`, `D100:S`\n- mixed snapshot forms: `D50.3`, `D100`, `D200:F`\n- current-value long families: `LTN`, `LSTN`, `LCN`\n- 32-bit index register: `LZ`\n\nLong-family route notes:\n\n- `LTN`, `LSTN`, `LCN`, and `LZ` default to 32-bit `:D` access in high-level helpers.\n- `LCN` current-value reads and writes use random dword access in the high-level helpers.\n- `LTS`, `LTC`, `LSTS`, and `LSTC` state reads use the long timer 4-word decode helpers.\n- `LCS` and `LCC` state reads use direct bit read.\n- High-level state writes for `LTS`/`LTC`/`LSTS`/`LSTC`/`LCS`/`LCC` use random bit write (`0x1402`).\n- Low-level direct bit writes and direct word writes to these long-family logical forms are guarded before transport.\n\nSee the full public table in [Supported PLC Registers](docsrc/user/SUPPORTED_REGISTERS.md).\n\n## Public Documentation\n\n- [Getting Started](docsrc/user/GETTING_STARTED.md)\n- [Supported PLC Registers](docsrc/user/SUPPORTED_REGISTERS.md)\n- [Latest Communication Verification](docsrc/user/LATEST_COMMUNICATION_VERIFICATION.md)\n- [User Guide](docsrc/user/USER_GUIDE.md)\n- [Samples](docsrc/user/SAMPLES.md)\n- [Error Codes](docsrc/user/ERROR_CODES.md)\n\nMaintainer-only notes and retained evidence live under `internal_docs/`.\n\n## High-Level API Guide\n\n### Address Normalization\n\n```python\nfrom slmp import format_address, normalize_address, parse_address\n\nprint(normalize_address(\"x20\"))   # X20\nprint(normalize_address(\"d200\"))  # D200\nprint(normalize_address(\"x100\", plc_family=\"iq-f\"))  # X100\n\nparsed = parse_address(\"d200:f\")\nprint(parsed.base_device, parsed.dtype)  # D200 F\nprint(format_address(parsed))            # D200:F\n```\n\n### Single Typed Values\n\n```python\nfrom slmp import read_typed, write_typed\n\ntemperature = await read_typed(client, \"D200\", \"F\")\ncounter = await read_typed(client, \"D300\", \"L\")\nawait write_typed(client, \"D100\", \"U\", 1234)\n```\n\nUse `.bit` notation only with word devices such as `D50.3`.\nAddress bit devices directly as `M1000`, `M1001`, `X20`, or `Y20`.\nFor communication, `X` / `Y` string addresses require explicit `plc_family`.\n\n### Device Range Catalog\n\nUse `plc_family` and read the derived family SD block once.\n\n```python\nfrom slmp import SlmpClient\n\nwith SlmpClient(\"192.168.250.100\", 1025, plc_family=\"qnu\") as client:\n    catalog = client.read_device_range_catalog()\n    for entry in catalog.entries:\n        print(entry.device, entry.point_count, entry.address_range)\n```\n\nThis path does not call `read_type_name()`. The client uses the fixed range family derived from `plc_family`.\n\n## Development\n\n```bash\nrun_ci.bat\nbuild_docs.bat\nrelease_check.bat\n```\n\n## License\n\nDistributed under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffa-yoshinobu%2Fplc-comm-slmp-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffa-yoshinobu%2Fplc-comm-slmp-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffa-yoshinobu%2Fplc-comm-slmp-python/lists"}