Example #1
0
File: plc.py Project: GypsyBud/eva3
 def set_prop(self, prop, val=None, save=False):
     if prop == 'pass_errors':
         v = val_to_boolean(val)
         if v is not None:
             if self.api.pass_errors != v:
                 self.api.pass_errors = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'send_critical':
         v = val_to_boolean(val)
         if v is not None:
             if self.api.send_critical != v:
                 self.api.send_critical = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'src':
         if isinstance(val, str):
             code = val
         elif isinstance(val, dict):
             try:
                 v = val.copy()
                 if 'name' in v:
                     del v['name']
                 code = '# SFC\n# auto generated code, ' + \
                         'do not modify\n"""\n{}\n"""\n'.format(
                     rapidjson.dumps(v)) + compile_macro_sfc(val)
             except Exception as e:
                 logging.error(
                     'Unable to compile macro source for {}: {}'.format(
                         self.oid, e))
                 return False
         else:
             return False
         try:
             file_name = eva.core.format_xc_fname(
                 fname=self.action_exec if self.action_exec else '{}.py'.
                 format(self.item_id))
             eva.core.prepare_save()
             with open(file_name, 'w') as fd:
                 fd.write(code)
             eva.core.finish_save()
             return True
         except FunctionFailed:
             raise
         except Exception as e:
             logging.error('Unable to write macro source for {}: {}'.format(
                 self.oid, e))
             return False
     return super().set_prop(prop, val, save)
Example #2
0
def update_config(cfg):
    try:
        host = cfg.get('msad/host')
    except LookupError:
        return
    logging.debug(f'msad.host = {host}')
    domain = cfg.get('msad/domain', default='')
    logging.debug(f'msad.domain = {domain}')
    ca = cfg.get('msad/ca', default=None)
    logging.debug(f'msad.ca = {ca}')
    key_prefix = cfg.get('msad/key-prefix', default=None)
    logging.debug(f'msad.key_prefix = {key_prefix}')
    ou = cfg.get('msad/ou', default=_d.msad_ou)
    logging.debug(f'msad.ou = {ou}')
    try:
        cache_time = float(cfg.get('msad/cache-time'))
    except:
        cache_time = 86400
    logging.debug(f'msad.cache_time = {cache_time}')
    try:
        cache_first = val_to_boolean(cfg.get('msad/cache-first'))
        if cache_first is None:
            raise ValueError
    except:
        cache_first = False
    logging.debug(f'msad.cache_first = {cache_first}')
    msad_init(host, domain, ca, key_prefix, ou, cache_time, cache_first)
Example #3
0
def load_keys_from_db():
    _keys = {}
    _keys_by_id = {}
    dbconn = userdb()
    meta = sa.MetaData()
    t_apikeys = sa.Table('apikeys', meta,
                         sa.Column('k_id', sa.String(64), primary_key=True),
                         sa.Column('k', sa.String(64)),
                         sa.Column('m', sa.Integer),
                         sa.Column('s', sa.Integer),
                         sa.Column('i', sa.String(1024)),
                         sa.Column('g', sa.String(1024)),
                         sa.Column('i_ro', sa.String(1024)),
                         sa.Column('g_ro', sa.String(1024)),
                         sa.Column('a', sa.String(256)),
                         sa.Column('hal', sa.String(1024)),
                         sa.Column('has', sa.String(1024)),
                         sa.Column('pvt', sa.String(1024)),
                         sa.Column('rpvt', sa.String(1024)))
    try:
        meta.create_all(dbconn)
    except:
        logging.critical('unable to create apikeys table in db')
        return _keys, _keys_by_id
    try:
        result = dbconn.execute(sql('select * from apikeys'))
        while True:
            r = result.fetchone()
            if not r: break
            key = APIKey(r.k, r.k_id)
            key.sysfunc = True if val_to_boolean(r.s) else False
            for i, v in {
                    'item_ids': 'i',
                    'groups': 'g',
                    'item_ids_ro': 'i_ro',
                    'groups_ro': 'g_ro',
                    'allow': 'a',
                    'pvt_files': 'pvt',
                    'rpvt_uris': 'rpvt'
            }.items():
                setattr(
                    key, i,
                    list(filter(None, [j.strip() for j in r[v].split(',')])))
            _hosts_allow = list(
                filter(None, [j.strip() for j in r.hal.split(',')]))
            key.hosts_allow = [IPNetwork(h) for h in _hosts_allow]
            _hosts_assign = list(
                filter(None, [x.strip() for x in r.has.split(',')]))
            key.hosts_assign = \
                    [ IPNetwork(h) for h in _hosts_assign ]
            key.dynamic = True
            key.in_db = True
            _keys[key.key] = key
            _keys_by_id[key.key_id] = key
    except:
        eva.core.report_userdb_error(raise_exeption=False)
    return _keys, _keys_by_id
