josefkyrian

pylon dataparser.py

Oct 10th, 2023
909
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.31 KB | None | 0 0
  1. import dateutil.parser
  2. import re
  3. import uuid
  4. import hashlib
  5.  
  6.  
  7. def isnumeric(val):
  8.     try:
  9.         float(val)
  10.         return True
  11.     except ValueError:
  12.         return False
  13.     #endtry
  14. #enddef
  15.  
  16. def parseData_disp_pwr(line):
  17.     # line format:
  18.     # ID    Time               Vo(mV) Cu(mA) Tempr   BTlow   BThigh  BVlow    BVhigh   Base.St  Volt.St  Curr.St  Temp.St  Per%  Coul(mAH) Per%  Coul(mWH) B.V.St   B.T.St   U.V.St   U.T.St   UTlow    UThigh   UVlow    UVhigh   BTAvg  
  19.     # 1     22-06-04 18:33:03  411986 0      40000   27000   29000   3431     3436     Idle     Normal   Normal   Normal   100%     36981 100%     14200320    Normal   Normal   Normal   Normal   27000    29000   102979   103022   27866
  20.     # [
  21.     #   '1',
  22.     #   '22-06-04',
  23.     #   '18:33:03',
  24.     #   '411986',
  25.     #   '0',
  26.     #   '40000',
  27.     #   '27000',
  28.     #   '29000',
  29.     #   '3431',
  30.     #   '3436',
  31.     #   'Idle',
  32.     #   'Normal',
  33.     #   'Normal',
  34.     #   'Normal',
  35.     #   '100%',
  36.     #   '36981',
  37.     #   '100%',
  38.     #   '14200320',
  39.     #   'Normal',
  40.     #   'Normal',
  41.     #   'Normal',
  42.     #   'Normal',
  43.     #   '27000',
  44.     #   '29000',
  45.     #   '102979',
  46.     #   '103022',
  47.     #   '27866',
  48.     # ]
  49.     columnsDefList = [
  50.         None,
  51.         'timestamp_date',
  52.         'timestamp_time',
  53.         'voltage',
  54.         'current',
  55.         'temperature',
  56.         'min_cell_temperature',
  57.         'max_cell_temperature',
  58.         'min_cell_voltage',
  59.         'max_cell_voltage',
  60.         'base_state_label',
  61.         'voltage_state_label',
  62.         'current_state_label',
  63.         'temperature_state_label',
  64.         'soc',
  65.         'coulomb_ah',
  66.         'coulomb_percent',
  67.         'coulomb_kwh',
  68.         'cell_voltage_state_label',
  69.         'cell_temperature_state_label',
  70.         'unit_voltage_state_label',
  71.         'unit_temperature_state_label',
  72.         'min_unit_temperature',
  73.         'max_unit_temperature',
  74.         'min_unit_voltage',
  75.         'max_unit_voltage',
  76.         'avg_cell_temperature',
  77.     ]
  78.     columns = line.split()
  79.     if (len(columns) < len(columnsDefList)):
  80.         return None
  81.     #endif
  82.     columnValues = {}
  83.     for columnIndex, columnName in enumerate(columnsDefList):
  84.         if (columnName == None):
  85.             continue
  86.         #endif
  87.         columnValues[columnName] = columns[columnIndex]
  88.     #endfor
  89.  
  90.     columnValues['timestamp'] = dateutil.parser.parse('20%s %s' % (columnValues['timestamp_date'], columnValues['timestamp_time']))
  91.     del columnValues['timestamp_date']
  92.     del columnValues['timestamp_time']
  93.     for columnName in [
  94.         'voltage',
  95.         'current',
  96.         'temperature',
  97.         'min_cell_temperature',
  98.         'max_cell_temperature',
  99.         'min_cell_voltage',
  100.         'max_cell_voltage',
  101.         'coulomb_ah',
  102.         'min_unit_temperature',
  103.         'max_unit_temperature',
  104.         'min_unit_voltage',
  105.         'max_unit_voltage',
  106.         'avg_cell_temperature',
  107.     ]:
  108.         columnValues[columnName] = float(columnValues[columnName]) / 1000
  109.     #endfor
  110.     columnValues['soc'] = float(columnValues['soc'].replace('%', ''))
  111.     columnValues['coulomb_percent'] = float(columnValues['coulomb_percent'].replace('%', ''))
  112.     columnValues['coulomb_kwh'] = float(columnValues['coulomb_kwh']) / 1000000
  113.  
  114.     return columnValues
  115. #enddef
  116.  
  117. def parseData_stat(data):
  118.     #print(data);return{}
  119.     columnValues = {}
  120.  
  121.     for line in data.split("\n"):
  122.         line = line.strip()
  123.         if (line):
  124.             #print(line)
  125.             if (':' in line):
  126.                 (key, value) = line.split(":", 1)
  127.                 columnValues[key.strip()] = float(value.strip())
  128.             #endif
  129.         #endif
  130.     #endfor
  131.  
  132.     return columnValues
  133. #enddef
  134.  
  135. def parseData_sysinfo(data):
  136.     #print(data);return{}
  137.  
  138.     columnValues = {}
  139.  
  140.     for line in data.split("\n"):
  141.         line = line.strip()
  142.         if (line):
  143.             #print(line)
  144.             if (':' in line):
  145.                 (key, value) = line.split(":", 1)
  146.                 value = value.strip().split()[0].strip()
  147.                 columnValues[key.strip()] = float(value) if isnumeric(value) else value
  148.             #endif
  149.         #endif
  150.     #endfor
  151.  
  152.     return columnValues
  153. #enddef
  154.  
  155. def parseData_bat(data):
  156.     #print(data);return{}
  157.  
  158.     columnValues = {}
  159.     batteries = []
  160.  
  161.     columnValues['uuid'] = str(uuid.uuid4())
  162.  
  163.     part = None
  164.     for line in data.split("\n"):
  165.         line = line.strip()
  166.         if (line):
  167.             #print(line)
  168.             if (part == None and ':' in line):
  169.                 part = 'values-with-colons'
  170.             #endif
  171.             if (part == 'values-with-colons'):
  172.                 if (':' in line):
  173.                     (key, value) = line.split(":", 1)
  174.                     firstValue = value.strip().split()[0].strip()
  175.                     columnValues[key.strip()] = float(firstValue) if isnumeric(firstValue) else value.strip()
  176.                 elif (re.match('^Bat +Volt +Curr +Tempr.+', line)):
  177.                     part = 'batteries'
  178.                     continue
  179.                 #endif
  180.             #endif
  181.             if (part == 'batteries'):
  182.                 headerDef = 'Bat|Volt|Curr|Tempr|V.State|T.State|AH(%)|AH(mAH)|WH(%)|WH(mWH)|Bal'
  183.  
  184.                 header = headerDef.split('|')
  185.                 #print(header)
  186.                 values = line.split()
  187.                 #print(values)
  188.                 #print(values)
  189.                 if len(values) == len(header):
  190.                     batteries.append(dict([(header[i], values[i]) for i, col in enumerate(header)]))
  191.                     batteries[-1]["parent_uuid"] = columnValues['uuid']
  192.                     batteries[-1]["AH(%)"] = batteries[-1]["AH(%)"].rstrip("%")
  193.                     batteries[-1]["WH(%)"] = batteries[-1]["WH(%)"].rstrip("%")
  194.                 else:
  195.                     part = 'end'
  196.                 #endif
  197.             #endif
  198.         #endif
  199.     #endfor
  200.  
  201.     return {
  202.         'columnValues':columnValues,
  203.         'batteries':batteries,
  204.     }
  205. #enddef
  206.  
  207. def parseData_soh(data):
  208.     #print(data);return{}
  209.  
  210.     columnValues = {}
  211.     batteries = []
  212.  
  213.     columnValues['uuid'] = str(uuid.uuid4())
  214.  
  215.     part = None
  216.     for line in data.split("\n"):
  217.         line = line.strip()
  218.         if (line):
  219.             #print(line)
  220.             if (part == None \
  221.             # and ':' in line
  222.             ):
  223.                 part = 'values-with-colons'
  224.             #endif
  225.             if (part == 'values-with-colons'):
  226.                 if (':' in line):
  227.                     (key, value) = line.split(":", 1)
  228.                     firstValue = value.strip().split()[0].strip()
  229.                     columnValues[key.strip()] = float(firstValue) if isnumeric(firstValue) else value.strip()
  230.                 elif (re.match('^Battery +Voltage +SOHCount.+', line)):
  231.                     part = 'batteries'
  232.                     continue
  233.                 #endif
  234.             #endif
  235.             if (part == 'batteries'):
  236.                 headerDef = 'Battery|Voltage|SOHCount|SOHStatus'
  237.  
  238.                 header = headerDef.split('|')
  239.                 #print(header)
  240.                 values = line.split()
  241.                 #print(values)
  242.                 #print(values)
  243.                 if len(values) == len(header):
  244.                     batteries.append(dict([(header[i], values[i]) for i, col in enumerate(header)]))
  245.                     batteries[-1]["parent_uuid"] = columnValues['uuid']
  246.                 else:
  247.                     part = 'end'
  248.                 #endif
  249.             #endif
  250.         #endif
  251.     #endfor
  252.  
  253.     return {
  254.         'columnValues':columnValues,
  255.         'batteries':batteries,
  256.     }
  257. #enddef
  258.  
  259. def parseData_log(data):
  260.     #print(data);return{}
  261.  
  262.     records = []
  263.  
  264.     columnValues = {}
  265.  
  266.     for line in data.split("\n"):
  267.         line = line.strip()
  268.         if (line):
  269.             #print(line)
  270.             if (':' in line):
  271.                 (key, value) = line.split(":", 1)
  272.                 key = key.strip()
  273.                 value = value.strip()
  274.                 if (key == "Time"):
  275.                     value = dateutil.parser.parse('20%s' % value)
  276.                 #endif
  277.                 columnValues[key] = value
  278.             #endif
  279.         else:
  280.             if (columnValues):
  281.                 records.append(columnValues)
  282.             #endif
  283.             columnValues = {}
  284.         #endif
  285.     #endfor
  286.     if (columnValues):
  287.         records.append(columnValues)
  288.     #endif
  289.     # pridat id jako kombinace casu a textu
  290.     for record in records:
  291.         record['uuid'] = hashlib.md5(("%s/%s" % (record['Time'].timestamp(), record['Info'])).encode('utf-8')).hexdigest()
  292.     #endfor
  293.  
  294.     return records
  295. #enddef
  296.  
  297. def parseData_data_X(data):
  298.     #print(data);return{}
  299.  
  300.     columnValues = {}
  301.     batteries = []
  302.     units = []
  303.  
  304.     part = None
  305.     for line in data.split("\n"):
  306.         line = line.strip()
  307.         if (line):
  308.             #print(line)
  309.             if (part == None and ':' in line):
  310.                 part = 'values-with-colons'
  311.             #endif
  312.             if (part == 'values-with-colons'):
  313.                 if (':' in line):
  314.                     (key, value) = line.split(":", 1)
  315.                     key = key.strip()
  316.                     value = value.strip()
  317.                     firstValue = value.split()[0].strip()
  318.                     if (key == "Time"):
  319.                         value = dateutil.parser.parse('20%s' % value)
  320.                     #endif
  321.                     columnValues[key] = float(firstValue) if isnumeric(firstValue) else value
  322.                 elif (re.match('^Battery +Volt +Tempr.+', line)):
  323.                     columnValues['uuid'] = hashlib.md5(("%s" % (columnValues['Time'].timestamp(), )).encode('utf-8')).hexdigest()
  324.                     part = 'batteries'
  325.                     continue
  326.                 #endif
  327.             #endif
  328.             if (part == 'batteries'):
  329.                 headerDef = 'Battery|Volt|Tempr|Volt. State|Temp. State|Coulomb(%)'
  330.  
  331.                 header = headerDef.split('|')
  332.                 #print(header)
  333.                 values = line.split()
  334.                 #print(values)
  335.                 #print(values)
  336.                 if len(values) == len(header):
  337.                     batteries.append(dict([(header[i], values[i]) for i, col in enumerate(header)]))
  338.                     batteries[-1]["parent_uuid"] = columnValues['uuid']
  339.                     batteries[-1]["Coulomb(%)"] = batteries[-1]["Coulomb(%)"].rstrip("%")
  340.                 elif (re.match('^Unit +Volt +Tempr +BTLow +BTHigh.+', line)):
  341.                     part = 'units'
  342.                     continue
  343.                 #endif
  344.             #endif
  345.             if (part == 'units'):
  346.                 headerDef = 'Unit|Volt|Tempr|BTLow|BTHigh|BVLow|BVHigh|Volt. State|Temp. State|Coulomb(%)'
  347.  
  348.                 header = headerDef.split('|')
  349.                 #print(header)
  350.                 values = line.split()
  351.                 #print(values)
  352.                 #print(values)
  353.                 if len(values) == len(header):
  354.                     units.append(dict([(header[i], values[i]) for i, col in enumerate(header)]))
  355.                     units[-1]["parent_uuid"] = columnValues['uuid']
  356.                     units[-1]["Coulomb(%)"] = units[-1]["Coulomb(%)"].rstrip("%")
  357.                 else:
  358.                     part = 'end'
  359.                 #endif
  360.             #endif
  361.         #endif
  362.     #endfor
  363.  
  364.     return {
  365.         'columnValues':columnValues,
  366.         'batteries':batteries,
  367.         'units':units,
  368.     }
  369. #enddef
  370.  
  371. def parseData_data_event(data):
  372.     return parseData_data_X(data)
  373. #enddef
  374.  
  375. def parseData_data_history(data):
  376.     return parseData_data_X(data)
  377. #enddef
  378.  
  379. def parseData_data_misc(data):
  380.     return parseData_data_X(data)
  381. #enddef
  382.  
Advertisement
Add Comment
Please, Sign In to add comment