上传初版SDK
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,257 @@
|
|||||||
|
# 项目架构
|
||||||
|
|
||||||
|
## 整体架构图
|
||||||
|
|
||||||
|
```
|
||||||
|
arxml_sdk/
|
||||||
|
├── src/ # 源代码
|
||||||
|
│ ├── __init__.py # 包入口,导出全部公共API
|
||||||
|
│ ├── core/ # 核心基础设施层
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── base.py # Base 基类
|
||||||
|
│ │ ├── constants.py # ARXML 标签常量
|
||||||
|
│ │ └── enums.py # AUTOSAR 枚举类型
|
||||||
|
│ ├── types/ # 数据类型层
|
||||||
|
│ │ ├── __init__.py
|
||||||
|
│ │ ├── base_type.py # 基础数据类型
|
||||||
|
│ │ ├── unit.py # 单位类型
|
||||||
|
│ │ ├── data_constraint.py # 数据约束
|
||||||
|
│ │ ├── compu_method.py # 计算方法
|
||||||
|
│ │ ├── application_types.py # 应用数据类型
|
||||||
|
│ │ ├── implementation_types.py # 实现数据类型
|
||||||
|
│ │ ├── sw_addr_method.py # 软件地址方法
|
||||||
|
│ │ ├── data_mapping.py # 数据类型映射
|
||||||
|
│ │ ├── sw_component_type.py # 软件组件类型
|
||||||
|
│ │ ├── interface.py # 接口定义
|
||||||
|
│ │ ├── package.py # 包管理
|
||||||
|
│ │ └── swc_internal_behavior.py # SWC内部行为
|
||||||
|
│ └── utils/ # 工具层
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ └── arxml_writer.py # ARXML文档写入
|
||||||
|
└── tests/ # 测试
|
||||||
|
```
|
||||||
|
|
||||||
|
## 模块职责
|
||||||
|
|
||||||
|
### core 模块 - 核心基础设施层
|
||||||
|
|
||||||
|
提供 SDK 运行所需的基础组件,不依赖其他业务模块。
|
||||||
|
|
||||||
|
| 文件 | 职责 | 关键类/函数 |
|
||||||
|
|------|------|-------------|
|
||||||
|
| base.py | 定义所有类型的基础类 | `Base` (dataclass), `create_uuid()`, `create_text_element()` |
|
||||||
|
| constants.py | ARXML 标签常量统一管理 | 约140个XML标签常量定义 |
|
||||||
|
| enums.py | AUTOSAR 枚举类型定义 | `Category`, `Encoding`, `PortDirection` 等12个枚举 |
|
||||||
|
|
||||||
|
**Base 类核心属性:**
|
||||||
|
|
||||||
|
| 属性 | 类型 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| name | str | 元素名称 |
|
||||||
|
| id | Optional[int] | 元素标识符 |
|
||||||
|
| parent | Optional[Base] | 父元素引用 |
|
||||||
|
| description | Optional[str] | 元素描述 |
|
||||||
|
| package_path | str | 完整包路径 (如 `/Pkg1/Pkg2/Name`) |
|
||||||
|
|
||||||
|
**Base 类核心方法:**
|
||||||
|
|
||||||
|
| 方法 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| to_arxml(doc) | 抽象方法,将对象序列化为 ARXML DOM 元素 |
|
||||||
|
| class_name | 属性,获取类型名称 |
|
||||||
|
| parent_id | 属性,获取父类 ID |
|
||||||
|
|
||||||
|
### types 模块 - 数据类型层
|
||||||
|
|
||||||
|
实现 AUTOSAR 数据模型的各个类型,依赖 core 模块。
|
||||||
|
|
||||||
|
| 文件 | 职责 | 主要类 |
|
||||||
|
|------|------|--------|
|
||||||
|
| base_type.py | 基础数据类型 (SW-BASE-TYPE) | `BaseType` |
|
||||||
|
| unit.py | 数据单位 | `Unit` |
|
||||||
|
| data_constraint.py | 数据约束范围 | `DataConstraint` |
|
||||||
|
| compu_method.py | 计算方法 (线性转换/文本表) | `Linear`, `TextTable`, `CompuMethod` |
|
||||||
|
| application_types.py | 应用层数据类型 | `ApplicationBooleanDataType`, `ApplicationValueDataType`, `ApplicationStructureDataType`, `ApplicationArrayDataType` |
|
||||||
|
| implementation_types.py | 实现层数据类型 | `ImplementationValueDataType`, `ImplementationStructureDataType`, `ImplementationArrayDataType` |
|
||||||
|
| sw_addr_method.py | 软件地址方法 | `SwAddrMethod` |
|
||||||
|
| data_mapping.py | 应用-实现类型映射 | `DataTypeMapping`, `DataTypeMappingSet` |
|
||||||
|
| sw_component_type.py | 软件组件类型和端口 | `ApplicationSwComponentType`, `RPortPrototype`, `PPortPrototype`, `PRPortPrototype` |
|
||||||
|
| interface.py | 接口定义 | `SenderReceiverInterface`, `ClientServerInterface`, `ModeSwitchInterface` |
|
||||||
|
| package.py | AUTOSAR 包 | `Package` |
|
||||||
|
| swc_internal_behavior.py | SWC 内部行为 | `RunnableEntity`, `TimingEvent`, `InitEvent`, `SwcInternalBehavior` |
|
||||||
|
|
||||||
|
### utils 模块 - 工具层
|
||||||
|
|
||||||
|
提供 ARXML 文档创建和写入功能。
|
||||||
|
|
||||||
|
| 文件 | 职责 | 关键函数 |
|
||||||
|
|------|------|----------|
|
||||||
|
| arxml_writer.py | ARXML 文档创建和写入 | `create_arxml_document()`, `write_arxml()`, `write_arxml_pretty()` |
|
||||||
|
|
||||||
|
## 类型继承体系
|
||||||
|
|
||||||
|
```
|
||||||
|
Base (core.base)
|
||||||
|
├── BaseType (types.base_type)
|
||||||
|
├── Unit (types.unit)
|
||||||
|
├── DataConstraint (types.data_constraint)
|
||||||
|
├── CompuMethod (types.compu_method)
|
||||||
|
│ ├── Linear
|
||||||
|
│ └── TextTable
|
||||||
|
├── ApplicationDataType (types.application_types)
|
||||||
|
│ ├── ApplicationBooleanDataType
|
||||||
|
│ ├── ApplicationValueDataType
|
||||||
|
│ ├── ApplicationStructureDataType
|
||||||
|
│ │ └── StructureElement (内部类)
|
||||||
|
│ └── ApplicationArrayDataType
|
||||||
|
│ └── ArrayElement (内部类)
|
||||||
|
├── ImplementationDataType (types.implementation_types)
|
||||||
|
│ ├── ImplementationValueDataType
|
||||||
|
│ ├── ImplementationStructureDataType
|
||||||
|
│ │ └── StructureElement (内部类)
|
||||||
|
│ └── ImplementationArrayDataType
|
||||||
|
│ └── ArrayElement (内部类)
|
||||||
|
├── SwAddrMethod (types.sw_addr_method)
|
||||||
|
├── DataTypeMapping (types.data_mapping)
|
||||||
|
│ └── DataTypeMappingSet
|
||||||
|
├── SwComponentType (types.sw_component_type)
|
||||||
|
│ ├── AtomicComponentType
|
||||||
|
│ │ └── ApplicationSwComponentType
|
||||||
|
│ └── CompositionSwComponentType
|
||||||
|
├── PortPrototype (types.sw_component_type)
|
||||||
|
│ ├── RPortPrototype
|
||||||
|
│ ├── PPortPrototype
|
||||||
|
│ └── PRPortPrototype
|
||||||
|
├── Interface (types.interface)
|
||||||
|
│ ├── SenderReceiverInterface
|
||||||
|
│ │ └── DataElement (内部类)
|
||||||
|
│ ├── ClientServerInterface
|
||||||
|
│ │ ├── Operation (内部类)
|
||||||
|
│ │ └── Argument (内部类)
|
||||||
|
│ ├── ModeSwitchInterface
|
||||||
|
│ ├── ParameterInterface
|
||||||
|
│ ├── TriggerInterface
|
||||||
|
│ └── NvDataInterface
|
||||||
|
├── Package (types.package)
|
||||||
|
└── SwcInternalBehavior (types.swc_internal_behavior)
|
||||||
|
├── RunnableEntity
|
||||||
|
└── EventType (Union)
|
||||||
|
├── InitEvent
|
||||||
|
├── TimingEvent
|
||||||
|
├── OperationInvokedEvent
|
||||||
|
└── DataReceivedEvent
|
||||||
|
```
|
||||||
|
|
||||||
|
## 依赖关系图
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────┐
|
||||||
|
│ arxml_sdk (src/__init__.py) │
|
||||||
|
│ 导出全部 193 个公共 API 符号 │
|
||||||
|
└─────────────────────────────────────┘
|
||||||
|
│
|
||||||
|
┌───────────────────────────┼───────────────────────────┐
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||||
|
│ core 模块 │ │ types 模块 │ │ utils 模块 │
|
||||||
|
│ (基础设施层) │ │ (业务逻辑层) │ │ (工具层) │
|
||||||
|
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
|
||||||
|
│ Base 基类 │ │ 数据类型类 │ │ ARXML文档创建 │
|
||||||
|
│ 常量定义 │◄─────►│ 组件类型类 │ │ ARXML文件写入 │
|
||||||
|
│ 枚举定义 │ │ 接口定义类 │ │ │
|
||||||
|
│ UUID/文本工具 │ │ 包管理类 │ │ │
|
||||||
|
└─────────────────┘ │ 内部行为类 │ └─────────────────┘
|
||||||
|
└─────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────┐
|
||||||
|
│ tests 模块 │
|
||||||
|
│ (测试层) │
|
||||||
|
├─────────────────┤
|
||||||
|
│ 单元测试 │
|
||||||
|
│ 集成测试 │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**依赖约束:**
|
||||||
|
- `core` → 无依赖(最底层)
|
||||||
|
- `types` → 依赖 `core`
|
||||||
|
- `utils` → 依赖 `core`
|
||||||
|
- `tests` → 依赖 `src` 所有模块
|
||||||
|
|
||||||
|
## 设计模式
|
||||||
|
|
||||||
|
### 1. 工厂函数模式
|
||||||
|
|
||||||
|
所有类型都配有 `create_xxx()` 工厂函数,简化对象创建:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 使用工厂函数
|
||||||
|
uint8 = create_base_type("UInt8", size=8)
|
||||||
|
|
||||||
|
# 替代直接实例化(如果存在构造函数)
|
||||||
|
uint8 = BaseType(name="UInt8", size=8)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 组合模式
|
||||||
|
|
||||||
|
通过 `add_xxx()` 方法支持动态添加子元素:
|
||||||
|
|
||||||
|
```python
|
||||||
|
component = ApplicationSwComponentType(name="Sensor")
|
||||||
|
component.add_port(PPortPrototype(name="DataPort"))
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 序列化模式
|
||||||
|
|
||||||
|
所有类型都实现 `to_arxml(doc)` 方法,将自身序列化为 ARXML DOM 元素:
|
||||||
|
|
||||||
|
```python
|
||||||
|
element = component.to_arxml(doc)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 数据类模式
|
||||||
|
|
||||||
|
使用 `@dataclass` 简化数据类定义:
|
||||||
|
|
||||||
|
```python
|
||||||
|
@dataclass
|
||||||
|
class BaseType:
|
||||||
|
name: str
|
||||||
|
size: int
|
||||||
|
category: Optional[Category] = None
|
||||||
|
encoding: Optional[Encoding] = None
|
||||||
|
```
|
||||||
|
|
||||||
|
## 数据流
|
||||||
|
|
||||||
|
```
|
||||||
|
用户代码
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
创建对象 (工厂函数)
|
||||||
|
│
|
||||||
|
├──► BaseType, ApplicationDataType, SwComponentType 等
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
序列化 (to_arxml)
|
||||||
|
│
|
||||||
|
├──► XML DOM Element
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
写入文件 (arxml_writer)
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
.arxml 文件
|
||||||
|
```
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
| 方面 | 详情 |
|
||||||
|
|------|------|
|
||||||
|
| 编程语言 | Python 3 |
|
||||||
|
| 标准库 | `uuid`, `xml.dom.minidom`, `dataclasses`, `typing`, `enum` |
|
||||||
|
| 测试框架 | pytest |
|
||||||
|
| 目标格式 | AUTOSAR ARXML (R4.4 schema) |
|
||||||
|
| 版本 | 2.0.1 |
|
||||||
+548
@@ -0,0 +1,548 @@
|
|||||||
|
# 使用指南
|
||||||
|
|
||||||
|
## 目录
|
||||||
|
|
||||||
|
- [快速开始](#快速开始)
|
||||||
|
- [基础类型创建](#基础类型创建)
|
||||||
|
- [应用数据类型](#应用数据类型)
|
||||||
|
- [接口定义](#接口定义)
|
||||||
|
- [软件组件](#软件组件)
|
||||||
|
- [内部行为](#内部行为)
|
||||||
|
- [打包与导出](#打包与导出)
|
||||||
|
- [完整示例](#完整示例)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 环境要求
|
||||||
|
|
||||||
|
- Python 3.8+
|
||||||
|
|
||||||
|
### 安装
|
||||||
|
|
||||||
|
将 `src` 目录添加到 Python 路径即可使用:
|
||||||
|
|
||||||
|
```python
|
||||||
|
import sys
|
||||||
|
sys.path.insert(0, '/path/to/arxml_sdk/src')
|
||||||
|
```
|
||||||
|
|
||||||
|
或直接使用相对导入:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import create_arxml_document, write_arxml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 最小示例
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
create_arxml_document, write_arxml, create_package,
|
||||||
|
create_base_type, Category, Encoding
|
||||||
|
)
|
||||||
|
|
||||||
|
doc = create_arxml_document()
|
||||||
|
base_type = create_base_type("UInt8", size=8, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
package = create_package("MyPackage", elements=[base_type])
|
||||||
|
package_element = package.to_arxml(doc)
|
||||||
|
doc.documentElement.appendChild(package_element)
|
||||||
|
write_arxml(doc, "minimal.arxml")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 基础类型创建
|
||||||
|
|
||||||
|
### 创建基本整数类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import create_base_type, Category, Encoding
|
||||||
|
|
||||||
|
uint8 = create_base_type("UInt8", size=8, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
uint16 = create_base_type("UInt16", size=16, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
sint8 = create_base_type("Sint8", size=8, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
float32 = create_base_type("Float32", size=32, encoding=Encoding.IEEE754)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 创建带文本表的类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
create_base_type, create_unit, create_data_constraint,
|
||||||
|
create_linear, create_text_table, create_compu_method,
|
||||||
|
Category, LowerSts, UpperSts
|
||||||
|
)
|
||||||
|
|
||||||
|
unit = create_unit("km/h", display="km/h", factor=1.0, offset=0.0)
|
||||||
|
|
||||||
|
constraint = create_data_constraint(
|
||||||
|
"SpeedConstraint",
|
||||||
|
lower=0, upper=250,
|
||||||
|
lower_sts=LowerSts.CLOSED,
|
||||||
|
upper_sts=UpperSts.OPEN
|
||||||
|
)
|
||||||
|
|
||||||
|
linear = create_linear(factor=0.01, offset=0)
|
||||||
|
|
||||||
|
compu = create_compu_method(
|
||||||
|
"SpeedConversion",
|
||||||
|
unit=unit,
|
||||||
|
linear=linear,
|
||||||
|
category=Category.LINEAR
|
||||||
|
)
|
||||||
|
|
||||||
|
value_type = create_value_type(
|
||||||
|
"Speed",
|
||||||
|
unit=unit,
|
||||||
|
compu_method=compu,
|
||||||
|
data_constraint=constraint
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 应用数据类型
|
||||||
|
|
||||||
|
### 布尔类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import create_boolean_type, create_compu_method, create_linear, Category
|
||||||
|
|
||||||
|
bool_compu = create_compu_method(
|
||||||
|
"BoolConversion",
|
||||||
|
linear=create_linear(factor=1, offset=0),
|
||||||
|
category=Category.BOOLEAN
|
||||||
|
)
|
||||||
|
|
||||||
|
bool_type = create_boolean_type("ErrorFlag", compu_method=bool_compu)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 值类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import create_value_type, create_unit, create_linear, create_compu_method, Category
|
||||||
|
|
||||||
|
unit = create_unit("deg", display="°C")
|
||||||
|
linear = create_linear(factor=0.1, offset=-40)
|
||||||
|
compu = create_compu_method("Temperature", unit=unit, linear=linear, category=Category.LINEAR)
|
||||||
|
|
||||||
|
temp_type = create_value_type("Temperature", unit=unit, compu_method=compu)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 结构体类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
ApplicationStructureDataType, create_value_type,
|
||||||
|
create_unit, create_linear, create_compu_method
|
||||||
|
)
|
||||||
|
|
||||||
|
unit = create_unit("V")
|
||||||
|
linear = create_linear(factor=0.001, offset=0)
|
||||||
|
compu = create_compu_method("Voltage", unit=unit, linear=linear, category=Category.LINEAR)
|
||||||
|
voltage_type = create_value_type("Voltage", unit=unit, compu_method=compu)
|
||||||
|
|
||||||
|
current_type = create_value_type("Current", unit=unit, compu_method=compu)
|
||||||
|
|
||||||
|
structure = ApplicationStructureDataType(name="PowerData")
|
||||||
|
structure.add_element(
|
||||||
|
ApplicationStructureDataType.StructureElement(name="voltage", data_type=voltage_type, offset=0)
|
||||||
|
)
|
||||||
|
structure.add_element(
|
||||||
|
ApplicationStructureDataType.StructureElement(name="current", data_type=current_type, offset=32)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数组类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import ApplicationArrayDataType, create_value_type, create_unit, Semantic
|
||||||
|
|
||||||
|
element_type = create_value_type("SensorValue", unit=create_unit("counts"))
|
||||||
|
|
||||||
|
array_type = ApplicationArrayDataType(name="SensorData")
|
||||||
|
array_type.element = ApplicationArrayDataType.ArrayElement(
|
||||||
|
length=10,
|
||||||
|
data_type=element_type,
|
||||||
|
array_size_semantics=Semantic.FIXED
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 实现数据类型
|
||||||
|
|
||||||
|
### 值类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import create_impl_value_type, create_base_type, create_value_type, Encoding
|
||||||
|
|
||||||
|
base_type = create_base_type("UInt16", size=16, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
app_type = create_value_type("AppCounter")
|
||||||
|
|
||||||
|
impl_type = create_impl_value_type("ImplCounter", base_type=base_type)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 结构体类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import ImplementationStructureDataType, create_impl_value_type, create_base_type, Encoding
|
||||||
|
|
||||||
|
base_u8 = create_base_type("UInt8", size=8, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
base_u16 = create_base_type("UInt16", size=16, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
|
||||||
|
impl_u8 = create_impl_value_type("ImplUInt8", base_type=base_u8)
|
||||||
|
impl_u16 = create_impl_value_type("ImplUInt16", base_type=base_u16)
|
||||||
|
|
||||||
|
struct_type = ImplementationStructureDataType(name="ImplStatus")
|
||||||
|
struct_type.add_element(
|
||||||
|
ImplementationStructureDataType.StructureElement(name="status", data_type=impl_u8, offset=0)
|
||||||
|
)
|
||||||
|
struct_type.add_element(
|
||||||
|
ImplementationStructureDataType.StructureElement(name="value", data_type=impl_u16, offset=8)
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 数组类型
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import ImplementationArrayDataType, create_impl_value_type, create_base_type, Semantic, Encoding
|
||||||
|
|
||||||
|
base = create_base_type("UInt32", size=32, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
element_type = create_impl_value_type("ImplUInt32", base_type=base)
|
||||||
|
|
||||||
|
impl_array = ImplementationArrayDataType(name="ImplBuffer")
|
||||||
|
impl_array.element = ImplementationArrayDataType.ArrayElement(
|
||||||
|
length=16,
|
||||||
|
data_type=element_type,
|
||||||
|
array_size_semantics=Semantic.FIXED
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数据类型映射
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
DataTypeMapping, DataTypeMappingSet,
|
||||||
|
create_value_type, create_impl_value_type, create_base_type, Encoding
|
||||||
|
)
|
||||||
|
|
||||||
|
base = create_base_type("UInt8", size=8, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
app_type = create_value_type("AppStatus")
|
||||||
|
impl_type = create_impl_value_type("ImplStatus", base_type=base)
|
||||||
|
|
||||||
|
mapping = DataTypeMapping(
|
||||||
|
name="StatusMapping",
|
||||||
|
application_data_type=app_type,
|
||||||
|
implementation_data_type=impl_type
|
||||||
|
)
|
||||||
|
|
||||||
|
mapping_set = DataTypeMappingSet(name="DefaultMappings")
|
||||||
|
mapping_set.add_mapping(mapping)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 接口定义
|
||||||
|
|
||||||
|
### 发送-接收接口
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
SenderReceiverInterface, create_sender_receiver_interface,
|
||||||
|
create_value_type, create_unit, Policy, CalibrationAccess
|
||||||
|
)
|
||||||
|
|
||||||
|
unit = create_unit("km/h")
|
||||||
|
data_element = SenderReceiverInterface.DataElement(
|
||||||
|
name="Speed",
|
||||||
|
data_type=create_value_type("Speed", unit=unit),
|
||||||
|
policy=Policy.STANDARD,
|
||||||
|
calibration_access=CalibrationAccess.READ_ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
interface = create_sender_receiver_interface("SpeedInterface", data_element=data_element)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 客户端-服务端接口
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
ClientServerInterface, create_value_type, create_unit,
|
||||||
|
PortDirection
|
||||||
|
)
|
||||||
|
|
||||||
|
unit = create_unit("counts")
|
||||||
|
|
||||||
|
operation = ClientServerInterface.Operation(
|
||||||
|
name="Initialize",
|
||||||
|
is_server=True,
|
||||||
|
arguments=[
|
||||||
|
ClientServerInterface.Argument(
|
||||||
|
name="config",
|
||||||
|
direction=PortDirection.IN,
|
||||||
|
data_type=create_value_type("Config", unit=unit)
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
cs_interface = ClientServerInterface(name="ControlInterface")
|
||||||
|
cs_interface.add_operation(operation)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 软件组件
|
||||||
|
|
||||||
|
### 创建组件
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
ApplicationSwComponentType, PPortPrototype, RPortPrototype,
|
||||||
|
SenderReceiverInterface, create_sender_receiver_interface,
|
||||||
|
AtomicType, ComponentType
|
||||||
|
)
|
||||||
|
|
||||||
|
interface = create_sender_receiver_interface("DataInterface")
|
||||||
|
port = PPortPrototype(name="DataPort", interface=interface)
|
||||||
|
|
||||||
|
component = ApplicationSwComponentType(
|
||||||
|
name="SensorComponent",
|
||||||
|
supports_multiple_instantiation=False,
|
||||||
|
atomic_type=AtomicType.APPLICATION
|
||||||
|
)
|
||||||
|
component.add_port(port)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 创建组合组件
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import SwComponentType, ComponentType, AtomicComponentType, CompositionSwComponentType
|
||||||
|
|
||||||
|
child1 = ApplicationSwComponentType(name="Child1")
|
||||||
|
child2 = ApplicationSwComponentType(name="Child2")
|
||||||
|
|
||||||
|
composition = CompositionSwComponentType(name="Composition")
|
||||||
|
composition._component_type = ComponentType.COMPOSITION
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 内部行为
|
||||||
|
|
||||||
|
### 创建 Runnable 和事件
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
SwcInternalBehavior, RunnableEntity, TimingEvent, InitEvent,
|
||||||
|
VariableAccess, create_swc_internal_behavior, create_runnable_entity,
|
||||||
|
create_timing_event, create_init_event, create_data_received_event
|
||||||
|
)
|
||||||
|
|
||||||
|
runnable = create_runnable_entity(
|
||||||
|
name="UpdateMeasurement",
|
||||||
|
symbol="UpdateMeasurement",
|
||||||
|
minimum_start_interval=0.01
|
||||||
|
)
|
||||||
|
runnable.add_variable_access(
|
||||||
|
VariableAccess(name="SpeedAccess", port_prototype_ref="SpeedPort")
|
||||||
|
)
|
||||||
|
|
||||||
|
timing_event = create_timing_event(name="Timing_10ms", period=0.01)
|
||||||
|
init_event = InitEvent(name="Init", runnable_ref="UpdateMeasurement")
|
||||||
|
|
||||||
|
data_rx_event = create_data_received_event(
|
||||||
|
name="DataReady",
|
||||||
|
data_element_ref="ReadyFlag",
|
||||||
|
period=0.05
|
||||||
|
)
|
||||||
|
|
||||||
|
behavior = create_swc_internal_behavior(
|
||||||
|
name="SensorBehavior",
|
||||||
|
runnable_entities=[runnable],
|
||||||
|
events=[timing_event, init_event, data_rx_event]
|
||||||
|
)
|
||||||
|
|
||||||
|
component = ApplicationSwComponentType(name="Sensor")
|
||||||
|
component.internal_behavior = behavior
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 打包与导出
|
||||||
|
|
||||||
|
### 基本导出流程
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
create_arxml_document, write_arxml, create_package,
|
||||||
|
get_ar_packages_element, add_package_to_document,
|
||||||
|
create_base_type, create_value_type, create_unit
|
||||||
|
)
|
||||||
|
|
||||||
|
doc = create_arxml_document()
|
||||||
|
packages_element = get_ar_packages_element(doc)
|
||||||
|
|
||||||
|
base_type = create_base_type("UInt8", size=8)
|
||||||
|
app_type = create_value_type("AppData")
|
||||||
|
package = create_package("MyPkg", elements=[base_type, app_type])
|
||||||
|
|
||||||
|
package_element = package.to_arxml(doc)
|
||||||
|
add_package_to_document(doc, package_element)
|
||||||
|
|
||||||
|
write_arxml(doc, "output.arxml")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 格式化输出
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import write_arxml_pretty
|
||||||
|
|
||||||
|
write_arxml_pretty(doc, "output_formatted.arxml")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 完整示例
|
||||||
|
|
||||||
|
以下示例创建一个完整的 AUTOSAR 软件组件配置:
|
||||||
|
|
||||||
|
```python
|
||||||
|
from src import (
|
||||||
|
create_arxml_document, write_arxml_pretty, create_package,
|
||||||
|
get_ar_packages_element, add_package_to_document,
|
||||||
|
create_base_type, create_unit, create_linear, create_compu_method,
|
||||||
|
create_value_type, create_impl_value_type,
|
||||||
|
create_sender_receiver_interface, SenderReceiverInterface,
|
||||||
|
ApplicationSwComponentType, PPortPrototype, RPortPrototype,
|
||||||
|
SwcInternalBehavior, RunnableEntity, TimingEvent, InitEvent,
|
||||||
|
Category, Encoding, AtomicType, Policy, CalibrationAccess,
|
||||||
|
create_sw_addr_method, SectionType, DataTypeMappingSet, DataTypeMapping
|
||||||
|
)
|
||||||
|
|
||||||
|
doc = create_arxml_document()
|
||||||
|
|
||||||
|
base_uint8 = create_base_type("UInt8", size=8, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
base_uint16 = create_base_type("UInt16", size=16, encoding=Encoding.TWO_COMPONENT)
|
||||||
|
|
||||||
|
kmh_unit = create_unit("kmh", display="km/h", factor=1.0, offset=0.0)
|
||||||
|
speed_linear = create_linear(factor=0.01, offset=0)
|
||||||
|
speed_compu = create_compu_method("SpeedCompu", unit=kmh_unit, linear=speed_linear, category=Category.LINEAR)
|
||||||
|
|
||||||
|
app_speed = create_value_type("AppSpeed", unit=kmh_unit, compu_method=speed_compu)
|
||||||
|
impl_speed = create_impl_value_type("ImplSpeed", base_type=base_uint16)
|
||||||
|
|
||||||
|
mapping = DataTypeMapping(
|
||||||
|
name="SpeedMapping",
|
||||||
|
application_data_type=app_speed,
|
||||||
|
implementation_data_type=impl_speed
|
||||||
|
)
|
||||||
|
mapping_set = DataTypeMappingSet(name="SpeedMappingSet")
|
||||||
|
mapping_set.add_mapping(mapping)
|
||||||
|
|
||||||
|
data_element = SenderReceiverInterface.DataElement(
|
||||||
|
name="SpeedData",
|
||||||
|
data_type=app_speed,
|
||||||
|
policy=Policy.STANDARD,
|
||||||
|
calibration_access=CalibrationAccess.READ_WRITE
|
||||||
|
)
|
||||||
|
speed_interface = create_sender_receiver_interface("SpeedInterface", data_element=data_element)
|
||||||
|
|
||||||
|
code_method = create_sw_addr_method("CODE", section_type=SectionType.CODE)
|
||||||
|
|
||||||
|
runnable = RunnableEntity(
|
||||||
|
name="UpdateSpeed",
|
||||||
|
symbol="UpdateSpeed",
|
||||||
|
minimum_start_interval=0.01,
|
||||||
|
can_be_invoked_concurrently=False
|
||||||
|
)
|
||||||
|
runnable.add_variable_access(
|
||||||
|
VariableAccess(name="SpeedAccess", port_prototype_ref="SpeedPort")
|
||||||
|
)
|
||||||
|
|
||||||
|
timing = TimingEvent(name="Timing_10ms", period=0.01)
|
||||||
|
init = InitEvent(name="Init", runnable_ref="UpdateSpeed")
|
||||||
|
|
||||||
|
behavior = SwcInternalBehavior(
|
||||||
|
name="SpeedSensorBehavior",
|
||||||
|
runnable_entities=[runnable],
|
||||||
|
events=[timing, init],
|
||||||
|
symbol="SpeedSensor"
|
||||||
|
)
|
||||||
|
|
||||||
|
port = PPortPrototype(name="SpeedPort", interface=speed_interface)
|
||||||
|
|
||||||
|
component = ApplicationSwComponentType(
|
||||||
|
name="SpeedSensorComponent",
|
||||||
|
supports_multiple_instantiation=False,
|
||||||
|
atomic_type=AtomicType.APPLICATION,
|
||||||
|
internal_behavior=behavior
|
||||||
|
)
|
||||||
|
component.add_port(port)
|
||||||
|
|
||||||
|
package = create_package("SpeedSensorPkg", elements=[
|
||||||
|
base_uint8,
|
||||||
|
base_uint16,
|
||||||
|
kmh_unit,
|
||||||
|
app_speed,
|
||||||
|
impl_speed,
|
||||||
|
mapping_set,
|
||||||
|
speed_interface,
|
||||||
|
code_method,
|
||||||
|
component
|
||||||
|
])
|
||||||
|
|
||||||
|
package_element = package.to_arxml(doc)
|
||||||
|
add_package_to_document(doc, package_element)
|
||||||
|
|
||||||
|
write_arxml_pretty(doc, "SpeedSensor.arxml")
|
||||||
|
print("Generated: SpeedSensor.arxml")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### Q: 如何创建多个端口?
|
||||||
|
|
||||||
|
```python
|
||||||
|
interface1 = create_sender_receiver_interface("DataInterface")
|
||||||
|
interface2 = create_sender_receiver_interface("StatusInterface")
|
||||||
|
|
||||||
|
component = ApplicationSwComponentType(name="MyComponent")
|
||||||
|
component.add_port(PPortPrototype(name="DataPort", interface=interface1))
|
||||||
|
component.add_port(RPortPrototype(name="StatusPort", interface=interface2))
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: 如何添加多个 Runnable?
|
||||||
|
|
||||||
|
```python
|
||||||
|
behavior = SwcInternalBehavior(name="Behavior")
|
||||||
|
|
||||||
|
runnable1 = create_runnable_entity(name="InitRunnable", symbol="Init")
|
||||||
|
runnable2 = create_runnable_entity(name="MainRunnable", symbol="Main", minimum_start_interval=0.01)
|
||||||
|
|
||||||
|
behavior.add_runnable(runnable1)
|
||||||
|
behavior.add_runnable(runnable2)
|
||||||
|
|
||||||
|
component = ApplicationSwComponentType(name="MyComponent")
|
||||||
|
component.internal_behavior = behavior
|
||||||
|
```
|
||||||
|
|
||||||
|
### Q: 如何创建嵌套结构体?
|
||||||
|
|
||||||
|
```python
|
||||||
|
inner_type = create_value_type("InnerValue")
|
||||||
|
inner_struct = ApplicationStructureDataType(name="InnerStruct")
|
||||||
|
inner_struct.add_element(
|
||||||
|
ApplicationStructureDataType.StructureElement(name="value", data_type=inner_type)
|
||||||
|
)
|
||||||
|
|
||||||
|
outer_struct = ApplicationStructureDataType(name="OuterStruct")
|
||||||
|
outer_struct.add_element(
|
||||||
|
ApplicationStructureDataType.StructureElement(name="inner", data_type=inner_struct)
|
||||||
|
)
|
||||||
|
```
|
||||||
+193
@@ -0,0 +1,193 @@
|
|||||||
|
"""
|
||||||
|
arxml_sdk - AUTOSAR ARXML 配置生成 SDK
|
||||||
|
"""
|
||||||
|
from .core import (
|
||||||
|
Base,
|
||||||
|
create_uuid,
|
||||||
|
create_text_element,
|
||||||
|
Category,
|
||||||
|
Encoding,
|
||||||
|
CalibrationAccess,
|
||||||
|
SwCalibrationAccess,
|
||||||
|
UpperSts,
|
||||||
|
LowerSts,
|
||||||
|
ConstraintSpecified,
|
||||||
|
CompuContents,
|
||||||
|
ComponentType,
|
||||||
|
AtomicType,
|
||||||
|
ImplementationCodeType,
|
||||||
|
AccessPoint,
|
||||||
|
PortDirection,
|
||||||
|
Semantic,
|
||||||
|
SectionType,
|
||||||
|
Policy,
|
||||||
|
)
|
||||||
|
from .types import (
|
||||||
|
BaseType,
|
||||||
|
create_base_type,
|
||||||
|
Unit,
|
||||||
|
create_unit,
|
||||||
|
DataConstraint,
|
||||||
|
create_data_constraint,
|
||||||
|
Linear,
|
||||||
|
TextTable,
|
||||||
|
CompuMethod,
|
||||||
|
create_linear,
|
||||||
|
create_text_table,
|
||||||
|
create_compu_method,
|
||||||
|
ApplicationDataType,
|
||||||
|
ApplicationBooleanDataType,
|
||||||
|
ApplicationValueDataType,
|
||||||
|
ApplicationStructureDataType,
|
||||||
|
ApplicationArrayDataType,
|
||||||
|
create_boolean_type,
|
||||||
|
create_value_type,
|
||||||
|
create_structure_type,
|
||||||
|
create_array_type,
|
||||||
|
ImplementationDataType,
|
||||||
|
ImplementationValueDataType,
|
||||||
|
ImplementationStructureDataType,
|
||||||
|
ImplementationArrayDataType,
|
||||||
|
create_impl_value_type,
|
||||||
|
create_impl_structure_type,
|
||||||
|
create_impl_array_type,
|
||||||
|
SwAddrMethod,
|
||||||
|
create_sw_addr_method,
|
||||||
|
DataTypeMapping,
|
||||||
|
DataTypeMappingSet,
|
||||||
|
create_data_type_mapping,
|
||||||
|
create_data_type_mapping_set,
|
||||||
|
SwComponentType,
|
||||||
|
AtomicComponentType,
|
||||||
|
CompositionSwComponentType,
|
||||||
|
ApplicationSwComponentType,
|
||||||
|
PortPrototype,
|
||||||
|
RPortPrototype,
|
||||||
|
PPortPrototype,
|
||||||
|
PRPortPrototype,
|
||||||
|
Interface,
|
||||||
|
SenderReceiverInterface,
|
||||||
|
ClientServerInterface,
|
||||||
|
ModeSwitchInterface,
|
||||||
|
ParameterInterface,
|
||||||
|
TriggerInterface,
|
||||||
|
NvDataInterface,
|
||||||
|
create_sender_receiver_interface,
|
||||||
|
Package,
|
||||||
|
create_package,
|
||||||
|
SwcInternalBehavior,
|
||||||
|
RunnableEntity,
|
||||||
|
VariableAccess,
|
||||||
|
InitEvent,
|
||||||
|
TimingEvent,
|
||||||
|
OperationInvokedEvent,
|
||||||
|
DataReceivedEvent,
|
||||||
|
create_runnable_entity,
|
||||||
|
create_timing_event,
|
||||||
|
create_init_event,
|
||||||
|
create_operation_invoked_event,
|
||||||
|
create_data_received_event,
|
||||||
|
create_swc_internal_behavior,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .utils import (
|
||||||
|
create_arxml_document,
|
||||||
|
write_arxml,
|
||||||
|
write_arxml_pretty,
|
||||||
|
get_ar_packages_element,
|
||||||
|
add_package_to_document,
|
||||||
|
)
|
||||||
|
|
||||||
|
__version__ = "2.0.1"
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Base",
|
||||||
|
"create_uuid",
|
||||||
|
"create_text_element",
|
||||||
|
"Category",
|
||||||
|
"Encoding",
|
||||||
|
"CalibrationAccess",
|
||||||
|
"SwCalibrationAccess",
|
||||||
|
"UpperSts",
|
||||||
|
"LowerSts",
|
||||||
|
"ConstraintSpecified",
|
||||||
|
"CompuContents",
|
||||||
|
"ComponentType",
|
||||||
|
"AtomicType",
|
||||||
|
"ImplementationCodeType",
|
||||||
|
"AccessPoint",
|
||||||
|
"PortDirection",
|
||||||
|
"Semantic",
|
||||||
|
"SectionType",
|
||||||
|
"Policy",
|
||||||
|
"BaseType",
|
||||||
|
"create_base_type",
|
||||||
|
"Unit",
|
||||||
|
"create_unit",
|
||||||
|
"DataConstraint",
|
||||||
|
"create_data_constraint",
|
||||||
|
"Linear",
|
||||||
|
"TextTable",
|
||||||
|
"CompuMethod",
|
||||||
|
"create_linear",
|
||||||
|
"create_text_table",
|
||||||
|
"create_compu_method",
|
||||||
|
"ApplicationDataType",
|
||||||
|
"ApplicationBooleanDataType",
|
||||||
|
"ApplicationValueDataType",
|
||||||
|
"ApplicationStructureDataType",
|
||||||
|
"ApplicationArrayDataType",
|
||||||
|
"create_boolean_type",
|
||||||
|
"create_value_type",
|
||||||
|
"create_structure_type",
|
||||||
|
"create_array_type",
|
||||||
|
"ImplementationDataType",
|
||||||
|
"ImplementationValueDataType",
|
||||||
|
"ImplementationStructureDataType",
|
||||||
|
"ImplementationArrayDataType",
|
||||||
|
"create_impl_value_type",
|
||||||
|
"create_impl_structure_type",
|
||||||
|
"create_impl_array_type",
|
||||||
|
"SwAddrMethod",
|
||||||
|
"create_sw_addr_method",
|
||||||
|
"DataTypeMapping",
|
||||||
|
"DataTypeMappingSet",
|
||||||
|
"create_data_type_mapping",
|
||||||
|
"create_data_type_mapping_set",
|
||||||
|
"SwComponentType",
|
||||||
|
"AtomicComponentType",
|
||||||
|
"CompositionSwComponentType",
|
||||||
|
"ApplicationSwComponentType",
|
||||||
|
"PortPrototype",
|
||||||
|
"RPortPrototype",
|
||||||
|
"PPortPrototype",
|
||||||
|
"PRPortPrototype",
|
||||||
|
"Interface",
|
||||||
|
"SenderReceiverInterface",
|
||||||
|
"ClientServerInterface",
|
||||||
|
"ModeSwitchInterface",
|
||||||
|
"ParameterInterface",
|
||||||
|
"TriggerInterface",
|
||||||
|
"NvDataInterface",
|
||||||
|
"create_sender_receiver_interface",
|
||||||
|
"Package",
|
||||||
|
"create_package",
|
||||||
|
"create_arxml_document",
|
||||||
|
"write_arxml",
|
||||||
|
"write_arxml_pretty",
|
||||||
|
"get_ar_packages_element",
|
||||||
|
"add_package_to_document",
|
||||||
|
"SwcInternalBehavior",
|
||||||
|
"RunnableEntity",
|
||||||
|
"VariableAccess",
|
||||||
|
"InitEvent",
|
||||||
|
"TimingEvent",
|
||||||
|
"OperationInvokedEvent",
|
||||||
|
"DataReceivedEvent",
|
||||||
|
"create_runnable_entity",
|
||||||
|
"create_timing_event",
|
||||||
|
"create_init_event",
|
||||||
|
"create_operation_invoked_event",
|
||||||
|
"create_data_received_event",
|
||||||
|
"create_swc_internal_behavior",
|
||||||
|
]
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
"""
|
||||||
|
core 模块
|
||||||
|
"""
|
||||||
|
from .base import Base, create_uuid, create_text_element
|
||||||
|
from .constants import *
|
||||||
|
from .enums import (
|
||||||
|
Category,
|
||||||
|
Encoding,
|
||||||
|
CalibrationAccess,
|
||||||
|
SwCalibrationAccess,
|
||||||
|
UpperSts,
|
||||||
|
LowerSts,
|
||||||
|
ConstraintSpecified,
|
||||||
|
CompuContents,
|
||||||
|
ComponentType,
|
||||||
|
AtomicType,
|
||||||
|
ImplementationCodeType,
|
||||||
|
AccessPoint,
|
||||||
|
PortDirection,
|
||||||
|
Semantic,
|
||||||
|
SectionType,
|
||||||
|
Policy,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Base",
|
||||||
|
"create_uuid",
|
||||||
|
"create_text_element",
|
||||||
|
"Category",
|
||||||
|
"Encoding",
|
||||||
|
"CalibrationAccess",
|
||||||
|
"SwCalibrationAccess",
|
||||||
|
"UpperSts",
|
||||||
|
"LowerSts",
|
||||||
|
"ConstraintSpecified",
|
||||||
|
"CompuContents",
|
||||||
|
"ComponentType",
|
||||||
|
"AtomicType",
|
||||||
|
"ImplementationCodeType",
|
||||||
|
"AccessPoint",
|
||||||
|
"PortDirection",
|
||||||
|
"Semantic",
|
||||||
|
"SectionType",
|
||||||
|
"Policy",
|
||||||
|
]
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
"""
|
||||||
|
核心基类和工具函数模块
|
||||||
|
"""
|
||||||
|
import uuid
|
||||||
|
import re
|
||||||
|
import xml.dom.minidom as Dom
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List
|
||||||
|
|
||||||
|
from .constants import UUID, SHORT_NAME
|
||||||
|
from .enums import Category, Encoding, CalibrationAccess, UpperSts, LowerSts
|
||||||
|
|
||||||
|
|
||||||
|
def create_uuid() -> str:
|
||||||
|
"""生成 UUID"""
|
||||||
|
return str(uuid.uuid4())
|
||||||
|
|
||||||
|
|
||||||
|
def create_text_element(doc: Dom.Document, tag: str, text: str) -> Dom.Element:
|
||||||
|
"""创建文本元素"""
|
||||||
|
element = doc.createElement(tag)
|
||||||
|
node = doc.createTextNode(text)
|
||||||
|
element.appendChild(node)
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Base:
|
||||||
|
"""所有类的基类,提供名称和层级结构支持"""
|
||||||
|
name: str
|
||||||
|
id: Optional[int] = field(default=None)
|
||||||
|
parent: Optional['Base'] = field(default=None, repr=False)
|
||||||
|
description: Optional[str] = field(default=None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def class_name(self) -> str:
|
||||||
|
"""获取类型名称"""
|
||||||
|
return self.__class__.__name__
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parent_id(self) -> Optional[int]:
|
||||||
|
"""获取父类ID"""
|
||||||
|
return self.parent.id if self.parent is not None else None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def package_path(self) -> str:
|
||||||
|
"""获取完整路径(包路径+名称)"""
|
||||||
|
path = []
|
||||||
|
current = self
|
||||||
|
while current is not None:
|
||||||
|
path.append(current.name)
|
||||||
|
current = current.parent
|
||||||
|
return '/' + '/'.join(reversed(path))
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Dom.Document) -> Dom.Element:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
raise NotImplementedError("to_arxml method must be implemented by subclass")
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
"""
|
||||||
|
AUTOSAR ARXML 标签常量统一管理模块
|
||||||
|
"""
|
||||||
|
|
||||||
|
UUID = "UUID"
|
||||||
|
AR_PACKAGE = "AR-PACKAGE"
|
||||||
|
AR_PACKAGES = "AR-PACKAGES"
|
||||||
|
ELEMENT = "ELEMENT"
|
||||||
|
ELEMENTS = "ELEMENTS"
|
||||||
|
CATEGORY = "CATEGORY"
|
||||||
|
SHORT_NAME = "SHORT-NAME"
|
||||||
|
DEST = "DEST"
|
||||||
|
UNIT = "UNIT"
|
||||||
|
UNIT_REF = "UNIT-REF"
|
||||||
|
COMPU_METHOD = "COMPU-METHOD"
|
||||||
|
COMPU_METHOD_REF = "COMPU-METHOD-REF"
|
||||||
|
DATA_CONSTR = "DATA-CONSTR"
|
||||||
|
DATA_CONSTR_REF = "DATA-CONSTR-REF"
|
||||||
|
TYPE_TREF = "TYPE-TREF"
|
||||||
|
SW_BASE_TYPE = "SW-BASE-TYPE"
|
||||||
|
BASE_TYPE_REF = "BASE-TYPE-REF"
|
||||||
|
IMPLEMENTATION_DATA_TYPE_REF = "IMPLEMENTATION-DATA-TYPE-REF"
|
||||||
|
APPLICATION_DATA_TYPE_REF = "APPLICATION-DATA-TYPE-REF"
|
||||||
|
IS_SERVICE = "IS-SERVICE"
|
||||||
|
SENDER_RECEIVER_INTERFACE = "SENDER-RECEIVER-INTERFACE"
|
||||||
|
APPLICATION_SW_COMPONENT_TYPE = "APPLICATION-SW-COMPONENT-TYPE"
|
||||||
|
PORTS = "PORTS"
|
||||||
|
R_PORT_PROTOTYPE = "R-PORT-PROTOTYPE"
|
||||||
|
P_PORT_PROTOTYPE = "P-PORT-PROTOTYPE"
|
||||||
|
REQUIRED_COM_SPECS = "REQUIRED-COM-SPECS"
|
||||||
|
PROVIDED_COM_SPECS = "PROVIDED-COM-SPECS"
|
||||||
|
PROVIDED_INTERFACE_TREF = "PROVIDED-INTERFACE-TREF"
|
||||||
|
REQUIRED_INTERFACE_TREF = "REQUIRED-INTERFACE-TREF"
|
||||||
|
NONQUEUED_SENDER_COM_SPEC = "NONQUEUED-SENDER-COM-SPEC"
|
||||||
|
NONQUEUED_RECEIVER_COM_SPEC = "NONQUEUED-RECEIVER-COM-SPEC"
|
||||||
|
FIELDS = "FIELDS"
|
||||||
|
TYPE_REF = "TYPE-REF"
|
||||||
|
VARIABLE_DATA_PROTOTYPE = "VARIABLE-DATA-PROTOTYPE"
|
||||||
|
PORT_REF = "PORT-REF"
|
||||||
|
ENABLE_TAKE_ADDRESS = "ENABLE-TAKE-ADDRESS"
|
||||||
|
ERROR_HANDLING = "ERROR-HANDLING"
|
||||||
|
INDIRECT_API = "INDIRECT-API"
|
||||||
|
ARRAY_VALUE_SPECIFICATION = "ARRAY-VALUE-SPECIFICATION"
|
||||||
|
RECORD_VALUE_SPECIFICATION = "RECORD-VALUE-SPECIFICATION"
|
||||||
|
NUMERICAL_VALUE_SPECIFICATION = "NUMERICAL-VALUE-SPECIFICATION"
|
||||||
|
DATA_ELEMENT_REF = "DATA-ELEMENT-REF"
|
||||||
|
HANDLE_OUT_OF_RANGE = "HANDLE-OUT-OF-RANGE"
|
||||||
|
USES_END_TO_END_PROTECTION = "USES-END-TO-END-PROTECTION"
|
||||||
|
ALIVE_TIMEOUT = "ALIVE-TIMEOUT"
|
||||||
|
ENABLE_UPDATE = "ENABLE-UPDATE"
|
||||||
|
HANDLE_NEVER_RECEIVED = "HANDLE-NEVER-RECEIVED"
|
||||||
|
HANDLE_TIMEOUT_TYPE = "HANDLE-TIMEOUT-TYPE"
|
||||||
|
INIT_VALUE = "INIT-VALUE"
|
||||||
|
APPLICATION_VALUE_SPECIFICATION = "APPLICATION-VALUE-SPECIFICATION"
|
||||||
|
SHORT_LABEL = "SHORT-LABEL"
|
||||||
|
SW_VALUE_CONT = "SW-VALUE-CONT"
|
||||||
|
SW_VALUES_PHYS = "SW-VALUES-PHYS"
|
||||||
|
INTERNAL_BEHAVIORS = "INTERNAL-BEHAVIORS"
|
||||||
|
SWC_INTERNAL_BEHAVIOR = "SWC-INTERNAL-BEHAVIOR"
|
||||||
|
DATA_TYPE_MAPPING_REF = "DATA-TYPE-MAPPING-REF"
|
||||||
|
DATA_TYPE_MAPPING_REFS = "DATA-TYPE-MAPPING-REFS"
|
||||||
|
EVENTS = "EVENTS"
|
||||||
|
PERIOD = "PERIOD"
|
||||||
|
SW_ADDR_METHOD_REF = "SW-ADDR-METHOD-REF"
|
||||||
|
CLIENT_SERVER_OPERATION_REF = "CLIENT-SERVER-OPERATION-REF"
|
||||||
|
INIT_EVENT = "INIT-EVENT"
|
||||||
|
TIMING_EVENT = "TIMING-EVENT"
|
||||||
|
START_ON_EVENT_REF = "START-ON-EVENT-REF"
|
||||||
|
PORT_API_OPTIONS = "PORT-API-OPTIONS"
|
||||||
|
PORT_API_OPTION = "PORT-API-OPTION"
|
||||||
|
HANDLE_TERMINATION_AND_RESTART = "HANDLE-TERMINATION-AND-RESTART"
|
||||||
|
SYMBOL = "SYMBOL"
|
||||||
|
RUNNABLES = "RUNNABLES"
|
||||||
|
RUNNABLE_ENTITY = "RUNNABLE-ENTITY"
|
||||||
|
MINIMUM_START_INTERVAL = "MINIMUM-START-INTERVAL"
|
||||||
|
CAN_BE_INVOKED_CONCURRENTLY = "CAN-BE-INVOKED-CONCURRENTLY"
|
||||||
|
DATA_RECEIVE_POINT_BY_ARGUMENTS = "DATA-RECEIVE-POINT-BY-ARGUMENTS"
|
||||||
|
VARIABLE_ACCESS = "VARIABLE-ACCESS"
|
||||||
|
ACCESSED_VARIABLE = "ACCESSED-VARIABLE"
|
||||||
|
AUTOSAR_VARIABLE_IREF = "AUTOSAR-VARIABLE-IREF"
|
||||||
|
PORT_PROTOTYPE_REF = "PORT-PROTOTYPE-REF"
|
||||||
|
TARGET_DATA_PROTOTYPE_REF = "TARGET-DATA-PROTOTYPE-REF"
|
||||||
|
DATA_SEND_POINTS = "DATA-SEND-POINTS"
|
||||||
|
SW_DATA_DEF_PROPS = "SW-DATA-DEF-PROPS"
|
||||||
|
SW_DATA_DEF_PROPS_VARIANTS = "SW-DATA-DEF-PROPS-VARIANTS"
|
||||||
|
SW_DATA_DEF_PROPS_CONDITIONAL = "SW-DATA-DEF-PROPS-CONDITIONAL"
|
||||||
|
SW_CALIBRATION_ACCESS = "SW-CALIBRATION-ACCESS"
|
||||||
|
SW_IMPL_POLICY = "SW-IMPL-POLICY"
|
||||||
|
SWC_IMPLEMENTATION = "SWC-IMPLEMENTATION"
|
||||||
|
CODE = "CODE"
|
||||||
|
CODE_DESCRIPTORS = "CODE-DESCRIPTORS"
|
||||||
|
BEHAVIOR_REF = "BEHAVIOR-REF"
|
||||||
|
AUTOSAR_ENGINEERING_OBJECT = "AUTOSAR-ENGINEERING-OBJECT"
|
||||||
|
ARTIFACT_DESCRIPTORS = "ARTIFACT-DESCRIPTORS"
|
||||||
|
SW_ADDR_METHOD = "SW-ADDR-METHOD"
|
||||||
|
SECTION_TYPE = "SECTION-TYPE"
|
||||||
|
APPLICATION_PRIMITIVE_DATA_TYPE = "APPLICATION-PRIMITIVE-DATA-TYPE"
|
||||||
|
APPLICATION_RECORD_DATA_TYPE = "APPLICATION-RECORD-DATA-TYPE"
|
||||||
|
APPLICATION_ARRAY_DATA_TYPE = "APPLICATION-ARRAY-DATA-TYPE"
|
||||||
|
ARRAY_SIZE = "ARRAY-SIZE"
|
||||||
|
ARRAY_SIZE_SEMANTICS = "ARRAY-SIZE-SEMANTICS"
|
||||||
|
MAX_NUMBER_OF_ELEMENTS = "MAX-NUMBER-OF-ELEMENTS"
|
||||||
|
PHYS_CONSTRS = "PHYS-CONSTRS"
|
||||||
|
DATA_CONSTR_RULE = "DATA-CONSTR-RULE"
|
||||||
|
DATA_CONSTR_RULES = "DATA-CONSTR-RULES"
|
||||||
|
LOWER_LIMIT = "LOWER-LIMIT"
|
||||||
|
UPPER_LIMIT = "UPPER-LIMIT"
|
||||||
|
V = "V"
|
||||||
|
VT = "VT"
|
||||||
|
COMPU_INTERNAL_TO_PHYS = "COMPU-INTERNAL-TO-PHYS"
|
||||||
|
COMPU_SCALES = "COMPU-SCALES"
|
||||||
|
COMPU_SCALE = "COMPU-SCALE"
|
||||||
|
COMPU_CONST = "COMPU-CONST"
|
||||||
|
INTERVAL_TYPE = "INTERVAL-TYPE"
|
||||||
|
COMPU_NUMERATOR = "COMPU-NUMERATOR"
|
||||||
|
COMPU_DENOMINATOR = "COMPU-DENOMINATOR"
|
||||||
|
COMPU_RATIONAL_COEFFS = "COMPU-RATIONAL-COEFFS"
|
||||||
|
IMPLEMENTATION_DATA_TYPE = "IMPLEMENTATION-DATA-TYPE"
|
||||||
|
IMPLEMENTATION_DATA_TYPE_ELEMENT = "IMPLEMENTATION-DATA-TYPE-ELEMENT"
|
||||||
|
SUB_ELEMENTS = "SUB-ELEMENTS"
|
||||||
|
BASE_TYPE_SIZE = "BASE-TYPE-SIZE"
|
||||||
|
BASE_TYPE_ENCODING = "BASE-TYPE-ENCODING"
|
||||||
|
NATIVE_DECLARATION = "NATIVE-DECLARATION"
|
||||||
|
FACTOR_SI_TO_UNIT = "FACTOR-SI-TO-UNIT"
|
||||||
|
OFFSET_SI_TO_UNIT = "OFFSET-SI-TO-UNIT"
|
||||||
|
DATA_TYPE_MAPPING_SET = "DATA-TYPE-MAPPING-SET"
|
||||||
|
DATA_TYPE_MAPS = "DATA-TYPE-MAPS"
|
||||||
|
DATA_TYPE_MAP = "DATA-TYPE-MAP"
|
||||||
|
AUTOSAR = "AUTOSAR"
|
||||||
|
APPLICATION_RECORD_ELEMENT = "APPLICATION-RECORD-ELEMENT"
|
||||||
|
DATA_ELEMENTS = "DATA-ELEMENTS"
|
||||||
|
CLIENT_SERVER_INTERFACE = "CLIENT-SERVER-INTERFACE"
|
||||||
|
CLIENT_SERVER_OPERATION = "CLIENT-SERVER-OPERATION"
|
||||||
|
ARGUMENT = "ARGUMENT"
|
||||||
|
APPLICATION_PRIMITIVE_TYPE_REF = "APPLICATION-PRIMITIVE-TYPE-REF"
|
||||||
|
DIRECTION = "DIRECTION"
|
||||||
|
OPERATION_INVOKED_EVENT = "OPERATION-INVOKED-EVENT"
|
||||||
|
DATA_RECEIVED_EVENT = "DATA-RECEIVED-EVENT"
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
"""
|
||||||
|
AUTOSAR 枚举类型统一管理模块
|
||||||
|
"""
|
||||||
|
from enum import Enum, auto
|
||||||
|
|
||||||
|
|
||||||
|
class Category(Enum):
|
||||||
|
"""数据分类类型"""
|
||||||
|
FIXED_LENGTH = auto()
|
||||||
|
IDENTICAL = auto()
|
||||||
|
TEXT_TABLE = auto()
|
||||||
|
LINEAR = auto()
|
||||||
|
BOOLEAN = auto()
|
||||||
|
VALUE = auto()
|
||||||
|
STRUCTURE = auto()
|
||||||
|
ARRAY = auto()
|
||||||
|
SCALE_LINEAR_AND_TEXT_TABLE = auto()
|
||||||
|
BITFIELD_TEXT_TABLE = auto()
|
||||||
|
SCALE_LINEAR = auto()
|
||||||
|
RECORD = auto()
|
||||||
|
UNION = auto()
|
||||||
|
DATA_REFERENCE = auto()
|
||||||
|
TYPE_REFERENCE = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class Encoding(Enum):
|
||||||
|
"""数据编码格式"""
|
||||||
|
ONE_COMPONENT = "1C - One's Complement"
|
||||||
|
TWO_COMPONENT = "2C - Two's Complement"
|
||||||
|
BCD_P = "BCD-p - Packed Binary Coded Decimals"
|
||||||
|
BCD_UP = "BCD-Up - Unpacked Binary Coded Decimals"
|
||||||
|
DSP_FRACTIONAL = "DSP-FRACTIONAL - Digital Signal Processor"
|
||||||
|
SM = "SM - Sign Magnitude"
|
||||||
|
IEEE754 = "IEEE754 - Floating Point"
|
||||||
|
ISO_8859_1 = "ISO-8859-1 - ASCII-Strings"
|
||||||
|
ISO_8859_2 = "ISO-8859-2 - ASCII-Strings"
|
||||||
|
WINDOWS_1252 = "Windows-1252 - ASCII Strings"
|
||||||
|
UTF_8 = "UTF-8 - UCS Transformation Format 8"
|
||||||
|
UCS_2 = "UCS-2 - Universal Character Set 2"
|
||||||
|
NONE = "NONE - Unsigned Integer"
|
||||||
|
VOID = "VOID - C Language"
|
||||||
|
BOOLEAN = "BOOLEAN - Logical Type"
|
||||||
|
UTF_16 = "UTF-16: Character encoding for Unicode code points"
|
||||||
|
|
||||||
|
|
||||||
|
class CalibrationAccess(Enum):
|
||||||
|
"""校准访问权限"""
|
||||||
|
READ_ONLY = 'Read-Only'
|
||||||
|
NOT_ACCESSIBLE = 'Not Accessible'
|
||||||
|
READ_WRITE = 'Read-Write'
|
||||||
|
NOT_SPECIFIED = 'Not Specified'
|
||||||
|
|
||||||
|
|
||||||
|
class SwCalibrationAccess(Enum):
|
||||||
|
"""校准访问权限(同 CalibrationAccess,保持向后兼容)"""
|
||||||
|
ReadOnly = 'Read-Only'
|
||||||
|
NotAccessible = 'Not Accessible'
|
||||||
|
ReadWrite = 'Read-Write'
|
||||||
|
NotSpecified = 'Not Specified'
|
||||||
|
|
||||||
|
|
||||||
|
class UpperSts(Enum):
|
||||||
|
"""上限区间状态"""
|
||||||
|
CLOSED = '['
|
||||||
|
OPEN = ']'
|
||||||
|
|
||||||
|
|
||||||
|
class LowerSts(Enum):
|
||||||
|
"""下限区间状态"""
|
||||||
|
CLOSED = ']'
|
||||||
|
OPEN = '['
|
||||||
|
|
||||||
|
|
||||||
|
class ConstraintSpecified(Enum):
|
||||||
|
"""约束指定类型"""
|
||||||
|
PHYSICAL = auto()
|
||||||
|
INTERNAL = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class CompuContents(Enum):
|
||||||
|
"""转换内容方向"""
|
||||||
|
USE_INTERNAL_TO_PHYSICAL = auto()
|
||||||
|
USE_PHYSICAL_TO_INTERNAL = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class ComponentType(Enum):
|
||||||
|
"""组件类型"""
|
||||||
|
COMPOSITION = auto()
|
||||||
|
ATOMIC = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class AtomicType(Enum):
|
||||||
|
"""原子组件类型"""
|
||||||
|
APPLICATION = "Application"
|
||||||
|
SENSOR_ACTUATOR = "SensorActuator"
|
||||||
|
HARDWARE_ABSTRACTION = "I/O - Hardware Abstraction (application layer)"
|
||||||
|
COMPLEX_DRIVER = "Complex Driver (application layer)"
|
||||||
|
SERVICE_PROXY = "Service Proxy"
|
||||||
|
|
||||||
|
|
||||||
|
class ImplementationCodeType(Enum):
|
||||||
|
"""实现代码类型"""
|
||||||
|
SOURCE_CODE = auto()
|
||||||
|
OBJECT_CODE = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class AccessPoint(Enum):
|
||||||
|
"""访问点"""
|
||||||
|
READ = auto()
|
||||||
|
WRITE = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class PortDirection(Enum):
|
||||||
|
"""端口方向"""
|
||||||
|
IN = auto()
|
||||||
|
OUT = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class Semantic(Enum):
|
||||||
|
"""语义/数组大小语义"""
|
||||||
|
FIXED = 'FIXED-SIZE'
|
||||||
|
VARIABLE = 'Variable'
|
||||||
|
|
||||||
|
|
||||||
|
class SectionType(Enum):
|
||||||
|
"""段类型"""
|
||||||
|
CODE = auto()
|
||||||
|
DATA = auto()
|
||||||
|
CONST = auto()
|
||||||
|
|
||||||
|
|
||||||
|
class Policy(Enum):
|
||||||
|
"""数据策略"""
|
||||||
|
STANDARD = auto()
|
||||||
|
EXTENDED = auto()
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
"""
|
||||||
|
types 模块 - 数据类型统一管理
|
||||||
|
"""
|
||||||
|
from .base_type import BaseType, create_base_type
|
||||||
|
from .unit import Unit, create_unit
|
||||||
|
from .data_constraint import DataConstraint, create_data_constraint
|
||||||
|
from .compu_method import (
|
||||||
|
Linear, TextTable, CompuMethod,
|
||||||
|
create_linear, create_text_table, create_compu_method
|
||||||
|
)
|
||||||
|
from .application_types import (
|
||||||
|
ApplicationDataType,
|
||||||
|
ApplicationBooleanDataType,
|
||||||
|
ApplicationValueDataType,
|
||||||
|
ApplicationStructureDataType,
|
||||||
|
ApplicationArrayDataType,
|
||||||
|
create_boolean_type,
|
||||||
|
create_value_type,
|
||||||
|
create_structure_type,
|
||||||
|
create_array_type,
|
||||||
|
)
|
||||||
|
from .implementation_types import (
|
||||||
|
ImplementationDataType,
|
||||||
|
ImplementationValueDataType,
|
||||||
|
ImplementationStructureDataType,
|
||||||
|
ImplementationArrayDataType,
|
||||||
|
create_impl_value_type,
|
||||||
|
create_impl_structure_type,
|
||||||
|
create_impl_array_type,
|
||||||
|
)
|
||||||
|
from .sw_addr_method import SwAddrMethod, create_sw_addr_method
|
||||||
|
from .data_mapping import (
|
||||||
|
DataTypeMapping,
|
||||||
|
DataTypeMappingSet,
|
||||||
|
create_data_type_mapping,
|
||||||
|
create_data_type_mapping_set,
|
||||||
|
)
|
||||||
|
from .sw_component_type import (
|
||||||
|
SwComponentType,
|
||||||
|
AtomicComponentType,
|
||||||
|
CompositionSwComponentType,
|
||||||
|
ApplicationSwComponentType,
|
||||||
|
PortPrototype,
|
||||||
|
RPortPrototype,
|
||||||
|
PPortPrototype,
|
||||||
|
PRPortPrototype,
|
||||||
|
)
|
||||||
|
from .interface import (
|
||||||
|
Interface,
|
||||||
|
SenderReceiverInterface,
|
||||||
|
ClientServerInterface,
|
||||||
|
ModeSwitchInterface,
|
||||||
|
ParameterInterface,
|
||||||
|
TriggerInterface,
|
||||||
|
NvDataInterface,
|
||||||
|
create_sender_receiver_interface,
|
||||||
|
)
|
||||||
|
from .package import Package, create_package
|
||||||
|
from .swc_internal_behavior import (
|
||||||
|
SwcInternalBehavior,
|
||||||
|
RunnableEntity,
|
||||||
|
VariableAccess,
|
||||||
|
InitEvent,
|
||||||
|
TimingEvent,
|
||||||
|
OperationInvokedEvent,
|
||||||
|
DataReceivedEvent,
|
||||||
|
create_runnable_entity,
|
||||||
|
create_timing_event,
|
||||||
|
create_init_event,
|
||||||
|
create_operation_invoked_event,
|
||||||
|
create_data_received_event,
|
||||||
|
create_swc_internal_behavior,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"BaseType",
|
||||||
|
"create_base_type",
|
||||||
|
"Unit",
|
||||||
|
"create_unit",
|
||||||
|
"DataConstraint",
|
||||||
|
"create_data_constraint",
|
||||||
|
"Linear",
|
||||||
|
"TextTable",
|
||||||
|
"CompuMethod",
|
||||||
|
"create_linear",
|
||||||
|
"create_text_table",
|
||||||
|
"create_compu_method",
|
||||||
|
"ApplicationDataType",
|
||||||
|
"ApplicationBooleanDataType",
|
||||||
|
"ApplicationValueDataType",
|
||||||
|
"ApplicationStructureDataType",
|
||||||
|
"ApplicationArrayDataType",
|
||||||
|
"create_boolean_type",
|
||||||
|
"create_value_type",
|
||||||
|
"create_structure_type",
|
||||||
|
"create_array_type",
|
||||||
|
"ImplementationDataType",
|
||||||
|
"ImplementationValueDataType",
|
||||||
|
"ImplementationStructureDataType",
|
||||||
|
"ImplementationArrayDataType",
|
||||||
|
"create_impl_value_type",
|
||||||
|
"create_impl_structure_type",
|
||||||
|
"create_impl_array_type",
|
||||||
|
"SwAddrMethod",
|
||||||
|
"create_sw_addr_method",
|
||||||
|
"DataTypeMapping",
|
||||||
|
"DataTypeMappingSet",
|
||||||
|
"create_data_type_mapping",
|
||||||
|
"create_data_type_mapping_set",
|
||||||
|
"SwComponentType",
|
||||||
|
"AtomicComponentType",
|
||||||
|
"CompositionSwComponentType",
|
||||||
|
"ApplicationSwComponentType",
|
||||||
|
"PortPrototype",
|
||||||
|
"RPortPrototype",
|
||||||
|
"PPortPrototype",
|
||||||
|
"PRPortPrototype",
|
||||||
|
"Interface",
|
||||||
|
"SenderReceiverInterface",
|
||||||
|
"ClientServerInterface",
|
||||||
|
"ModeSwitchInterface",
|
||||||
|
"ParameterInterface",
|
||||||
|
"TriggerInterface",
|
||||||
|
"NvDataInterface",
|
||||||
|
"create_sender_receiver_interface",
|
||||||
|
"Package",
|
||||||
|
"create_package",
|
||||||
|
"SwcInternalBehavior",
|
||||||
|
"RunnableEntity",
|
||||||
|
"VariableAccess",
|
||||||
|
"InitEvent",
|
||||||
|
"TimingEvent",
|
||||||
|
"OperationInvokedEvent",
|
||||||
|
"DataReceivedEvent",
|
||||||
|
"create_runnable_entity",
|
||||||
|
"create_timing_event",
|
||||||
|
"create_init_event",
|
||||||
|
"create_operation_invoked_event",
|
||||||
|
"create_data_received_event",
|
||||||
|
"create_swc_internal_behavior",
|
||||||
|
]
|
||||||
@@ -0,0 +1,273 @@
|
|||||||
|
"""
|
||||||
|
应用数据类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List, TYPE_CHECKING, Union
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
APPLICATION_PRIMITIVE_DATA_TYPE, APPLICATION_RECORD_DATA_TYPE, APPLICATION_ARRAY_DATA_TYPE,
|
||||||
|
SHORT_NAME, CATEGORY, SW_DATA_DEF_PROPS, SW_DATA_DEF_PROPS_VARIANTS,
|
||||||
|
SW_DATA_DEF_PROPS_CONDITIONAL, SW_CALIBRATION_ACCESS, COMPU_METHOD_REF, DEST,
|
||||||
|
COMPU_METHOD, DATA_CONSTR_REF, DATA_CONSTR, UNIT_REF, UNIT, ELEMENTS, ELEMENT,
|
||||||
|
ARRAY_SIZE_SEMANTICS, MAX_NUMBER_OF_ELEMENTS, TYPE_TREF, APPLICATION_RECORD_ELEMENT
|
||||||
|
)
|
||||||
|
from ..core.enums import Category, CalibrationAccess, Semantic
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .unit import Unit
|
||||||
|
from .compu_method import CompuMethod
|
||||||
|
from .data_constraint import DataConstraint
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApplicationDataType(Base):
|
||||||
|
"""应用数据类型基类"""
|
||||||
|
category: Optional[Category] = None
|
||||||
|
calibration_access: CalibrationAccess = CalibrationAccess.READ_WRITE
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApplicationBooleanDataType(ApplicationDataType):
|
||||||
|
"""布尔类型"""
|
||||||
|
compu_method: Optional['CompuMethod'] = None
|
||||||
|
data_constraint: Optional['DataConstraint'] = None
|
||||||
|
category: Category = Category.BOOLEAN
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
sw_data_def_props_conditional.appendChild(
|
||||||
|
create_text_element(doc, SW_CALIBRATION_ACCESS, self.calibration_access.value.upper())
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.compu_method is not None:
|
||||||
|
compu_method_ref = create_text_element(doc, COMPU_METHOD_REF, self.compu_method.package_path)
|
||||||
|
compu_method_ref.setAttribute(DEST, COMPU_METHOD)
|
||||||
|
sw_data_def_props_conditional.appendChild(compu_method_ref)
|
||||||
|
|
||||||
|
if self.data_constraint is not None:
|
||||||
|
data_constr_ref = create_text_element(doc, DATA_CONSTR_REF, self.data_constraint.package_path)
|
||||||
|
data_constr_ref.setAttribute(DEST, DATA_CONSTR)
|
||||||
|
sw_data_def_props_conditional.appendChild(data_constr_ref)
|
||||||
|
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApplicationValueDataType(ApplicationDataType):
|
||||||
|
"""值类型(标量值)"""
|
||||||
|
unit: Optional['Unit'] = None
|
||||||
|
compu_method: Optional['CompuMethod'] = None
|
||||||
|
data_constraint: Optional['DataConstraint'] = None
|
||||||
|
category: Category = Category.VALUE
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
sw_data_def_props_conditional.appendChild(
|
||||||
|
create_text_element(doc, SW_CALIBRATION_ACCESS, self.calibration_access.value.upper())
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.unit is not None:
|
||||||
|
unit_ref = create_text_element(doc, UNIT_REF, self.unit.package_path)
|
||||||
|
unit_ref.setAttribute(DEST, UNIT)
|
||||||
|
sw_data_def_props_conditional.appendChild(unit_ref)
|
||||||
|
|
||||||
|
if self.compu_method is not None:
|
||||||
|
compu_method_ref = create_text_element(doc, COMPU_METHOD_REF, self.compu_method.package_path)
|
||||||
|
compu_method_ref.setAttribute(DEST, COMPU_METHOD)
|
||||||
|
sw_data_def_props_conditional.appendChild(compu_method_ref)
|
||||||
|
|
||||||
|
if self.data_constraint is not None:
|
||||||
|
data_constr_ref = create_text_element(doc, DATA_CONSTR_REF, self.data_constraint.package_path)
|
||||||
|
data_constr_ref.setAttribute(DEST, DATA_CONSTR)
|
||||||
|
sw_data_def_props_conditional.appendChild(data_constr_ref)
|
||||||
|
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApplicationStructureDataType(ApplicationDataType):
|
||||||
|
"""结构体类型"""
|
||||||
|
category: Category = Category.STRUCTURE
|
||||||
|
structure_elements: List['ApplicationStructureDataType.StructureElement'] = field(default_factory=list)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class StructureElement(Base):
|
||||||
|
"""结构体成员"""
|
||||||
|
data_type: Optional[ApplicationDataType] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(APPLICATION_RECORD_ELEMENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
if self.data_type:
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.data_type.category.name))
|
||||||
|
type_ref = create_text_element(doc, TYPE_TREF, self.data_type.package_path)
|
||||||
|
type_ref.setAttribute('DEST', APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
element.appendChild(type_ref)
|
||||||
|
return element
|
||||||
|
|
||||||
|
def get_element(self, name: str) -> Optional['StructureElement']:
|
||||||
|
"""根据名称查找成员"""
|
||||||
|
for element in self.structure_elements:
|
||||||
|
if element.name == name:
|
||||||
|
return element
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_element(self, element: 'StructureElement') -> None:
|
||||||
|
"""添加结构成员"""
|
||||||
|
if self.get_element(element.name) is not None:
|
||||||
|
return
|
||||||
|
self.structure_elements.append(element)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(APPLICATION_RECORD_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
sw_data_def_props_conditional.appendChild(
|
||||||
|
create_text_element(doc, SW_CALIBRATION_ACCESS, self.calibration_access.value.upper())
|
||||||
|
)
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
elements = doc.createElement(ELEMENTS)
|
||||||
|
for structure_element in self.structure_elements:
|
||||||
|
elements.appendChild(structure_element.to_arxml(doc))
|
||||||
|
element.appendChild(elements)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApplicationArrayDataType(ApplicationDataType):
|
||||||
|
"""数组类型"""
|
||||||
|
category: Category = Category.ARRAY
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ArrayElement(Base):
|
||||||
|
"""数组成员"""
|
||||||
|
length: Optional[int] = None
|
||||||
|
data_type: Optional[ApplicationDataType] = None
|
||||||
|
array_size_semantics: Semantic = Semantic.FIXED
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(ELEMENT)
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
if self.data_type:
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.data_type.category.name))
|
||||||
|
type_ref = create_text_element(doc, TYPE_TREF, self.data_type.package_path)
|
||||||
|
type_ref.setAttribute('DEST', APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
element.appendChild(type_ref)
|
||||||
|
element.appendChild(create_text_element(doc, ARRAY_SIZE_SEMANTICS, self.array_size_semantics.value))
|
||||||
|
element.appendChild(create_text_element(doc, MAX_NUMBER_OF_ELEMENTS, str(self.length or 0)))
|
||||||
|
return element
|
||||||
|
|
||||||
|
element: Optional['ArrayElement'] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(APPLICATION_ARRAY_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
sw_data_def_props_conditional.appendChild(
|
||||||
|
create_text_element(doc, SW_CALIBRATION_ACCESS, self.calibration_access.value.upper())
|
||||||
|
)
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
if self.element:
|
||||||
|
array_element = doc.createElement(ELEMENT)
|
||||||
|
array_element.appendChild(self.element.to_arxml(doc))
|
||||||
|
element.appendChild(array_element)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_boolean_type(
|
||||||
|
name: str,
|
||||||
|
compu_method: Optional['CompuMethod'] = None,
|
||||||
|
data_constraint: Optional['DataConstraint'] = None,
|
||||||
|
) -> ApplicationBooleanDataType:
|
||||||
|
"""创建布尔类型的工厂函数"""
|
||||||
|
return ApplicationBooleanDataType(
|
||||||
|
name=name,
|
||||||
|
compu_method=compu_method,
|
||||||
|
data_constraint=data_constraint,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_value_type(
|
||||||
|
name: str,
|
||||||
|
unit: Optional['Unit'] = None,
|
||||||
|
compu_method: Optional['CompuMethod'] = None,
|
||||||
|
data_constraint: Optional['DataConstraint'] = None,
|
||||||
|
) -> ApplicationValueDataType:
|
||||||
|
"""创建值类型的工厂函数"""
|
||||||
|
return ApplicationValueDataType(
|
||||||
|
name=name,
|
||||||
|
unit=unit,
|
||||||
|
compu_method=compu_method,
|
||||||
|
data_constraint=data_constraint,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_structure_type(
|
||||||
|
name: str,
|
||||||
|
elements: Optional[List['ApplicationStructureDataType.StructureElement']] = None,
|
||||||
|
) -> ApplicationStructureDataType:
|
||||||
|
"""创建结构体类型的工厂函数"""
|
||||||
|
return ApplicationStructureDataType(
|
||||||
|
name=name,
|
||||||
|
structure_elements=elements or [],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_array_type(
|
||||||
|
name: str,
|
||||||
|
element: Optional['ApplicationArrayDataType.ArrayElement'] = None,
|
||||||
|
) -> ApplicationArrayDataType:
|
||||||
|
"""创建数组类型的工厂函数"""
|
||||||
|
return ApplicationArrayDataType(
|
||||||
|
name=name,
|
||||||
|
element=element,
|
||||||
|
)
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
"""
|
||||||
|
基础数据类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import SW_BASE_TYPE, SHORT_NAME, CATEGORY, BASE_TYPE_SIZE, BASE_TYPE_ENCODING, NATIVE_DECLARATION
|
||||||
|
from ..core.enums import Category, Encoding
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class BaseType(Base):
|
||||||
|
"""基础数据类型"""
|
||||||
|
size: Optional[int] = 8
|
||||||
|
category: Category = Category.FIXED_LENGTH
|
||||||
|
encoding: Encoding = Encoding.ONE_COMPONENT
|
||||||
|
native_description: Optional[str] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def encoding_value(self) -> str:
|
||||||
|
"""获取编码值"""
|
||||||
|
if self.encoding == Encoding.ONE_COMPONENT:
|
||||||
|
return "1C"
|
||||||
|
elif self.encoding == Encoding.TWO_COMPONENT:
|
||||||
|
return "2C"
|
||||||
|
return self.encoding.name.upper()
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(SW_BASE_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
element.appendChild(create_text_element(doc, BASE_TYPE_SIZE, str(self.size)))
|
||||||
|
element.appendChild(create_text_element(doc, BASE_TYPE_ENCODING, self.encoding_value))
|
||||||
|
if self.native_description:
|
||||||
|
element.appendChild(create_text_element(doc, NATIVE_DECLARATION, self.native_description))
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_base_type(
|
||||||
|
name: str,
|
||||||
|
size: int = 8,
|
||||||
|
category: Category = Category.FIXED_LENGTH,
|
||||||
|
encoding: Encoding = Encoding.ONE_COMPONENT,
|
||||||
|
native_description: Optional[str] = None,
|
||||||
|
) -> BaseType:
|
||||||
|
"""创建基础数据类型的工厂函数"""
|
||||||
|
return BaseType(
|
||||||
|
name=name,
|
||||||
|
size=size,
|
||||||
|
category=category,
|
||||||
|
encoding=encoding,
|
||||||
|
native_description=native_description,
|
||||||
|
)
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
"""
|
||||||
|
计算方法类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
COMPU_METHOD, SHORT_NAME, CATEGORY, UNIT_REF, DEST, UNIT,
|
||||||
|
COMPU_INTERNAL_TO_PHYS, COMPU_SCALES, COMPU_SCALE, COMPU_CONST,
|
||||||
|
LOWER_LIMIT, UPPER_LIMIT, INTERVAL_TYPE, VT,
|
||||||
|
COMPU_NUMERATOR, COMPU_DENOMINATOR, COMPU_RATIONAL_COEFFS, V
|
||||||
|
)
|
||||||
|
from ..core.enums import Category, CompuContents, LowerSts, UpperSts
|
||||||
|
from .unit import Unit
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Linear(Base):
|
||||||
|
"""线性转换"""
|
||||||
|
factor: Optional[float] = None
|
||||||
|
offset: Optional[float] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
compu_scale = doc.createElement(COMPU_SCALE)
|
||||||
|
compu_rational_coeffes = doc.createElement(COMPU_RATIONAL_COEFFS)
|
||||||
|
|
||||||
|
compu_numerator = doc.createElement(COMPU_NUMERATOR)
|
||||||
|
compu_numerator.appendChild(create_text_element(doc, V, str(self.offset or 0)))
|
||||||
|
compu_numerator.appendChild(create_text_element(doc, V, str(self.factor or 0)))
|
||||||
|
compu_rational_coeffes.appendChild(compu_numerator)
|
||||||
|
|
||||||
|
compu_denominator = doc.createElement(COMPU_DENOMINATOR)
|
||||||
|
compu_denominator.appendChild(create_text_element(doc, V, '1'))
|
||||||
|
compu_rational_coeffes.appendChild(compu_denominator)
|
||||||
|
|
||||||
|
compu_scale.appendChild(compu_rational_coeffes)
|
||||||
|
return compu_scale
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TextTable(Base):
|
||||||
|
"""文本表"""
|
||||||
|
vt: Optional[str] = None
|
||||||
|
lower: Optional[int] = None
|
||||||
|
upper: Optional[int] = None
|
||||||
|
lower_sts: LowerSts = LowerSts.CLOSED
|
||||||
|
upper_sts: UpperSts = UpperSts.CLOSED
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
compu_scale = doc.createElement(COMPU_SCALE)
|
||||||
|
lower_limit = create_text_element(doc, LOWER_LIMIT, str(self.lower or 0))
|
||||||
|
lower_limit.setAttribute(INTERVAL_TYPE, self.lower_sts.value)
|
||||||
|
compu_scale.appendChild(lower_limit)
|
||||||
|
|
||||||
|
upper_limit = create_text_element(doc, UPPER_LIMIT, str(self.upper or 0))
|
||||||
|
upper_limit.setAttribute(INTERVAL_TYPE, self.upper_sts.value)
|
||||||
|
compu_scale.appendChild(upper_limit)
|
||||||
|
|
||||||
|
compu_const = doc.createElement(COMPU_CONST)
|
||||||
|
compu_const.appendChild(create_text_element(doc, VT, self.vt or ''))
|
||||||
|
compu_scale.appendChild(compu_const)
|
||||||
|
|
||||||
|
return compu_scale
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CompuMethod(Base):
|
||||||
|
"""计算方法"""
|
||||||
|
unit: Optional[Unit] = None
|
||||||
|
linear: Optional[Linear] = None
|
||||||
|
text_tables: List[TextTable] = field(default_factory=list)
|
||||||
|
category: Category = Category.IDENTICAL
|
||||||
|
compu_contents: CompuContents = CompuContents.USE_INTERNAL_TO_PHYSICAL
|
||||||
|
|
||||||
|
def get_text_table(self, vt: str) -> Optional[TextTable]:
|
||||||
|
"""根据 vt 查找文本表"""
|
||||||
|
for text_table in self.text_tables:
|
||||||
|
if text_table.vt == vt:
|
||||||
|
return text_table
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_text_table(self, text_table: TextTable) -> None:
|
||||||
|
"""添加文本表"""
|
||||||
|
if self.get_text_table(text_table.vt) is not None:
|
||||||
|
return
|
||||||
|
self.text_tables.append(text_table)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(COMPU_METHOD)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name.replace("_", "")))
|
||||||
|
|
||||||
|
if self.unit is not None:
|
||||||
|
unit_ref = create_text_element(doc, UNIT_REF, self.unit.package_path)
|
||||||
|
unit_ref.setAttribute(DEST, UNIT)
|
||||||
|
element.appendChild(unit_ref)
|
||||||
|
|
||||||
|
compu_internal_to_phys = doc.createElement(COMPU_INTERNAL_TO_PHYS)
|
||||||
|
compu_scales = doc.createElement(COMPU_SCALES)
|
||||||
|
|
||||||
|
for text_table in self.text_tables:
|
||||||
|
compu_scales.appendChild(text_table.to_arxml(doc))
|
||||||
|
|
||||||
|
if self.linear is not None:
|
||||||
|
compu_scales.appendChild(self.linear.to_arxml(doc))
|
||||||
|
|
||||||
|
compu_internal_to_phys.appendChild(compu_scales)
|
||||||
|
element.appendChild(compu_internal_to_phys)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_linear(factor: float, offset: float, name: str = "Linear") -> Linear:
|
||||||
|
"""创建线性转换的工厂函数"""
|
||||||
|
return Linear(name=name, factor=factor, offset=offset)
|
||||||
|
|
||||||
|
|
||||||
|
def create_text_table(name: str, vt: str, lower: int = 0, upper: int = 0) -> TextTable:
|
||||||
|
"""创建文本表的工厂函数"""
|
||||||
|
return TextTable(name=name, vt=vt, lower=lower, upper=upper)
|
||||||
|
|
||||||
|
|
||||||
|
def create_compu_method(
|
||||||
|
name: str,
|
||||||
|
unit: Optional[Unit] = None,
|
||||||
|
linear: Optional[Linear] = None,
|
||||||
|
text_tables: Optional[List[TextTable]] = None,
|
||||||
|
category: Category = Category.IDENTICAL,
|
||||||
|
) -> CompuMethod:
|
||||||
|
"""创建计算方法的工厂函数"""
|
||||||
|
return CompuMethod(
|
||||||
|
name=name,
|
||||||
|
unit=unit,
|
||||||
|
linear=linear,
|
||||||
|
text_tables=text_tables or [],
|
||||||
|
category=category,
|
||||||
|
)
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
"""
|
||||||
|
数据约束类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, Union
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
DATA_CONSTR, SHORT_NAME, DATA_CONSTR_RULES, DATA_CONSTR_RULE,
|
||||||
|
PHYS_CONSTRS, LOWER_LIMIT, UPPER_LIMIT, UNIT_REF, DEST, UNIT, INTERVAL_TYPE
|
||||||
|
)
|
||||||
|
from ..core.enums import UpperSts, LowerSts, ConstraintSpecified
|
||||||
|
from .unit import Unit
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataConstraint(Base):
|
||||||
|
"""数据约束"""
|
||||||
|
unit: Optional[Unit] = None
|
||||||
|
lower: Union[int, float] = 0
|
||||||
|
upper: Union[int, float] = 1
|
||||||
|
lower_sts: LowerSts = LowerSts.CLOSED
|
||||||
|
upper_sts: UpperSts = UpperSts.CLOSED
|
||||||
|
constraint_specified: ConstraintSpecified = ConstraintSpecified.PHYSICAL
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(DATA_CONSTR)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
data_constr_rules = doc.createElement(DATA_CONSTR_RULES)
|
||||||
|
data_constr_rule = doc.createElement(DATA_CONSTR_RULE)
|
||||||
|
phys_constrs = doc.createElement(PHYS_CONSTRS)
|
||||||
|
|
||||||
|
lower_limit = create_text_element(doc, LOWER_LIMIT, str(self.lower))
|
||||||
|
lower_limit.setAttribute(INTERVAL_TYPE, self.lower_sts.name.upper())
|
||||||
|
phys_constrs.appendChild(lower_limit)
|
||||||
|
|
||||||
|
upper_limit = create_text_element(doc, UPPER_LIMIT, str(self.upper))
|
||||||
|
upper_limit.setAttribute(INTERVAL_TYPE, self.upper_sts.name.upper())
|
||||||
|
phys_constrs.appendChild(upper_limit)
|
||||||
|
|
||||||
|
if self.unit is not None:
|
||||||
|
unit_ref = create_text_element(doc, UNIT_REF, self.unit.package_path)
|
||||||
|
unit_ref.setAttribute(DEST, UNIT)
|
||||||
|
phys_constrs.appendChild(unit_ref)
|
||||||
|
|
||||||
|
data_constr_rule.appendChild(phys_constrs)
|
||||||
|
data_constr_rules.appendChild(data_constr_rule)
|
||||||
|
element.appendChild(data_constr_rules)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_data_constraint(
|
||||||
|
name: str,
|
||||||
|
lower: Union[int, float] = 0,
|
||||||
|
upper: Union[int, float] = 1,
|
||||||
|
lower_sts: LowerSts = LowerSts.CLOSED,
|
||||||
|
upper_sts: UpperSts = UpperSts.CLOSED,
|
||||||
|
unit: Optional[Unit] = None,
|
||||||
|
) -> DataConstraint:
|
||||||
|
"""创建数据约束的工厂函数"""
|
||||||
|
return DataConstraint(
|
||||||
|
name=name,
|
||||||
|
lower=lower,
|
||||||
|
upper=upper,
|
||||||
|
lower_sts=lower_sts,
|
||||||
|
upper_sts=upper_sts,
|
||||||
|
unit=unit,
|
||||||
|
)
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
"""
|
||||||
|
数据类型映射集模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List, TYPE_CHECKING
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
DATA_TYPE_MAPPING_SET, DATA_TYPE_MAPS, DATA_TYPE_MAP,
|
||||||
|
SHORT_NAME, APPLICATION_DATA_TYPE_REF, DEST, APPLICATION_PRIMITIVE_DATA_TYPE,
|
||||||
|
IMPLEMENTATION_DATA_TYPE_REF, DEST as REF_DEST, IMPLEMENTATION_DATA_TYPE
|
||||||
|
)
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .application_types import ApplicationDataType
|
||||||
|
from .implementation_types import ImplementationDataType
|
||||||
|
else:
|
||||||
|
from .application_types import ApplicationDataType as ApplicationDataType
|
||||||
|
from .implementation_types import ImplementationDataType as ImplementationDataType
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataTypeMapping(Base):
|
||||||
|
"""数据类型映射"""
|
||||||
|
application_data_type: Optional['ApplicationDataType'] = None
|
||||||
|
implementation_data_type: Optional['ImplementationDataType'] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(DATA_TYPE_MAP)
|
||||||
|
|
||||||
|
if self.application_data_type:
|
||||||
|
app_type_ref = create_text_element(
|
||||||
|
doc, APPLICATION_DATA_TYPE_REF, self.application_data_type.package_path
|
||||||
|
)
|
||||||
|
app_type_ref.setAttribute(DEST, APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
element.appendChild(app_type_ref)
|
||||||
|
|
||||||
|
if self.implementation_data_type:
|
||||||
|
impl_type_ref = create_text_element(
|
||||||
|
doc, IMPLEMENTATION_DATA_TYPE_REF, self.implementation_data_type.package_path
|
||||||
|
)
|
||||||
|
impl_type_ref.setAttribute(DEST, IMPLEMENTATION_DATA_TYPE)
|
||||||
|
element.appendChild(impl_type_ref)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataTypeMappingSet(Base):
|
||||||
|
"""数据类型映射集"""
|
||||||
|
data_type_mappings: List[DataTypeMapping] = field(default_factory=list)
|
||||||
|
|
||||||
|
def get_mapping(self, name: str) -> Optional[DataTypeMapping]:
|
||||||
|
"""根据名称查找映射"""
|
||||||
|
for mapping in self.data_type_mappings:
|
||||||
|
if mapping.name == name:
|
||||||
|
return mapping
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_mapping(self, mapping: DataTypeMapping) -> None:
|
||||||
|
"""添加映射"""
|
||||||
|
if self.get_mapping(mapping.name) is None:
|
||||||
|
self.data_type_mappings.append(mapping)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(DATA_TYPE_MAPPING_SET)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
data_type_maps = doc.createElement(DATA_TYPE_MAPS)
|
||||||
|
for mapping in self.data_type_mappings:
|
||||||
|
data_type_maps.appendChild(mapping.to_arxml(doc))
|
||||||
|
element.appendChild(data_type_maps)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_data_type_mapping(
|
||||||
|
name: str,
|
||||||
|
application_data_type: Optional['ApplicationDataType'] = None,
|
||||||
|
implementation_data_type: Optional['ImplementationDataType'] = None,
|
||||||
|
) -> DataTypeMapping:
|
||||||
|
"""创建数据类型映射的工厂函数"""
|
||||||
|
return DataTypeMapping(
|
||||||
|
name=name,
|
||||||
|
application_data_type=application_data_type,
|
||||||
|
implementation_data_type=implementation_data_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_data_type_mapping_set(
|
||||||
|
name: str,
|
||||||
|
mappings: Optional[List[DataTypeMapping]] = None,
|
||||||
|
) -> DataTypeMappingSet:
|
||||||
|
"""创建数据类型映射集的工厂函数"""
|
||||||
|
return DataTypeMappingSet(
|
||||||
|
name=name,
|
||||||
|
data_type_mappings=mappings or [],
|
||||||
|
)
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
"""
|
||||||
|
实现数据类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List, TYPE_CHECKING
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
IMPLEMENTATION_DATA_TYPE, IMPLEMENTATION_DATA_TYPE_ELEMENT, SHORT_NAME, CATEGORY,
|
||||||
|
SW_DATA_DEF_PROPS, SW_DATA_DEF_PROPS_VARIANTS, SW_DATA_DEF_PROPS_CONDITIONAL,
|
||||||
|
BASE_TYPE_REF, DEST, SW_BASE_TYPE, COMPU_METHOD_REF, COMPU_METHOD,
|
||||||
|
IMPLEMENTATION_DATA_TYPE_REF, SUB_ELEMENTS, ARRAY_SIZE, ARRAY_SIZE_SEMANTICS
|
||||||
|
)
|
||||||
|
from ..core.enums import Category, CalibrationAccess, Semantic
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .base_type import BaseType
|
||||||
|
from .compu_method import CompuMethod
|
||||||
|
from .data_constraint import DataConstraint
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ImplementationDataType(Base):
|
||||||
|
"""实现数据类型基类"""
|
||||||
|
category: Optional[Category] = None
|
||||||
|
calibration_access: CalibrationAccess = CalibrationAccess.NOT_SPECIFIED
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ImplementationValueDataType(ImplementationDataType):
|
||||||
|
"""值类型(标量值)"""
|
||||||
|
base_type: Optional['BaseType'] = None
|
||||||
|
compu_method: Optional['CompuMethod'] = None
|
||||||
|
data_constraint: Optional['DataConstraint'] = None
|
||||||
|
category: Category = Category.VALUE
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(IMPLEMENTATION_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
|
||||||
|
if self.base_type is not None:
|
||||||
|
base_type_ref = create_text_element(doc, BASE_TYPE_REF, self.base_type.package_path)
|
||||||
|
base_type_ref.setAttribute(DEST, SW_BASE_TYPE)
|
||||||
|
sw_data_def_props_conditional.appendChild(base_type_ref)
|
||||||
|
|
||||||
|
if self.compu_method is not None:
|
||||||
|
compu_method_ref = create_text_element(doc, COMPU_METHOD_REF, self.compu_method.package_path)
|
||||||
|
compu_method_ref.setAttribute(DEST, COMPU_METHOD)
|
||||||
|
sw_data_def_props_conditional.appendChild(compu_method_ref)
|
||||||
|
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ImplementationStructureDataType(ImplementationDataType):
|
||||||
|
"""结构体类型"""
|
||||||
|
category: Category = Category.STRUCTURE
|
||||||
|
structure_elements: List['ImplementationStructureDataType.StructureElement'] = field(default_factory=list)
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class StructureElement(Base):
|
||||||
|
"""结构体成员"""
|
||||||
|
data_type: Optional[ImplementationDataType] = None
|
||||||
|
category: Category = Category.TYPE_REFERENCE
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(IMPLEMENTATION_DATA_TYPE_ELEMENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
|
||||||
|
if self.data_type:
|
||||||
|
impl_type_ref = create_text_element(
|
||||||
|
doc, IMPLEMENTATION_DATA_TYPE_REF, self.data_type.package_path
|
||||||
|
)
|
||||||
|
impl_type_ref.setAttribute(DEST, IMPLEMENTATION_DATA_TYPE)
|
||||||
|
sw_data_def_props_conditional.appendChild(impl_type_ref)
|
||||||
|
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
def get_element(self, name: str) -> Optional['StructureElement']:
|
||||||
|
"""根据名称查找成员"""
|
||||||
|
for element in self.structure_elements:
|
||||||
|
if element.name == name:
|
||||||
|
return element
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_element(self, element: 'StructureElement') -> None:
|
||||||
|
"""添加结构成员"""
|
||||||
|
if self.get_element(element.name) is not None:
|
||||||
|
return
|
||||||
|
self.structure_elements.append(element)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(IMPLEMENTATION_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sub_elements = doc.createElement(SUB_ELEMENTS)
|
||||||
|
for structure_element in self.structure_elements:
|
||||||
|
sub_elements.appendChild(structure_element.to_arxml(doc))
|
||||||
|
element.appendChild(sub_elements)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ImplementationArrayDataType(ImplementationDataType):
|
||||||
|
"""数组类型"""
|
||||||
|
category: Category = Category.ARRAY
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ArrayElement(Base):
|
||||||
|
"""数组成员"""
|
||||||
|
length: Optional[int] = None
|
||||||
|
data_type: Optional[ImplementationDataType] = None
|
||||||
|
category: Category = Category.TYPE_REFERENCE
|
||||||
|
array_size_semantics: Semantic = Semantic.FIXED
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(IMPLEMENTATION_DATA_TYPE_ELEMENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
element.appendChild(create_text_element(doc, ARRAY_SIZE, str(self.length or 0)))
|
||||||
|
element.appendChild(create_text_element(doc, ARRAY_SIZE_SEMANTICS, self.array_size_semantics.value))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
|
||||||
|
if self.data_type:
|
||||||
|
impl_type_ref = create_text_element(
|
||||||
|
doc, IMPLEMENTATION_DATA_TYPE_REF, self.data_type.package_path
|
||||||
|
)
|
||||||
|
impl_type_ref.setAttribute(DEST, IMPLEMENTATION_DATA_TYPE)
|
||||||
|
sw_data_def_props_conditional.appendChild(impl_type_ref)
|
||||||
|
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
element: Optional['ArrayElement'] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(IMPLEMENTATION_DATA_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.category.name))
|
||||||
|
|
||||||
|
sub_elements = doc.createElement(SUB_ELEMENTS)
|
||||||
|
if self.element:
|
||||||
|
sub_elements.appendChild(self.element.to_arxml(doc))
|
||||||
|
element.appendChild(sub_elements)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_impl_value_type(
|
||||||
|
name: str,
|
||||||
|
base_type: Optional['BaseType'] = None,
|
||||||
|
compu_method: Optional['CompuMethod'] = None,
|
||||||
|
) -> ImplementationValueDataType:
|
||||||
|
"""创建实现值类型的工厂函数"""
|
||||||
|
return ImplementationValueDataType(
|
||||||
|
name=name,
|
||||||
|
base_type=base_type,
|
||||||
|
compu_method=compu_method,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_impl_structure_type(
|
||||||
|
name: str,
|
||||||
|
elements: Optional[List['ImplementationStructureDataType.StructureElement']] = None,
|
||||||
|
) -> ImplementationStructureDataType:
|
||||||
|
"""创建实现结构体类型的工厂函数"""
|
||||||
|
return ImplementationStructureDataType(
|
||||||
|
name=name,
|
||||||
|
structure_elements=elements or [],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_impl_array_type(
|
||||||
|
name: str,
|
||||||
|
element: Optional['ImplementationArrayDataType.ArrayElement'] = None,
|
||||||
|
) -> ImplementationArrayDataType:
|
||||||
|
"""创建实现数组类型的工厂函数"""
|
||||||
|
return ImplementationArrayDataType(
|
||||||
|
name=name,
|
||||||
|
element=element,
|
||||||
|
)
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
"""
|
||||||
|
接口定义模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List, TYPE_CHECKING, Union
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
SENDER_RECEIVER_INTERFACE, SHORT_NAME, IS_SERVICE, DATA_ELEMENTS,
|
||||||
|
VARIABLE_DATA_PROTOTYPE, CATEGORY, SW_DATA_DEF_PROPS, SW_DATA_DEF_PROPS_VARIANTS,
|
||||||
|
SW_DATA_DEF_PROPS_CONDITIONAL, SW_CALIBRATION_ACCESS, SW_IMPL_POLICY,
|
||||||
|
TYPE_TREF, DEST, APPLICATION_PRIMITIVE_DATA_TYPE, APPLICATION_RECORD_DATA_TYPE,
|
||||||
|
APPLICATION_ARRAY_DATA_TYPE, CLIENT_SERVER_INTERFACE, CLIENT_SERVER_OPERATION,
|
||||||
|
ARGUMENT, APPLICATION_PRIMITIVE_TYPE_REF, DIRECTION
|
||||||
|
)
|
||||||
|
from ..core.enums import Policy, CalibrationAccess
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .base_type import BaseType
|
||||||
|
from .compu_method import CompuMethod
|
||||||
|
from .data_constraint import DataConstraint
|
||||||
|
from .sw_addr_method import SwAddrMethod
|
||||||
|
from .application_types import ApplicationDataType
|
||||||
|
from .implementation_types import ImplementationDataType
|
||||||
|
|
||||||
|
|
||||||
|
TYPE_DEST_MAPPING = {
|
||||||
|
"ApplicationStructureDataType": APPLICATION_RECORD_DATA_TYPE,
|
||||||
|
"ApplicationArrayDataType": APPLICATION_ARRAY_DATA_TYPE,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Interface(Base):
|
||||||
|
"""接口基类"""
|
||||||
|
is_service: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SenderReceiverInterface(Interface):
|
||||||
|
"""发送-接收接口"""
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataElement(Base):
|
||||||
|
"""数据元素"""
|
||||||
|
sw_addr_method: Optional['SwAddrMethod'] = None
|
||||||
|
data_constraint: Optional['DataConstraint'] = None
|
||||||
|
data_type: Optional[Union['ApplicationDataType', 'ImplementationDataType']] = None
|
||||||
|
policy: Policy = Policy.STANDARD
|
||||||
|
calibration_access: CalibrationAccess = CalibrationAccess.READ_ONLY
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(VARIABLE_DATA_PROTOTYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
if self.data_type:
|
||||||
|
element.appendChild(create_text_element(doc, CATEGORY, self.data_type.category.name))
|
||||||
|
|
||||||
|
sw_data_def_props = doc.createElement(SW_DATA_DEF_PROPS)
|
||||||
|
sw_data_def_props_variants = doc.createElement(SW_DATA_DEF_PROPS_VARIANTS)
|
||||||
|
sw_data_def_props_conditional = doc.createElement(SW_DATA_DEF_PROPS_CONDITIONAL)
|
||||||
|
sw_data_def_props_conditional.appendChild(
|
||||||
|
create_text_element(doc, SW_CALIBRATION_ACCESS, self.calibration_access.value.upper())
|
||||||
|
)
|
||||||
|
sw_data_def_props_conditional.appendChild(
|
||||||
|
create_text_element(doc, SW_IMPL_POLICY, self.policy.name.upper())
|
||||||
|
)
|
||||||
|
sw_data_def_props_variants.appendChild(sw_data_def_props_conditional)
|
||||||
|
sw_data_def_props.appendChild(sw_data_def_props_variants)
|
||||||
|
element.appendChild(sw_data_def_props)
|
||||||
|
|
||||||
|
type_dest = TYPE_DEST_MAPPING.get(type(self.data_type).__name__, APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
type_tref = create_text_element(doc, TYPE_TREF, self.data_type.package_path)
|
||||||
|
type_tref.setAttribute(DEST, type_dest)
|
||||||
|
element.appendChild(type_tref)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
data_element: Optional[DataElement] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(SENDER_RECEIVER_INTERFACE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, IS_SERVICE, str(self.is_service).lower()))
|
||||||
|
|
||||||
|
if self.data_element:
|
||||||
|
data_elements = doc.createElement(DATA_ELEMENTS)
|
||||||
|
data_elements.appendChild(self.data_element.to_arxml(doc))
|
||||||
|
element.appendChild(data_elements)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ClientServerInterface(Interface):
|
||||||
|
"""客户端-服务端接口"""
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Operation(Base):
|
||||||
|
"""操作方法定义"""
|
||||||
|
is_server: bool = True
|
||||||
|
arguments: List['ClientServerInterface.Argument'] = field(default_factory=list)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(CLIENT_SERVER_OPERATION)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, DIRECTION, "SERVER" if self.is_server else "CLIENT"))
|
||||||
|
return element
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Argument(Base):
|
||||||
|
"""操作参数定义"""
|
||||||
|
direction: str = "IN"
|
||||||
|
data_type: Optional['ApplicationDataType'] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(ARGUMENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, DIRECTION, self.direction))
|
||||||
|
if self.data_type:
|
||||||
|
type_ref = create_text_element(doc, APPLICATION_PRIMITIVE_TYPE_REF, self.data_type.package_path)
|
||||||
|
type_ref.setAttribute(DEST, APPLICATION_PRIMITIVE_DATA_TYPE)
|
||||||
|
element.appendChild(type_ref)
|
||||||
|
return element
|
||||||
|
|
||||||
|
operations: List[Operation] = field(default_factory=list)
|
||||||
|
|
||||||
|
def get_operation(self, name: str) -> Optional['Operation']:
|
||||||
|
"""根据名称查找操作"""
|
||||||
|
for op in self.operations:
|
||||||
|
if op.name == name:
|
||||||
|
return op
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_operation(self, operation: 'Operation') -> None:
|
||||||
|
"""添加操作"""
|
||||||
|
if self.get_operation(operation.name) is None:
|
||||||
|
self.operations.append(operation)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(CLIENT_SERVER_INTERFACE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, IS_SERVICE, str(self.is_service).lower()))
|
||||||
|
|
||||||
|
for op in self.operations:
|
||||||
|
element.appendChild(op.to_arxml(doc))
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ModeSwitchInterface(Interface):
|
||||||
|
"""模式切换接口"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ParameterInterface(Interface):
|
||||||
|
"""参数接口"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TriggerInterface(Interface):
|
||||||
|
"""触发接口"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class NvDataInterface(Interface):
|
||||||
|
"""NvData接口"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def create_sender_receiver_interface(
|
||||||
|
name: str,
|
||||||
|
data_element: Optional[SenderReceiverInterface.DataElement] = None,
|
||||||
|
is_service: bool = False,
|
||||||
|
) -> SenderReceiverInterface:
|
||||||
|
"""创建发送-接收接口的工厂函数"""
|
||||||
|
return SenderReceiverInterface(
|
||||||
|
name=name,
|
||||||
|
data_element=data_element,
|
||||||
|
is_service=is_service,
|
||||||
|
)
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
"""
|
||||||
|
Package 模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import List, Optional, TYPE_CHECKING
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import AR_PACKAGE, SHORT_NAME, ELEMENTS
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .base_type import BaseType
|
||||||
|
from .application_types import ApplicationDataType
|
||||||
|
from .implementation_types import ImplementationDataType
|
||||||
|
from .compu_method import CompuMethod
|
||||||
|
from .data_constraint import DataConstraint
|
||||||
|
from .data_mapping import DataTypeMappingSet
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Package(Base):
|
||||||
|
"""AUTOSAR 包"""
|
||||||
|
elements: List[Base] = field(default_factory=list)
|
||||||
|
|
||||||
|
def get_element(self, name: str) -> Optional[Base]:
|
||||||
|
"""根据名称查找元素"""
|
||||||
|
for element in self.elements:
|
||||||
|
if element.name == name:
|
||||||
|
return element
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_element(self, element: Base) -> None:
|
||||||
|
"""添加元素"""
|
||||||
|
existing = self.get_element(element.name)
|
||||||
|
if existing is None:
|
||||||
|
self.elements.append(element)
|
||||||
|
else:
|
||||||
|
element.id = existing.id
|
||||||
|
element.description = existing.description
|
||||||
|
self.elements.remove(existing)
|
||||||
|
self.elements.append(element)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(AR_PACKAGE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
elements = doc.createElement(ELEMENTS)
|
||||||
|
for elem in self.elements:
|
||||||
|
elements.appendChild(elem.to_arxml(doc))
|
||||||
|
element.appendChild(elements)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_package(name: str, elements: Optional[List[Base]] = None) -> Package:
|
||||||
|
"""创建包的工厂函数"""
|
||||||
|
return Package(name=name, elements=elements or [])
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
"""
|
||||||
|
软件地址方法模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import SW_ADDR_METHOD, SHORT_NAME, SECTION_TYPE
|
||||||
|
from ..core.enums import SectionType
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SwAddrMethod(Base):
|
||||||
|
"""软件地址方法"""
|
||||||
|
section_type: Optional[SectionType] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(SW_ADDR_METHOD)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
if self.section_type:
|
||||||
|
element.appendChild(create_text_element(doc, SECTION_TYPE, self.section_type.name))
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_sw_addr_method(name: str, section_type: Optional[SectionType] = None) -> SwAddrMethod:
|
||||||
|
"""创建软件地址方法的工厂函数"""
|
||||||
|
return SwAddrMethod(name=name, section_type=section_type)
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
"""
|
||||||
|
软件组件类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List, TYPE_CHECKING
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
APPLICATION_SW_COMPONENT_TYPE, SHORT_NAME, PORTS, R_PORT_PROTOTYPE, P_PORT_PROTOTYPE,
|
||||||
|
REQUIRED_COM_SPECS, PROVIDED_COM_SPECS, PROVIDED_INTERFACE_TREF, REQUIRED_INTERFACE_TREF,
|
||||||
|
NONQUEUED_RECEIVER_COM_SPEC, NONQUEUED_SENDER_COM_SPEC, DATA_ELEMENT_REF, VARIABLE_DATA_PROTOTYPE,
|
||||||
|
DEST, SENDER_RECEIVER_INTERFACE, HANDLE_OUT_OF_RANGE, USES_END_TO_END_PROTECTION,
|
||||||
|
ALIVE_TIMEOUT, ENABLE_UPDATE, HANDLE_NEVER_RECEIVED, HANDLE_TIMEOUT_TYPE, SW_DATA_DEF_PROPS,
|
||||||
|
SW_DATA_DEF_PROPS_VARIANTS, SW_DATA_DEF_PROPS_CONDITIONAL, SW_CALIBRATION_ACCESS, SW_IMPL_POLICY,
|
||||||
|
TYPE_TREF, INTERNAL_BEHAVIORS, SWC_INTERNAL_BEHAVIOR, RUNNABLES, RUNNABLE_ENTITY,
|
||||||
|
MINIMUM_START_INTERVAL, CAN_BE_INVOKED_CONCURRENTLY, DATA_RECEIVE_POINT_BY_ARGUMENTS,
|
||||||
|
VARIABLE_ACCESS, ACCESSED_VARIABLE, AUTOSAR_VARIABLE_IREF, PORT_PROTOTYPE_REF,
|
||||||
|
TARGET_DATA_PROTOTYPE_REF, DATA_SEND_POINTS, EVENTS, INIT_EVENT, TIMING_EVENT,
|
||||||
|
OPERATION_INVOKED_EVENT, DATA_RECEIVED_EVENT, START_ON_EVENT_REF, PERIOD, CODE,
|
||||||
|
SW_ADDR_METHOD_REF, CLIENT_SERVER_INTERFACE,
|
||||||
|
)
|
||||||
|
from ..core.enums import ComponentType, AtomicType, ImplementationCodeType, CalibrationAccess, Policy
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .interface import SenderReceiverInterface, ClientServerInterface
|
||||||
|
from .data_mapping import SwAddrMethod
|
||||||
|
from .swc_internal_behavior import SwcInternalBehavior
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SwComponentType(Base):
|
||||||
|
"""软件组件类型基类"""
|
||||||
|
component_type: ComponentType = ComponentType.ATOMIC
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AtomicComponentType(SwComponentType):
|
||||||
|
"""原子组件类型"""
|
||||||
|
supports_multiple_instantiation: bool = True
|
||||||
|
atomic_type: AtomicType = AtomicType.APPLICATION
|
||||||
|
implementation_code_type: ImplementationCodeType = ImplementationCodeType.SOURCE_CODE
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CompositionSwComponentType(SwComponentType):
|
||||||
|
"""组合组件类型"""
|
||||||
|
component_type: ComponentType = ComponentType.COMPOSITION
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ParameterSwComponentType(SwComponentType):
|
||||||
|
"""参数组件类型"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ApplicationSwComponentType(AtomicComponentType):
|
||||||
|
"""应用软件组件类型"""
|
||||||
|
atomic_type: AtomicType = AtomicType.APPLICATION
|
||||||
|
ports: List['PortPrototype'] = field(default_factory=list)
|
||||||
|
internal_behavior: Optional['SwcInternalBehavior'] = None
|
||||||
|
|
||||||
|
def get_port(self, name: str) -> Optional['PortPrototype']:
|
||||||
|
"""根据名称查找端口"""
|
||||||
|
for port in self.ports:
|
||||||
|
if port.name == name:
|
||||||
|
return port
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_port(self, port: 'PortPrototype') -> None:
|
||||||
|
"""添加端口"""
|
||||||
|
if self.get_port(port.name) is None:
|
||||||
|
self.ports.append(port)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(APPLICATION_SW_COMPONENT_TYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
if self.ports:
|
||||||
|
ports_elem = doc.createElement(PORTS)
|
||||||
|
for port in self.ports:
|
||||||
|
ports_elem.appendChild(port.to_arxml(doc))
|
||||||
|
element.appendChild(ports_elem)
|
||||||
|
|
||||||
|
if self.internal_behavior:
|
||||||
|
internal_behaviors = doc.createElement(INTERNAL_BEHAVIORS)
|
||||||
|
internal_behaviors.appendChild(self.internal_behavior.to_arxml(doc))
|
||||||
|
element.appendChild(internal_behaviors)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ServiceSwComponentType(AtomicComponentType):
|
||||||
|
"""服务组件类型"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SensorActuatorSwComponentType(AtomicComponentType):
|
||||||
|
"""传感器/执行器组件类型"""
|
||||||
|
atomic_type: AtomicType = AtomicType.SENSOR_ACTUATOR
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EcuAbstractionSwComponentType(AtomicComponentType):
|
||||||
|
"""ECU抽象组件类型"""
|
||||||
|
atomic_type: AtomicType = AtomicType.HARDWARE_ABSTRACTION
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ComplexDeviceDriverSwComponentType(AtomicComponentType):
|
||||||
|
"""复杂驱动组件类型"""
|
||||||
|
atomic_type: AtomicType = AtomicType.COMPLEX_DRIVER
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ServiceProxySwComponentType(AtomicComponentType):
|
||||||
|
"""服务代理组件类型"""
|
||||||
|
atomic_type: AtomicType = AtomicType.SERVICE_PROXY
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PortPrototype(Base):
|
||||||
|
"""端口原型基类"""
|
||||||
|
interface: Optional['SenderReceiverInterface'] = None
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RPortPrototype(PortPrototype):
|
||||||
|
"""接收端口(R-Port)"""
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(R_PORT_PROTOTYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
if self.interface:
|
||||||
|
required_com_specs = doc.createElement(REQUIRED_COM_SPECS)
|
||||||
|
nonqueued_receiver_com_spec = doc.createElement(NONQUEUED_RECEIVER_COM_SPEC)
|
||||||
|
|
||||||
|
if hasattr(self.interface, 'data_element') and self.interface.data_element:
|
||||||
|
data_element_ref = create_text_element(
|
||||||
|
doc, DATA_ELEMENT_REF, self.interface.data_element.package_path
|
||||||
|
)
|
||||||
|
data_element_ref.setAttribute(DEST, VARIABLE_DATA_PROTOTYPE)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(data_element_ref)
|
||||||
|
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, HANDLE_OUT_OF_RANGE, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, USES_END_TO_END_PROTECTION, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, ALIVE_TIMEOUT, '0')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, ENABLE_UPDATE, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, HANDLE_NEVER_RECEIVED, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, HANDLE_TIMEOUT_TYPE, 'NONE')
|
||||||
|
)
|
||||||
|
|
||||||
|
required_com_specs.appendChild(nonqueued_receiver_com_spec)
|
||||||
|
element.appendChild(required_com_specs)
|
||||||
|
|
||||||
|
required_interface_tref = create_text_element(
|
||||||
|
doc, REQUIRED_INTERFACE_TREF, self.interface.package_path
|
||||||
|
)
|
||||||
|
required_interface_tref.setAttribute(DEST, SENDER_RECEIVER_INTERFACE)
|
||||||
|
element.appendChild(required_interface_tref)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PPortPrototype(PortPrototype):
|
||||||
|
"""发送端口(P-Port)"""
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(P_PORT_PROTOTYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
if self.interface:
|
||||||
|
provided_com_specs = doc.createElement(PROVIDED_COM_SPECS)
|
||||||
|
nonqueued_sender_com_spec = doc.createElement(NONQUEUED_SENDER_COM_SPEC)
|
||||||
|
|
||||||
|
if hasattr(self.interface, 'data_element') and self.interface.data_element:
|
||||||
|
data_element_ref = create_text_element(
|
||||||
|
doc, DATA_ELEMENT_REF, self.interface.data_element.package_path
|
||||||
|
)
|
||||||
|
data_element_ref.setAttribute(DEST, VARIABLE_DATA_PROTOTYPE)
|
||||||
|
nonqueued_sender_com_spec.appendChild(data_element_ref)
|
||||||
|
|
||||||
|
provided_com_specs.appendChild(nonqueued_sender_com_spec)
|
||||||
|
element.appendChild(provided_com_specs)
|
||||||
|
|
||||||
|
provided_interface_tref = create_text_element(
|
||||||
|
doc, PROVIDED_INTERFACE_TREF, self.interface.package_path
|
||||||
|
)
|
||||||
|
provided_interface_tref.setAttribute(DEST, SENDER_RECEIVER_INTERFACE)
|
||||||
|
element.appendChild(provided_interface_tref)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PRPortPrototype(PortPrototype):
|
||||||
|
"""双向端口(PR-Port)"""
|
||||||
|
required_interface: Optional['SenderReceiverInterface'] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(P_PORT_PROTOTYPE)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
|
||||||
|
if self.interface:
|
||||||
|
provided_com_specs = doc.createElement(PROVIDED_COM_SPECS)
|
||||||
|
nonqueued_sender_com_spec = doc.createElement(NONQUEUED_SENDER_COM_SPEC)
|
||||||
|
|
||||||
|
if hasattr(self.interface, 'data_element') and self.interface.data_element:
|
||||||
|
data_element_ref = create_text_element(
|
||||||
|
doc, DATA_ELEMENT_REF, self.interface.data_element.package_path
|
||||||
|
)
|
||||||
|
data_element_ref.setAttribute(DEST, VARIABLE_DATA_PROTOTYPE)
|
||||||
|
nonqueued_sender_com_spec.appendChild(data_element_ref)
|
||||||
|
|
||||||
|
provided_com_specs.appendChild(nonqueued_sender_com_spec)
|
||||||
|
element.appendChild(provided_com_specs)
|
||||||
|
|
||||||
|
provided_interface_tref = create_text_element(
|
||||||
|
doc, PROVIDED_INTERFACE_TREF, self.interface.package_path
|
||||||
|
)
|
||||||
|
provided_interface_tref.setAttribute(DEST, SENDER_RECEIVER_INTERFACE)
|
||||||
|
element.appendChild(provided_interface_tref)
|
||||||
|
|
||||||
|
if self.required_interface:
|
||||||
|
required_com_specs = doc.createElement(REQUIRED_COM_SPECS)
|
||||||
|
nonqueued_receiver_com_spec = doc.createElement(NONQUEUED_RECEIVER_COM_SPEC)
|
||||||
|
|
||||||
|
if hasattr(self.required_interface, 'data_element') and self.required_interface.data_element:
|
||||||
|
data_element_ref = create_text_element(
|
||||||
|
doc, DATA_ELEMENT_REF, self.required_interface.data_element.package_path
|
||||||
|
)
|
||||||
|
data_element_ref.setAttribute(DEST, VARIABLE_DATA_PROTOTYPE)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(data_element_ref)
|
||||||
|
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, HANDLE_OUT_OF_RANGE, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, USES_END_TO_END_PROTECTION, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, ALIVE_TIMEOUT, '0')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, ENABLE_UPDATE, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, HANDLE_NEVER_RECEIVED, 'FALSE')
|
||||||
|
)
|
||||||
|
nonqueued_receiver_com_spec.appendChild(
|
||||||
|
create_text_element(doc, HANDLE_TIMEOUT_TYPE, 'NONE')
|
||||||
|
)
|
||||||
|
|
||||||
|
required_com_specs.appendChild(nonqueued_receiver_com_spec)
|
||||||
|
element.appendChild(required_com_specs)
|
||||||
|
|
||||||
|
required_interface_tref = create_text_element(
|
||||||
|
doc, REQUIRED_INTERFACE_TREF, self.required_interface.package_path
|
||||||
|
)
|
||||||
|
required_interface_tref.setAttribute(DEST, SENDER_RECEIVER_INTERFACE)
|
||||||
|
element.appendChild(required_interface_tref)
|
||||||
|
|
||||||
|
return element
|
||||||
@@ -0,0 +1,276 @@
|
|||||||
|
"""
|
||||||
|
SWC 内部行为模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional, List, Union, TYPE_CHECKING
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import (
|
||||||
|
RUNNABLE_ENTITY, SHORT_NAME, MINIMUM_START_INTERVAL, CAN_BE_INVOKED_CONCURRENTLY,
|
||||||
|
DATA_RECEIVE_POINT_BY_ARGUMENTS, VARIABLE_ACCESS, ACCESSED_VARIABLE, AUTOSAR_VARIABLE_IREF,
|
||||||
|
PORT_PROTOTYPE_REF, TARGET_DATA_PROTOTYPE_REF, DATA_SEND_POINTS, SYMBOL,
|
||||||
|
SW_ADDR_METHOD_REF, DATA_ELEMENT_REF, RUNNABLES, EVENTS, INIT_EVENT, TIMING_EVENT,
|
||||||
|
OPERATION_INVOKED_EVENT, DATA_RECEIVED_EVENT, START_ON_EVENT_REF, PERIOD,
|
||||||
|
CLIENT_SERVER_OPERATION_REF, DEST, VARIABLE_DATA_PROTOTYPE, SWC_INTERNAL_BEHAVIOR
|
||||||
|
)
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from .interface import ClientServerInterface
|
||||||
|
from .sw_addr_method import SwAddrMethod
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VariableAccess(Base):
|
||||||
|
"""变量访问"""
|
||||||
|
port_prototype_ref: Optional[str] = None
|
||||||
|
target_data_prototype_ref: Optional[str] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(ACCESSED_VARIABLE)
|
||||||
|
autosar_var_iref = doc.createElement(AUTOSAR_VARIABLE_IREF)
|
||||||
|
|
||||||
|
if self.port_prototype_ref:
|
||||||
|
port_ref = create_text_element(doc, PORT_PROTOTYPE_REF, self.port_prototype_ref)
|
||||||
|
port_ref.setAttribute(DEST, "PORT-PROTOTYPE")
|
||||||
|
autosar_var_iref.appendChild(port_ref)
|
||||||
|
|
||||||
|
if self.target_data_prototype_ref:
|
||||||
|
target_ref = create_text_element(doc, TARGET_DATA_PROTOTYPE_REF, self.target_data_prototype_ref)
|
||||||
|
target_ref.setAttribute(DEST, VARIABLE_DATA_PROTOTYPE)
|
||||||
|
autosar_var_iref.appendChild(target_ref)
|
||||||
|
|
||||||
|
element.appendChild(autosar_var_iref)
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class RunnableEntity(Base):
|
||||||
|
"""Runnable 实体"""
|
||||||
|
minimum_start_interval: int = 0
|
||||||
|
can_be_invoked_concurrently: bool = False
|
||||||
|
data_receive_points: List[VariableAccess] = field(default_factory=list)
|
||||||
|
data_send_points: List[VariableAccess] = field(default_factory=list)
|
||||||
|
variable_accesses: List[VariableAccess] = field(default_factory=list)
|
||||||
|
symbol: Optional[str] = None
|
||||||
|
sw_addr_method_ref: Optional[str] = None
|
||||||
|
|
||||||
|
def add_data_receive_point(self, access: VariableAccess) -> None:
|
||||||
|
"""添加数据接收点"""
|
||||||
|
self.data_receive_points.append(access)
|
||||||
|
|
||||||
|
def add_data_send_point(self, access: VariableAccess) -> None:
|
||||||
|
"""添加数据发送点"""
|
||||||
|
self.data_send_points.append(access)
|
||||||
|
|
||||||
|
def add_variable_access(self, access: VariableAccess) -> None:
|
||||||
|
"""添加变量访问"""
|
||||||
|
self.variable_accesses.append(access)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(RUNNABLE_ENTITY)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, MINIMUM_START_INTERVAL, str(self.minimum_start_interval)))
|
||||||
|
element.appendChild(create_text_element(doc, CAN_BE_INVOKED_CONCURRENTLY, str(self.can_be_invoked_concurrently).lower()))
|
||||||
|
|
||||||
|
if self.symbol:
|
||||||
|
element.appendChild(create_text_element(doc, SYMBOL, self.symbol))
|
||||||
|
|
||||||
|
if self.sw_addr_method_ref:
|
||||||
|
method_ref = create_text_element(doc, SW_ADDR_METHOD_REF, self.sw_addr_method_ref)
|
||||||
|
method_ref.setAttribute(DEST, "SW-ADDR-METHOD")
|
||||||
|
element.appendChild(method_ref)
|
||||||
|
|
||||||
|
if self.data_receive_points:
|
||||||
|
data_receive_elem = doc.createElement(DATA_RECEIVE_POINT_BY_ARGUMENTS)
|
||||||
|
for access in self.data_receive_points:
|
||||||
|
data_receive_elem.appendChild(access.to_arxml(doc))
|
||||||
|
element.appendChild(data_receive_elem)
|
||||||
|
|
||||||
|
if self.data_send_points:
|
||||||
|
data_send_elem = doc.createElement(DATA_SEND_POINTS)
|
||||||
|
for access in self.data_send_points:
|
||||||
|
data_send_elem.appendChild(access.to_arxml(doc))
|
||||||
|
element.appendChild(data_send_elem)
|
||||||
|
|
||||||
|
if self.variable_accesses:
|
||||||
|
var_access_elem = doc.createElement(VARIABLE_ACCESS)
|
||||||
|
for access in self.variable_accesses:
|
||||||
|
var_access_elem.appendChild(access.to_arxml(doc))
|
||||||
|
element.appendChild(var_access_elem)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class InitEvent(Base):
|
||||||
|
"""初始化事件"""
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(INIT_EVENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TimingEvent(Base):
|
||||||
|
"""定时事件"""
|
||||||
|
period: float = 0.01
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(TIMING_EVENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, PERIOD, str(self.period)))
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OperationInvokedEvent(Base):
|
||||||
|
"""操作调用事件"""
|
||||||
|
operation_ref: Optional[str] = None
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(OPERATION_INVOKED_EVENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
if self.operation_ref:
|
||||||
|
op_ref = create_text_element(doc, START_ON_EVENT_REF, self.operation_ref)
|
||||||
|
op_ref.setAttribute(DEST, CLIENT_SERVER_OPERATION_REF)
|
||||||
|
element.appendChild(op_ref)
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DataReceivedEvent(Base):
|
||||||
|
"""数据接收事件"""
|
||||||
|
data_element_ref: Optional[str] = None
|
||||||
|
period: float = 0.01
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(DATA_RECEIVED_EVENT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
if self.data_element_ref:
|
||||||
|
data_ref = create_text_element(doc, START_ON_EVENT_REF, self.data_element_ref)
|
||||||
|
data_ref.setAttribute(DEST, DATA_ELEMENT_REF)
|
||||||
|
element.appendChild(data_ref)
|
||||||
|
element.appendChild(create_text_element(doc, PERIOD, str(self.period)))
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
EventType = Union[InitEvent, TimingEvent, OperationInvokedEvent, DataReceivedEvent]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SwcInternalBehavior(Base):
|
||||||
|
"""SWC 内部行为"""
|
||||||
|
runnable_entities: List[RunnableEntity] = field(default_factory=list)
|
||||||
|
events: List[EventType] = field(default_factory=list)
|
||||||
|
symbol: Optional[str] = None
|
||||||
|
|
||||||
|
def get_runnable(self, name: str) -> Optional[RunnableEntity]:
|
||||||
|
"""根据名称查找 Runnable"""
|
||||||
|
for runnable in self.runnable_entities:
|
||||||
|
if runnable.name == name:
|
||||||
|
return runnable
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_runnable(self, runnable: RunnableEntity) -> None:
|
||||||
|
"""添加 Runnable"""
|
||||||
|
if self.get_runnable(runnable.name) is None:
|
||||||
|
self.runnable_entities.append(runnable)
|
||||||
|
|
||||||
|
def get_event(self, name: str) -> Optional[EventType]:
|
||||||
|
"""根据名称查找事件"""
|
||||||
|
for event in self.events:
|
||||||
|
if event.name == name:
|
||||||
|
return event
|
||||||
|
return None
|
||||||
|
|
||||||
|
def add_event(self, event: EventType) -> None:
|
||||||
|
"""添加事件"""
|
||||||
|
if self.get_event(event.name) is None:
|
||||||
|
self.events.append(event)
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(SWC_INTERNAL_BEHAVIOR)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
|
||||||
|
if self.symbol:
|
||||||
|
element.appendChild(create_text_element(doc, SYMBOL, self.symbol))
|
||||||
|
|
||||||
|
if self.runnable_entities:
|
||||||
|
runnables = doc.createElement(RUNNABLES)
|
||||||
|
for runnable in self.runnable_entities:
|
||||||
|
runnables.appendChild(runnable.to_arxml(doc))
|
||||||
|
element.appendChild(runnables)
|
||||||
|
|
||||||
|
if self.events:
|
||||||
|
events_elem = doc.createElement(EVENTS)
|
||||||
|
for event in self.events:
|
||||||
|
events_elem.appendChild(event.to_arxml(doc))
|
||||||
|
element.appendChild(events_elem)
|
||||||
|
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_runnable_entity(
|
||||||
|
name: str,
|
||||||
|
minimum_start_interval: int = 0,
|
||||||
|
can_be_invoked_concurrently: bool = False,
|
||||||
|
symbol: Optional[str] = None,
|
||||||
|
sw_addr_method_ref: Optional[str] = None,
|
||||||
|
) -> RunnableEntity:
|
||||||
|
"""创建 Runnable 实体的工厂函数"""
|
||||||
|
return RunnableEntity(
|
||||||
|
name=name,
|
||||||
|
minimum_start_interval=minimum_start_interval,
|
||||||
|
can_be_invoked_concurrently=can_be_invoked_concurrently,
|
||||||
|
symbol=symbol,
|
||||||
|
sw_addr_method_ref=sw_addr_method_ref,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def create_timing_event(name: str, period: float = 0.01) -> TimingEvent:
|
||||||
|
"""创建定时事件的工厂函数"""
|
||||||
|
return TimingEvent(name=name, period=period)
|
||||||
|
|
||||||
|
|
||||||
|
def create_init_event(name: str) -> InitEvent:
|
||||||
|
"""创建初始化事件的工厂函数"""
|
||||||
|
return InitEvent(name=name)
|
||||||
|
|
||||||
|
|
||||||
|
def create_operation_invoked_event(name: str, operation_ref: Optional[str] = None) -> OperationInvokedEvent:
|
||||||
|
"""创建操作调用事件的工厂函数"""
|
||||||
|
return OperationInvokedEvent(name=name, operation_ref=operation_ref)
|
||||||
|
|
||||||
|
|
||||||
|
def create_data_received_event(name: str, data_element_ref: Optional[str] = None, period: float = 0.01) -> DataReceivedEvent:
|
||||||
|
"""创建数据接收事件的工厂函数"""
|
||||||
|
return DataReceivedEvent(name=name, data_element_ref=data_element_ref, period=period)
|
||||||
|
|
||||||
|
|
||||||
|
def create_swc_internal_behavior(
|
||||||
|
name: str,
|
||||||
|
runnable_entities: Optional[List[RunnableEntity]] = None,
|
||||||
|
events: Optional[List[EventType]] = None,
|
||||||
|
symbol: Optional[str] = None,
|
||||||
|
) -> SwcInternalBehavior:
|
||||||
|
"""创建 SWC 内部行为的工厂函数"""
|
||||||
|
return SwcInternalBehavior(
|
||||||
|
name=name,
|
||||||
|
runnable_entities=runnable_entities or [],
|
||||||
|
events=events or [],
|
||||||
|
symbol=symbol,
|
||||||
|
)
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
"""
|
||||||
|
单位数据类型模块
|
||||||
|
"""
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Optional
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from ..core.base import Base, create_uuid, create_text_element
|
||||||
|
from ..core.constants import UNIT, SHORT_NAME, FACTOR_SI_TO_UNIT, OFFSET_SI_TO_UNIT
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Unit(Base):
|
||||||
|
"""数据单位"""
|
||||||
|
display: Optional[str] = ''
|
||||||
|
factor: int = 1
|
||||||
|
offset: int = 0
|
||||||
|
|
||||||
|
def to_arxml(self, doc: Document) -> Document:
|
||||||
|
"""转换为 ARXML 元素"""
|
||||||
|
element = doc.createElement(UNIT)
|
||||||
|
element.setAttribute("UUID", create_uuid())
|
||||||
|
element.appendChild(create_text_element(doc, SHORT_NAME, self.name))
|
||||||
|
element.appendChild(create_text_element(doc, FACTOR_SI_TO_UNIT, str(self.factor)))
|
||||||
|
element.appendChild(create_text_element(doc, OFFSET_SI_TO_UNIT, str(self.offset)))
|
||||||
|
if self.display:
|
||||||
|
element.appendChild(create_text_element(doc, "DISPLAY", self.display))
|
||||||
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def create_unit(
|
||||||
|
name: str,
|
||||||
|
display: Optional[str] = None,
|
||||||
|
factor: int = 1,
|
||||||
|
offset: int = 0,
|
||||||
|
) -> Unit:
|
||||||
|
"""创建单位的工厂函数"""
|
||||||
|
return Unit(
|
||||||
|
name=name,
|
||||||
|
display=display or '',
|
||||||
|
factor=factor,
|
||||||
|
offset=offset,
|
||||||
|
)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
"""
|
||||||
|
utils 模块 - ARXML 工具函数
|
||||||
|
"""
|
||||||
|
from .arxml_writer import (
|
||||||
|
create_arxml_document,
|
||||||
|
write_arxml,
|
||||||
|
write_arxml_pretty,
|
||||||
|
get_ar_packages_element,
|
||||||
|
add_package_to_document,
|
||||||
|
)
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"create_arxml_document",
|
||||||
|
"write_arxml",
|
||||||
|
"write_arxml_pretty",
|
||||||
|
"get_ar_packages_element",
|
||||||
|
"add_package_to_document",
|
||||||
|
]
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
"""
|
||||||
|
ARXML 文件写入工具模块
|
||||||
|
"""
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
from xml.dom.minidom import Element
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
from ..core.constants import AUTOSAR, AR_PACKAGES
|
||||||
|
|
||||||
|
|
||||||
|
def create_arxml_document() -> Document:
|
||||||
|
"""创建 ARXML 文档"""
|
||||||
|
doc = Document()
|
||||||
|
autosar = doc.createElement(AUTOSAR)
|
||||||
|
autosar.setAttribute("xmlns", "http://autosar.org/schema/r4.4")
|
||||||
|
autosar.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance")
|
||||||
|
autosar.setAttribute("xsi:schemaLocation", "http://autosar.org/schema/r4.4 AUTOSAR_4-4.xsd")
|
||||||
|
ar_packages = doc.createElement(AR_PACKAGES)
|
||||||
|
autosar.appendChild(ar_packages)
|
||||||
|
doc.appendChild(autosar)
|
||||||
|
return doc
|
||||||
|
|
||||||
|
|
||||||
|
def write_arxml(doc: Document, filepath: str, encoding: str = 'utf-8') -> None:
|
||||||
|
"""将 ARXML Document 写入文件
|
||||||
|
|
||||||
|
Args:
|
||||||
|
doc: ARXML Document 对象
|
||||||
|
filepath: 输出文件路径
|
||||||
|
encoding: 文件编码(默认 utf-8)
|
||||||
|
"""
|
||||||
|
with open(filepath, 'w', encoding=encoding) as f:
|
||||||
|
xml_string = doc.toprettyxml(indent=' ', encoding=encoding)
|
||||||
|
f.write(xml_string.decode(encoding))
|
||||||
|
|
||||||
|
|
||||||
|
def write_arxml_pretty(doc: Document, filepath: str, encoding: str = 'utf-8') -> None:
|
||||||
|
"""将 ARXML Document 写入文件(格式化输出)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
doc: ARXML Document 对象
|
||||||
|
filepath: 输出文件路径
|
||||||
|
encoding: 文件编码(默认 utf-8)
|
||||||
|
"""
|
||||||
|
with open(filepath, 'w', encoding=encoding) as f:
|
||||||
|
f.write(doc.toprettyxml(indent=' '))
|
||||||
|
|
||||||
|
|
||||||
|
def get_ar_packages_element(doc: Document) -> Optional[Element]:
|
||||||
|
"""获取 AR-PACKAGES 元素"""
|
||||||
|
if doc.documentElement and doc.documentElement.tagName == AUTOSAR:
|
||||||
|
packages = doc.documentElement.getElementsByTagName(AR_PACKAGES)
|
||||||
|
if packages:
|
||||||
|
return packages[0]
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def add_package_to_document(doc: Document, package_element: Element) -> None:
|
||||||
|
"""添加 Package 元素到文档"""
|
||||||
|
packages = get_ar_packages_element(doc)
|
||||||
|
if packages is not None:
|
||||||
|
packages.appendChild(package_element)
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"""测试包初始化"""
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
"""
|
||||||
|
核心模块测试
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
from src.core.base import Base, create_uuid, create_text_element
|
||||||
|
from src.core.enums import Category, Encoding, CalibrationAccess
|
||||||
|
|
||||||
|
|
||||||
|
class TestBase:
|
||||||
|
"""Base 基类测试"""
|
||||||
|
|
||||||
|
def test_base_creation(self):
|
||||||
|
"""测试基本创建"""
|
||||||
|
base = Base(name="TestElement")
|
||||||
|
assert base.name == "TestElement"
|
||||||
|
assert base.id is None
|
||||||
|
assert base.parent is None
|
||||||
|
assert base.description is None
|
||||||
|
|
||||||
|
def test_base_with_parent(self):
|
||||||
|
"""测试带父元素的创建"""
|
||||||
|
parent = Base(name="Parent")
|
||||||
|
child = Base(name="Child", parent=parent)
|
||||||
|
assert child.parent == parent
|
||||||
|
assert child.parent_id == parent.id
|
||||||
|
|
||||||
|
def test_package_path(self):
|
||||||
|
"""测试包路径计算"""
|
||||||
|
parent = Base(name="Parent")
|
||||||
|
child = Base(name="Child", parent=parent)
|
||||||
|
assert child.package_path == "/Parent/Child"
|
||||||
|
|
||||||
|
def test_package_path_deep(self):
|
||||||
|
"""测试深层包路径"""
|
||||||
|
level1 = Base(name="Level1")
|
||||||
|
level2 = Base(name="Level2", parent=level1)
|
||||||
|
level3 = Base(name="Level3", parent=level2)
|
||||||
|
level4 = Base(name="Level4", parent=level3)
|
||||||
|
assert level4.package_path == "/Level1/Level2/Level3/Level4"
|
||||||
|
|
||||||
|
|
||||||
|
class TestUtilityFunctions:
|
||||||
|
"""工具函数测试"""
|
||||||
|
|
||||||
|
def test_create_uuid(self):
|
||||||
|
"""测试 UUID 生成"""
|
||||||
|
uuid1 = create_uuid()
|
||||||
|
uuid2 = create_uuid()
|
||||||
|
assert uuid1 != uuid2
|
||||||
|
assert len(uuid1) == 36
|
||||||
|
|
||||||
|
def test_create_text_element(self):
|
||||||
|
"""测试文本元素创建"""
|
||||||
|
import xml.dom.minidom as Dom
|
||||||
|
|
||||||
|
doc = Dom.Document()
|
||||||
|
element = create_text_element(doc, "TEST_TAG", "test_value")
|
||||||
|
|
||||||
|
assert element.tagName == "TEST_TAG"
|
||||||
|
assert element.firstChild.nodeValue == "test_value"
|
||||||
|
|
||||||
|
|
||||||
|
class TestEnums:
|
||||||
|
"""枚举类型测试"""
|
||||||
|
|
||||||
|
def test_category_enum(self):
|
||||||
|
"""测试 Category 枚举"""
|
||||||
|
assert Category.FIXED_LENGTH is not None
|
||||||
|
assert Category.VALUE is not None
|
||||||
|
assert Category.STRUCTURE is not None
|
||||||
|
assert Category.ARRAY is not None
|
||||||
|
|
||||||
|
def test_calibration_access_enum(self):
|
||||||
|
"""测试 CalibrationAccess 枚举"""
|
||||||
|
assert CalibrationAccess.READ_ONLY is not None
|
||||||
|
assert CalibrationAccess.READ_WRITE is not None
|
||||||
|
assert CalibrationAccess.NOT_ACCESSIBLE is not None
|
||||||
|
assert CalibrationAccess.NOT_SPECIFIED is not None
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
pytest.main([__file__, "-v"])
|
||||||
@@ -0,0 +1,136 @@
|
|||||||
|
"""
|
||||||
|
集成测试 - 完整 ARXML 文件生成
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
from src import (
|
||||||
|
create_base_type,
|
||||||
|
create_unit,
|
||||||
|
create_data_constraint,
|
||||||
|
create_compu_method,
|
||||||
|
create_linear,
|
||||||
|
create_boolean_type,
|
||||||
|
create_value_type,
|
||||||
|
create_structure_type,
|
||||||
|
create_impl_value_type,
|
||||||
|
create_sender_receiver_interface,
|
||||||
|
SenderReceiverInterface,
|
||||||
|
ApplicationStructureDataType,
|
||||||
|
Category,
|
||||||
|
CalibrationAccess,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestARXMLGeneration:
|
||||||
|
"""ARXML 生成测试"""
|
||||||
|
|
||||||
|
def test_full_type_chain(self):
|
||||||
|
"""测试完整的类型链(应用类型 -> 实现类型 -> 基础类型)"""
|
||||||
|
base_type = create_base_type("UInt8", size=8)
|
||||||
|
assert base_type.name == "UInt8"
|
||||||
|
|
||||||
|
impl_type = create_impl_value_type("ImplUInt8", base_type=base_type)
|
||||||
|
assert impl_type.name == "ImplUInt8"
|
||||||
|
assert impl_type.base_type == base_type
|
||||||
|
|
||||||
|
app_type = create_value_type("AppUInt8")
|
||||||
|
assert app_type.name == "AppUInt8"
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
base_element = base_type.to_arxml(doc)
|
||||||
|
assert base_element.tagName == "SW-BASE-TYPE"
|
||||||
|
|
||||||
|
impl_element = impl_type.to_arxml(doc)
|
||||||
|
assert impl_element.tagName == "IMPLEMENTATION-DATA-TYPE"
|
||||||
|
|
||||||
|
app_element = app_type.to_arxml(doc)
|
||||||
|
assert app_element.tagName == "APPLICATION-PRIMITIVE-DATA-TYPE"
|
||||||
|
|
||||||
|
def test_unit_with_compu_method(self):
|
||||||
|
"""测试单位与计算方法关联"""
|
||||||
|
unit = create_unit("kmh", display="km/h")
|
||||||
|
|
||||||
|
linear = create_linear(factor=0.01, offset=0)
|
||||||
|
compu = create_compu_method("SpeedConversion", unit=unit, linear=linear)
|
||||||
|
assert compu.unit == unit
|
||||||
|
assert compu.linear == linear
|
||||||
|
|
||||||
|
def test_complex_structure(self):
|
||||||
|
"""测试复杂结构体"""
|
||||||
|
member1 = ApplicationStructureDataType.StructureElement(name="temperature")
|
||||||
|
member2 = ApplicationStructureDataType.StructureElement(name="humidity")
|
||||||
|
|
||||||
|
struct = create_structure_type("EnvironmentData", elements=[member1, member2])
|
||||||
|
assert len(struct.structure_elements) == 2
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = struct.to_arxml(doc)
|
||||||
|
assert element.tagName == "APPLICATION-RECORD-DATA-TYPE"
|
||||||
|
|
||||||
|
def test_interface_creation(self):
|
||||||
|
"""测试接口创建"""
|
||||||
|
data_element = SenderReceiverInterface.DataElement(name="SpeedData")
|
||||||
|
interface = create_sender_receiver_interface(
|
||||||
|
"SpeedInterface",
|
||||||
|
data_element=data_element,
|
||||||
|
is_service=False
|
||||||
|
)
|
||||||
|
|
||||||
|
assert interface.name == "SpeedInterface"
|
||||||
|
assert interface.data_element == data_element
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = interface.to_arxml(doc)
|
||||||
|
assert element.tagName == "SENDER-RECEIVER-INTERFACE"
|
||||||
|
|
||||||
|
def test_data_constraint_chain(self):
|
||||||
|
"""测试数据约束链"""
|
||||||
|
unit = create_unit("percent", display="%")
|
||||||
|
constraint = create_data_constraint(
|
||||||
|
"PercentageRange",
|
||||||
|
lower=0,
|
||||||
|
upper=100,
|
||||||
|
unit=unit
|
||||||
|
)
|
||||||
|
|
||||||
|
assert constraint.unit == unit
|
||||||
|
assert constraint.lower == 0
|
||||||
|
assert constraint.upper == 100
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = constraint.to_arxml(doc)
|
||||||
|
assert element.tagName == "DATA-CONSTR"
|
||||||
|
|
||||||
|
def test_package_creation(self):
|
||||||
|
"""测试包创建"""
|
||||||
|
from src import create_package, create_base_type
|
||||||
|
|
||||||
|
base_type = create_base_type("TestType")
|
||||||
|
pkg = create_package("TestPackage", elements=[base_type])
|
||||||
|
|
||||||
|
assert pkg.name == "TestPackage"
|
||||||
|
assert len(pkg.elements) == 1
|
||||||
|
assert pkg.get_element("TestType") == base_type
|
||||||
|
|
||||||
|
def test_package_to_arxml(self):
|
||||||
|
"""测试包 ARXML 转换"""
|
||||||
|
from src import create_package, create_base_type
|
||||||
|
|
||||||
|
base_type = create_base_type("PackageType")
|
||||||
|
pkg = create_package("MyPackage", elements=[base_type])
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = pkg.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "AR-PACKAGE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "MyPackage"
|
||||||
|
|
||||||
|
elements = element.getElementsByTagName("ELEMENTS")
|
||||||
|
assert len(elements) == 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
pytest.main([__file__, "-v"])
|
||||||
@@ -0,0 +1,294 @@
|
|||||||
|
"""
|
||||||
|
SWC 组件和内部行为测试
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from src import (
|
||||||
|
ApplicationSwComponentType,
|
||||||
|
RPortPrototype,
|
||||||
|
PPortPrototype,
|
||||||
|
PRPortPrototype,
|
||||||
|
SenderReceiverInterface,
|
||||||
|
create_sender_receiver_interface,
|
||||||
|
create_runnable_entity,
|
||||||
|
create_timing_event,
|
||||||
|
create_init_event,
|
||||||
|
create_operation_invoked_event,
|
||||||
|
create_data_received_event,
|
||||||
|
create_swc_internal_behavior,
|
||||||
|
SwcInternalBehavior,
|
||||||
|
VariableAccess,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestRunnableEntity:
|
||||||
|
"""RunnableEntity 测试"""
|
||||||
|
|
||||||
|
def test_create_runnable_entity(self):
|
||||||
|
"""测试创建 Runnable 实体"""
|
||||||
|
runnable = create_runnable_entity(
|
||||||
|
name="Runnable_Init",
|
||||||
|
minimum_start_interval=10,
|
||||||
|
can_be_invoked_concurrently=False,
|
||||||
|
symbol="Runnable_Init_Function"
|
||||||
|
)
|
||||||
|
assert runnable.name == "Runnable_Init"
|
||||||
|
assert runnable.minimum_start_interval == 10
|
||||||
|
assert runnable.can_be_invoked_concurrently is False
|
||||||
|
assert runnable.symbol == "Runnable_Init_Function"
|
||||||
|
|
||||||
|
def test_runnable_entity_add_data_access(self):
|
||||||
|
"""测试 Runnable 添加数据访问"""
|
||||||
|
runnable = create_runnable_entity(name="TestRunnable")
|
||||||
|
access = VariableAccess(name="DataAccess", port_prototype_ref="Port1")
|
||||||
|
runnable.add_variable_access(access)
|
||||||
|
|
||||||
|
assert len(runnable.variable_accesses) == 1
|
||||||
|
|
||||||
|
def test_runnable_entity_to_arxml(self):
|
||||||
|
"""测试 Runnable 实体 ARXML 转换"""
|
||||||
|
runnable = create_runnable_entity(
|
||||||
|
name="TestRunnable",
|
||||||
|
symbol="TestRunnable_Func"
|
||||||
|
)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = runnable.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "RUNNABLE-ENTITY"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "TestRunnable"
|
||||||
|
|
||||||
|
|
||||||
|
class TestEvents:
|
||||||
|
"""事件测试"""
|
||||||
|
|
||||||
|
def test_create_timing_event(self):
|
||||||
|
"""测试创建定时事件"""
|
||||||
|
event = create_timing_event("TimingEvent_10ms", period=0.01)
|
||||||
|
assert event.name == "TimingEvent_10ms"
|
||||||
|
assert event.period == 0.01
|
||||||
|
|
||||||
|
def test_timing_event_to_arxml(self):
|
||||||
|
"""测试定时事件 ARXML 转换"""
|
||||||
|
event = create_timing_event("PeriodicTask", period=0.05)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = event.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "TIMING-EVENT"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "PeriodicTask"
|
||||||
|
|
||||||
|
def test_create_init_event(self):
|
||||||
|
"""测试创建初始化事件"""
|
||||||
|
event = create_init_event("InitEvent")
|
||||||
|
assert event.name == "InitEvent"
|
||||||
|
|
||||||
|
def test_init_event_to_arxml(self):
|
||||||
|
"""测试初始化事件 ARXML 转换"""
|
||||||
|
event = create_init_event("InitEvent")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = event.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "INIT-EVENT"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
def test_create_operation_invoked_event(self):
|
||||||
|
"""测试创建操作调用事件"""
|
||||||
|
event = create_operation_invoked_event(
|
||||||
|
"OpInvokeEvent",
|
||||||
|
operation_ref="/Package/Interface/Operation"
|
||||||
|
)
|
||||||
|
assert event.name == "OpInvokeEvent"
|
||||||
|
assert event.operation_ref == "/Package/Interface/Operation"
|
||||||
|
|
||||||
|
def test_operation_invoked_event_to_arxml(self):
|
||||||
|
"""测试操作调用事件 ARXML 转换"""
|
||||||
|
event = create_operation_invoked_event("OpInvokeEvent")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = event.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "OPERATION-INVOKED-EVENT"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
def test_create_data_received_event(self):
|
||||||
|
"""测试创建数据接收事件"""
|
||||||
|
event = create_data_received_event(
|
||||||
|
"DataReceived",
|
||||||
|
data_element_ref="/Package/Interface/Port",
|
||||||
|
period=0.02
|
||||||
|
)
|
||||||
|
assert event.name == "DataReceived"
|
||||||
|
assert event.data_element_ref == "/Package/Interface/Port"
|
||||||
|
assert event.period == 0.02
|
||||||
|
|
||||||
|
def test_data_received_event_to_arxml(self):
|
||||||
|
"""测试数据接收事件 ARXML 转换"""
|
||||||
|
event = create_data_received_event("DataReceived", period=0.01)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = event.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "DATA-RECEIVED-EVENT"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestSwcInternalBehavior:
|
||||||
|
"""SWC 内部行为测试"""
|
||||||
|
|
||||||
|
def test_create_swc_internal_behavior(self):
|
||||||
|
"""测试创建 SWC 内部行为"""
|
||||||
|
runnable = create_runnable_entity(name="MainRunnable")
|
||||||
|
timing = create_timing_event("MainTiming", period=0.01)
|
||||||
|
|
||||||
|
behavior = create_swc_internal_behavior(
|
||||||
|
name="ComponentBehavior",
|
||||||
|
runnable_entities=[runnable],
|
||||||
|
events=[timing],
|
||||||
|
symbol="Component_Symbol"
|
||||||
|
)
|
||||||
|
assert behavior.name == "ComponentBehavior"
|
||||||
|
assert len(behavior.runnable_entities) == 1
|
||||||
|
assert len(behavior.events) == 1
|
||||||
|
assert behavior.symbol == "Component_Symbol"
|
||||||
|
|
||||||
|
def test_swc_internal_behavior_add_runnable(self):
|
||||||
|
"""测试 SWC 内部行为添加 Runnable"""
|
||||||
|
behavior = create_swc_internal_behavior(name="Behavior")
|
||||||
|
runnable = create_runnable_entity(name="NewRunnable")
|
||||||
|
|
||||||
|
behavior.add_runnable(runnable)
|
||||||
|
assert behavior.get_runnable("NewRunnable") == runnable
|
||||||
|
|
||||||
|
def test_swc_internal_behavior_add_event(self):
|
||||||
|
"""测试 SWC 内部行为添加事件"""
|
||||||
|
behavior = create_swc_internal_behavior(name="Behavior")
|
||||||
|
event = create_timing_event("NewTiming", period=0.02)
|
||||||
|
|
||||||
|
behavior.add_event(event)
|
||||||
|
assert behavior.get_event("NewTiming") == event
|
||||||
|
|
||||||
|
def test_swc_internal_behavior_to_arxml(self):
|
||||||
|
"""测试 SWC 内部行为 ARXML 转换"""
|
||||||
|
runnable = create_runnable_entity(name="MainRunnable", symbol="MainRunnable_Func")
|
||||||
|
timing = create_timing_event("Periodic", period=0.01)
|
||||||
|
|
||||||
|
behavior = create_swc_internal_behavior(
|
||||||
|
name="ComponentBehavior",
|
||||||
|
runnable_entities=[runnable],
|
||||||
|
events=[timing]
|
||||||
|
)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = behavior.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "SWC-INTERNAL-BEHAVIOR"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestSwComponent:
|
||||||
|
"""软件组件测试"""
|
||||||
|
|
||||||
|
def test_create_application_swc(self):
|
||||||
|
"""测试创建应用组件"""
|
||||||
|
swc = ApplicationSwComponentType(name="TestComponent")
|
||||||
|
assert swc.name == "TestComponent"
|
||||||
|
assert swc.atomic_type.value == "Application"
|
||||||
|
|
||||||
|
def test_application_swc_add_port(self):
|
||||||
|
"""测试应用组件添加端口"""
|
||||||
|
swc = ApplicationSwComponentType(name="TestComponent")
|
||||||
|
|
||||||
|
data_element = SenderReceiverInterface.DataElement(name="TestData")
|
||||||
|
interface = create_sender_receiver_interface("TestInterface", data_element=data_element)
|
||||||
|
port = PPortPrototype(name="TestPort", interface=interface)
|
||||||
|
|
||||||
|
swc.add_port(port)
|
||||||
|
assert swc.get_port("TestPort") == port
|
||||||
|
|
||||||
|
def test_application_swc_to_arxml(self):
|
||||||
|
"""测试应用组件 ARXML 转换"""
|
||||||
|
swc = ApplicationSwComponentType(name="TestComponent")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = swc.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "APPLICATION-SW-COMPONENT-TYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "TestComponent"
|
||||||
|
|
||||||
|
def test_application_swc_with_ports_to_arxml(self):
|
||||||
|
"""测试带端口的应用组件 ARXML 转换"""
|
||||||
|
swc = ApplicationSwComponentType(name="ComponentWithPorts")
|
||||||
|
|
||||||
|
data_element = SenderReceiverInterface.DataElement(name="StatusData")
|
||||||
|
interface = create_sender_receiver_interface("StatusInterface", data_element=data_element)
|
||||||
|
port = PPortPrototype(name="StatusPort", interface=interface)
|
||||||
|
swc.add_port(port)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = swc.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "APPLICATION-SW-COMPONENT-TYPE"
|
||||||
|
ports = element.getElementsByTagName("PORTS")
|
||||||
|
assert len(ports) == 1
|
||||||
|
|
||||||
|
|
||||||
|
class TestPortPrototypes:
|
||||||
|
"""端口原型测试"""
|
||||||
|
|
||||||
|
def test_r_port_prototype_to_arxml(self):
|
||||||
|
"""测试 R-Port ARXML 转换"""
|
||||||
|
data_element = SenderReceiverInterface.DataElement(name="RxData")
|
||||||
|
interface = create_sender_receiver_interface("RxInterface", data_element=data_element)
|
||||||
|
port = RPortPrototype(name="RPort1", interface=interface)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = port.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "R-PORT-PROTOTYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "RPort1"
|
||||||
|
|
||||||
|
def test_p_port_prototype_to_arxml(self):
|
||||||
|
"""测试 P-Port ARXML 转换"""
|
||||||
|
data_element = SenderReceiverInterface.DataElement(name="TxData")
|
||||||
|
interface = create_sender_receiver_interface("TxInterface", data_element=data_element)
|
||||||
|
port = PPortPrototype(name="PPort1", interface=interface)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = port.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "P-PORT-PROTOTYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "PPort1"
|
||||||
|
|
||||||
|
def test_pr_port_prototype_to_arxml(self):
|
||||||
|
"""测试 PR-Port ARXML 转换"""
|
||||||
|
data_element = SenderReceiverInterface.DataElement(name="BidirectionalData")
|
||||||
|
interface = create_sender_receiver_interface("BiInterface", data_element=data_element)
|
||||||
|
port = PRPortPrototype(name="PRPort1", interface=interface)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = port.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "P-PORT-PROTOTYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
pytest.main([__file__, "-v"])
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
"""
|
||||||
|
数据类型测试
|
||||||
|
"""
|
||||||
|
import pytest
|
||||||
|
from xml.dom.minidom import Document
|
||||||
|
|
||||||
|
from src import (
|
||||||
|
BaseType,
|
||||||
|
create_base_type,
|
||||||
|
Unit,
|
||||||
|
create_unit,
|
||||||
|
Category,
|
||||||
|
Encoding,
|
||||||
|
)
|
||||||
|
from src.core.base import create_uuid, create_text_element
|
||||||
|
|
||||||
|
|
||||||
|
class TestBaseType:
|
||||||
|
"""BaseType 测试"""
|
||||||
|
|
||||||
|
def test_create_base_type(self):
|
||||||
|
"""测试创建基础类型"""
|
||||||
|
base_type = create_base_type("UInt8", size=8)
|
||||||
|
assert base_type.name == "UInt8"
|
||||||
|
assert base_type.size == 8
|
||||||
|
assert base_type.category == Category.FIXED_LENGTH
|
||||||
|
|
||||||
|
def test_base_type_encoding(self):
|
||||||
|
"""测试编码属性"""
|
||||||
|
base_type = create_base_type(
|
||||||
|
"SInt8",
|
||||||
|
encoding=Encoding.TWO_COMPONENT
|
||||||
|
)
|
||||||
|
assert base_type.encoding_value == "2C"
|
||||||
|
|
||||||
|
def test_base_type_to_arxml(self):
|
||||||
|
"""测试 ARXML 转换"""
|
||||||
|
base_type = create_base_type("UInt16", size=16)
|
||||||
|
doc = Document()
|
||||||
|
element = base_type.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "SW-BASE-TYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "UInt16"
|
||||||
|
|
||||||
|
|
||||||
|
class TestUnit:
|
||||||
|
"""Unit 测试"""
|
||||||
|
|
||||||
|
def test_create_unit(self):
|
||||||
|
"""测试创建单位"""
|
||||||
|
unit = create_unit("kmh", display="km/h", factor=1, offset=0)
|
||||||
|
assert unit.name == "kmh"
|
||||||
|
assert unit.display == "km/h"
|
||||||
|
assert unit.factor == 1
|
||||||
|
assert unit.offset == 0
|
||||||
|
|
||||||
|
def test_unit_to_arxml(self):
|
||||||
|
"""测试单位 ARXML 转换"""
|
||||||
|
unit = create_unit("m/s", display="meters per second")
|
||||||
|
doc = Document()
|
||||||
|
element = unit.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "UNIT"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "m/s"
|
||||||
|
|
||||||
|
|
||||||
|
class TestDataConstraint:
|
||||||
|
"""DataConstraint 测试"""
|
||||||
|
|
||||||
|
def test_create_data_constraint(self):
|
||||||
|
"""测试创建数据约束"""
|
||||||
|
from src import create_data_constraint
|
||||||
|
|
||||||
|
constraint = create_data_constraint(
|
||||||
|
"SpeedConstraint",
|
||||||
|
lower=0,
|
||||||
|
upper=250
|
||||||
|
)
|
||||||
|
assert constraint.name == "SpeedConstraint"
|
||||||
|
assert constraint.lower == 0
|
||||||
|
assert constraint.upper == 250
|
||||||
|
|
||||||
|
def test_data_constraint_to_arxml(self):
|
||||||
|
"""测试数据约束 ARXML 转换"""
|
||||||
|
from src import create_data_constraint
|
||||||
|
|
||||||
|
constraint = create_data_constraint(
|
||||||
|
"RangeConstraint",
|
||||||
|
lower=0,
|
||||||
|
upper=100
|
||||||
|
)
|
||||||
|
doc = Document()
|
||||||
|
element = constraint.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "DATA-CONSTR"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestCompuMethod:
|
||||||
|
"""CompuMethod 测试"""
|
||||||
|
|
||||||
|
def test_create_compu_method(self):
|
||||||
|
"""测试创建计算方法"""
|
||||||
|
from src import create_compu_method, create_linear
|
||||||
|
|
||||||
|
linear = create_linear(factor=0.1, offset=10)
|
||||||
|
compu = create_compu_method(
|
||||||
|
"LinearConversion",
|
||||||
|
linear=linear
|
||||||
|
)
|
||||||
|
assert compu.name == "LinearConversion"
|
||||||
|
assert compu.linear == linear
|
||||||
|
assert compu.category == Category.IDENTICAL
|
||||||
|
|
||||||
|
def test_compu_method_with_text_table(self):
|
||||||
|
"""测试带文本表的计算方法"""
|
||||||
|
from src import create_compu_method, create_text_table
|
||||||
|
|
||||||
|
text_table = create_text_table("OnOff", "ON", 0, 1)
|
||||||
|
compu = create_compu_method(
|
||||||
|
"OnOffTable",
|
||||||
|
text_tables=[text_table]
|
||||||
|
)
|
||||||
|
assert len(compu.text_tables) == 1
|
||||||
|
assert compu.get_text_table("ON") == text_table
|
||||||
|
|
||||||
|
def test_compu_method_to_arxml(self):
|
||||||
|
"""测试计算方法 ARXML 转换"""
|
||||||
|
from src import create_compu_method
|
||||||
|
|
||||||
|
compu = create_compu_method("TestMethod")
|
||||||
|
doc = Document()
|
||||||
|
element = compu.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "COMPU-METHOD"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestApplicationTypes:
|
||||||
|
"""应用数据类型测试"""
|
||||||
|
|
||||||
|
def test_create_boolean_type(self):
|
||||||
|
"""测试创建布尔类型"""
|
||||||
|
from src import create_boolean_type
|
||||||
|
|
||||||
|
bool_type = create_boolean_type("BooleanSignal")
|
||||||
|
assert bool_type.name == "BooleanSignal"
|
||||||
|
assert bool_type.category == Category.BOOLEAN
|
||||||
|
|
||||||
|
def test_create_value_type(self):
|
||||||
|
"""测试创建值类型"""
|
||||||
|
from src import create_value_type
|
||||||
|
|
||||||
|
value_type = create_value_type("SpeedValue")
|
||||||
|
assert value_type.name == "SpeedValue"
|
||||||
|
assert value_type.category == Category.VALUE
|
||||||
|
|
||||||
|
def test_create_structure_type(self):
|
||||||
|
"""测试创建结构体类型"""
|
||||||
|
from src import create_structure_type, ApplicationStructureDataType
|
||||||
|
|
||||||
|
element = ApplicationStructureDataType.StructureElement(name="member1")
|
||||||
|
struct_type = create_structure_type("MyStruct", elements=[element])
|
||||||
|
assert struct_type.name == "MyStruct"
|
||||||
|
assert len(struct_type.structure_elements) == 1
|
||||||
|
assert struct_type.get_element("member1") == element
|
||||||
|
|
||||||
|
|
||||||
|
class TestImplementationTypes:
|
||||||
|
"""实现数据类型测试"""
|
||||||
|
|
||||||
|
def test_create_impl_value_type(self):
|
||||||
|
"""测试创建实现值类型"""
|
||||||
|
from src import create_impl_value_type, create_base_type
|
||||||
|
|
||||||
|
base = create_base_type("UInt8")
|
||||||
|
impl_type = create_impl_value_type("ImplUInt8", base_type=base)
|
||||||
|
assert impl_type.name == "ImplUInt8"
|
||||||
|
assert impl_type.base_type == base
|
||||||
|
assert impl_type.category == Category.VALUE
|
||||||
|
|
||||||
|
def test_create_impl_structure_type(self):
|
||||||
|
"""测试创建实现结构体类型"""
|
||||||
|
from src import create_impl_structure_type, ImplementationStructureDataType
|
||||||
|
|
||||||
|
element = ImplementationStructureDataType.StructureElement(name="field1")
|
||||||
|
struct = create_impl_structure_type("ImplStruct", elements=[element])
|
||||||
|
assert struct.name == "ImplStruct"
|
||||||
|
assert len(struct.structure_elements) == 1
|
||||||
|
|
||||||
|
def test_impl_value_type_to_arxml(self):
|
||||||
|
"""测试实现值类型 ARXML 转换"""
|
||||||
|
from src import create_impl_value_type, create_base_type
|
||||||
|
|
||||||
|
base = create_base_type("UInt8")
|
||||||
|
impl_type = create_impl_value_type("ImplUInt8", base_type=base)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = impl_type.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "IMPLEMENTATION-DATA-TYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "ImplUInt8"
|
||||||
|
|
||||||
|
def test_impl_structure_type_to_arxml(self):
|
||||||
|
"""测试实现结构体类型 ARXML 转换"""
|
||||||
|
from src import create_impl_structure_type, ImplementationStructureDataType
|
||||||
|
|
||||||
|
element = ImplementationStructureDataType.StructureElement(name="field1")
|
||||||
|
struct = create_impl_structure_type("ImplStruct", elements=[element])
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = struct.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "IMPLEMENTATION-DATA-TYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestLinear:
|
||||||
|
"""Linear 转换测试"""
|
||||||
|
|
||||||
|
def test_linear_to_arxml(self):
|
||||||
|
"""测试线性转换 ARXML 转换"""
|
||||||
|
from src import create_linear
|
||||||
|
|
||||||
|
linear = create_linear(factor=0.1, offset=10)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = linear.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "COMPU-SCALE"
|
||||||
|
assert element.hasChildNodes()
|
||||||
|
|
||||||
|
|
||||||
|
class TestTextTable:
|
||||||
|
"""TextTable 文本表测试"""
|
||||||
|
|
||||||
|
def test_create_text_table(self):
|
||||||
|
"""测试创建文本表"""
|
||||||
|
from src import create_text_table
|
||||||
|
|
||||||
|
text_table = create_text_table("OnOff", "ON", 0, 1)
|
||||||
|
assert text_table.name == "OnOff"
|
||||||
|
assert text_table.vt == "ON"
|
||||||
|
assert text_table.lower == 0
|
||||||
|
assert text_table.upper == 1
|
||||||
|
|
||||||
|
def test_text_table_to_arxml(self):
|
||||||
|
"""测试文本表 ARXML 转换"""
|
||||||
|
from src import create_text_table
|
||||||
|
|
||||||
|
text_table = create_text_table("Status", "ACTIVE", 1, 2)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = text_table.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "COMPU-SCALE"
|
||||||
|
assert element.hasChildNodes()
|
||||||
|
|
||||||
|
vt_elem = element.getElementsByTagName("VT")
|
||||||
|
assert len(vt_elem) > 0
|
||||||
|
|
||||||
|
|
||||||
|
class TestInterfaces:
|
||||||
|
"""接口测试"""
|
||||||
|
|
||||||
|
def test_client_server_interface_creation(self):
|
||||||
|
"""测试创建客户端-服务端接口"""
|
||||||
|
from src import ClientServerInterface
|
||||||
|
|
||||||
|
cs_interface = ClientServerInterface(name="TestService")
|
||||||
|
assert cs_interface.name == "TestService"
|
||||||
|
assert cs_interface.is_service is False
|
||||||
|
|
||||||
|
operation = ClientServerInterface.Operation(name="StartOperation")
|
||||||
|
cs_interface.add_operation(operation)
|
||||||
|
assert cs_interface.get_operation("StartOperation") == operation
|
||||||
|
|
||||||
|
def test_client_server_interface_to_arxml(self):
|
||||||
|
"""测试客户端-服务端接口 ARXML 转换"""
|
||||||
|
from src import ClientServerInterface
|
||||||
|
|
||||||
|
cs_interface = ClientServerInterface(name="TestService")
|
||||||
|
operation = ClientServerInterface.Operation(name="StartOperation")
|
||||||
|
cs_interface.add_operation(operation)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = cs_interface.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "CLIENT-SERVER-INTERFACE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
def test_client_server_operation_to_arxml(self):
|
||||||
|
"""测试操作方法 ARXML 转换"""
|
||||||
|
from src import ClientServerInterface
|
||||||
|
|
||||||
|
operation = ClientServerInterface.Operation(name="TestOp", is_server=True)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = operation.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "CLIENT-SERVER-OPERATION"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestDataMapping:
|
||||||
|
"""数据类型映射测试"""
|
||||||
|
|
||||||
|
def test_data_type_mapping_creation(self):
|
||||||
|
"""测试创建数据类型映射"""
|
||||||
|
from src import create_data_type_mapping
|
||||||
|
|
||||||
|
mapping = create_data_type_mapping("TestMapping")
|
||||||
|
assert mapping.name == "TestMapping"
|
||||||
|
|
||||||
|
def test_data_type_mapping_to_arxml(self):
|
||||||
|
"""测试数据类型映射 ARXML 转换"""
|
||||||
|
from src import create_data_type_mapping
|
||||||
|
|
||||||
|
mapping = create_data_type_mapping("TestMapping")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = mapping.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "DATA-TYPE-MAP"
|
||||||
|
|
||||||
|
def test_data_type_mapping_set_creation(self):
|
||||||
|
"""测试创建数据类型映射集"""
|
||||||
|
from src import create_data_type_mapping_set, create_data_type_mapping
|
||||||
|
|
||||||
|
mapping1 = create_data_type_mapping("Mapping1")
|
||||||
|
mapping_set = create_data_type_mapping_set("TestSet", mappings=[mapping1])
|
||||||
|
|
||||||
|
assert mapping_set.name == "TestSet"
|
||||||
|
assert len(mapping_set.data_type_mappings) == 1
|
||||||
|
assert mapping_set.get_mapping("Mapping1") == mapping1
|
||||||
|
|
||||||
|
def test_data_type_mapping_set_to_arxml(self):
|
||||||
|
"""测试数据类型映射集 ARXML 转换"""
|
||||||
|
from src import create_data_type_mapping_set
|
||||||
|
|
||||||
|
mapping_set = create_data_type_mapping_set("TestSet")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = mapping_set.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "DATA-TYPE-MAPPING-SET"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
class TestApplicationTypesToArxml:
|
||||||
|
"""应用数据类型 ARXML 测试"""
|
||||||
|
|
||||||
|
def test_value_type_to_arxml(self):
|
||||||
|
"""测试应用值类型 ARXML 转换"""
|
||||||
|
from src import create_value_type
|
||||||
|
|
||||||
|
value_type = create_value_type("SpeedValue")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = value_type.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "APPLICATION-PRIMITIVE-DATA-TYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
short_name = element.getElementsByTagName("SHORT-NAME")[0]
|
||||||
|
assert short_name.firstChild.nodeValue == "SpeedValue"
|
||||||
|
|
||||||
|
def test_boolean_type_to_arxml(self):
|
||||||
|
"""测试布尔类型 ARXML 转换"""
|
||||||
|
from src import create_boolean_type
|
||||||
|
|
||||||
|
bool_type = create_boolean_type("IsActive")
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
element = bool_type.to_arxml(doc)
|
||||||
|
|
||||||
|
assert element.tagName == "APPLICATION-PRIMITIVE-DATA-TYPE"
|
||||||
|
assert element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
def test_structure_type_to_arxml(self):
|
||||||
|
"""测试应用结构体类型 ARXML 转换"""
|
||||||
|
from src import create_structure_type, ApplicationStructureDataType
|
||||||
|
|
||||||
|
element = ApplicationStructureDataType.StructureElement(name="member1")
|
||||||
|
struct = create_structure_type("MyStruct", elements=[element])
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
arxml_element = struct.to_arxml(doc)
|
||||||
|
|
||||||
|
assert arxml_element.tagName == "APPLICATION-RECORD-DATA-TYPE"
|
||||||
|
assert arxml_element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
def test_array_type_to_arxml(self):
|
||||||
|
"""测试应用数组类型 ARXML 转换"""
|
||||||
|
from src import create_array_type, create_value_type, ApplicationArrayDataType, Semantic
|
||||||
|
|
||||||
|
element_type = create_value_type("ArrayElement")
|
||||||
|
array_element = ApplicationArrayDataType.ArrayElement(
|
||||||
|
name="element",
|
||||||
|
data_type=element_type,
|
||||||
|
array_size_semantics=Semantic.FIXED,
|
||||||
|
length=10
|
||||||
|
)
|
||||||
|
array_type = create_array_type("MyArray", element=array_element)
|
||||||
|
|
||||||
|
doc = Document()
|
||||||
|
arxml_element = array_type.to_arxml(doc)
|
||||||
|
|
||||||
|
assert arxml_element.tagName == "APPLICATION-ARRAY-DATA-TYPE"
|
||||||
|
assert arxml_element.hasAttribute("UUID")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
pytest.main([__file__, "-v"])
|
||||||
Reference in New Issue
Block a user