Example #4
0
 def __init__(self, **kwargs):
     self.ports = self.phi_cfg.get('port')
     self.no_pullup = val_to_boolean(self.phi_cfg.get('no_pullup'))
     self.devices = []
     try:
         self.gpiozero = importlib.import_module('gpiozero')
     except:
         self.log_error('gpiozero python module not found')
         self.ready = False
         return
Example #5
0
 def __init__(self, **kwargs):
     self.host = self.phi_cfg.get('host')
     self.pw = self.phi_cfg.get('pw')
     # set logout='skip' to speed up the operations
     # but keep device bound to UC ip address
     self.skip_logout = val_to_boolean(self.phi_cfg.get('skip_logout'))
     self.re_ss = re.compile('sockstates = \[([01,]+)\]')
     if not self.host or not self.pw:
         self.ready = False
     self.lock = threading.Lock()
Example #6
0
File: jobs.py Project: alttch/eva3
 def set_prop(self, prop, val=None, save=False):
     if prop == 'enabled':
         v = val_to_boolean(val)
         if v is not None:
             if self.enabled != v:
                 self.enabled = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'macro':
         if self.macro != val:
             self.macro = val
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'every':
         if self.every_set != val:
             self.every_set = val
             self.log_set(prop, val)
             self.set_modified(save)
             self.reschedule()
         return True
     elif prop == 'macro_args':
         if val is not None:
             if isinstance(val, list):
                 v = val
             elif isinstance(val, tuple):
                 v = list(val)
             else:
                 try:
                     v = shlex.split(val)
                 except:
                     v = val.split(' ')
         else:
             v = []
         self.macro_args = v
         self.log_set(prop, val)
         self.set_modified(save)
         return True
     elif prop == 'macro_kwargs':
         if val is None:
             self.macro_kwargs = {}
         else:
             self.macro_kwargs = dict_from_str(val)
         self.log_set(prop, val)
         self.set_modified(save)
         return True
     return super().set_prop(prop, val, save)
Example #7
0
def write_bool(port, reg, values, **kwargs):
    """
    Write boolean values

    Args:
        values: a single boolean, list of boolean, list of strings or list of
                integers
    """
    reg_type, addr = _parse_reg(reg)
    if not isinstance(values, list) and not isinstance(values, tuple):
        values = [values]
    values = [val_to_boolean(x) for x in values]
    if reg_type == 'c':
        result = port.write_coils(addr, values, **kwargs)
    else:
        raise ValueError(f'Method not supported for register type {reg_type}')
    if result.isError():
        raise RuntimeError('Modbus I/O error')
    else:
        return True
Example #8
0
 def __init__(self, **kwargs):
     # skip - skip sensor errors (log error and continue)
     # otherwise if one sensor in a group failed, stop polling others
     #
     # may be overriden with skip_errors param in a state request cfg
     self.skip_err = val_to_boolean(self.lpi_cfg.get('skip_err'))
     # when polling a sensor group
     # avg - return avg sensor value
     # max - return max sensor value
     # min - return min sensor value
     # first - return first sensor value unless it's failed
     #
     # may be overriden with gpf param in a state request cfg
     self.gpf = self.lpi_cfg.get('gpf') if \
             self.lpi_cfg.get('gpf') is not None else 'avg'
     # when polling a sensor group, mark sensor as broken if its value is
     # different from avg on max_diff. Setting variable to 'skip' disables
     # this feature
     try:
         self.max_diff = float(self.lpi_cfg.get('max_diff'))
     except:
         self.max_diff = None
Example #9
0
 def PATCH(self, rtp, k, ii, save, kind, method, for_dir, props):
     if rtp == 'cvar':
         return self.set_cvar(k=k, i=ii, **props)
     elif rtp == 'core':
         success = False
         if 'debug' in props:
             if not self.set_debug(k=k, debug=props['debug']):
                 raise FunctionFailed
             success = True
         if 'setup' in props:
             if not self.setup_mode(k=k, setup=props['setup']):
                 raise FunctionFailed
             success = True
         if success: return True
         else: raise ResourceNotFound
     elif rtp == 'key':
         for i, v in props.items():
             if not SysAPI.set_key_prop(
                     self, k=k, i=ii, p=i, v=v, save=save):
                 raise FunctionFailed
         return True
     elif rtp == 'notifier':
         if not 'enabled' in props:
             raise FunctionFailed
         return self.enable_notifier(k=k, i=ii) if val_to_boolean(
             props.get('enabled')) else self.disable_notifier(k=k, i=ii)
     elif rtp == 'runtime':
         m, e = parse_api_params(props, 'me', '.b')
         if m is not None:
             SysAPI.file_put(self, k=k, i=ii, m=m)
         if e is not None:
             self.file_set_exec(k=k, i=ii, e=e)
         return True
     elif rtp == 'user':
         for p, v in props.items():
             if not self.user_set(k=k, u=ii, p=p, v=v):
                 return False
         return True
     raise MethodNotFound
