|
|
@@ -18,7 +18,6 @@ SUPPORTED_POINT_TYPES = {
|
|
|
"float64",
|
|
|
}
|
|
|
|
|
|
-
|
|
|
class S7IpRequest(BaseModel):
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
@@ -35,12 +34,22 @@ class S7IpRequest(BaseModel):
|
|
|
|
|
|
|
|
|
class S7BaseRequest(S7IpRequest):
|
|
|
- device_type: Literal["S7TCP"] = "S7TCP"
|
|
|
+ device_type: Literal["S7-1200", "S7-Smart200"] = "S7-1200"
|
|
|
port: int = Field(default=102, ge=1, le=65535)
|
|
|
rock: int = Field(ge=0, le=31)
|
|
|
slot: int = Field(ge=0, le=31)
|
|
|
tsap_conn_type: Literal["PG", "OP", "BASIC"] = "PG"
|
|
|
|
|
|
+ @field_validator("device_type", mode="before")
|
|
|
+ @classmethod
|
|
|
+ def normalize_device_type(cls, value: str) -> str:
|
|
|
+ normalized = str(value).upper()
|
|
|
+ if normalized == "S7-1200":
|
|
|
+ return "S7-1200"
|
|
|
+ if normalized == "S7-SMART200":
|
|
|
+ return "S7-Smart200"
|
|
|
+ return str(value)
|
|
|
+
|
|
|
@field_validator("tsap_conn_type", mode="before")
|
|
|
@classmethod
|
|
|
def normalize_tsap_conn_type(cls, value: str) -> str:
|
|
|
@@ -50,7 +59,7 @@ class S7BaseRequest(S7IpRequest):
|
|
|
class S7ReadSpec(BaseModel):
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
- area: Literal["DB", "M", "I", "Q"]
|
|
|
+ area: Literal["DB", "M", "I", "Q", "V"]
|
|
|
db: int = Field(default=0, ge=0)
|
|
|
start: int = Field(ge=0)
|
|
|
size: int = Field(ge=1, le=65535)
|
|
|
@@ -70,11 +79,17 @@ class S7ReadSpec(BaseModel):
|
|
|
class S7RawReadRequest(S7BaseRequest):
|
|
|
read: S7ReadSpec
|
|
|
|
|
|
+ @model_validator(mode="after")
|
|
|
+ def validate_v_area(self) -> "S7RawReadRequest":
|
|
|
+ if self.device_type != "S7-Smart200" and self.read.area == "V":
|
|
|
+ raise ValueError("V area is only supported when device_type is S7-Smart200")
|
|
|
+ return self
|
|
|
+
|
|
|
|
|
|
class S7PointSpec(BaseModel):
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
- area: Literal["DB", "M", "I", "Q"]
|
|
|
+ area: Literal["DB", "M", "I", "Q", "V"]
|
|
|
db: int = Field(default=0, ge=0)
|
|
|
start: int = Field(ge=0)
|
|
|
type: str
|
|
|
@@ -107,6 +122,17 @@ class S7PointSpec(BaseModel):
|
|
|
class S7PointReadRequest(S7BaseRequest):
|
|
|
points: list[S7PointSpec] = Field(min_length=1)
|
|
|
|
|
|
+ @model_validator(mode="after")
|
|
|
+ def validate_v_area(self) -> "S7PointReadRequest":
|
|
|
+ if self.device_type != "S7-Smart200" and any(point.area == "V" for point in self.points):
|
|
|
+ raise ValueError("V area is only supported when device_type is S7-Smart200")
|
|
|
+ return self
|
|
|
+
|
|
|
|
|
|
class S7ConnectScanRequest(S7IpRequest):
|
|
|
- pass
|
|
|
+ device_type: Literal["S7-1200", "S7-Smart200"] = "S7-1200"
|
|
|
+
|
|
|
+ @field_validator("device_type", mode="before")
|
|
|
+ @classmethod
|
|
|
+ def normalize_device_type(cls, value: str) -> str:
|
|
|
+ return S7BaseRequest.normalize_device_type(value)
|