| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- // ignore_for_file: unused_import, unused_field, prefer_final_fields
- import 'dart:async';
- import 'dart:typed_data';
- import 'package:chicken_farm/components/vb_app_bar.dart';
- import 'package:chicken_farm/core/services/win/win_reader_channel.dart';
- import 'package:chicken_farm/core/services/win/win_reader_manager.dart';
- import 'package:chicken_farm/core/utils/logger.dart';
- import 'package:chicken_farm/core/utils/toast.dart';
- import 'package:flutter/material.dart';
- class SerialSettingPage extends StatefulWidget {
- const SerialSettingPage({super.key});
- @override
- State<SerialSettingPage> createState() => _SerialSettingPageState();
- }
- class _SerialSettingPageState extends State<SerialSettingPage> {
- final WinReaderManager _readerManager = WinReaderManager();
- List<String> _availablePorts = [];
- String? _selectedPort;
- final TextEditingController _dataController = TextEditingController();
- final List<String> _receivedData = [];
- bool _isConnected = false;
- bool _isReading = false;
- // 设备信息
- String _deviceSN = '';
- String _softVersion = '';
- String _hardVersion = '';
- // 功率相关状态
- int? _currentPower;
- int _selectedPower = 20; // 默认值
- @override
- void initState() {
- super.initState();
- // 注册回调函数
- _readerManager.registerCallbacks(
- onConnect: _onConnect,
- onDataReceived: _onDataReceived,
- onError: _onError,
- );
- _loadUsbPorts();
- // 监听数据流 - 使用WinReaderManager内部处理,无需重复监听
- }
- /// 加载可用Usb列表
- void _loadUsbPorts() async {
- try {
- final ports = await _readerManager.scanUsb();
- if (mounted) {
- // 检查组件是否仍然挂载
- setState(() {
- _availablePorts = ports ?? [];
- if (_availablePorts.isNotEmpty) {
- _selectedPort = _availablePorts.first;
- }
- });
- }
- } catch (e) {
- if (mounted) {
- // 检查组件是否仍然挂载
- logger.e(e);
- ToastUtil.error("扫描USB设备失败: $e");
- }
- }
- }
- /// 连接状态回调
- void _onConnect(bool connected) {
- if (mounted) {
- setState(() {
- _isConnected = connected;
- if (!connected) {
- _isReading = false;
- _deviceSN = '';
- _softVersion = '';
- _hardVersion = '';
- _currentPower = null;
- }
- });
- if (connected) {
- _addLog("成功连接到设备: $_selectedPort");
- // 连接成功后自动查询设备信息
- _autoQueryDeviceInfo();
- // 连接成功后自动查询功率
- _autoQueryPower();
- } else {
- _addLog("已断开设备连接");
- }
- }
- }
- /// 自动查询设备信息
- void _autoQueryDeviceInfo() async {
- String? deviceInfo = await _readerManager.getDeviceInfo();
- if (deviceInfo != null && mounted) {
- // 解析设备信息
- _parseDeviceInfo(deviceInfo);
- _addLog("设备信息查询成功: $deviceInfo");
- } else {
- _addLog("设备信息查询失败");
- }
- }
- /// 自动查询功率
- void _autoQueryPower() async {
- int? power = await _readerManager.getPower();
- if (power != null && mounted) {
- setState(() {
- _currentPower = power;
- _selectedPower = power; // 设置下拉框的默认值为当前功率
- });
- _addLog("功率查询成功: ${power}dBm");
- } else {
- _addLog("功率查询失败");
- }
- }
- /// 解析设备信息字符串
- void _parseDeviceInfo(String deviceInfo) {
- if (mounted) {
- // deviceInfo 格式: "SN:1234567890ABCDEF,SoftVer:1.2,HardVer:3.4"
- List<String> parts = deviceInfo.split(',');
- for (String part in parts) {
- if (part.startsWith('SN:')) {
- setState(() {
- _deviceSN = part.substring(3); // 去掉'SN:'前缀
- });
- } else if (part.startsWith('SoftVer:')) {
- setState(() {
- _softVersion = part.substring(8); // 去掉'SoftVer:'前缀
- });
- } else if (part.startsWith('HardVer:')) {
- setState(() {
- _hardVersion = part.substring(8); // 去掉'HardVer:'前缀
- });
- }
- }
- }
- }
- /// 数据接收回调
- void _onDataReceived(String data) {
- if (mounted) {
- _addLog("读取标签: $data");
- }
- }
- /// 错误回调
- void _onError(String error) {
- if (mounted) {
- _addLog("错误: $error");
- ToastUtil.error("操作失败: $error");
- }
- }
- /// 连接USB
- void _connectUsbPort() async {
- if (_selectedPort == null) {
- ToastUtil.error("请先选择一个USB设备");
- return;
- }
- if (!_isConnected) {
- // 获取当前选中设备的索引
- int deviceIndex = _availablePorts.indexOf(_selectedPort!);
- bool success = await _readerManager.connect(deviceIndex);
- if (!success) {
- ToastUtil.error("连接设备失败");
- }
- } else {
- await _readerManager.disconnect();
- }
- }
- /// 开始读取
- void _startRead() async {
- bool success = await _readerManager.startRead();
- if (success && mounted) {
- setState(() {
- _isReading = true;
- });
- _addLog("开始读取数据");
- }
- }
- /// 停止读取
- void _stopRead() async {
- await _readerManager.stopRead();
- if (mounted) {
- setState(() {
- _isReading = false;
- });
- _addLog("已停止读取数据");
- }
- }
- /// 查询功率
- void _queryPower() async {
- if (!_isConnected) {
- ToastUtil.error("请先连接设备");
- return;
- }
- int? power = await _readerManager.getPower();
- if (power != null && mounted) {
- setState(() {
- _currentPower = power;
- _selectedPower = power;
- });
- _addLog("功率查询成功: ${power}dBm");
- } else {
- _addLog("功率查询失败");
- }
- }
- /// 设置功率
- void _setPower() async {
- if (!_isConnected) {
- ToastUtil.error("请先连接设备");
- return;
- }
- bool success = await _readerManager.setPower(_selectedPower);
- if (success) {
- ToastUtil.success("功率设置成功");
- if (mounted) {
- _addLog("功率设置成功: ${_selectedPower}dBm");
- }
- Future.delayed(const Duration(milliseconds: 500), () {
- _queryPower();
- });
- } else {
- _addLog("功率设置失败");
- }
- }
- /// 添加日志
- void _addLog(String log) {
- if (mounted) {
- setState(() {
- _receivedData.add("${DateTime.now()}: $log");
- });
- }
- }
- /// 清空日志
- void _clearLogs() {
- if (mounted) {
- setState(() {
- _receivedData.clear();
- });
- }
- }
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: VberAppBar(title: 'USB测试工具'),
- body: Padding(
- padding: const EdgeInsets.all(16.0),
- child: SingleChildScrollView(
- physics: const BouncingScrollPhysics(),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- // 设备信息卡片
- Card(
- child: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- const Text('USB设备:'),
- const SizedBox(width: 10),
- Expanded(
- child: DropdownButton<String>(
- value: _selectedPort,
- items: _availablePorts.map((port) {
- return DropdownMenuItem(
- value: port,
- child: Text(
- port,
- overflow: TextOverflow.ellipsis,
- ),
- );
- }).toList(),
- onChanged: (value) {
- if (!_isConnected) {
- setState(() {
- _selectedPort = value;
- });
- }
- },
- hint: const Text('选择USB'),
- isExpanded: true,
- ),
- ),
- const SizedBox(width: 20),
- SizedBox(
- height: 30,
- child: ElevatedButton(
- onPressed: _loadUsbPorts,
- child: const Text('刷新'),
- ),
- ),
- const SizedBox(width: 20),
- if (_selectedPort != null) ...[
- SizedBox(
- height: 30,
- child: ElevatedButton(
- onPressed: _connectUsbPort,
- child: Text(_isConnected ? '关闭连接' : '打开连接'),
- ),
- ),
- ],
- const SizedBox(width: 20),
- if (_isConnected) ...[
- SizedBox(
- height: 30,
- child: ElevatedButton(
- onPressed: _isReading ? _stopRead : _startRead,
- child: Text(_isReading ? '停止读取' : '开始读取'),
- ),
- ),
- ],
- ],
- ),
- if (_isConnected) ...[
- const SizedBox(height: 10),
- Row(
- children: [
- const Text(
- '设备信息: ',
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.bold,
- ),
- ),
- Expanded(
- child: _deviceSN.isNotEmpty
- ? Row(
- children: [
- const Text(
- 'SN: ',
- style: TextStyle(
- fontWeight: FontWeight.bold,
- ),
- ),
- Text(
- _deviceSN,
- style: const TextStyle(
- fontWeight: FontWeight.w500,
- ),
- ),
- const SizedBox(width: 16),
- const Text(
- 'SoftVer: ',
- style: TextStyle(
- fontWeight: FontWeight.bold,
- ),
- ),
- Text(
- _softVersion,
- style: const TextStyle(
- fontWeight: FontWeight.w500,
- ),
- ),
- const SizedBox(width: 16),
- const Text(
- 'HardVer: ',
- style: TextStyle(
- fontWeight: FontWeight.bold,
- ),
- ),
- Text(
- _hardVersion,
- style: const TextStyle(
- fontWeight: FontWeight.w500,
- ),
- ),
- ],
- )
- : const Text(
- '未连接',
- style: TextStyle(
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- const SizedBox(width: 20),
- SizedBox(
- height: 30,
- child: ElevatedButton(
- onPressed: _autoQueryDeviceInfo,
- child: const Text('刷新设备信息'),
- ),
- ),
- ],
- ),
- const SizedBox(height: 10),
- // 功率设置卡片
- Row(
- children: [
- const Text(
- '当前功率: ',
- style: TextStyle(
- fontSize: 14,
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(width: 10),
- Text(
- _currentPower != null
- ? '${_currentPower}dBm'
- : '未查询',
- style: const TextStyle(
- fontSize: 14,
- fontWeight: FontWeight.w500,
- ),
- ),
- const SizedBox(width: 30),
- SizedBox(
- height: 30,
- child: ElevatedButton(
- onPressed: _queryPower,
- child: const Text('查询功率'),
- ),
- ),
- const SizedBox(width: 50),
- const Text(
- '功率设置: ',
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(width: 10),
- Expanded(
- child: DropdownButton<int>(
- value: _selectedPower,
- items:
- List.generate(
- 26,
- (index) => index + 5,
- ) // 5-30的值
- .map((value) {
- return DropdownMenuItem(
- value: value,
- child: Text('${value}dBm'),
- );
- })
- .toList(),
- onChanged: (value) {
- if (value != null && _isConnected) {
- setState(() {
- _selectedPower = value;
- });
- }
- },
- isExpanded: true,
- ),
- ),
- const SizedBox(width: 20),
- SizedBox(
- height: 30,
- child: ElevatedButton(
- onPressed: _setPower,
- child: const Text('设置功率'),
- ),
- ),
- ],
- ),
- const SizedBox(height: 5),
- ],
- ],
- ),
- ),
- ),
- const SizedBox(height: 20),
- Card(
- child: Padding(
- padding: const EdgeInsets.all(16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const Text(
- '数据日志',
- style: TextStyle(
- fontSize: 16,
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(height: 10),
- Row(
- children: [
- ElevatedButton(
- onPressed: _clearLogs,
- child: const Text('清空日志'),
- ),
- const SizedBox(width: 10),
- Text(
- '日志数量: ${_receivedData.length}',
- style: const TextStyle(fontWeight: FontWeight.bold),
- ),
- ],
- ),
- const SizedBox(height: 10),
- Container(
- height: 250,
- decoration: BoxDecoration(
- border: Border.all(color: Colors.grey),
- borderRadius: BorderRadius.circular(4),
- ),
- child: _receivedData.isEmpty
- ? const Center(child: Text('暂无日志数据'))
- : ListView.builder(
- itemCount: _receivedData.length,
- itemBuilder: (context, index) {
- return Padding(
- padding: const EdgeInsets.all(8.0),
- child: Text(
- _receivedData[_receivedData.length -
- 1 -
- index],
- style: const TextStyle(fontSize: 12),
- ),
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- }
- @override
- void dispose() {
- // 在页面销毁时断开设备连接
- if (_isConnected) {
- _readerManager.disconnect();
- }
-
- _readerManager.clearCallbacks();
- _readerManager.dispose();
- _dataController.dispose();
- super.dispose();
- }
- }
|