Metadata-Version: 2.4
Name: ilesp
Version: 0.2.2
Summary: Tomas (同枢) — deterministic WCS + RCS scheduling, built-in simulation, Modbus/VDA5050 adapter seam — ILESP standard edition
Author: ILESP Contributors
License: MIT
Project-URL: Homepage, https://ilesp.123aiot.com
Project-URL: Source, https://github.com/123aiot/ILESP
Project-URL: Documentation, https://github.com/123aiot/ILESP/tree/main/docs
Project-URL: Changelog, https://github.com/123aiot/ILESP/blob/main/CHANGELOG.md
Keywords: tomas,wcs,rcs,logistics,warehouse,amr,simulation,digital-twin,modbus,vda5050
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Manufacturing
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: api
Requires-Dist: fastapi>=0.110; extra == "api"
Requires-Dist: uvicorn[standard]>=0.27; extra == "api"
Provides-Extra: modbus
Requires-Dist: pymodbus>=3.6; extra == "modbus"
Provides-Extra: vda5050
Requires-Dist: paho-mqtt>=1.6; extra == "vda5050"
Provides-Extra: aethon
Provides-Extra: all
Requires-Dist: fastapi>=0.110; extra == "all"
Requires-Dist: uvicorn[standard]>=0.27; extra == "all"
Requires-Dist: pymodbus>=3.6; extra == "all"
Requires-Dist: paho-mqtt>=1.6; extra == "all"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Requires-Dist: fastapi>=0.110; extra == "dev"
Requires-Dist: uvicorn[standard]>=0.27; extra == "dev"
Requires-Dist: pymodbus>=3.6; extra == "dev"
Requires-Dist: ruff>=0.6; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Dynamic: license-file

# ilesp — Tomas 同枢（ILESP 标准版）

> **双枢同源，预演万线** —— 海神双芯，智造同频。

**统一物流设备调度平台**：一个代码库内实现 **WCS（仓库控制系统）+ RCS（机器人调度系统）+ 内置仿真**，
通过**适配器缝**向真实设备平滑过渡——模拟与真实是同一接口的两种实现，切换 = 换配置，代码零分叉。

> 📖 **完整使用说明（含专业版塔台）**：[docs/USAGE.md](docs/USAGE.md) —— 安装启动 · 控制台与塔台图解 ·
> 任务状态机 / 三层交通管制 / 事故 WarRoom 概念详解 · API 速查 · FAQ（配 8 张界面截图 + 5 张 SVG 图）。
> 🌐 **官网**：https://ilesp.123aiot.com ｜ 家族产品：[Nereus 同衡 · CPS 数字孪生](https://cps.123aiot.com)（体系：海神双芯，智造同频）
> 📚 **文档**：[docs/USAGE.md](docs/USAGE.md) · [docs/DEPLOY.md](docs/DEPLOY.md) · 源码：https://github.com/123AIoT/ILESP
> 🛠 **生产部署运维手册**：[docs/DEPLOY.md](docs/DEPLOY.md) —— 环境变量全集 · TLS/反代 · 备份恢复 · 升级回滚 · 安全清单。
> 📋 **发布记录**：[CHANGELOG.md](CHANGELOG.md) · **安全报告**：[SECURITY.md](SECURITY.md)

## 设计决策与演进规划

见 [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)（统一 vs 分散）与 [docs/ROADMAP.md](docs/ROADMAP.md)（三阶段生产化：试点 → 交通管制内核 → 多厂商矩阵）。结论：**模块化单体**——WCS/RCS/SIM 是三个有界上下文，
内部通过任务契约通信（与将来拆分后对外的契约同形）；模拟层实现与真实设备驱动**相同的 Adapter 接口**。

## 能力边界（先说清不做什么）

ILESP 只做**设备调度与执行**：站台拓扑、路径规划、设备级推进、车队派工与交通管制。
**它不做仓库/库存仿真**——货架、库位、巷道、料箱、托盘、入出库、拣选、盘点、移库、库存台账
都不在 ILESP 的模型里（`payload` 是任意字典，无容器类型模型）。
物理场景与生产仿真是姊妹产品 **Nereus 同衡（CPS）** 的定位（万物同衡，虚实相应）；ILESP 与它通过标准协议对接。
误把 ILESP 当仓库仿真工具用，会期待它根本不具备的能力。