Example #10
0
 def set_prop(self, prop, value=None, save=False):
     with key_lock:
         if not self.dynamic or self.master:
             raise FunctionFailed(
                 'Master and static keys can not be changed')
         if prop == 'key':
             if value is None or value == '' or value.find(
                     ':') != -1 or value.find('|') != -1:
                 return False
             if self.key != value:
                 if value in keys:
                     raise ResourceAlreadyExists('API key')
                 regenerate_key(self.key_id, k=value, save=False)
                 self.set_modified(save)
             return True
         elif prop == 'dynamic':
             return False
         elif prop == 'sysfunc':
             val = val_to_boolean(value)
             if val is None:
                 return False
             if self.sysfunc != val:
                 self.sysfunc = val
                 self.set_modified(save)
             return True
         elif prop == 'items':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.item_ids != val:
                 self.item_ids = val
                 self.set_modified(save)
             return True
         elif prop == 'groups':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.groups != val:
                 self.groups = val
                 self.set_modified(save)
             return True
         elif prop == 'items_ro':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.item_ids_ro != val:
                 self.item_ids_ro = val
                 self.set_modified(save)
             return True
         elif prop == 'groups_ro':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.groups_ro != val:
                 self.groups_ro = val
                 self.set_modified(save)
             return True
         elif prop == 'items_deny':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.item_ids_deny != val:
                 self.item_ids_deny = val
                 self.set_modified(save)
             return True
         elif prop == 'groups_deny':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.groups_deny != val:
                 self.groups_deny = val
                 self.set_modified(save)
             return True
         elif prop == 'allow':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             for v in val:
                 if v not in all_allows:
                     return False
             if self.allow != val:
                 self.allow = val
                 self.set_modified(save)
             return True
         elif prop == 'hosts_allow':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = ['0.0.0.0/0']
             val = [IPNetwork(h) for h in val]
             if self.hosts_allow != val:
                 self.hosts_allow = val
                 self.set_modified(save)
             return True
         elif prop == 'hosts_assign':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             val = [IPNetwork(h) for h in val]
             if self.hosts_assign != val:
                 self.hosts_assign = val
                 self.set_modified(save)
             return True
         elif prop == 'pvt':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.pvt_files != val:
                 self.pvt_files = val
                 self.set_modified(save)
             return True
         elif prop == 'rpvt':
             if isinstance(value, list):
                 val = value
             else:
                 if value:
                     val = value.split(',')
                 else:
                     val = []
             if self.rpvt_uris != val:
                 self.rpvt_uris = val
                 self.set_modified(save)
             return True
         elif prop == 'cdata':
             val = [] if value is None else value
             if isinstance(val, str):
                 val = val.split(',')
             res = []
             for v in val:
                 if v not in res:
                     res.append(str(v))
             if self.cdata != res:
                 self.cdata = res
                 self.set_modified(save)
             return True
         raise ResourceNotFound('property ' + prop)
Example #11
0
 def __init__(self, **kwargs):
     self.bose = val_to_boolean(self.lpi_cfg.get('bose'))
     logic = self.lpi_cfg.get('logic')
     if logic and logic not in ['default', 'rdc']:
         raise Exception('logic not supported: {}'.format(logic))
     self.logic_rdc = logic == 'rdc'
