feat: add socket control and temperature humidity modules (#7)

## Summary
- **Smart Socket Module**:
  - Implemented `SocketUiState` and `SocketViewModel` with support for querying power state, toggle control, duplicate click debouncing, and state confirmation timestamping.
  - Implemented Material 3 responsive `SocketScreen` with power indicator badge, toggle action, explicit on/off buttons, offline banner, and error handling.
- **Temperature & Humidity Module**:
  - Implemented `TemperatureHumidityUiState` and `TemperatureHumidityViewModel` for read-only environmental telemetry.
  - Implemented `TemperatureHumidityScreen` featuring distinct temperature and humidity cards, read-only notice, no-data placeholder, and pull-to-refresh actions.
- **Common & Infrastructure**:
  - Added `UiText` and `DomainErrorMapper` for localizing domain errors (`DomainError`).
  - Added navigation graph extensions (`deviceDetailGraph`) in `DeviceDetailNavigation.kt` and wired into `ABoxManagerApp.kt`.
  - Added `ReleaseModule` for Hilt dependency injection in release builds.
  - Added full English and Simplified Chinese resource translations in `values/strings.xml` and `values-zh-rCN/strings.xml`.
- **Testing**:
  - Added `SocketViewModelTest` and `TemperatureHumidityViewModelTest` covering normal operations, offline states, error mapping, and refresh scenarios.

## Test Plan
- [x] Run `./gradlew test` (all modules passed)
- [x] Run `./gradlew :android:app:testDebugUnitTest` (passed)
- [x] Run `./gradlew assembleDebug` (build successful)

?? Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: KremeCN <3265494849@qq.com>
Reviewed-on: #7
Co-authored-by: Aurum <aurum_197@outlook.com>
This commit was merged in pull request #7.
This commit is contained in:
2026-08-25 15:41:34 +08:00
committed by KremeCN
co-authored by KremeCN
parent 0c783ca2f4
commit 30d6d39597
16 changed files with 1823 additions and 0 deletions
@@ -53,4 +53,49 @@
<string name="device_infrared_description">进入红外控制器相关功能。</string>
<string name="infrared_control_action">红外控制</string>
<string name="infrared_session_invalid_message">ABox 会话未认证,请先登录。</string>
<!-- Socket strings -->
<string name="socket_title">智能插座</string>
<string name="socket_status_label">电源状态</string>
<string name="socket_status_on">已开启</string>
<string name="socket_status_off">已关闭</string>
<string name="socket_status_offline">已离线</string>
<string name="socket_status_unknown">未知状态</string>
<string name="socket_action_toggle">切换电源</string>
<string name="socket_action_turn_on">开启插座</string>
<string name="socket_action_turn_off">关闭插座</string>
<string name="socket_operating_label">正在切换状态…</string>
<string name="socket_confirmed_at">已于 %1$s 确认状态</string>
<!-- Temperature & Humidity strings -->
<string name="th_title">温湿度传感器</string>
<string name="th_temperature_label">温度</string>
<string name="th_humidity_label">湿度</string>
<string name="th_unit_celsius">°C</string>
<string name="th_unit_percent">%</string>
<string name="th_read_only_notice">传感器设备(只读监控)</string>
<string name="th_read_only_description">本设备提供实时环境温湿度遥测,不支持远程控制操作。</string>
<string name="th_no_data_title">暂无传感器数据</string>
<string name="th_no_data_description">尚未获取到该传感器的遥测数据,请点击刷新重新查询。</string>
<string name="th_last_updated">更新于 %1$s</string>
<!-- Common action & error strings -->
<string name="action_refresh">刷新</string>
<string name="action_retry">重试</string>
<string name="action_back">返回</string>
<string name="action_edit_device_name">修改设备名称</string>
<string name="dialog_edit_device_name_title">修改设备名称</string>
<string name="dialog_edit_device_name_hint">请输入网关中的设备名称</string>
<string name="action_confirm">确定</string>
<string name="action_cancel">取消</string>
<string name="status_loading">加载中…</string>
<string name="status_device_offline_banner">设备已离线,无法进行通信。</string>
<string name="error_authentication">认证失败,请重新登录。</string>
<string name="error_token_invalid">登录已过期,请重新登录。</string>
<string name="error_network">网络连接异常,请检查网络设置。</string>
<string name="error_device_not_found">未找到该设备。</string>
<string name="error_device_offline">设备当前处于离线状态。</string>
<string name="error_invalid_request">请求参数无效。</string>
<string name="error_operation_failed">操作执行失败,请重试。</string>
<string name="error_no_data">暂无可用数据。</string>
<string name="error_unknown">发生未知错误。</string>
</resources>
@@ -53,4 +53,49 @@
<string name="device_infrared_description">Access infrared controller features.</string>
<string name="infrared_control_action">Infrared Control</string>
<string name="infrared_session_invalid_message">ABox session is not authenticated. Please log in first.</string>
<!-- Socket strings -->
<string name="socket_title">Smart Socket</string>
<string name="socket_status_label">Power Status</string>
<string name="socket_status_on">ON</string>
<string name="socket_status_off">OFF</string>
<string name="socket_status_offline">Offline</string>
<string name="socket_status_unknown">Unknown</string>
<string name="socket_action_toggle">Toggle Power</string>
<string name="socket_action_turn_on">Turn ON</string>
<string name="socket_action_turn_off">Turn OFF</string>
<string name="socket_operating_label">Updating socket state…</string>
<string name="socket_confirmed_at">Confirmed at %1$s</string>
<!-- Temperature & Humidity strings -->
<string name="th_title">Temperature &amp; Humidity</string>
<string name="th_temperature_label">Temperature</string>
<string name="th_humidity_label">Humidity</string>
<string name="th_unit_celsius">°C</string>
<string name="th_unit_percent">%</string>
<string name="th_read_only_notice">Sensor Device (Read-only)</string>
<string name="th_read_only_description">This sensor provides real-time environmental telemetry and does not support remote control actions.</string>
<string name="th_no_data_title">No Sensor Data</string>
<string name="th_no_data_description">No telemetry data has been received from this sensor. Tap Refresh to query again.</string>
<string name="th_last_updated">Updated at %1$s</string>
<!-- Common action & error strings -->
<string name="action_refresh">Refresh</string>
<string name="action_retry">Retry</string>
<string name="action_back">Back</string>
<string name="action_edit_device_name">Edit Device Name</string>
<string name="dialog_edit_device_name_title">Edit Device Name</string>
<string name="dialog_edit_device_name_hint">Enter gateway device name</string>
<string name="action_confirm">Confirm</string>
<string name="action_cancel">Cancel</string>
<string name="status_loading">Loading…</string>
<string name="status_device_offline_banner">Device is offline. Commands cannot be sent.</string>
<string name="error_authentication">Authentication failed. Please log in again.</string>
<string name="error_token_invalid">Session expired. Please log in again.</string>
<string name="error_network">Network error. Please check your connection.</string>
<string name="error_device_not_found">Device not found.</string>
<string name="error_device_offline">Device is currently offline.</string>
<string name="error_invalid_request">Invalid request parameters.</string>
<string name="error_operation_failed">Operation failed. Please try again.</string>
<string name="error_no_data">No sensor data available.</string>
<string name="error_unknown">An unexpected error occurred.</string>
</resources>