|
|
@@ -180,16 +180,49 @@ def _port_status_to_pic(port_state_entry):
|
|
|
|
|
|
|
|
|
def _get_display_ip():
|
|
|
- """获取用于屏幕显示的本机 IP 地址。"""
|
|
|
+ """获取用于屏幕显示的本机 IP 地址。
|
|
|
+
|
|
|
+ 优先选择 192.168.199.x 管理网段;其次选择物理网卡 eth*/en* 上的 IPv4;
|
|
|
+ 最后回退到任意非回环 IPv4 或静态配置 IP。
|
|
|
+ """
|
|
|
try:
|
|
|
net_status = network_manager.get_network_status()
|
|
|
- for iface, data in net_status.get('interfaces', {}).items():
|
|
|
+ interfaces = net_status.get('interfaces', {})
|
|
|
+
|
|
|
+ # 1. 优先 192.168.199.x 管理网段
|
|
|
+ for iface, data in interfaces.items():
|
|
|
+ if iface in ('lo', 'docker0') or iface.startswith(('br-', 'veth')):
|
|
|
+ continue
|
|
|
+ for addr in data.get('ip_addresses', []):
|
|
|
+ if addr.startswith('192.168.199.') and '.' in addr:
|
|
|
+ return addr
|
|
|
+
|
|
|
+ # 2. 优先物理网卡 eth*/en*/wlan* 上的 IPv4
|
|
|
+ physical_ips = []
|
|
|
+ for iface, data in interfaces.items():
|
|
|
+ if iface in ('lo', 'docker0') or iface.startswith(('br-', 'veth', 'docker')):
|
|
|
+ continue
|
|
|
+ if not (iface.startswith(('eth', 'en', 'wlan', 'wl')) or iface == 'end0'):
|
|
|
+ continue
|
|
|
+ for addr in data.get('ip_addresses', []):
|
|
|
+ if '.' in addr and not addr.startswith('127.'):
|
|
|
+ physical_ips.append((iface, addr))
|
|
|
+ # 优先有线接口
|
|
|
+ for iface, addr in physical_ips:
|
|
|
+ if iface.startswith(('eth', 'en', 'end')):
|
|
|
+ return addr
|
|
|
+ if physical_ips:
|
|
|
+ return physical_ips[0][1]
|
|
|
+
|
|
|
+ # 3. 任意非回环 IPv4
|
|
|
+ for iface, data in interfaces.items():
|
|
|
if iface in ('lo', 'docker0') or iface.startswith(('br-', 'veth')):
|
|
|
continue
|
|
|
for addr in data.get('ip_addresses', []):
|
|
|
if '.' in addr and not addr.startswith('127.'):
|
|
|
return addr
|
|
|
- # 回退:尝试网络配置中的静态 IP
|
|
|
+
|
|
|
+ # 4. 回退:尝试网络配置中的静态 IP
|
|
|
net_config = network_manager.get_network_config()
|
|
|
static_ip = net_config.get('static_config', {}).get('ip_address')
|
|
|
if static_ip:
|
|
|
@@ -1706,6 +1739,30 @@ def load_device_config():
|
|
|
return {}
|
|
|
|
|
|
|
|
|
+def sync_panel_config():
|
|
|
+ """根据 address_config.stored_devices 同步 panel_config"""
|
|
|
+ global panel_config
|
|
|
+ try:
|
|
|
+ devices = address_config.get_stored_devices()
|
|
|
+ panel_id_map = dtu_config.get('panel_id_mapping', {}) or {}
|
|
|
+ new_config = {}
|
|
|
+ for uid_hex, addr in devices.items():
|
|
|
+ custom_id = panel_id_map.get(uid_hex) or panel_id_map.get(addr)
|
|
|
+ if custom_id:
|
|
|
+ panel_id = str(custom_id)
|
|
|
+ else:
|
|
|
+ panel_id = f"PANEL_{dtu_config.get('dtu_id', 'DTU001')}_{addr}"
|
|
|
+ new_config[panel_id] = {
|
|
|
+ 'address': addr,
|
|
|
+ 'position': addr,
|
|
|
+ 'panel_uid': uid_hex
|
|
|
+ }
|
|
|
+ panel_config = new_config
|
|
|
+ logger.info(f"已同步面板配置: {len(panel_config)} 个面板")
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"同步面板配置失败: {str(e)}")
|
|
|
+
|
|
|
+
|
|
|
def confirm_loop():
|
|
|
"""后台确认线程:每10秒对所有已存储设备发送 confirm_address"""
|
|
|
global confirm_loop_running
|
|
|
@@ -2572,9 +2629,8 @@ def modbus_broadcast_query():
|
|
|
assign_results = []
|
|
|
if responses:
|
|
|
assign_results = address_config.process_responses(responses)
|
|
|
- for r in assign_results:
|
|
|
- uid_bytes = r.get('uid', r.get('request', ''))
|
|
|
save_device_config()
|
|
|
+ sync_panel_config()
|
|
|
return jsonify({
|
|
|
'success': True,
|
|
|
'responses': responses,
|
|
|
@@ -2598,8 +2654,9 @@ def modbus_auto_configure():
|
|
|
return jsonify({'success': False, 'message': '串口未连接'}), 400
|
|
|
|
|
|
result = address_config.auto_configure(timeout)
|
|
|
- if result.get('success') and (result.get('discovered', 0) > 0 or result.get('confirmed', 0) > 0 or result.get('assigned', 0) > 0):
|
|
|
+ if result.get('success') and (result.get('discovered', 0) > 0 or result.get('assigned', 0) > 0):
|
|
|
save_device_config()
|
|
|
+ sync_panel_config()
|
|
|
return jsonify(result)
|
|
|
|
|
|
except Exception as e:
|
|
|
@@ -3622,10 +3679,7 @@ if __name__ == '__main__':
|
|
|
# 加载设备配置
|
|
|
loaded = load_device_config()
|
|
|
logger.info(f"已加载 {len(loaded)} 个设备配置")
|
|
|
- panel_config.clear()
|
|
|
- for uid_hex, addr in loaded.items():
|
|
|
- panel_id = f"PANEL_{dtu_config.get('dtu_id', 'DTU001')}_{addr}"
|
|
|
- panel_config[panel_id] = {'address': addr, 'position': addr, 'panel_uid': uid_hex}
|
|
|
+ sync_panel_config()
|
|
|
logger.info(f"已加载 {len(panel_config)} 个面板配置")
|
|
|
# 启动自动发现循环
|
|
|
def auto_discover_loop():
|
|
|
@@ -3638,9 +3692,12 @@ if __name__ == '__main__':
|
|
|
if not dtu_config.get('enabled'):
|
|
|
continue
|
|
|
result = address_config.auto_configure(timeout=2.0)
|
|
|
- if result.get('discovered', 0) > 0:
|
|
|
- logger.info(f"自动发现: {result.get('discovered')} 个设备")
|
|
|
+ assigned = result.get('assigned', 0)
|
|
|
+ discovered = result.get('discovered', 0)
|
|
|
+ if discovered > 0 or assigned > 0:
|
|
|
+ logger.info(f"自动发现: discovered={discovered}, assigned={assigned}")
|
|
|
save_device_config()
|
|
|
+ sync_panel_config()
|
|
|
now = time.time()
|
|
|
for uid in address_config.get_stored_devices():
|
|
|
device_last_seen[uid] = now
|