> **标准版 vs 专业版**：本包为**标准版**——调度服务 + 内置仿真 + 控制台（零构建链，
> `pip install` 即用）。专业版 3D 塔台、事故 WarRoom、数字实验台、Copilot、生态集成
> 随源码仓库交付，见 [仓库](https://github.com/123AIoT/ILESP)。

## 架构

```
WMS / MES / Aethon ──HTTP(幂等任务接口)──► ┌─────────── ILESP ───────────┐
                                          │ wcs: 站台拓扑/**加权路由**/   │
                                          │      **故障重规划**/设备级调度│
                                          │ rcs: 车队注册/**多目标派工**   │
                                          │      (预留+TTL+**L1按段路权**)│
                                          │ core: 任务状态机/幂等账本/事件  │
                                          │ adapters: ◄─ 适配器缝 ─►      │
                                          │   ├── simulated/（内置仿真）    │
                                          │   └── modbus 等（真实驱动）     │
CPS 数字孪生 ◄──遥测/状态(标准协议)──────────└─────────────────────────────┘
```

## 快速开始

```bash
pip install -e ".[api]"
uvicorn ilesp.api:app --port 8800     # 或 python -m ilesp.api
pytest                                # 测试（含端到端竖切）
```

### Docker（可选）

```bash
docker compose up -d                      # 仅 app（内置仿真，零外部依赖）
docker compose --profile mqtt up -d       # 额外起 mosquitto（接真车 VDA5050 时需要）
ILESP_API_KEY=... docker compose up -d    # 生产：务必配鉴权
```

> ⚠️ **未构建验证**：本机没有安装 docker（实测 `docker: command not found`），
> `Dockerfile` / `docker-compose.yml` 是按规范手写并做了静态校验（多阶段、非 root、
> 健康检查、数据卷、密钥排除），但**尚未 `docker build` 跑通**。
> 首次使用请先 `docker compose build`；本地开发不需要 Docker（见上方 pip 方式）。

## 端到端语义（竖切）

`POST /api/v1/tasks`（幂等）→ WCS 依站台拓扑规划路径 → 逐站设备级执行
（simulated 输送线状态机）→ 需要搬运时创建 RCS 搬运腿 → 派给模拟 AMR（行驶/电池）→
到达 → 下一腿 → 任务 COMPLETED。全程迁移进 SQLite 事件账本（WAL），来源归因。

## 确定性

仿真适配器以固定 tick + 可传 seed 的 Random 驱动——相同 seed + 相同任务序列 ⇒ 相同结局
（对拍/回归友好，与 CPS 的确定性文化一致）。

## 生产化路线

| 已内置 | 路线图 |
|---|---|
| 幂等任务接口（主键+指纹+201/200/409） | 鉴权/TLS、多实例会话路由 |
| 严格状态机 + DISPATCHED 超时回退（补参考实现的缺口） | 真实设备驱动补全（Modbus 点表由配置生成） |
| WCS **加权路由 + 故障重规划**（绕开故障站台，无解则诚实 FAILED） | VDA5050 over MQTT 生产化（多厂商 AMR） |
| L1 **按区段释放**路权 + L2 时空 A* 预约（先取后还，无真空窗口） | L3 动态避让闭环 |
| 事件账本 + 断线补发（PENDING 与 DISPATCHED 超时双覆盖） | 塔台可视化（复用 CPS 3D 管线） |
| 确定性仿真 + seed 对拍（同 seed 同结局，含重规划） | 多车型能力模型（叉取/顶升/料箱） |
| 调度质量指标（端到端时长/首动延迟/吞吐/车队利用率） | 充电策略优化（现为阈值触发） |
| 多车型能力模型（载重/容器/可对接 kind，派工硬约束 + 执行侧双保险） | VDA5050 `nodePosition` 精度接入（L3 现用 progress 近似） |
| L1/L2/L3 三层交通管制（L3 让行保留 L1/L2，不改路） | 外部 IdP / JWS 非对称签名 |
| RBAC 三角色 + HMAC 令牌 + 请求签名族 + 鉴权审计（**默认拒绝**） | 审计外送 SIEM |

## 鉴权（**升级必读**）

2026-10-07 起写面默认拒绝；配了凭据后**读写都要凭据**：

| 配置 | 读面 | 写面 |
|---|---|---|
| 无任何凭据（观察模式） | 开放 | **403**（`ILESP_ANONYMOUS_WRITE=1` 可放开，**仅限演示**） |
| 配了 `ILESP_API_KEY` / `ILESP_TOKEN_SECRET` / `ILESP_SIGNATURE_SECRET` | **401** 需凭据 | 需凭据 + 角色足够（否则 403） |

角色：`viewer`（只读）/ `operator`（任务与仿真操作）/ `admin`（布局热重载、车队扩缩容、鉴权）。
凭据形式：`X-ILESP-API-Key`、`Authorization: Bearer <token>`、
或 RCS-2000 风格签名（`X-ILESP-Key` + `X-ILESP-Timestamp` + `X-ILESP-Signature`）。
**生产部署务必配置凭据**，否则写操作会被拒——这是安全目标的修正，不是缺陷。

### 浏览器里怎么填凭据

控制台与塔台顶栏都有 **🔑 凭据** 按钮，点开粘贴 API Key 或 `Bearer` 令牌即可
（存 `sessionStorage`，关标签页即失效）。未填时界面显示「只读」，
写操作会给出明确提示而不是静默失败。

SSE / WebSocket 受浏览器限制**无法自定义请求头**，凭据通过 `?key=` 查询参数传递
（与 WS 命令鉴权既有做法一致）。SSE 虽在中间件白名单里，但**端点内会再校验一次**，
不构成绕过鉴权的后门。

## 测试

```bash
pytest tests/ -q
```