Example #12
0
File: unit.py Project: alttch/eva3
 def set_prop(self, prop, val=None, save=False):
     if prop == 'action_exec':
         if self.action_exec != val:
             if val and val[0] == '|':
                 d = eva.uc.driverapi.get_driver(val[1:])
                 if not d:
                     logging.error(
                         'Can not set ' + \
                             '%s.action_exec = %s, no such driver'
                             % (self.oid, val))
                     return False
             self.action_exec = val
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'action_driver_config':
         if val is None:
             self.action_driver_config = None
             self.log_set(prop, None)
             self.set_modified(save)
             return True
         else:
             try:
                 v = dict_from_str(val)
             except:
                 eva.core.log_traceback()
                 return False
             self.action_driver_config = v
             self.log_set(prop, 'dict')
             self.set_modified(save)
             return True
     elif prop == 'modbus_status':
         if self.modbus_status == val:
             return True
         if val is None:
             self.unregister_modbus_status_updates()
             self.modbus_status = None
         else:
             if val[0] not in ['h', 'c']:
                 return False
             try:
                 addr = safe_int(val[1:])
                 if addr > eva.uc.modbus.slave_reg_max or addr < 0:
                     return False
             except:
                 return False
             self.unregister_modbus_status_updates()
             self.modbus_status = val
             self.modbus_update_status(addr,
                                       eva.uc.modbus.get_data(addr, val[0]))
             self.register_modbus_status_updates()
         self.log_set('modbus_status', val)
         self.set_modified(save)
         return True
     elif prop == 'action_always_exec':
         v = val_to_boolean(val)
         if v is not None:
             if self.action_always_exec != v:
                 self.action_always_exec = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'update_exec_after_action':
         v = val_to_boolean(val)
         if v is not None:
             if self.update_exec_after_action != v:
                 self.update_exec_after_action = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'update_state_after_action':
         v = val_to_boolean(val)
         if v is not None:
             if self.update_state_after_action != v:
                 self.update_state_after_action = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'update_if_action':
         v = val_to_boolean(val)
         if v is not None:
             if self.update_if_action != v:
                 self.update_if_action = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'auto_off':
         if val is None:
             auto_off = 0
         else:
             try:
                 auto_off = float(val)
             except:
                 return False
         if auto_off < 0:
             return False
         if self.auto_off != auto_off:
             self.auto_off = auto_off
             self.log_set(prop, auto_off)
             self.set_modified(save)
             if self.auto_off == 0:
                 self.stop_auto_processor()
             else:
                 self.start_auto_processor()
         return True
     elif prop == 'status_labels' and isinstance(val, dict):
         self.status_labels = val
         self.log_set(prop, 'dict')
         self.set_modified(save)
         self.ieid = eva.core.generate_ieid()
         return True
     elif prop[:7] == 'status:':
         try:
             s = int(prop.split(':')[1])
         except:
             return False
         s = str(s)
         if s == '0' and (val is None or val == ''):
             if self.status_labels['0'] != status_label_off:
                 self.status_labels['0'] = status_label_off
                 self.log_set('status_labels[0]', status_label_off)
                 self.set_modified(save)
                 self.ieid = eva.core.generate_ieid()
         elif s == '1' and (val is None or val == ''):
             if self.status_labels['1'] != status_label_on:
                 self.status_labels['1'] = status_label_on
                 self.log_set('status_labels[1]', status_label_on)
                 self.set_modified(save)
                 self.ieid = eva.core.generate_ieid()
         elif val is not None and val != '':
             if not s in self.status_labels or self.status_labels[s] != val:
                 self.status_labels[s] = val
                 self.log_set('status_labels[' + s + ']', val)
                 self.set_modified(save)
                 self.ieid = eva.core.generate_ieid()
         else:
             if not s in self.status_labels:
                 return False
             del self.status_labels[s]
             self.set_modified(save)
             self.ieid = eva.core.generate_ieid()
         return True
     else:
         return super().set_prop(prop, val, save)
