def clone_item(item_id, new_item_id=None, group=None, save=False): i = get_item(item_id) ni = get_item((group + '/') if group else '' + new_item_id) if not i or not new_item_id or i.is_destroyed() or \ i.item_type not in ['unit', 'sensor']: raise ResourceNotFound if ni: raise ResourceAlreadyExists(ni.oid) if group and new_item_id.find('/') != -1: raise InvalidParameter('Group specified but item id contains /') if is_oid(new_item_id): if oid_type(new_item_id) != i.item_type: return InvalidParameter('oids should be equal') _ni = oid_to_id(new_item_id) else: _ni = new_item_id if _ni.find('/') == -1: ni_id = _ni _g = i.group if group is None else group else: ni_id = _ni.split('/')[-1] _g = '/'.join(_ni.split('/')[:-1]) ni = create_item(ni_id, i.item_type, _g, start=False, save=False) cfg = i.serialize(props=True) if 'description' in cfg: del cfg['description'] ni.update_config(cfg) if save: ni.save() ni.start_processors() return ni
def create_item(item_id, item_type, group=None, save=False): if not item_id: raise InvalidParameter('item id not specified') if group and item_id.find('/') != -1: raise InvalidParameter( 'Unable to create item: invalid symbols in ID {}'.format(item_id)) if item_id.find('/') == -1: i = item_id grp = group else: i = item_id.split('/')[-1] grp = '/'.join(item_id.split('/')[:-1]) if not grp: grp = 'nogroup' if not re.match("^[A-Za-z0-9_\.-]*$", i) or \ not re.match("^[A-Za-z0-9_\./-]*$", grp): raise InvalidParameter( 'Unable to create item: invalid symbols in ID {}'.format(item_id)) i_full = grp + '/' + i if (not eva.core.config.enterprise_layout and i in items_by_id) or \ i_full in items_by_full_id: raise ResourceAlreadyExists(get_item(i_full).oid) item = None if item_type == 'LV' or item_type == 'lvar': item = eva.lm.lvar.LVar(i) if not item: return False cfg = {'group': grp} if eva.core.config.mqtt_update_default: cfg['mqtt_update'] = eva.core.config.mqtt_update_default item.update_config(cfg) append_item(item, start=True, load=False) if save: item.save() if item_type == 'LV' or item_type == 'lvar': item.notify() logging.info('created new %s %s' % (item.item_type, item.full_id)) return item
def get_controller(controller_id): if not controller_lock.acquire(timeout=eva.core.config.timeout): logging.critical('controller_lock locking broken') eva.core.critical() return try: if not controller_id: raise InvalidParameter('controller id not specified') if is_oid(controller_id): tp, i = parse_oid(controller_id) else: tp, i = None, controller_id if i.find('/') > -1: i = i.split('/') if len(i) > 2: raise InvalidParameter('controller type unknown') if i[0] == 'uc' and i[1] in remote_ucs and (tp is None or tp == 'remote_uc'): return remote_ucs[i[1]] if i[0] == 'lm' and i[1] in remote_lms and (tp is None or tp == 'remote_lm'): return remote_lms[i[1]] raise ResourceNotFound finally: controller_lock.release()
def create_data_puller(name, cmd, timeout=None, event_timeout=None, save=False): try: if datapullers[name].active: raise FunctionFailed('Data puller exists and is active') except KeyError: pass dp = DataPuller(name, cmd, polldelay=eva.core.config.polldelay, timeout=timeout, event_timeout=event_timeout) datapullers[name] = dp try: dp_destroyed.remove(name) except KeyError: pass if timeout is not None and timeout <= 0: raise InvalidParameter('timeout must be greater than zero') if event_timeout is not None and event_timeout <= 0: raise InvalidParameter('event timeout must be greater than zero') if save: if not eva.core.prepare_save(): raise FunctionFailed('prepare save error') eva.registry.key_set(f'config/uc/datapullers/{name}', { 'cmd': cmd, 'timeout': timeout, 'event-timeout': event_timeout }) if not eva.core.finish_save(): raise FunctionFailed('finish save error') dp.saved = True
def create_cycle(m_id, group=None, save=False): _m_id = oid_to_id(m_id, 'lcycle') if not _m_id: raise InvalidParameter('macro id not specified') if group and _m_id.find('/') != -1: raise InvalidParameter('group specified but cycle id contains /') if _m_id.find('/') == -1: i = _m_id grp = group else: i = _m_id.split('/')[-1] grp = '/'.join(_m_id.split('/')[:-1]) if not grp: grp = 'nogroup' if not re.match("^[A-Za-z0-9_\.-]*$", i) or \ not re.match("^[A-Za-z0-9_\./-]*$", grp): raise InvalidParameter('Invalid symbols in cycle id') i_full = grp + '/' + i if i in cycles_by_id or i_full in cycles_by_full_id: raise ResourceAlreadyExists m = eva.lm.plc.Cycle(i) if grp: m.update_config({'group': grp}) cycles_by_id[i] = m cycles_by_full_id[m.full_id] = m if save: m.save() m.notify() logging.info('cycle "%s" created' % m.full_id) return m
def load_driver(lpi_id, lpi_mod_id, phi_id, lpi_cfg=None, start=True): if get_phi(phi_id) is None: raise ResourceNotFound( 'Unable to load LPI, unknown PHI: {}'.format(phi_id)) if not lpi_id: raise InvalidParameter('LPI id not specified') if not re.match("^[A-Za-z0-9_-]*$", lpi_id): raise InvalidParameter( 'LPI {} id contains forbidden symbols'.format(lpi_id)) try: lpi_mod = importlib.import_module('eva.uc.drivers.lpi.' + lpi_mod_id) # doesn't work but we hope importlib.reload(lpi_mod) _api = lpi_mod.__api__ _author = lpi_mod.__author__ _version = lpi_mod.__version__ _description = lpi_mod.__description__ _license = lpi_mod.__license__ _logic = lpi_mod.__logic__ logging.info('LPI loaded %s v%s, author: %s, license: %s' % (lpi_mod_id, _version, _author, _license)) logging.debug('%s: %s' % (lpi_mod_id, _description)) if _logic == 'abstract': logging.error( 'Unable to activate LPI %s: ' % lpi_mod_id + \ 'abstract module' ) return False if _api > __api__: logging.error( 'Unable to activate LPI %s: ' % lpi_mod_id + \ 'controller driver API version is %s, ' % __api__ + \ 'LPI driver API version is %s' % _api) return False except Exception as e: raise FunctionFailed('unable to load LPI mod {}: {}'.format( lpi_mod_id, e)) lpi = lpi_mod.LPI(lpi_cfg=lpi_cfg, phi_id=phi_id) if not lpi.ready: raise FunctionFailed('unable to init LPI mod %s' % lpi_mod_id) lpi.lpi_id = lpi_id lpi.driver_id = phi_id + '.' + lpi_id lpi.oid = 'driver:uc/%s/%s' % (eva.core.config.system_name, lpi.driver_id) if lpi.driver_id in drivers: try: drivers[lpi.driver_id]._stop() except: eva.core.log_traceback() drivers[lpi.driver_id] = lpi if start: try: lpi._start() except: eva.core.log_traceback() return lpi
def load_phi(phi_id, phi_mod_id, phi_cfg=None, start=True): if not phi_id: raise InvalidParameter('PHI id not specified') if not re.match("^[A-Za-z0-9_-]*$", phi_id): raise InvalidParameter('PHI %s id contains forbidden symbols' % phi_id) try: phi_mod = importlib.import_module('eva.uc.drivers.phi.' + phi_mod_id) # doesn't work but we hope importlib.reload(phi_mod) _api = phi_mod.__api__ _author = phi_mod.__author__ _version = phi_mod.__version__ _description = phi_mod.__description__ _license = phi_mod.__license__ _equipment = phi_mod.__equipment__ logging.info('PHI loaded %s v%s, author: %s, license: %s' % (phi_mod_id, _version, _author, _license)) logging.debug('%s: %s' % (phi_mod_id, _description)) if _equipment == 'abstract': logging.error( 'Unable to activate PHI %s: ' % phi_mod_id + \ 'abstract module' ) raise FunctionFailed('PHI module is abstract') if _api > __api__: logging.error( 'Unable to activate PHI %s: ' % phi_mod_id + \ 'controller driver API version is %s, ' % __api__ + \ 'PHI driver API version is %s' % _api) raise FunctionFailed('unsupported driver API version') except Exception as e: raise FunctionFailed('unable to load PHI mod {}: {}'.format( phi_mod_id, e)) phi = phi_mod.PHI(phi_cfg=phi_cfg) if not phi.ready: raise FunctionFailed('unable to init PHI mod %s' % phi_mod_id) phi.phi_id = phi_id phi.oid = 'phi:uc/%s/%s' % (eva.core.config.system_name, phi_id) if phi_id in phis: try: phis[phi_id]._stop() except: eva.core.log_traceback() phis[phi_id] = phi if not phi_id in items_by_phi: items_by_phi[phi_id] = set() if start: try: phi._start() except: eva.core.log_traceback() ld = phi.get_default_lpi() if ld: load_driver('default', ld, phi_id, start=True) return phi
def load_ext(ext_id, ext_mod_id, cfg=None, start=True, rebuild=True, config_validated=False, _o=None, set_modified=True): if not ext_id: raise InvalidParameter('ext id not specified') if not re.match("^[A-Za-z0-9_-]*$", ext_id): raise InvalidParameter('ext %s id contains forbidden symbols' % ext_id) if _o is None: # import module try: ext_mod = import_x(_get_ext_module_fname(ext_mod_id)) _api = ext_mod.__api__ _author = ext_mod.__author__ _version = ext_mod.__version__ _description = ext_mod.__description__ _license = ext_mod.__license__ _functions = ext_mod.__functions__ logging.info('Extension loaded %s v%s, author: %s, license: %s' % (ext_mod_id, _version, _author, _license)) logging.debug('%s: %s' % (ext_mod_id, _description)) if _api > __api__: logging.error( 'Unable to activate extension %s: ' % ext_mod_id + \ 'controller extension API version is %s, ' % __api__ + \ 'extension API version is %s' % _api) raise FunctionFailed('unsupported ext API version') except Exception as e: raise FunctionFailed('unable to load ext mod {}: {}'.format( ext_mod_id, e)) else: ext_mod = _o.__xmod__ ext = ext_mod.LMExt(cfg=cfg, config_validated=config_validated, _xmod=ext_mod) if not ext.ready: raise FunctionFailed('unable to init ext mod %s' % ext_mod_id) ext.ext_id = ext_id if ext_id in exts: exts[ext_id].stop() exts[ext_id] = ext if set_modified: _d.modified.add(ext_id) ext.load() if start: ext.start() if rebuild: rebuild_env() return ext
def create_modbus_port(port_id, params, **kwargs): """Create new modbus port Args: port_id: port ID params: port params (i.e. tcp:localhost:502, rtu:/dev/ttyS0:9600:8:N:1) lock: should the port be locked, True/False (default: True) timeout: port timeout (default: EVA timeout) delay: delay between operations (default: 0.02 sec) retries: retry attempts for port read/write operations (default: 0) """ try: if not port_id or not re.match(eva.core.ID_ALLOWED_SYMBOLS, port_id): raise InvalidParameter('port id') p = ModbusPort(port_id, params, **kwargs) if not p.client: raise FunctionFailed except InvalidParameter: raise except: raise FunctionFailed( 'Failed to create modbus port {}, params: {}'.format( port_id, params)) else: if port_id in ports: ports[port_id].stop() ports[port_id] = p set_modified(port_id) logging.info('created modbus port {} : {}'.format(port_id, params)) return True
def set_driver_prop(driver_id, p, v): if not p and not isinstance(v, dict): raise InvalidParameter('property not specified') lpi = get_driver(driver_id) if not lpi: raise ResourceNotFound cfg = lpi.lpi_cfg.copy() if p and not isinstance(v, dict): cfg[p] = v else: for prop, value in v.items(): if value is not None and value != '': cfg[prop] = value else: try: del cfg[prop] except: pass if v is None: del cfg[p] lpi.validate_config(cfg, config_type='config') lpi = load_driver(lpi.lpi_id, lpi.lpi_mod_id, lpi.phi_id, cfg, start=True, config_validated=True, _o=lpi) if lpi: return True
def get_controller(controller_id): controller_lock.acquire() try: _controller_id = oid_to_id(controller_id, 'remote_uc') if not _controller_id: raise InvalidParameter('controller id not specified') if _controller_id.find('/') > -1: i = _controller_id.split('/') if len(i) > 2 or i[0] != 'uc': raise InvalidParameter('controller type unknown') if i[1] in remote_ucs: return remote_ucs[i[1]] else: if _controller_id in remote_ucs: return remote_ucs[_controller_id] raise ResourceNotFound finally: controller_lock.release()
def remove_controller(controller_id): _controller_id = oid_to_id(controller_id, 'remote_uc') if not _controller_id: raise InvalidParameter('controller id not specified') if _controller_id.find('/') != -1: _controller_id = _controller_id.split('/')[-1] if _controller_id not in remote_ucs: raise ResourceNotFound controller_lock.acquire() try: i = remote_ucs[_controller_id] i.destroy() if eva.core.config.db_update == 1 and i.config_file_exists: try: os.unlink(i.get_fname()) except: logging.error('Can not remove controller %s config' % \ _controller_id) eva.core.log_traceback() elif i.config_file_exists: configs_to_remove.add(i.get_fname()) del (remote_ucs[_controller_id]) logging.info('controller %s removed' % _controller_id) return True except Exception as e: eva.core.log_traceback() raise FunctionFailed(e) finally: controller_lock.release()
def create_owfs_bus(bus_id, location, **kwargs): """Create new owfs bus Args: bus_id: bus ID location: bus location (e.g. --i2c=/dev/i2c-1:ALL or localhost:4302 for owfs server) lock: should bus be locked, True/False (default: True) timeout: bus timeout (default: EVA timeout) delay: delay between operations (default: 0.02 sec) retries: retry attempts for bus read/write operations (default: 0) """ try: if not bus_id or not re.match(eva.core.ID_ALLOWED_SYMBOLS, bus_id): raise InvalidParameter('bus id') bus = OWFSBus(bus_id, location, **kwargs) if not bus._ow: raise FunctionFailed except InvalidParameter: raise except: raise FunctionFailed( 'Failed to create owfs bus {}, location: {}'.format( bus_id, location)) else: if bus_id in owbus: owbus[bus_id].stop() owbus[bus_id] = bus set_modified(bus_id) logging.info('owfs bus {} : {}'.format(bus_id, location)) return True
def create_item(item_id, item_type, group=None, start=True, create=False, save=False): if not item_id: raise InvalidParameter('item id not specified') if group and item_id.find('/') != -1: raise InvalidParameter( 'Unable to create item: invalid symbols in ID {}'.format(item_id)) if item_id.find('/') == -1: i = item_id grp = group else: i = item_id.split('/')[-1] grp = '/'.join(item_id.split('/')[:-1]) if not grp: grp = 'nogroup' if not re.match(eva.core.OID_ALLOWED_SYMBOLS, i) or \ not re.match(eva.core.GROUP_ALLOWED_SYMBOLS, grp): raise InvalidParameter( 'Unable to create item: invalid symbols in ID {}'.format(item_id)) i_full = grp + '/' + i if (not eva.core.config.enterprise_layout and i in items_by_id) or \ i_full in items_by_full_id: raise ResourceAlreadyExists(get_item(i_full).oid) item = None if item_type == 'U' or item_type == 'unit': item = eva.uc.unit.Unit(i, create=create) elif item_type == 'S' or item_type == 'sensor': item = eva.uc.sensor.Sensor(i, create=create) elif item_type == 'MU' or item_type == 'mu': item = eva.uc.ucmu.UCMultiUpdate(i) if not item: raise FunctionFailed cfg = {'group': grp} if eva.core.config.mqtt_update_default: cfg['mqtt_update'] = eva.core.config.mqtt_update_default item.update_config(cfg) append_item(item, start=start) if save: item.save() logging.info('created new %s %s' % (item.item_type, item.full_id)) return item
def get_log_level_by_id(l): level = None if isinstance(l, str): lv = l.lower() if lv in log_levels_by_name: return lv else: level = log_levels_by_id(l) if not level: raise InvalidParameter('Invalid log level specified: {}'.format(l)) return level
def load_ext(ext_id, ext_mod_id, cfg=None, start=True, rebuild=True): if not ext_id: raise InvalidParameter('ext id not specified') if not re.match("^[A-Za-z0-9_-]*$", ext_id): raise InvalidParameter('ext %s id contains forbidden symbols' % ext_id) try: ext_mod = importlib.import_module('eva.lm.extensions.' + ext_mod_id) importlib.reload(ext_mod) _api = ext_mod.__api__ _author = ext_mod.__author__ _version = ext_mod.__version__ _description = ext_mod.__description__ _license = ext_mod.__license__ _functions = ext_mod.__functions__ logging.info('Extension loaded %s v%s, author: %s, license: %s' % (ext_mod_id, _version, _author, _license)) logging.debug('%s: %s' % (ext_mod_id, _description)) if not _functions: logging.error( 'Unable to activate extension %s: ' % ext_mod_id + \ 'does not provide any functions' ) raise FunctionFailed('ext module does not provide any functions') if _api > __api__: logging.error( 'Unable to activate extension %s: ' % ext_mod_id + \ 'controller extension API version is %s, ' % __api__ + \ 'extension API version is %s' % _api) raise FunctionFailed('unsupported ext API version') except Exception as e: raise FunctionFailed('unable to load ext mod {}: {}'.format( ext_mod_id, e)) ext = ext_mod.LMExt(cfg=cfg) if not ext.ready: raise FunctionFailed('unable to init ext mod %s' % ext_mod_id) ext.ext_id = ext_id if ext_id in exts: exts[ext_id].stop() exts[ext_id] = ext if start: ext.start() if rebuild: rebuild_env() return ext
def destroy_macro_function(fname): if not re.match("^[A-Za-z0-9_-]*$", fname): raise InvalidParameter( 'Unable to destroy function: invalid symbols in ID {}'.format( fname)) file_name = '{}/lm/functions/{}'.format(eva.core.dir_xc, fname) if file_name in macro_functions_m: del macro_functions_m[file_name] eva.lm.plc.remove_macro_function(file_name) if not eva.core.prepare_save(): raise FunctionFailed os.unlink(file_name) eva.core.finish_save() return True else: raise ResourceNotFound
def set_ext_prop(ext_id, p, v): if not p and not isinstance(v, dict): raise InvalidParameter('property not specified') ext = get_ext(ext_id) if not ext: raise ResourceNotFound cfg = ext.cfg mod_id = ext.mod_id if p and not isinstance(v, dict): cfg[p] = v else: cfg.update(v) if v is None: del cfg[p] ext = load_ext(ext_id, mod_id, cfg) if ext: exts[ext_id] = ext return True
def user_set(self, **kwargs): """ .set user property Args: k: .master .u: user login p: property (password or key) v: value """ u, p, v = parse_api_params(kwargs, 'upv', 'SSS') tokens.remove_token(user=u) if p == 'password': return eva.users.set_user_password(u, v) elif p == 'key': return eva.users.set_user_key(u, v) else: raise InvalidParameter('Property unknown: {}'.format(p))
def set_ext_prop(ext_id, p, v): if not p and not isinstance(v, dict): raise InvalidParameter('property not specified') ext = get_ext(ext_id) if not ext: raise ResourceNotFound cfg = ext.cfg.copy() mod_id = ext.mod_id if p and not isinstance(v, dict): cfg[p] = v else: cfg.update(v) if v is None: del cfg[p] ext.validate_config(cfg, config_type='config') ext = load_ext(ext_id, mod_id, cfg, config_validated=True, _o=ext) if ext: return True
def put_phi_mod(mod, content, force=False): if mod.find('/') != -1: raise InvalidParameter('Invalid module file name') if mod == 'generic_phi': raise ResourceAlreadyExists('generic PHI can not be overriden') fname = '{}/drivers/phi/{}.py'.format(eva.core.dir_xc, mod) if os.path.isfile(fname) and not force: raise ResourceAlreadyExists('PHI module {}'.format(fname)) valid = False try: compile(content, fname, 'exec') try: eva.core.prepare_save() with open(fname, 'w') as fd: fd.write(content) eva.core.finish_save() except Exception as e: raise FunctionFailed('Unable to put PHI module {}: {}'.format( fname, e)) d = {} code = 'from eva.uc.drivers.phi.%s import PHI;' % mod + \ ' s=PHI(info_only=True).serialize(full=True)' exec(code, d) if 's' not in d or 'mod' not in d['s']: raise FunctionFailed('Unable to verify module') valid = True return True except FunctionFailed: raise except: raise FunctionFailed( 'Unable to check PHI module {}, invalid module code'.format(mod)) finally: if not valid: try: eva.core.prepare_save() os.unlink(fname) eva.core.finish_save() except: logging.warning( 'Unable to delete invalid module {}'.format(fname)) eva.core.log_traceback()
def put_phi_mod(mod, content, force=False): if mod.find('/') != -1: raise InvalidParameter('Invalid module file name') if mod == 'generic_phi': raise ResourceAlreadyExists('generic PHI can not be overriden') fname = _get_phi_module_fname(mod) if os.path.isfile(fname) and not force: raise ResourceAlreadyExists('PHI module {}'.format(fname)) valid = False try: # verify code compilation compile(content, fname, 'exec') # save module code try: eva.core.prepare_save() with open(fname, 'w') as fd: fd.write(content) eva.core.finish_save() except Exception as e: raise FunctionFailed('Unable to put PHI module {}: {}'.format( fname, e)) # verify saved module if 'mod' not in serialize_x(fname, 'PHI', full=True): raise FunctionFailed('Unable to verify module') valid = True return True except FunctionFailed: raise except: raise FunctionFailed( 'Unable to check PHI module {}, invalid module code'.format(mod)) finally: if not valid: try: eva.core.prepare_save() os.unlink(fname) eva.core.finish_save() except: logging.warning( 'Unable to delete invalid module {}'.format(fname)) eva.core.log_traceback()
def set_phi_prop(phi_id, p, v): if not p and not isinstance(v, dict): raise InvalidParameter('property not specified') phi = get_phi(phi_id) if not phi: raise ResourceNotFound cfg = phi.phi_cfg phi_mod_id = phi.phi_mod_id if p and not isinstance(v, dict): cfg[p] = v else: for prop, value in v.items(): if value is not None and value != '': cfg[prop] = value else: try: del cfg[prop] except: pass if v is None: del cfg[p] phi = load_phi(phi_id, phi_mod_id, cfg, start=True) if phi: phis[phi_id] = phi return True
def reload_macro_function(file_name=None, fname=None, rebuild=True): if file_name is None and fname: if not re.match("^[A-Za-z0-9_-]*$", fname): raise InvalidParameter( 'Unable to reload function: invalid symbols in ID {}'.format( fname)) file_name = '{}/lm/functions/{}.py'.format(eva.core.dir_xc, fname) if file_name is None: logging.info('Loading macro functions') fncs = [] for f in glob.glob('{}/lm/functions/*.py'.format(eva.core.dir_xc)): fncs.append(f) reload_macro_function(f, rebuild=False) for f in macro_functions_m.copy().keys(): if f not in fncs: del macro_functions_m[f] eva.lm.plc.remove_macro_function(f, rebuild=False) if rebuild: eva.lm.plc.rebuild_mfcode() else: logging.info('Loading macro function {}'.format(file_name if file_name else fname)) if file_name in macro_functions_m: omtime = macro_functions_m[file_name] else: omtime = None try: mtime = os.path.getmtime(file_name) except: raise FunctionFailed('File not found: {}'.format(file_name)) try: eva.lm.plc.append_macro_function(file_name, rebuild=rebuild) macro_functions_m[file_name] = mtime except: eva.core.log_traceback() return False return True
def put_macro_function(fname=None, fdescr=None, i={}, o={}, fcode=None): try: if isinstance(fcode, dict): pcode = eva.lm.plc.compile_macro_function_fbd(fcode) fn = fcode['function'] else: if not fname: raise InvalidParameter('Function name not specified') pcode = eva.lm.plc.prepare_macro_function_code( fcode, fname, fdescr, i, o) fn = fname file_name = eva.core.format_xc_fname(fname='functions/{}.py'.format(fn)) if not isinstance(fcode, dict): compile(pcode, file_name, 'exec') except Exception as e: eva.core.log_traceback() raise FunctionFailed('Function compile failed: {}'.format(e)) try: eva.core.prepare_save() with open(file_name, 'w') as f: if isinstance(fcode, dict): f.write('# FBD\n') f.write('# auto generated code, do not modify\n') f.write('"""\n{}\n"""\n{}\n'.format( rapidjson.dumps(fcode), pcode)) else: f.write(pcode) eva.core.finish_save() if not reload_macro_function(fname=fn): raise FunctionFailed return fn except FunctionFailed: raise except Exception as e: eva.core.log_traceback() raise FunctionFailed('Function write failed: {}'.format(e))
def validate_config(self, config={}, config_type='config'): self.validate_config_whi(config=config, config_type=config_type) if 'taglist' in config and not os.path.isfile(config['taglist']): raise InvalidParameter('taglist file not found')
def get_log_level_by_name(l): for k, v in log_levels_by_name.items(): if l == k[:len(l)]: return v raise InvalidParameter('Invalid log level specified: {}'.format(l))
def __init__(self, port_id, params, **kwargs): self.port_id = port_id self.lock = kwargs.get('lock', True) self.lock = True if self.lock else False try: self.timeout = float(kwargs.get('timeout')) self._timeout = self.timeout except: self.timeout = eva.core.config.timeout - 1 self._timeout = None if self.timeout < 1: self.timeout = 1 try: self.delay = float(kwargs.get('delay')) except: self.delay = default_delay try: self.retries = int(kwargs.get('retries')) except: self.retries = 0 self.tries = self.retries + 1 if self.tries < 0: self.tries = 1 self.params = params self.client = None self.client_type = None self.locker = threading.Lock() self.last_action = 0 try: modbus_client = importlib.import_module('pymodbus.client.sync') except: logging.error('Unable to import pymodbus module') raise if params: p = params.split(':') if p[0] in ['tcp', 'udp']: try: host = p[1] try: port = int(p[2]) except: port = 502 if p[0] == 'tcp': self.client = modbus_client.ModbusTcpClient(host, port) else: self.client = modbus_client.ModbusUdpClient(host, port) self.client.timeout = self.timeout except: eva.core.log_traceback() elif p[0] in ['rtu', 'ascii', 'binary']: port = p[1] speed = int(p[2]) bits = int(p[3]) parity = p[4] stopbits = int(p[5]) if bits < 5 or bits > 9: raise InvalidParameter('bits not in range 5..9') if parity not in ['N', 'E', 'O', 'M', 'S']: raise InvalidParameter('parity should be: N, E, O, M or S') if stopbits < 1 or stopbits > 2: raise InvalidParameter('stopbits not in range 1..2') self.client = modbus_client.ModbusSerialClient( method=p[0], port=port, stopbits=stopbits, parity=parity, baudrate=speed) if self.client: self.client_type = p[0]
def validate_config_whi(self, config=None, config_type='config', allow_extra=False, ignore_private=False, xparams=[]): """ Validate config with module help info Help info: module help info variable (e.g. __config_help__ for config) Args: config: config to validate config_type: config type (help var to parse, default is 'config') allow_extra: allow any extra params in config xparams: list of allowed extra params Returns: True if config is validated. Config dict variables are automatically parsed and converted to the required types (except extra params if not listed) Raises: eva.exceptions.InvalidParameter: if configuration is invalid """ if config is None: config = {} def _convert_type(v, type_required): if type_required == 'any': return v from pyaltt2.converters import val_to_boolean from pyaltt2.converters import safe_int if type_required == 'bool': value = val_to_boolean(v) if value is None: raise ValueError else: return value elif type_required == 'str': return str(v) elif type_required == 'url': v = str(v) if v.startswith('http://') or v.startswith('https://'): return v else: raise ValueError elif type_required == 'int': return safe_int(v) elif type_required == 'uint': v = safe_int(v) if v < 0: raise ValueError else: return v elif type_required == 'hex': return int(v, 16) elif type_required == 'bin': return int(v, 2) elif type_required == 'float': return float(v) elif type_required == 'ufloat': v = float(v) if v < 0: raise ValueError else: return v elif type_required.startswith('list:'): type_required = type_required.split(':', 1)[1] for i, val in enumerate(v): v[i] = _convert_type(val, type_required) return v elif type_required.startswith('enum:'): _, type_required, values = type_required.split(':', 2) values = [ _convert_type(x, type_required) for x in values.split(',') ] v = _convert_type(v, type_required) if v not in values: raise ValueError else: return v else: err = f'Unsupported value type required: "{type_required}"' self.log_error(err) raise TypeError(err) help_array = getattr(self, f'_{config_type}_help').copy() help_array += xparams help_info = {v['name']: v for v in help_array} required_list = [v['name'] for v in help_array if v.get('required')] defaults = { v['name']: v['default'] for v in help_array if v.get('required') and 'default' in v } errors = [] for i in required_list: if i not in config: if i in defaults: config[i] = defaults[i] else: errors.append(f'required param "{i}" is missing') for i, v in config.items(): if i in help_info: try: type_required = help_info[i].get('type', 'any') config[i] = _convert_type(v, type_required) except: from eva.core import log_traceback log_traceback() errors.append('invalid param ' f'value {i}="{v}" should be {type_required}') elif not allow_extra and (ignore_private is False or not i.startswith('_')): errors.append(f'param "{i}" is not allowed') if errors: raise InvalidParameter(', '.join(errors)) else: return True
def _check_file_name(fname): if fname is None or \ fname[0] == '/' or \ fname.find('..') != -1: raise InvalidParameter('File name contains invalid characters') return True