示例#1
0
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
示例#2
0
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
示例#3
0
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()
示例#4
0
文件: datapuller.py 项目: alttch/eva3
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
示例#5
0
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
示例#6
0
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
示例#7
0
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
示例#8
0
文件: extapi.py 项目: alttch/eva3
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
示例#9
0
文件: modbus.py 项目: alttch/eva3
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
示例#10
0
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
示例#11
0
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()
示例#12
0
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()
示例#13
0
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
示例#14
0
文件: controller.py 项目: alttch/eva3
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
示例#15
0
文件: logs.py 项目: GypsyBud/eva3
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
示例#16
0
文件: extapi.py 项目: GypsyBud/eva3
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
示例#17
0
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
示例#18
0
文件: extapi.py 项目: GypsyBud/eva3
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
示例#19
0
文件: sysapi.py 项目: GypsyBud/eva3
    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))
示例#20
0
文件: extapi.py 项目: alttch/eva3
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
示例#21
0
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()
示例#22
0
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()
示例#23
0
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
示例#24
0
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
示例#25
0
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))
示例#26
0
 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')
示例#27
0
文件: logs.py 项目: GypsyBud/eva3
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))
示例#28
0
文件: modbus.py 项目: GypsyBud/eva3
 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]
示例#29
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
示例#30
0
文件: sysapi.py 项目: GypsyBud/eva3
 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