Example #13
0
 def set_prop(self, prop, val=None, save=False):
     if prop == 'maintenance_duration':
         if val:
             try:
                 v = float(val)
                 if v < 0:
                     raise Exception
             except:
                 return False
         else:
             v = 0
         if self.maintenance_duration != v:
             self.maintenance_duration = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'update_exec':
         if self.update_exec != val:
             if val and val[0] == '|':
                 d = eva.uc.driverapi.get_driver(val[1:])
                 if not d:
                     logging.error(
                         'Can not set ' + \
                             '%s.update_exec = %s, no such driver'
                             % (self.oid, val))
                     return False
             if not val:
                 self.unregister_driver_updates()
             self.update_exec = val
             self.log_set(prop, val)
             self.set_modified(save)
             self.register_driver_updates()
         return True
     elif prop == 'update_driver_config':
         if val is None:
             self.update_driver_config = None
             self.log_set(prop, None)
             self.set_modified(save)
             return True
         else:
             try:
                 v = dict_from_str(val)
             except:
                 eva.core.log_traceback()
                 return False
             self.update_driver_config = v
             self.log_set(prop, 'dict')
             self.set_modified(save)
             return True
     elif prop == 'modbus_value':
         if self.modbus_value == val:
             return True
         if val is None:
             self.unregister_modbus_value_updates()
             self.modbus_value = None
         else:
             reg, addr, multiplier, signed = format_modbus_value(val)
             if reg is None or addr is None or multiplier is None:
                 return False
             self.unregister_modbus_value_updates()
             self.modbus_value = val
             self.modbus_value_reg = reg
             self.modbus_value_addr = addr
             self.modbus_value_multiplier = multiplier
             self.modbus_value_signed = signed
             self.modbus_update_value(addr,
                                      eva.uc.modbus.get_data(addr, reg))
             self.register_modbus_value_updates()
         self.log_set('modbus_value', val)
         self.set_modified(save)
         return True
     elif prop == 'snmp_trap':
         if val is None:
             self.snmp_trap = None
             self.unsubscribe_snmp_traps()
             self.log_set(prop, None)
             self.set_modified(save)
             return True
         elif isinstance(val, dict):
             self.snmp_trap = val
             self.subscribe_snmp_traps()
             self.log_set('snmp_trap', 'dict')
             self.set_modified(save)
             return True
         return False
     elif prop == 'snmp_trap.ident_vars':
         if val is None:
             if self.snmp_trap and 'ident_vars' in self.snmp_trap:
                 del self.snmp_trap['ident_vars']
                 if not self.snmp_trap:
                     self.unsubscribe_snmp_traps()
                 self.log_set('snmp_trap.ident_vars', None)
                 self.set_modified(save)
             return True
         else:
             ivars = {}
             try:
                 for x in val.split(','):
                     k, v = x.split('=')
                     ivars[k] = v
             except:
                 return False
             if not self.snmp_trap:
                 self.snmp_trap = {}
             self.snmp_trap['ident_vars'] = ivars
             self.subscribe_snmp_traps()
             self.log_set('snmp_trap.ident_vars', val)
             self.set_modified(save)
             return True
     elif prop == 'snmp_trap.set_down':
         if val is None:
             if self.snmp_trap and 'set_down' in self.snmp_trap:
                 del self.snmp_trap['set_down']
                 if not self.snmp_trap:
                     self.unsubscribe_snmp_traps()
                 self.log_set('snmp_trap.set_down', None)
                 self.set_modified(save)
             return True
         else:
             ivars = {}
             try:
                 for x in val.split(','):
                     k, v = x.split('=')
                     ivars[k] = v
             except:
                 return False
             if not self.snmp_trap:
                 self.snmp_trap = {}
             self.snmp_trap['set_down'] = ivars
             self.log_set('snmp_trap.set_down', val)
             self.subscribe_snmp_traps()
             self.set_modified(save)
             return True
     elif prop == 'snmp_trap.set_status':
         if val is None:
             if self.snmp_trap and 'set_status' in self.snmp_trap:
                 del self.snmp_trap['set_status']
                 if not self.snmp_trap:
                     self.unsubscribe_snmp_traps()
                 self.log_set('snmp_trap.set_status', None)
                 self.set_modified(save)
             return True
         else:
             if not self.snmp_trap:
                 self.snmp_trap = {}
             self.snmp_trap['set_status'] = val
             self.subscribe_snmp_traps()
             self.log_set('snmp_trap.set_status', val)
             self.set_modified(save)
             return True
     elif prop == 'snmp_trap.set_value':
         if val is None:
             if self.snmp_trap and 'set_value' in self.snmp_trap:
                 del self.snmp_trap['set_value']
                 if not self.snmp_trap:
                     self.unsubscribe_snmp_traps()
                 self.log_set('snmp_trap.set_value', None)
                 self.set_modified(save)
             return True
         else:
             if not self.snmp_trap:
                 self.snmp_trap = {}
             self.snmp_trap['set_value'] = val
             self.subscribe_snmp_traps()
             self.log_set('snmp_trap.set_value', val)
             self.set_modified(save)
             return True
     elif prop[:16] == 'snmp_trap.set_if':
         if val is None:
             if self.snmp_trap and 'set_if' in self.snmp_trap:
                 del self.snmp_trap['set_if']
                 self.log_set('snmp_trap.set_if', None)
                 self.set_modified(save)
                 if not self.snmp_trap:
                     self.unsubscribe_snmp_traps()
             return True
         try:
             state, iv = val.split(':')
             s, va = state.split(',')
             ivars = {}
             for x in iv.split(','):
                 k, v = x.split('=')
                 ivars[k] = v
             if not self.snmp_trap:
                 self.snmp_trap = {}
             if not 'set_if' in self.snmp_trap:
                 self.snmp_trap['set_if'] = []
             r = {'vars': ivars}
             if s != 'null' and s != '':
                 r['status'] = int(s)
             if va != 'null' and va != '':
                 r['value'] = va
             self.log_set('snmp_trap.set_if+', val)
             self.snmp_trap['set_if'].append(r)
         except:
             return False
         self.subscribe_snmp_traps()
         self.set_modified(save)
         return True
     elif prop in ['value_condition']:
         try:
             d = self.parse_value_condition(val)
             for k, v in d.items():
                 try:
                     if not self.set_prop(k, v):
                         return False
                 except:
                     eva.core.log_traceback()
                     return False
             return True
         except Exception as e:
             logging.error('Unable to parse condition: {}'.format(e))
             eva.core.log_traceback()
             return False
     elif prop == 'value_in_range_min':
         if val is not None and val != '':
             try:
                 v = float(val)
             except:
                 v = val
         else:
             v = None
         if self.value_in_range_min != v:
             self.value_in_range_min = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'value_in_range_max':
         if val is not None and val != '':
             try:
                 v = float(val)
             except:
                 v = val
         else:
             v = None
         if self.value_in_range_max != v:
             self.value_in_range_max = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'value_in_range_min_eq':
         v = val_to_boolean(val)
         if v is not None:
             if self.value_in_range_min_eq != v:
                 self.value_in_range_min_eq = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'value_in_range_max_eq':
         v = val_to_boolean(val)
         if v is not None:
             if self.value_in_range_max_eq != v:
                 self.value_in_range_max_eq = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     else:
         return super().set_prop(prop, val, save)
