#!/usr/bin/env python3 import json # Read flows.json with open('/home/mdares/.node-red/flows.json', 'r') as f: flows = json.load(f) # Find the main flow tab and home group main_tab_id = None home_group_id = None home_tab_id = None for node in flows: if node.get('type') == 'tab' and node.get('label') not in ['Startup Recovery']: if not main_tab_id: main_tab_id = node['id'] if node.get('type') == 'ui_group' and 'home' in node.get('name', '').lower(): home_group_id = node['id'] home_tab_id = node.get('z') print(f"Main tab ID: {main_tab_id}") print(f"Home group ID: {home_group_id}") print(f"Home tab ID: {home_tab_id}") # Fix nodes without proper flow IDs fixed_count = 0 for node in flows: # Skip tab nodes if node.get('type') == 'tab': continue # Fix nodes with null or missing 'z' (except config nodes) if node.get('z') is None and node.get('type') not in ['MySQLdatabase', 'ui_base', 'ui_tab', 'ui_group']: # If it's a ui_template for stop reason, assign to home tab if node.get('type') == 'ui_template' and 'Stop Reason' in node.get('name', ''): if home_tab_id: node['z'] = home_tab_id print(f"✓ Fixed Stop Reason UI template (assigned to tab {home_tab_id})") fixed_count += 1 # Otherwise assign to main tab elif main_tab_id: node['z'] = main_tab_id print(f"✓ Fixed node {node.get('name', node.get('id'))} (assigned to tab {main_tab_id})") fixed_count += 1 # Also check for any nodes in Recovered Nodes tab and move them for node in flows: if node.get('type') == 'tab' and 'Recovered' in node.get('label', ''): recovered_tab_id = node['id'] print(f"\nFound 'Recovered Nodes' tab: {recovered_tab_id}") # Find nodes in this tab and reassign them for n in flows: if n.get('z') == recovered_tab_id: if n.get('type') == 'ui_template': n['z'] = home_tab_id if home_tab_id else main_tab_id print(f"✓ Moved {n.get('name', n.get('id'))} from Recovered to proper tab") fixed_count += 1 else: n['z'] = main_tab_id print(f"✓ Moved {n.get('name', n.get('id'))} from Recovered to main tab") fixed_count += 1 # Write updated flows with open('/home/mdares/.node-red/flows.json', 'w') as f: json.dump(flows, f, indent=4) print(f"\n✅ Fixed {fixed_count} nodes with invalid flow IDs") print("Node-RED should now load without 'Recovered Nodes' error")