""" This python script will go through a given ThingsBoard device profile For each alarm found it will create a line in a csv that will have the following pieces Alarm name, Severity, Create Rule, Create data point, Clear Rule, Clear Data point """ import json import csv def extract_alarm_data(profile_path, tags_path, csv_path): """ Extracts alarm data from a ThingsBoard device profile JSON and writes it to a CSV file. Args: profile_path (str): Path to the ThingsBoard device profile JSON file. csv_path (str): Path to the output CSV file. """ with open(profile_path, 'r') as f: profile = json.load(f) alarms = profile.get("profileData", {}).get('alarms', []) #print(alarms) with open(csv_path, 'w', newline='') as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(['Alarm Name', 'Severity', 'Create Rule', 'Create Data Point', 'PLC Tag Name', 'Clear Rule', 'Clear Data Point']) # Write header for alarm in alarms: #print(alarm.get("alarmType")) alarm_name = alarm.get('alarmType', 'N/A') create_levels = alarm.get("createRules", {}).keys() for level in create_levels: severity = level # Assuming MAJOR for now, can be enhanced to parse other severities. create_rule = parse_create_rule(alarm, level) create_data_point = parse_create_data_point(alarm, level) mapped_tag = map_to_tag(create_data_point) # Assuming there's a function to map tags to clear_rule = parse_clear_rule(alarm) clear_data_point = parse_clear_data_point(alarm) csv_writer.writerow([alarm_name, severity, create_rule, create_data_point, mapped_tag, clear_rule, clear_data_point]) def map_to_tag(datapoint): """Loops through csv data found in tags_path and finds the row with given datapoint and extracts data from the appropriate column of the same row and returns that value """ with open(tags_path, 'r') as file: reader = csv.reader(file) for row in reader: if row[0] == datapoint: # Extract the value from the appropriate column and return it # Example: Assuming the value is in column 10 value = row[10] return value return None def parse_create_rule(alarm, level): """Extracts the create rule information from the alarm.""" create_rule = alarm.get('createRules', {}).get(level, {}).get('condition', {}) # Simplify the extraction, including only the key and predicate if create_rule: spec = create_rule.get('spec', [{}]) type = spec.get('type', "N/A") return f"{type}" else: return "N/A" def parse_create_data_point(alarm, level): """Extracts the create data point information from the alarm.""" create_rule = alarm.get('createRules', {}).get(level, {}).get('condition', {}) if create_rule: condition = create_rule.get('condition', [{}])[0] key = condition.get('key', {}) return key.get('key', 'N/A') else: return "N/A" def parse_clear_rule(alarm): """Extracts the clear rule information from the alarm.""" clear_rule = alarm.get('clearRule', {}).get('condition', {}) if clear_rule: condition = clear_rule.get('condition', [{}])[0] key = condition.get('key', {}) predicate = condition.get('predicate', {}) return f"{key.get('type', 'N/A')} - {predicate.get('operation', 'N/A')}" else: return "N/A" def parse_clear_data_point(alarm): """Extracts the clear data point information from the alarm.""" clear_rule = alarm.get('clearRule', {}).get('condition', {}) if clear_rule: spec = clear_rule.get('spec', [{}]) type = spec.get('type', {}) return f"{type} - {spec.get("predicate", {}).get("defaultValue", 0)} {spec.get("unit", "N/A")}" else: return "N/A" if __name__ == "__main__": # Replace with your actual file path profile_path = '/Users/nico/Documents/GitHub/ThingsBoard/Code Snippets/ek_facility_device_profile.json' tags_path = './ek_facility_measures.csv' csv_path = './ek_facility_alarm_data.csv' extract_alarm_data(profile_path, tags_path, csv_path)