Example #14
0
 def set_prop(self, prop, val=None, save=False):
     if prop == 'enabled':
         v = val_to_boolean(val)
         if v is not None:
             if self.enabled != v:
                 self.enabled = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'block_on_exec':
         v = val_to_boolean(val)
         if v is not None:
             if self.block_on_exec != v:
                 self.block_on_exec = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop in ['c', 'cond', 'condition']:
         try:
             d = self.parse_rule_condition(val)
             for k, v in d.items():
                 try:
                     if not self.set_prop(k, v):
                         return False
                 except:
                     eva.core.log_traceback()
                     return False
             return True
         except Exception as e:
             logging.error('Unable to parse condition: {}'.format(e))
             eva.core.log_traceback()
             return False
     elif prop in ['o', 'oid', 'for_oid', 'for']:
         try:
             d = self.parse_rule_for_oid(val)
             for k, v in d.items():
                 try:
                     if not self.set_prop(k, v):
                         return False
                 except:
                     eva.core.log_traceback()
                     return False
             return True
         except Exception as e:
             logging.error('Unable to parse for_oid: {}'.format(e))
             eva.core.log_traceback()
             return False
     elif prop == 'for_expire':
         if not self.in_range_max_eq or \
                 self.in_range_min_eq or \
                 self.in_range_min is not None or \
                 self.in_range_max != -1 or \
                 self.for_prop != 'status' or \
                 not isinstance(self.in_range_max, float):
             self.in_range_min_eq = False
             self.in_range_max_eq = True
             self.in_range_min = None
             self.in_range_max = -1.0
             self.for_prop = 'status'
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'for_set':
         if not self.in_range_max_eq or \
                 not self.in_range_min_eq or \
                 self.in_range_min != 1 or \
                 self.in_range_max != 1 or \
                 self.for_prop != 'status' or \
                 not isinstance(self.in_range_min, float) or \
                 not isinstance(self.in_range_max, float):
             self.in_range_min_eq = True
             self.in_range_max_eq = True
             self.in_range_min = 1.0
             self.in_range_max = 1.0
             self.for_prop = 'status'
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'priority':
         try:
             v = int(val)
             if v <= 0:
                 return False
         except:
             return False
         if self.priority != v:
             self.priority = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'for_item_type':
         if val is not None:
             if val == 'U':
                 v = 'unit'
             elif val == 'S':
                 v = 'sensor'
             elif val == 'LV':
                 v = 'lvar'
             else:
                 v = val
             if not v in ['#', 'unit', 'sensor', 'lvar']:
                 return False
         else:
             v = None
         if self.for_item_type != v:
             self.for_item_type = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'for_item_id':
         if self.for_item_id != val:
             self.for_item_id = val
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'for_item_group':
         if self.for_item_group != val:
             self.for_item_group = val
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'for_prop':
         if val not in ['status', 'value', 'nstatus', 'nvalue']:
             return False
         if self.for_prop != val:
             self.for_prop = val
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'for_initial':
         if val is not None and \
                 val not in [ 'only', 'skip', 'any', 'none', 'None' ]:
             return False
         v = val
         if v in ['any', 'none', 'None']:
             v = None
         if self.for_initial != v:
             self.for_initial = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'in_range_min':
         if val is not None and val != '':
             try:
                 v = float(val)
             except:
                 if self.for_prop == 'status':
                     return False
                 v = val
         else:
             v = None
         if self.in_range_min != v:
             self.in_range_min = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'in_range_max':
         if val is not None and val != '':
             try:
                 v = float(val)
             except:
                 if self.for_prop == 'status':
                     return False
                 v = val
         else:
             v = None
         if self.in_range_max != v:
             self.in_range_max = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     elif prop == 'in_range_min_eq':
         v = val_to_boolean(val)
         if v is not None:
             if self.in_range_min_eq != v:
                 self.in_range_min_eq = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'in_range_max_eq':
         v = val_to_boolean(val)
         if v is not None:
             if self.in_range_max_eq != v:
                 self.in_range_max_eq = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'for_prop_bit':
         try:
             if val is None or val == '':
                 v = None
             else:
                 v = int(val)
                 if v < 0:
                     raise ValueError('bit number can not be negative')
             if self.for_prop_bit != v:
                 self.for_prop_bit = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         except:
             eva.core.log_traceback()
             return False
     elif prop == 'macro':
         if self.macro != val:
             self.macro = val
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     elif prop == 'macro_args':
         if val is not None:
             if isinstance(val, list):
                 v = val
             elif isinstance(val, tuple):
                 v = list(val)
             else:
                 try:
                     v = shlex.split(val)
                 except:
                     v = val.split(' ')
         else:
             v = []
         self.macro_args = v
         self.log_set(prop, val)
         self.set_modified(save)
         return True
     elif prop == 'macro_kwargs':
         if val is None:
             self.macro_kwargs = {}
         else:
             try:
                 self.macro_kwargs = dict_from_str(val)
             except:
                 return False
         self.log_set(prop, val)
         self.set_modified(save)
         return True
     elif prop == 'break_after_exec':
         v = val_to_boolean(val)
         if v is not None:
             if self.break_after_exec != v:
                 self.break_after_exec = v
                 self.log_set(prop, v)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'chillout_time':
         try:
             v = float(val)
         except:
             return False
         if self.chillout_time != v:
             self.chillout_time = v
             self.log_set(prop, v)
             self.set_modified(save)
         return True
     return super().set_prop(prop, val, save)
