#!/usr/bin/env python3 import sys sys.path.insert(0, '..') from database.tm_db import scoped_session_maker dbcon = scoped_session_maker('idb') # get IDB version information idb_version = dbcon.execute('select vdf_release, vdf_issue,_UpdateTime from vdf').fetchall()[0] vmaj, vmin, date = (*idb_version[:2], idb_version[-1].strftime('%Y-%m-%d')) def get_cdescr(cname): try: descr, = dbcon.execute('select ccf_descr from ccf where ccf_cname="{}"'.format(cname)).fetchall()[0] except IndexError: descr = cname finally: dbcon.close() return descr def get_piddescr(pcf_name): try: descr, = dbcon.execute('select pcf_descr from pcf where pcf_name="{}"'.format(pcf_name)).fetchall()[0] except IndexError: descr = pcf_name finally: dbcon.close() return descr def get_calibrated(cpc_pname, pvalue): try: altxt, = dbcon.execute('SELECT pas_altxt FROM cpc LEFT JOIN pas ON cpc.cpc_pafref=pas.pas_numbr ' 'WHERE cpc_pname="{}" AND pas_alval={}'.format(cpc_pname, pvalue)).fetchall()[0] except IndexError: altxt = None finally: dbcon.close() return altxt def cuc_to_bytes(cuc, sync='U'): if isinstance(cuc, str): sync = cuc[-1] cuc = float(cuc[:-1]) coarse = int(cuc) fine = int((cuc % 1) * 2 ** 15) if sync.upper() == 'S': sync = '1' else: sync = '0' c = coarse.to_bytes(4, 'big') f = int(bin(fine) + sync, 0).to_bytes(2, 'big') return c + f def add_quotes(s): if isinstance(s, str): s = '"' + s + '"' return s def tc_string(descr, pars=None, ack=None, prefix='ccs.Tcsend_DB', sleep=None): if descr.startswith(('ASC', 'CSC', 'RSC')): if sleep is None: sleep = '' else: sleep = 'time.sleep({:.3f})'.format(sleep) return '# {}\n{}'.format(descr, sleep) if ack is None: ack = '' else: ack = ', ack="{}"'.format(ack) if sleep is None: sleep = '' else: sleep = ', sleep={:.3f}'.format(sleep) pars = ', '.join(map(str, map(add_quotes, pars))) if pars != '': pars = ', ' + pars return '{}("{}"{}{}{})'.format(prefix, descr, pars, ack, sleep) fname = sys.argv[1] with open(fname, 'r') as fd: data = fd.read().split('\n') data.remove('') nrows = len(data) idx = 0 seq = 1 cmds = {} base_header = '' while idx < nrows: row = data[idx] if not row.startswith('C|'): if row.startswith('1|'): base_header += row idx += 1 continue head = row.split('|') npars = int(head[13]) cname = head[1] ack = bin(int(head[26])) ctime = float(head[16]) ftime = float(head[17]) / 1e6 timestamp = ctime + ftime descr = get_cdescr(cname) cmds[seq] = {'CNAME': cname, 'DESCR': descr, 'ack': ack, 'timestamp': timestamp} parameters = [] for i in range(npars): idx += 1 par_data = data[idx].split('|') pname = par_data[0] if int(par_data[2]) in (0, 1): value = int(par_data[5]) cal = get_calibrated(pname, value) if cal is not None: value = cal elif int(par_data[2]) in (2, 3): value = float(par_data[5]) elif int(par_data[2]) == 4: value = str(par_data[5]) elif int(par_data[2]) == 5: value = bytes.fromhex(par_data[5]) elif int(par_data[2]) == 7: time = par_data[5].replace(' ', '.') value = cuc_to_bytes(time) elif int(par_data[2]) == 14: value = get_piddescr(par_data[5]) else: value = par_data[5] parameters.append(value) if npars != len(parameters): print(">>> {} parameters found, should be {} [{}]! <<<".format(len(parameters), npars, cname)) if descr.startswith('DPU_IFSW_UPDT_PAR_'): dtype = 'TYPE_' + descr.split('_')[-1] for i in range(parameters[0]): parameters.insert(2 + (i * 4), dtype) cmds[seq]['parameters'] = parameters idx += 1 seq += 1 script_cmds = [] for seq in range(1, len(cmds) + 1): data = cmds[seq] if seq < len(cmds): sleep = cmds[seq + 1]['timestamp'] - cmds[seq]['timestamp'] if sleep < 0: print('>>> Negative timestamp difference between commands {} & {} ({:.3f}s)! Setting sleep to 0. <<<'.format (seq, seq + 1, sleep)) sleep = 0 else: sleep = None comment = '# CMD {:d} [{:.6f}]\n'.format(seq, cmds[seq]['timestamp']) script_cmds.append(comment + tc_string(data['DESCR'], data['parameters'], ack=data['ack'], sleep=sleep)) header = "# Commands generated from file: {}\n# IDB v{}.{} used ({})\n".format(fname.split('/')[-1], vmaj, vmin, date) script = header + '# Base header: {}\n\n'.format(base_header) + '\n\n'.join(script_cmds) + '\n' if len(sys.argv) > 2: outfile = sys.argv[2] else: outfile = fname[:-4] + '_CCS.py' with open(outfile, 'w') as fd: fd.write(script) print('Script written to file: ', outfile)