def validate_timestamp(timestamp, polling_interval): """Validate timestamp to be a multiple of 'polling_interval' seconds. Args: timestamp: epoch timestamp in seconds polling_interval: Polling interval for data Returns: valid: True if valid """ # Initialize key variables valids = [] valid = False # Evaluate validity of the parameters valids.append(bool(polling_interval)) valids.append(data.is_numeric(timestamp)) valids.append(data.is_numeric(polling_interval)) valids.append(isinstance(polling_interval, (int, float))) # Process data if False not in valids: test = (int(timestamp) // polling_interval) * polling_interval if test == timestamp: valid = True # Return return valid
def test_is_numeric(self): """Testing function is_numeric.""" # Test False items = [None, True, False, 'False'] for item in items: result = data.is_numeric(item) self.assertFalse(result) # Test True items = [1, 1.1, '1.1'] for item in items: result = data.is_numeric(item) self.assertTrue(result)
def normalized_timestamp(_pi, timestamp=None): """Normalize timestamp to a multiple of 'polling_interval' seconds. Args: timestamp: epoch style timestamp in millseconds _pi: Polling interval for data in milliseconds. Defaults to assuming 1000 if 'None'. Returns: value: Normalized value """ # Initialize key variables if bool(_pi) is True: if isinstance(_pi, int) is False: log_message = ('''\ Invalid non-integer "polling_interval" value of {}'''.format(_pi)) log.log2die(1029, log_message) else: polling_interval = abs(_pi) else: # Don't allow 0 values for polling_interval polling_interval = 1000 # Process data if (timestamp is None) or (data.is_numeric(timestamp) is False): value = (int(time.time() * 1000) // polling_interval) * polling_interval else: value = (int(timestamp) // polling_interval) * polling_interval # Return return value
def _get_target_datapoints(self, item): """Poll each spoke in parallel. Args: item: TargetPollingPoints object Returns: ddv: TargetDataPoints for the SNMPVariable target """ # Intialize data gathering ip_target = item.target ddv = TargetDataPoints(ip_target) # BAC0 only works with IP addresses ip_address = network.get_ipaddress(ip_target) if bool(ip_address) is False: return ddv # Get list of type DataPoint datapoints = [] for polltarget in item.data: # Get polling results value = poll_target_address(ip_address, polltarget.address, 'presentValue', self._bacnet) name = poll_target_address(ip_address, polltarget.address, 'objectName', self._bacnet) # Skip if invalid data is received if value is None: continue # Do multiplication if data.is_numeric(value) is True: value = float(value) * polltarget.multiplier data_type = DATA_FLOAT else: data_type = DATA_STRING # Update datapoints datapoint = DataPoint('analog_value_point_{}'.format( polltarget.address), value, data_type=data_type) datapoint.add(DataPointMetadata('target', ip_target)) if name is not None: datapoint.add(DataPointMetadata('object_name', name)) datapoints.append(datapoint) # Return ddv.add(datapoints) return ddv
def valid_format(self): """Determine whether the format of the oid is correct. Args: None Returns: invalid: False if OK """ # Initialize key variables oid = self.oid valid = True # oid cannot be boolean if oid is True: valid = False if oid is False: valid = False if oid is None: valid = False # oid cannot be numeric if isinstance(oid, str) is False: valid = False # Make sure the oid is not blank stripped_oid = oid.strip() if len(stripped_oid) == 0: valid = False return valid # Must start with a '.' if oid[0] != '.': valid = False # Must not end with a '.' if oid[-1] == '.': valid = False # Test each node to be numeric nodes = oid.split('.') # Remove the first element of the list nodes.pop(0) for value in nodes: if data.is_numeric(value) is False: valid = False # Otherwise valid return valid
def __init__(self, register=None, count=1, unit=0, multiplier=1): """Initialize the class. Args: register: Register number count: The number of registers to read unit: The slave unit this request is targeting multiplier: Value to multiply register results by Returns: None """ # Initialize key variables self.address = None # Apply the multiplier if bool(multiplier) is False: self.multiplier = 1 elif data.is_numeric(multiplier) is True: self.multiplier = float(multiplier) else: self.multiplier = 1 # Set object as being.valid valid = False not in [ isinstance(register, int), bool(register), register is not False, register is not True, register is not None, isinstance(count, int), count is not False, count is not True, count is not None, isinstance(unit, int) is True, unit is not False, unit is not True, unit is not None ] # This part is separate as we need to do some mathematical functions # that are based on the validity of the previous tests if valid is True: self.valid = False not in [ valid, 0 <= unit <= 246, 0 < count < 2008 ] else: self.valid = False # Assign values self.count = count self.unit = unit self.register = register
def __init__(self, oid): """Initialize the class. Args: oid: OID to process Returns: None """ # Initialize key variables self.oid = str(oid) # OID must be string if data.is_numeric(self.oid): log_message = ('OID value {} is not a string.'.format(self.oid)) log.log2die(51380, log_message)
def __init__(self, address=None, multiplier=1): """Initialize the class. Args: address: Address to poll multiplier: Multiplier to use when polled Returns: None """ # Initialize variables self.address = address if data.is_numeric(multiplier) is True: self.multiplier = multiplier else: self.multiplier = 1 self.valid = address is not None # Create checksum seed = '{}{}'.format(address, multiplier) self.checksum = data.hashstring(seed)
def _get_unit(data): """Get the unit to be polled in the polling_group. Args: data: Configuration dict for the polling_group Returns: result: unit value """ # Ignore invalid non-dicts if isinstance(data, dict) is False: result = 0 return result # Default value if 'unit' not in data: result = 0 return result # Non integer values got to default unit = data['unit'] valid = False in [ lib_data.is_numeric(unit) is False, isinstance(unit, str) is True, unit is False, unit is True, unit is None ] if valid is False: result = 0 return result # Convert float values to integer values if isinstance(unit, float) is True: result = int(unit) else: result = unit # Return return result
def __init__(self, key, value, data_type=DATA_INT, timestamp=None): """Initialize the class. Args: key: Key related to data value value: Data value data_type: This MUST be one of the types listed in constants.py timestamp: Integer EPOCH timestamp in milliseconds Returns: None Variables: self.timestamp: Integer of epoch milliseconds self.valid: True if the object has a valid data_type self.checksum: Hash of self.key, self.data_type and metadata to ensure uniqueness when assigned to a target. """ # Initialize variables (self.key, self.value, self.valid) = _key_value_valid(key, value, metadata=False) self.data_type = data_type self.metadata = {} self._metakeys = [] # Round timestamp to the nearest millisecond. if data.is_numeric(timestamp) is False: self.timestamp = int(round(time(), 3) * 1000) else: self.timestamp = int(timestamp) # False validity if value is not of the right type self.valid = False not in [ data_type in [ DATA_INT, DATA_FLOAT, DATA_COUNT64, DATA_COUNT, DATA_STRING, DATA_NONE ], data_type is not False, data_type is not True, data_type is not None, self.valid is True ] # Validity check: Make sure numeric data_types have numeric values if False not in [ data_type in [DATA_INT, DATA_FLOAT, DATA_COUNT64, DATA_COUNT], self.valid is True, data.is_numeric(value) is False ]: self.valid = False # Convert floatable strings to float, and integers to ints if False not in [ self.valid is True, data.is_numeric(value) is True, isinstance(value, str) is True ]: if data_type in [DATA_FLOAT, DATA_COUNT64, DATA_COUNT]: self.value = float(value) elif data_type in [DATA_INT]: self.value = int(float(value)) # Convert strings to string if data_type in [DATA_STRING]: self.value = str(value) # Create checksum self.checksum = data.hashstring('{}{}'.format(self.key, self.data_type))
async def _serial_poller_async(tpp): """Poll OPCUA agent data. Args: tpp: TargetDataPoints object Returns: target_datapoints: TargetDataPoints object """ # Initialize key variables connected = False # Test for validity if isinstance(tpp, TargetPollingPoints) is False: return None if isinstance(tpp.target, OPCUAauth) is False: return None if tpp.valid is False: return None # Create URL for polling ip_target = tpp.target.ip_target ip_port = tpp.target.ip_port username = tpp.target.username password = tpp.target.password url = 'opc.tcp://{}:{}'.format(ip_target, ip_port) # Intialize data gathering target_datapoints = TargetDataPoints(ip_target) # Create a client object to connect to OPCUA server client = Client(url=url) client.set_user(username) client.set_password(password) # Connect try: await client.connect() connected = True except: log_message = ( 'Authentication for polling target {} is incorrect'.format(url)) log.log2warning(51011, log_message) pass if connected is True: for point in tpp.data: # Make sure we have the right data type if isinstance(point, PollingPoint) is False: log_message = ('''\ Invalid polling point {} for OPC UA URL {}'''.format(point, url)) log.log2info(51012, log_message) continue # Get data address = point.address try: node = client.get_node(address) value = await node.read_value() except BadNodeIdUnknown: log_message = ('''\ OPC UA node {} not found on server {}'''.format(address, url)) log.log2warning(51015, log_message) continue except: _exception = sys.exc_info() log_message = ('OPC UA server communication error') log.log2exception(51014, _exception, message=log_message) log_message = ('''\ Cannot get value from polling point {} for OPC UA URL {}\ '''.format(address, url)) log.log2info(51013, log_message) continue # Create datapoint if bool(point.multiplier) is True: if is_numeric(value) is True and (is_numeric(point.multiplier) is True): value = value * point.multiplier else: value = 0 datapoint = DataPoint(address, value) datapoint.add(DataPointMetadata('OPCUA Server', ip_target)) target_datapoints.add(datapoint) # Disconnect client await client.disconnect() return target_datapoints