Example #15
0
 def set(self, port=None, data=None, cfg=None, timeout=0):
     value = data[1] if isinstance(data, tuple) else data
     try:
         modbus_port = modbus.get_port(self.modbus_port, timeout)
     except Exception as e:
         self.log_error(e)
         log_traceback()
         return None
     try:
         if port[0] in ['c', 'd']:
             modbus.write_bool(modbus_port, port, [value], unit=self.unit_id)
         else:
             data_type = cfg.get('type', 'u16')
             if data_type.startswith('v'):
                 import math
                 try:
                     size = math.ceil(int(data_type[1:]) / 2)
                 except Exception as e:
                     self.log_error(f'invalid size: {e}')
                     log_traceback()
                     return None
                 val = value[:size * 2]
                 if len(val) % 4:
                     val += '00'
                 val = [int(val[i:i + 4], 16) for i in range(0, len(val), 4)]
                 modbus.write_u16(modbus_port, port, val, unit=self.unit_id)
                 return True
             try:
                 fn_set = self._setter_functions[data_type]
                 value = float(value) if data_type == 'f32' else int(value)
             except KeyError:
                 self.log_error(f'Invalid register data type: {data_type}')
                 raise
             if '/' in port:
                 try:
                     fn_get = self._getter_functions[data_type]
                     value = float(value) if data_type == 'f32' else int(
                         value)
                 except KeyError:
                     self.log_error(
                         f'Invalid register data type: {data_type}')
                     raise
                 reg, offset = port.split('/', 1)
                 offset = int(offset)
                 with self.bitlock:
                     try:
                         b = self.cache[reg]
                     except KeyError:
                         b = fn_get(modbus_port, reg, unit=self.unit_id)[0]
                         self.cache[reg] = b
                     if val_to_boolean(value):
                         b = b | 1 << offset
                     else:
                         if b >> offset & 1:
                             b = b ^ 1 << offset
                     fn_set(modbus_port, reg, [b], unit=self.unit_id)
                     try:
                         del self.cache[reg]
                     except:
                         pass
             else:
                 value = transform_value(value,
                                         multiply=cfg.get('divide'),
                                         divide=cfg.get('multiply'))
                 if data_type != 'f32':
                     value = int(value)
                 fn_set(modbus_port, port, [value], unit=self.unit_id)
         return True
     except:
         log_traceback()
         return False
     finally:
         modbus_port.release()
Example #16
0
File: plc.py Project: GypsyBud/eva3
 def set_prop(self, prop, val=None, save=False):
     if prop == 'macro':
         if self.cycle_enabled:
             return False
         if val is None:
             if self.macro is not None:
                 self.macro = val
                 self.log_set(prop, val)
                 self.set_modified(save)
             return True
         macro = eva.lm.controller.get_macro(val, pfm=True)
         if macro:
             if not self.macro or self.macro.oid != macro.oid:
                 self.macro = macro
                 self.log_set(prop, val)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'macro_args':
         if val is not None:
             if isinstance(val, list):
                 v = val
             else:
                 try:
                     v = shlex.split(val)
                 except:
                     v = val.split(' ')
         else:
             v = []
         self.macro_args = v
         self.log_set(prop, val)
         self.set_modified(save)
         return True
     elif prop == 'macro_kwargs':
         if val is None:
             self.macro_kwargs = {}
         else:
             self.macro_kwargs = dict_from_str(val)
         self.log_set(prop, val)
         self.set_modified(save)
         return True
     elif prop == 'on_error':
         if val is None:
             if self.on_error is not None:
                 self.on_error = val
                 self.log_set(prop, val)
                 self.set_modified(save)
             return True
         macro = eva.lm.controller.get_macro(val, pfm=True)
         if macro:
             if not self.on_error or self.on_error.oid != macro.oid:
                 self.on_error = macro
                 self.log_set(prop, val)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'interval':
         if self.cycle_enabled:
             return False
         try:
             interval = float(val)
         except:
             return False
         if interval > 0:
             if self.interval != interval:
                 self.interval = interval
                 self.log_set(prop, val)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'ict':
         try:
             ict = int(val)
         except:
             return False
         if ict > 0:
             if self.ict != ict:
                 self.ict = ict
                 self.log_set(prop, val)
                 self.set_modified(save)
             return True
         else:
             return False
     elif prop == 'autostart':
         try:
             autostart = val_to_boolean(val)
             if autostart is None: raise ('Invalid val')
         except:
             return False
         if self.autostart != autostart:
             self.autostart = autostart
             self.log_set(prop, val)
             self.set_modified(save)
         return True
     else:
         return super().set_prop(prop, val, save)
