Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions zzupy/aio/app/ecard.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import gmalg
import httpx2
from pydantic import ValidationError

from zzupy.aio.app.interfaces import ICASClient
from zzupy.exception import (
Expand All @@ -24,6 +25,7 @@
log_http_response_body,
logger,
)
from zzupy.model.ecard import ECardAccountModel
from zzupy.utils import sm4_decrypt_ecb, require_auth


Expand Down Expand Up @@ -699,17 +701,12 @@ async def get_remaining_energy(self, room: str | None = None) -> float:
)

response_data = response.json()
account_data = ECardAccountModel.model_validate(response_data)
remaining_energy = account_data.remaining_energy

if "resultData" not in response_data:
logger.error("响应中缺少 resultData")
raise ParsingError("服务器响应格式不正确")

template_list = response_data["resultData"].get("templateList", [])
if len(template_list) < 4:
logger.error("templateList 数据不完整")
raise ParsingError("服务器响应数据不完整")
if remaining_energy is None:
raise ParsingError("服务器响应数据不完整,无法找到剩余电量 quantity")

remaining_energy = float(template_list[3]["value"])
logger.info("房间 {} 剩余电量: {} 度", room, remaining_energy)
return remaining_energy

Expand All @@ -726,6 +723,7 @@ async def get_remaining_energy(self, room: str | None = None) -> float:
IndexError,
TypeError,
ValueError,
ValidationError,
) as exc:
logger.error("从剩余电量响应中提取数据失败: {}", exc)
raise ParsingError.from_exception(
Expand Down
16 changes: 7 additions & 9 deletions zzupy/app/ecard.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import gmalg
import httpx2
from pydantic import ValidationError

from zzupy.app.interfaces import ICASClient
from zzupy.exception import (
Expand All @@ -24,6 +25,7 @@
log_http_response_body,
logger,
)
from zzupy.model.ecard import ECardAccountModel
from zzupy.utils import sm4_decrypt_ecb, require_auth


Expand Down Expand Up @@ -689,17 +691,12 @@ def get_remaining_energy(self, room: str | None = None) -> float:
)

response_data = response.json()
account_data = ECardAccountModel.model_validate(response_data)
remaining_energy = account_data.remaining_energy

if "resultData" not in response_data:
logger.error("响应中缺少 resultData")
raise ParsingError("服务器响应格式不正确")

template_list = response_data["resultData"].get("templateList", [])
if len(template_list) < 4:
logger.error("templateList 数据不完整")
raise ParsingError("服务器响应数据不完整")
if remaining_energy is None:
raise ParsingError("服务器响应数据不完整,无法找到剩余电量 quantity")

remaining_energy = float(template_list[3]["value"])
logger.info("房间 {} 剩余电量: {} 度", room, remaining_energy)
return remaining_energy

Expand All @@ -716,6 +713,7 @@ def get_remaining_energy(self, room: str | None = None) -> float:
IndexError,
TypeError,
ValueError,
ValidationError,
) as exc:
logger.error("从剩余电量响应中提取数据失败: {}", exc)
raise ParsingError.from_exception(
Expand Down
58 changes: 58 additions & 0 deletions zzupy/model/ecard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from typing import Any

from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel


class ECardTemplate(BaseModel):
"""一卡通模板项"""

model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

code: str
name: str | None = None
name_english: str | None = None
show: bool | None = None
unit: str | None = None
unit_english: str | None = None
value: str | int | float | None = None


class ECardAccountData(BaseModel):
"""一卡通账户数据"""

model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

acc_status: str | None = None
acc_status_name: str | None = None
account_num: Any | None = None
balance: str | int | float | None = None
network_package_list: list[Any] | None = None
support_details: bool | None = None
template_list: list[ECardTemplate] = Field(default_factory=list)
utility_account: str | None = None
utility_status: str | None = None
utility_status_name: str | None = None
utility_username: str | None = None

@property
def remaining_energy(self) -> float | None:
for template in self.template_list:
if template.code == "quantity" and template.value is not None:
return float(template.value)
return None


class ECardAccountModel(BaseModel):
"""一卡通账户 API 响应根模型"""

model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)

code: str | int | None = None
message: str | None = None
result_data: ECardAccountData
success: bool | None = None

@property
def remaining_energy(self) -> float | None:
return self.result_data.remaining_energy