diff --git a/application_events.json b/application_events.json index 2f0774a..301c1d1 100644 --- a/application_events.json +++ b/application_events.json @@ -1,465 +1,5 @@ { "events": [ - { - "timestamp": "2025-08-25T14:02:29.981110", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.0% CPU", - "details": { - "duration": 10.027307510375977, - "points_saved": 40, - "points_rate": 3.989106742623493, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.0, - "cpu_max": 0.0, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.027162200212478636, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:02:40.008028", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026918172836304, - "points_saved": 40, - "points_rate": 3.9892616365777362, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.02955700159072876, - "csv_write_time_avg": 3.319978713989258e-06 - } - }, - { - "timestamp": "2025-08-25T14:02:50.034470", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.02644157409668, - "points_saved": 40, - "points_rate": 3.9894512628827394, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.028314751386642457, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:03:00.060741", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026271104812622, - "points_saved": 40, - "points_rate": 3.989519092576696, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.029216140508651733, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:03:10.091122", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.0% CPU", - "details": { - "duration": 10.030381202697754, - "points_saved": 40, - "points_rate": 3.987884327790221, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.0, - "cpu_max": 0.0, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03202961683273316, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:03:20.121878", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.030755996704102, - "points_saved": 40, - "points_rate": 3.987735322556263, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.028543853759765626, - "csv_write_time_avg": 2.3484230041503905e-06 - } - }, - { - "timestamp": "2025-08-25T14:03:30.148923", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.027044773101807, - "points_saved": 40, - "points_rate": 3.98921126863845, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03223702907562256, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:03:40.177615", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.02869176864624, - "points_saved": 40, - "points_rate": 3.988556127037051, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.029716211557388305, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:03:50.205219", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026633262634277, - "points_saved": 40, - "points_rate": 3.9893749928069955, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.034369897842407224, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:04:00.234789", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.030540943145752, - "points_saved": 40, - "points_rate": 3.987820819108815, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.030520808696746827, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:04:10.261749", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026959896087646, - "points_saved": 40, - "points_rate": 3.98924503683388, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03205314874649048, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:04:20.290427", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.028677940368652, - "points_saved": 40, - "points_rate": 3.9885616267511335, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.031254750490188596, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:04:30.317707", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.0272798538208, - "points_saved": 40, - "points_rate": 3.98911774510396, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03653101325035095, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:04:40.347341", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.3% CPU", - "details": { - "duration": 10.029634714126587, - "points_saved": 40, - "points_rate": 3.98818113920546, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.3, - "cpu_max": 0.3, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03144925832748413, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:04:50.373515", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026173830032349, - "points_saved": 40, - "points_rate": 3.9895577992258833, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03237649202346802, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:05:00.400342", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026827096939087, - "points_saved": 40, - "points_rate": 3.989297871927092, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.031496965885162355, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:05:10.427694", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.026376724243164, - "points_saved": 40, - "points_rate": 3.9894770663546337, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03402681946754456, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:05:20.461769", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.3% CPU", - "details": { - "duration": 10.035049676895142, - "points_saved": 40, - "points_rate": 3.986029096806231, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.3, - "cpu_max": 0.3, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.032566672563552855, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:05:30.491522", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.02975344657898, - "points_saved": 40, - "points_rate": 3.988133927025244, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.03259522318840027, - "csv_write_time_avg": 0.0 - } - }, - { - "timestamp": "2025-08-25T14:05:40.519035", - "level": "info", - "event_type": "performance_report", - "message": "Performance report: 40 points saved, 0 lost, 0.2% CPU", - "details": { - "duration": 10.027512550354004, - "points_saved": 40, - "points_rate": 3.989025174402586, - "variables_saved": 120, - "udp_points_sent": 0, - "points_lost": 0, - "cpu_average": 0.2, - "cpu_max": 0.2, - "delay_average": 0.0, - "delay_max": 0.0, - "read_errors": 0, - "csv_errors": 0, - "udp_errors": 0, - "read_time_avg": 0.034430992603302, - "csv_write_time_avg": 0.0 - } - }, { "timestamp": "2025-08-25T14:05:50.550723", "level": "info", @@ -21248,8 +20788,311 @@ "event_type": "application_started", "message": "Application initialization completed successfully", "details": {} + }, + { + "timestamp": "2025-08-25T18:06:38.975607", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-25T18:06:40.012005", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-25T18:14:29.288722", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-25T18:14:30.332808", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-25T18:37:19.932684", + "level": "info", + "event_type": "config_reload", + "message": "Dataset configuration reloaded from files with CSV header validation", + "details": { + "datasets_count": 1, + "active_datasets_count": 1, + "csv_recording_active": false + } + }, + { + "timestamp": "2025-08-25T18:39:46.281395", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-25T18:39:47.318112", + "level": "info", + "event_type": "application_started", + "message": "Application initialization completed successfully", + "details": {} + }, + { + "timestamp": "2025-08-25T18:39:53.767096", + "level": "info", + "event_type": "dataset_activated", + "message": "Dataset activated: DAR", + "details": { + "dataset_id": "DAR", + "variables_count": 4, + "streaming_count": 3, + "prefix": "dar" + } + }, + { + "timestamp": "2025-08-25T18:39:53.793213", + "level": "info", + "event_type": "csv_recording_started", + "message": "🔥 CRITICAL PRIORITY: CSV recording started with MAXIMUM PRIORITY, async buffering, and performance monitoring: 1 datasets activated", + "details": { + "activated_datasets": 1, + "total_datasets": 1, + "priority": "CRITICAL", + "recording_protection": true, + "performance_monitoring": true, + "async_csv_buffering": true, + "csv_flush_interval": 5.0 + } + }, + { + "timestamp": "2025-08-25T18:39:53.825723", + "level": "info", + "event_type": "plc_connection", + "message": "Successfully connected to PLC 10.1.33.11 and auto-started CSV recording for 1 datasets", + "details": { + "ip": "10.1.33.11", + "rack": 0, + "slot": 2, + "symbols_path": "C:/Users/migue/Downloads/symSAE452.asc", + "auto_started_recording": true, + "recording_datasets": 1, + "dataset_names": [ + "DAR" + ] + } + }, + { + "timestamp": "2025-08-25T18:40:03.766490", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 0.0% CPU", + "details": { + "duration": 17.452539920806885, + "points_saved": 20, + "points_rate": 1.1459650051369337, + "variables_saved": 80, + "udp_points_sent": 0, + "points_lost": 0, + "cpu_average": 0.0, + "cpu_max": 0.0, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.033115696907043454, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:40:10.740922", + "level": "info", + "event_type": "udp_streaming_started", + "message": "UDP streaming to PlotJuggler started", + "details": { + "udp_host": "127.0.0.1", + "udp_port": 9870, + "datasets_available": 1 + } + }, + { + "timestamp": "2025-08-25T18:40:13.805084", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 1.2% CPU", + "details": { + "duration": 10.038594007492065, + "points_saved": 20, + "points_rate": 1.9923108739205386, + "variables_saved": 80, + "udp_points_sent": 18, + "points_lost": 0, + "cpu_average": 1.2, + "cpu_max": 1.2, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.03423429727554321, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:40:21.249789", + "level": "info", + "event_type": "config_reload", + "message": "Dataset configuration reloaded from files with CSV header validation", + "details": { + "datasets_count": 1, + "active_datasets_count": 1, + "csv_recording_active": true + } + }, + { + "timestamp": "2025-08-25T18:40:23.859171", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 21 points saved, 0 lost, 1.6% CPU", + "details": { + "duration": 10.054086923599243, + "points_saved": 21, + "points_rate": 2.088702848859223, + "variables_saved": 84, + "udp_points_sent": 63, + "points_lost": 0, + "cpu_average": 1.6, + "cpu_max": 1.6, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.035013005847022646, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:40:33.917226", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 1.7% CPU", + "details": { + "duration": 10.058055639266968, + "points_saved": 20, + "points_rate": 1.988455892202402, + "variables_saved": 80, + "udp_points_sent": 60, + "points_lost": 0, + "cpu_average": 1.7, + "cpu_max": 1.7, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.031715011596679686, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:40:43.953703", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 0.8% CPU", + "details": { + "duration": 10.036476373672485, + "points_saved": 20, + "points_rate": 1.9927312390694867, + "variables_saved": 80, + "udp_points_sent": 60, + "points_lost": 0, + "cpu_average": 0.8, + "cpu_max": 0.8, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.03160557746887207, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:40:53.987085", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 0.9% CPU", + "details": { + "duration": 10.033382177352905, + "points_saved": 20, + "points_rate": 1.9933457777720747, + "variables_saved": 80, + "udp_points_sent": 60, + "points_lost": 0, + "cpu_average": 0.9, + "cpu_max": 0.9, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.034756577014923094, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:41:04.037132", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 1.1% CPU", + "details": { + "duration": 10.050047159194946, + "points_saved": 20, + "points_rate": 1.9900404130642995, + "variables_saved": 80, + "udp_points_sent": 60, + "points_lost": 0, + "cpu_average": 1.1, + "cpu_max": 1.1, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.03677387237548828, + "csv_write_time_avg": 0.0 + } + }, + { + "timestamp": "2025-08-25T18:41:14.094379", + "level": "info", + "event_type": "performance_report", + "message": "Performance report: 20 points saved, 0 lost, 0.8% CPU", + "details": { + "duration": 10.056742906570435, + "points_saved": 20, + "points_rate": 1.9887154504997115, + "variables_saved": 80, + "udp_points_sent": 60, + "points_lost": 0, + "cpu_average": 0.8, + "cpu_max": 0.8, + "delay_average": 0.0, + "delay_max": 0.0, + "read_errors": 0, + "csv_errors": 0, + "udp_errors": 0, + "read_time_avg": 0.03401594161987305, + "csv_write_time_avg": 0.0 + } } ], - "last_updated": "2025-08-25T17:54:00.414879", + "last_updated": "2025-08-25T18:41:14.094379", "total_entries": 1000 } \ No newline at end of file diff --git a/config/data/dataset_variables.json b/config/data/dataset_variables.json index c93d270..ba0a1c9 100644 --- a/config/data/dataset_variables.json +++ b/config/data/dataset_variables.json @@ -33,10 +33,10 @@ { "configType": "manual", "area": "PEW", - "type": "word", - "streaming": false, "name": "CTS306_PEW", - "offset": 256 + "offset": 256, + "streaming": true, + "type": "word" } ] }, @@ -44,16 +44,13 @@ "dataset_id": "Fast", "variables": [ { - "area": "DB", - "configType": "symbol", + "name": "AUX Blink_2.0S", "streaming": true, - "symbol": "AUX Blink_2.0S", - "type": "real" + "symbol": "AUX Blink_2.0S" }, { "area": "M", "bit": 1, - "configType": "manual", "name": "M50.1", "offset": 50, "streaming": false, @@ -62,7 +59,6 @@ { "area": "M", "bit": 2, - "configType": "manual", "name": "M50.2", "offset": 50, "streaming": false, diff --git a/config/schema/dataset-variables.schema.json b/config/schema/dataset-variables.schema.json index 2c11801..01740ae 100644 --- a/config/schema/dataset-variables.schema.json +++ b/config/schema/dataset-variables.schema.json @@ -24,140 +24,161 @@ "description": "Array of PLC variables for this dataset", "items": { "type": "object", - "oneOf": [ + "properties": { + "configType": { + "type": "string", + "title": "Configuration Type", + "enum": ["manual", "symbol"], + "default": "manual" + } + }, + "allOf": [ { - "title": "Manual Configuration", - "description": "Manually configure PLC variable parameters", - "properties": { - "name": { - "type": "string", - "title": "Variable Name", - "description": "Human-readable name for the variable" - }, - "area": { - "type": "string", - "title": "Memory Area", - "enum": [ - "DB", - "MW", - "M", - "PEW", - "PE", - "PAW", - "PA", - "E", - "A", - "MB" - ] - }, - "db": { - "type": [ - "integer", - "null" - ], - "title": "DB Number", - "minimum": 1, - "maximum": 9999 - }, - "offset": { - "type": "integer", - "title": "Offset", - "minimum": 0, - "maximum": 8191 - }, - "bit": { - "type": [ - "integer", - "null" - ], - "title": "Bit Position", - "minimum": 0, - "maximum": 7 - }, - "type": { - "type": "string", - "title": "Data Type", - "enum": [ - "real", - "int", - "bool", - "dint", - "word", - "byte", - "uint", - "udint", - "sint", - "usint", - "dword" - ] - }, - "streaming": { - "type": "boolean", - "title": "Stream to PlotJuggler", - "description": "Include this variable in UDP streaming", - "default": false + "if": { + "properties": { + "configType": { + "const": "manual" + } } }, - "required": [ - "name", - "area", - "offset", - "type" - ], - "allOf": [ - { - "if": { - "properties": { - "area": { - "const": "DB" - } - } + "then": { + "properties": { + "name": { + "type": "string", + "title": "Variable Name", + "description": "Human-readable name for the variable" }, - "then": { - "required": ["db"] + "area": { + "type": "string", + "title": "Memory Area", + "enum": [ + "DB", + "MW", + "M", + "PEW", + "PE", + "PAW", + "PA", + "E", + "A", + "MB" + ] + }, + "db": { + "type": [ + "integer", + "null" + ], + "title": "DB Number", + "minimum": 1, + "maximum": 9999 + }, + "offset": { + "type": "integer", + "title": "Offset", + "minimum": 0, + "maximum": 8191 + }, + "bit": { + "type": [ + "integer", + "null" + ], + "title": "Bit Position", + "minimum": 0, + "maximum": 7 + }, + "type": { + "type": "string", + "title": "Data Type", + "enum": [ + "real", + "int", + "bool", + "dint", + "word", + "byte", + "uint", + "udint", + "sint", + "usint", + "dword" + ] + }, + "streaming": { + "type": "boolean", + "title": "Stream to PlotJuggler", + "description": "Include this variable in UDP streaming", + "default": false } }, - { - "if": { - "properties": { - "type": { - "const": "bool" + "required": [ + "configType", + "name", + "area", + "offset", + "type" + ], + "allOf": [ + { + "if": { + "properties": { + "area": { + "const": "DB" + } } + }, + "then": { + "required": ["db"] } }, - "then": { - "required": ["bit"] + { + "if": { + "properties": { + "type": { + "const": "bool" + } + } + }, + "then": { + "required": ["bit"] + } } - } - ] + ] + } }, { - "title": "Symbol-based Configuration", - "description": "Use a symbol from the loaded ASC file", - "properties": { - "name": { - "type": "string", - "title": "Variable Name", - "description": "Human-readable name for the variable (auto-filled from symbol)" - }, - "symbol": { - "type": "string", - "title": "PLC Symbol", - "description": "Select a symbol from the loaded ASC file", - "options": { - "widget": "symbol-selector" + "if": { + "properties": { + "configType": { + "const": "symbol" } - }, - "streaming": { - "type": "boolean", - "title": "Stream to PlotJuggler", - "description": "Include this variable in UDP streaming", - "default": false } }, - "required": [ - "symbol" - ] + "then": { + "properties": { + "name": { + "type": "string", + "title": "Variable Name", + "description": "Human-readable name for the variable (auto-filled from symbol)" + }, + "symbol": { + "type": "string", + "title": "PLC Symbol", + "description": "Select a symbol from the loaded ASC file" + }, + "streaming": { + "type": "boolean", + "title": "Stream to PlotJuggler", + "description": "Include this variable in UDP streaming", + "default": false + } + }, + "required": [ + "configType", + "symbol" + ] + } } ] } diff --git a/config/schema/ui/dataset-variables.uischema.json b/config/schema/ui/dataset-variables.uischema.json index b8e69ae..84118a7 100644 --- a/config/schema/ui/dataset-variables.uischema.json +++ b/config/schema/ui/dataset-variables.uischema.json @@ -25,221 +25,206 @@ "removable": true }, "items": { - "oneOf": [ - { - "ui:title": "Manual Configuration", - "ui:description": "Configure PLC variable parameters manually", - "ui:order": [ - "name", - "area", - "db", - "offset", - "bit", - "type", - "streaming" - ], - "ui:layout": [ - [ - { - "name": "name", - "width": 4 - }, - { - "name": "area", - "width": 2 - }, - { - "name": "db", - "width": 2 - }, - { - "name": "offset", - "width": 2 - }, - { - "name": "type", - "width": 2 - } - ], - [ - { - "name": "bit", - "width": 3 - }, - { - "name": "streaming", - "width": 9 - } - ] - ], - "name": { - "ui:widget": "text", - "ui:placeholder": "Variable name", - "ui:help": "📝 Human-readable name for this variable" - }, - "area": { - "ui:widget": "select", - "ui:help": "PLC memory area (DB=DataBlock, MW=MemoryWord, etc.)", - "ui:options": { - "enumOptions": [ - { - "value": "DB", - "label": "🗃️ DB (Data Block)" - }, - { - "value": "MW", - "label": "📊 MW (Memory Word)" - }, - { - "value": "M", - "label": "💾 M (Memory)" - }, - { - "value": "PEW", - "label": "📥 PEW (Process Input Word)" - }, - { - "value": "PE", - "label": "📥 PE (Process Input)" - }, - { - "value": "PAW", - "label": "📤 PAW (Process Output Word)" - }, - { - "value": "PA", - "label": "📤 PA (Process Output)" - }, - { - "value": "E", - "label": "🔌 E (Input)" - }, - { - "value": "A", - "label": "🔌 A (Output)" - }, - { - "value": "MB", - "label": "💾 MB (Memory Byte)" - } - ] - } - }, - "db": { - "ui:widget": "updown", - "ui:help": "⚠️ Data Block number (only required for DB area - will be ignored for other areas like PE, PA, MW, etc.)", - "ui:placeholder": "1011", - "ui:description": "🗃️ This field is only used when Area = 'DB (Data Block)'" - }, - "offset": { - "ui:widget": "updown", - "ui:help": "Byte offset within the memory area" - }, - "bit": { - "ui:widget": "updown", - "ui:help": "⚠️ Bit position (0-7) - only required for BOOL data type, will be ignored for other types", - "ui:description": "✅ This field is only used when Type = 'BOOL (1-bit boolean)'" - }, - "type": { - "ui:widget": "select", - "ui:help": "PLC data type", - "ui:options": { - "enumOptions": [ - { - "value": "real", - "label": "🔢 REAL (32-bit float)" - }, - { - "value": "int", - "label": "🔢 INT (16-bit signed)" - }, - { - "value": "bool", - "label": "✅ BOOL (1-bit boolean)" - }, - { - "value": "dint", - "label": "🔢 DINT (32-bit signed)" - }, - { - "value": "word", - "label": "🔢 WORD (16-bit unsigned)" - }, - { - "value": "byte", - "label": "🔢 BYTE (8-bit unsigned)" - }, - { - "value": "uint", - "label": "🔢 UINT (16-bit unsigned)" - }, - { - "value": "udint", - "label": "🔢 UDINT (32-bit unsigned)" - }, - { - "value": "sint", - "label": "🔢 SINT (8-bit signed)" - }, - { - "value": "usint", - "label": "🔢 USINT (8-bit unsigned)" - }, - { - "value": "dword", - "label": "🔢 DWORD (32-bit unsigned)" - } - ] - } - }, - "streaming": { - "ui:widget": "switch", - "ui:help": "📡 Enable real-time streaming to PlotJuggler for visualization" + "ui:order": [ + "configType", + "name", + "symbol", + "area", + "db", + "offset", + "bit", + "type", + "streaming" + ], + "ui:layout": [ + [ + { + "name": "configType", + "width": 3 } - }, - { - "ui:title": "Symbol-based Configuration", - "ui:description": "Use a symbol from the loaded ASC file", - "ui:order": [ - "name", - "symbol", - "streaming" - ], - "ui:layout": [ - [ - { - "name": "name", - "width": 6 - }, - { - "name": "symbol", - "width": 6 - } - ], - [ - { - "name": "streaming", - "width": 12 - } - ] - ], - "name": { - "ui:widget": "text", - "ui:placeholder": "Variable name (auto-filled from symbol)", - "ui:help": "📝 Human-readable name for this variable", - "ui:readonly": true + ], + [ + { + "name": "name", + "width": 6 }, - "symbol": { - "ui:widget": "dataset-variable-symbol", - "ui:placeholder": "Select a PLC symbol...", - "ui:help": "🔍 Search and select a symbol from the loaded ASC file" - }, - "streaming": { - "ui:widget": "switch", - "ui:help": "📡 Enable real-time streaming to PlotJuggler for visualization" + { + "name": "symbol", + "width": 6 } + ], + [ + { + "name": "area", + "width": 2 + }, + { + "name": "db", + "width": 2 + }, + { + "name": "offset", + "width": 2 + }, + { + "name": "bit", + "width": 2 + }, + { + "name": "type", + "width": 2 + }, + { + "name": "streaming", + "width": 2 + } + ] + ], + "configType": { + "ui:widget": "select", + "ui:help": "Choose between manual configuration or symbol-based setup", + "ui:options": { + "enumOptions": [ + { + "value": "manual", + "label": "🔧 Manual Configuration" + }, + { + "value": "symbol", + "label": "🔍 Symbol-based Configuration" + } + ] } - ] + }, + "name": { + "ui:widget": "text", + "ui:placeholder": "Variable name", + "ui:help": "📝 Human-readable name for this variable" + }, + "symbol": { + "ui:widget": "dataset-variable-symbol", + "ui:placeholder": "Select a PLC symbol...", + "ui:help": "🔍 Search and select a symbol from the loaded ASC file" + }, + "area": { + "ui:widget": "select", + "ui:help": "PLC memory area (DB=DataBlock, MW=MemoryWord, etc.)", + "ui:options": { + "enumOptions": [ + { + "value": "DB", + "label": "🗃️ DB (Data Block)" + }, + { + "value": "MW", + "label": "📊 MW (Memory Word)" + }, + { + "value": "M", + "label": "💾 M (Memory)" + }, + { + "value": "PEW", + "label": "📥 PEW (Process Input Word)" + }, + { + "value": "PE", + "label": "📥 PE (Process Input)" + }, + { + "value": "PAW", + "label": "📤 PAW (Process Output Word)" + }, + { + "value": "PA", + "label": "📤 PA (Process Output)" + }, + { + "value": "E", + "label": "🔌 E (Input)" + }, + { + "value": "A", + "label": "🔌 A (Output)" + }, + { + "value": "MB", + "label": "💾 MB (Memory Byte)" + } + ] + } + }, + "db": { + "ui:widget": "updown", + "ui:help": "⚠️ Data Block number (only required for DB area - will be ignored for other areas like PE, PA, MW, etc.)", + "ui:placeholder": "1011", + "ui:description": "🗃️ This field is only used when Area = 'DB (Data Block)'" + }, + "offset": { + "ui:widget": "updown", + "ui:help": "Byte offset within the memory area" + }, + "bit": { + "ui:widget": "updown", + "ui:help": "⚠️ Bit position (0-7) - only required for BOOL data type, will be ignored for other types", + "ui:description": "✅ This field is only used when Type = 'BOOL (1-bit boolean)'" + }, + "type": { + "ui:widget": "select", + "ui:help": "PLC data type", + "ui:options": { + "enumOptions": [ + { + "value": "real", + "label": "🔢 REAL (32-bit float)" + }, + { + "value": "int", + "label": "🔢 INT (16-bit signed)" + }, + { + "value": "bool", + "label": "✅ BOOL (1-bit boolean)" + }, + { + "value": "dint", + "label": "🔢 DINT (32-bit signed)" + }, + { + "value": "word", + "label": "🔢 WORD (16-bit unsigned)" + }, + { + "value": "byte", + "label": "🔢 BYTE (8-bit unsigned)" + }, + { + "value": "uint", + "label": "🔢 UINT (16-bit unsigned)" + }, + { + "value": "udint", + "label": "🔢 UDINT (32-bit unsigned)" + }, + { + "value": "sint", + "label": "🔢 SINT (8-bit signed)" + }, + { + "value": "usint", + "label": "🔢 USINT (8-bit unsigned)" + }, + { + "value": "dword", + "label": "🔢 DWORD (32-bit unsigned)" + } + ] + } + }, + "streaming": { + "ui:widget": "switch", + "ui:help": "📡 Enable real-time streaming to PlotJuggler for visualization" + } } } } diff --git a/frontend/src/pages/Dashboard.jsx b/frontend/src/pages/Dashboard.jsx index 5dd6e26..21cd212 100644 --- a/frontend/src/pages/Dashboard.jsx +++ b/frontend/src/pages/Dashboard.jsx @@ -1374,129 +1374,56 @@ function DatasetManager() { /> - {/* Simplified schema for selected dataset variables */} + {/* Schema for selected dataset variables - derived from external schema */} {(() => { const selectedDatasetVars = getSelectedDatasetVariables() - // Schema for this dataset's variables - const singleDatasetSchema = { - type: "object", - properties: { - variables: { - type: "array", - title: `Variables for Dataset: ${availableDatasets.find(d => d.id === selectedDatasetId)?.name || selectedDatasetId}`, - description: `PLC variables to record in dataset ${selectedDatasetId}`, - items: { - type: "object", - properties: { - configType: { - type: "string", - title: "Configuration Type", - enum: ["manual", "symbol"], - default: "manual" - } - }, - allOf: [ - { - if: { properties: { configType: { const: "manual" } } }, - then: { - properties: { - name: { type: "string", title: "Variable Name" }, - area: { - type: "string", - title: "Memory Area", - enum: ["DB", "MW", "M", "PEW", "PE", "PAW", "PA", "E", "A", "MB"], - default: "DB" - }, - db: { type: "integer", title: "DB Number", minimum: 1, maximum: 9999 }, - offset: { type: "integer", title: "Offset", minimum: 0, maximum: 8191 }, - bit: { type: "integer", title: "Bit Position", minimum: 0, maximum: 7 }, - type: { - type: "string", - title: "Data Type", - enum: ["real", "int", "dint", "bool", "word", "byte"], - default: "real" - }, - streaming: { type: "boolean", title: "Stream to UDP", default: false } - }, - required: ["name", "area", "offset", "type"] - } - }, - { - if: { properties: { configType: { const: "symbol" } } }, - then: { - properties: { - name: { - type: "string", - title: "Variable Name", - description: "Auto-filled from symbol", - readOnly: true - }, - symbol: { - type: "string", - title: "PLC Symbol", - description: "Select a symbol from loaded ASC file" - }, - streaming: { type: "boolean", title: "Stream to UDP", default: false } - }, - required: ["symbol"] - } - } - ] + // Create simplified schema from external schema for single dataset variables + let singleDatasetSchema = null + let singleDatasetUiSchema = null + + if (variablesSchemaData?.schema) { + // Extract the variables array schema from the external schema + // Path: schema.properties.variables.items.properties.variables + const datasetItemSchema = variablesSchemaData.schema.properties?.variables?.items + const variablesArraySchema = datasetItemSchema?.properties?.variables + + if (variablesArraySchema) { + singleDatasetSchema = { + type: "object", + properties: { + variables: { + ...variablesArraySchema, + title: `Variables for Dataset: ${availableDatasets.find(d => d.id === selectedDatasetId)?.name || selectedDatasetId}`, + description: `PLC variables to record in dataset ${selectedDatasetId}` + } } } } } - - const singleDatasetUiSchema = { - variables: { - items: { - "ui:order": ["configType", "name", "symbol", "area", "db", "offset", "bit", "type", "streaming"], - "ui:layout": [ - [ - { "name": "configType", "width": 3 } - ], - [ - { "name": "name", "width": 4 }, - { "name": "symbol", "width": 8 } - ], - [ - { "name": "area", "width": 2 }, - { "name": "db", "width": 2 }, - { "name": "offset", "width": 2 }, - { "name": "bit", "width": 2 }, - { "name": "type", "width": 2 }, - { "name": "streaming", "width": 2 } - ] - ], - "configType": { - "ui:widget": "select", - "ui:help": "Choose between manual configuration or symbol-based setup", - "ui:enumNames": ["Manual Configuration", "Symbol-based Configuration"] - }, - "symbol": { - "ui:widget": "symbol-selector", - "ui:placeholder": "Select a PLC symbol...", - "ui:help": "🔍 Search and select a symbol from the loaded ASC file" - }, - "name": { - "ui:help": "Human-readable name for this variable" - }, - "area": { - "ui:widget": "select", - "ui:help": "PLC memory area" - }, - "type": { - "ui:widget": "select", - "ui:help": "PLC data type" - }, - "streaming": { - "ui:widget": "switch", - "ui:help": "Enable UDP streaming to PlotJuggler" - } + + if (variablesSchemaData?.uiSchema) { + // Extract the variables UI schema from the external UI schema + // Path: uiSchema.variables.items.variables + const datasetItemUiSchema = variablesSchemaData.uiSchema.variables?.items + const variablesUiSchema = datasetItemUiSchema?.variables + + if (variablesUiSchema) { + singleDatasetUiSchema = { + variables: variablesUiSchema } } } + + // Fallback if external schemas are not available + if (!singleDatasetSchema || !singleDatasetUiSchema) { + return ( + + + External schemas not loaded. Please refresh the page. + + ) + } // Function to expand symbol data using backend API const expandSymbolToManualConfig = async (symbolName, currentVariable = {}) => { @@ -1504,8 +1431,7 @@ function DatasetManager() { // Create a temporary variable array with just this symbol const tempVariables = [{ symbol: symbolName, - streaming: currentVariable.streaming || false, - configType: "symbol" + streaming: currentVariable.streaming || false }] // Call backend API to process the symbol @@ -1589,68 +1515,10 @@ function DatasetManager() { } } - // Custom onChange handler that detects configType changes and auto-fills data - const handleFormChange = async ({ formData }) => { - // Check if there are variables and if any configType changed from symbol to manual - if (formData?.variables && selectedDatasetVars?.variables) { - const updatedVariables = [] - let hasSymbolToManualChange = false - - for (let index = 0; index < formData.variables.length; index++) { - const newVar = formData.variables[index] - const oldVar = selectedDatasetVars.variables[index] - - // Detect if configType changed from "symbol" to "manual" - if (oldVar?.configType === "symbol" && - newVar?.configType === "manual" && - oldVar?.symbol) { - - hasSymbolToManualChange = true - - try { - // Auto-fill manual fields from symbol data using backend API - const symbolData = await expandSymbolToManualConfig(oldVar.symbol, oldVar) - - // Add the variable with auto-filled data - updatedVariables.push({ - ...newVar, - ...symbolData, - configType: "manual", // Ensure configType is set correctly - symbol: undefined // Clear symbol field to avoid confusion - }) - - } catch (error) { - console.error('Error expanding symbol:', error) - // Fallback: add variable as-is on error - updatedVariables.push(newVar) - } - } else { - // For other cases, return the variable as-is - updatedVariables.push(newVar) - } - } - - if (hasSymbolToManualChange) { - // Show toast notification about the auto-fill - toast({ - title: '🔄 Auto-filled from symbol', - description: 'Symbol data has been copied to manual configuration fields', - status: 'success', - duration: 3000 - }) - } - - // Update with the modified variables - const updatedFormData = { - ...formData, - variables: updatedVariables - } - - updateSelectedDatasetVariables(updatedFormData) - } else { - // Normal update without special processing - updateSelectedDatasetVariables(formData) - } + // Standard form change handler for external schema compatibility + const handleFormChange = ({ formData }) => { + // Direct update without special processing for external schema compatibility + updateSelectedDatasetVariables(formData) } return ( @@ -1669,12 +1537,7 @@ function DatasetManager() { }) }} onChange={({ formData }) => { - // Call the async handler - handleFormChange({ formData }).catch(error => { - console.error('Error in form change handler:', error) - // Fallback to normal update on error - updateSelectedDatasetVariables(formData) - }) + handleFormChange({ formData }) }} > diff --git a/system_state.json b/system_state.json index 33afb79..d3171fe 100644 --- a/system_state.json +++ b/system_state.json @@ -1,10 +1,12 @@ { "last_state": { - "should_connect": false, - "should_stream": false, - "active_datasets": [] + "should_connect": true, + "should_stream": true, + "active_datasets": [ + "DAR" + ] }, "auto_recovery_enabled": true, - "last_update": "2025-08-25T17:50:18.320817", + "last_update": "2025-08-25T18:40:24.478882", "plotjuggler_path": "C:\\Program Files\\PlotJuggler\\plotjuggler.exe" } \ No newline at end of file