Example #17
0
 def do_state(self, _uuid, cfg, timeout, tki, state_in):
     # we don't handle events
     if state_in:
         return self.state_result_error(_uuid)
     if cfg is None or cfg.get(self.io_label) is None:
         return self.state_result_error(_uuid)
     phi_cfg = self.prepare_phi_cfg(cfg)
     if self.phi._is_required.aao_get:
         _state_in = self.phi.get(cfg=phi_cfg, timeout=timeouter.get())
         if not _state_in:
             return self.state_result_error(_uuid)
     else:
         _state_in = {}
     skip_err = val_to_boolean(cfg.get('skip_err')) if \
             cfg.get('skip_err') is not None else self.skip_err
     gpf = cfg.get('gpf') if \
             cfg.get('gpf') is not None else self.gpf
     max_diff = cfg.get('max_diff') if \
             cfg.get('max_diff') is not None else self.max_diff
     try:
         max_diff = float(max_diff)
     except:
         max_diff = self.max_diff
     port = cfg.get(self.io_label)
     if not isinstance(port, list):
         _port = [port]
     else:
         _port = port
     multi = False
     for p in _port:
         if isinstance(p, list):
             multi = True
             break
     else:
         _port = [_port]
     if multi:
         st = []
     else:
         st = None
     for pi in _port:
         if isinstance(pi, list):
             pp = pi
         else:
             pp = [pi]
         st_arr = []
         st_ports = []
         _status = 1
         for p in pp:
             if _state_in and str(p) in _state_in:
                 value = _state_in.get(str(p))
             else:
                 value = self.phi.get(str(p),
                                      phi_cfg,
                                      timeout=timeouter.get())
             try:
                 value = float(value)
             except:
                 value = None
             if value is None:
                 if not skip_err:
                     _status = -1
                     break
                 else:
                     self.log_error('%s %s failed to get value' %
                                    (self.io_label, p))
             else:
                 st_arr.append(value)
                 st_ports.append(str(p))
         if max_diff and _status != -1 and len(st_arr) > 1:
             _st_ports = st_ports.copy()
             while True:
                 diver = False
                 for i in range(0, len(st_arr)):
                     _s = st_arr.copy()
                     del _s[i]
                     _avg = sum(_s) / float(len(_s))
                     if abs(st_arr[i] - _avg) > max_diff:
                         if len(st_arr) == 2:
                             self.log_error(
                             'one %s of %s failed' %
                             (self.io_label, ', '.join(_st_ports)) + \
                             '  - value is too different')
                             if multi:
                                 _status = -1
                                 break
                             else:
                                 return self.state_result_error(_uuid)
                         else:
                             diver = True
                             break
                 if diver and _status != -1:
                     diffs = []
                     for i in range(0, len(st_arr)):
                         diff = 0
                         for i2 in range(0, len(st_arr)):
                             if i != i2:
                                 diff += abs(st_arr[i2] - st_arr[i])
                         diffs.append(diff)
                     bi = diffs.index(max(diffs))
                     self.log_error('%s %s seems to be failed' %
                                    (self.io_label, st_ports[bi]) +
                                    ' - value is too different')
                     del st_arr[bi]
                     del st_ports[bi]
                 else:
                     break
         if _status == -1 or not st_arr:
             if multi:
                 st.append((-1, None))
                 continue
             else:
                 return self.state_result_error(_uuid)
         if gpf == 'first':
             value = st_arr[0]
         elif gpf == 'max':
             value = max(st_arr)
         elif gpf == 'min':
             value = min(st_arr)
         else:
             value = sum(st_arr) / float(len(st_arr))
         if multi:
             st.append((1, str(value)))
         else:
             st = str(value)
     if multi:
         self.set_result(_uuid, st)
     else:
         self.set_result(_uuid, (1, st))
     return