def get(self, skipCache=0): result = self._cbus.blocking_command("Ga=%s,g=%g\n" % (self._app, self._grp)) for line in result: name, value = line.split(":") return int(value) raise EInvalidMessage(result)
def _write_cr_value(self, value, wait_time=None, numretries=None): """Only to be used by set_cr_value method Value should only be an integer """ if not self.is_running(): raise ENotRunning() if numretries is None: numretries = self.retry_count data = self.cr_request_obj.findChildByName('data') bcc = self.cr_request_obj.findChildByName('bcc') checksum = (self.cr_checksum + value) & 0xFF data.setValue(value) bcc.setValue(checksum) while numretries: try: self._send_request(self.cr_request_obj, self.cr_response_obj, wait_time, 1) resp_addr = self.cr_response_obj.findChildByName('addr') resp_bcc = self.cr_response_obj.findChildByName('bcc') addr = resp_addr.getValue() bcc = resp_bcc.getValue() checksum = (0xD3 + calc_sum(addr)) & 0xFF if checksum != bcc: raise EBadChecksum() if self.bin_addr != addr: raise EInvalidMessage() return except: numretries -= 1 raise
def _read(self, wait_time=None, numretries=None): """Reads the device. Sends the request packet, recieves the response packet. Parses it. Updates the current reading value Should be called only by get_value() """ if numretries is None: numretries = self.retry_count while numretries: try: self._send_request(self.request_obj, self.response_obj, wait_time, 1) resp_addr = self.response_obj.findChildByName('addr') resp_cs = self.response_obj.findChildByName('cs') resp_data = self.response_obj.findChildByName('data') addr = resp_addr.getValue() cs = resp_cs.getValue() data = resp_data.getValue() checksum = (0x5D + calc_sum(addr) + calc_sum(data)) & 0xFF if checksum != cs: #some error in the response packet if self.debug: msglog.log("omnimeter", msglog.types.WARN, "Checksum didn't match %s" % self.address) raise EBadChecksum() if self.bin_addr != addr: #it's not me. don't think this would ever happen, but who knows if self.debug: msglog.log( 'omnimeter', msglog.types.WARN, "Got some other meter's response (Strange!!) %s" % self.address) raise EInvalidMessage() meter_reading = format_reading(data) self.update_value(meter_reading) return except: numretries -= 1 raise
def __init__(self, sock): command = "COMMAND" protocol = "PROTOCOL" if (sock == None): return retry_count = 0 data = '' # Although the following calls can throw Exceptions, we want them # caught by the callers, not by this ctor. # Read header from incoming socket while (len(data) < self.HEADER_LENGTH) and (retry_count < 10): # Call to recv() blocks for up to preset timeout sec: data += sock.recv(self.HEADER_LENGTH - len(data)) retry_count += 1 if (len(data) < self.HEADER_LENGTH or data[self.ISEP1] != self.SEP or data[self.ISEP2] != self.SEP or data[self.ISEP3] != self.SEP): raise EInvalidMessage(data) self.protocol = data[0:self.ISEP1] self.command = data[self.ISEP1 + 1:self.ISEP2] self.len = int(data[self.ISEP2 + 1:self.ISEP3]) self.buffer = None return
def _read_rt_value(self, wait_time=None, numretries=None): """Don't use Me. """ if numretries is None: numretries = self.retry_count while numretries: try: self._send_request(self.rt_request_obj, self.rt_response_obj, wait_time, 1) resp_addr = self.rt_response_obj.findChildByName('addr') resp_data = self.rt_response_obj.findChildByName('data') resp_bcc = self.rt_response_obj.findChildByName('bcc') addr = resp_addr.getValue() data = resp_data.getValue() bcc = resp_bcc.getValue() checksum = (0xD9 + calc_sum(addr) + calc_sum(data)) & 0xFF if checksum != bcc: raise EBadChecksum() if self.bin_addr != addr: raise EInvalidMessage() values = {} values['EM_RecMeterValue'] = format_rt_reading(data[0:4]) values['EM_SenMeterValue'] = format_rt_reading(data[4:8]) values['EM_RecActivePower'] = format_rt_reading(data[8:12]) values['EM_SenActivePower'] = format_rt_reading(data[12:16]) values['EM_RecPassive1MeterValue'] = format_rt_reading( data[16:20]) values['EM_RecPassive2MeterValue'] = format_rt_reading( data[20:24]) values['EM_RecPassivePower1'] = format_rt_reading(data[24:28]) values['EM_RecPassivePower2'] = format_rt_reading(data[28:32]) values['EM_SenPassive1MeterValue'] = format_rt_reading( data[32:36]) values['EM_SenPassive2MeterValue'] = format_rt_reading( data[36:40]) values['EM_SenPassivePower1'] = format_rt_reading(data[40:44]) values['EM_SenPassivePower2'] = format_rt_reading(data[44:48]) #have to rename voltages and currents values['EM_Voltage_1'] = format_rt_reading(data[48:52]) values['EM_Voltage_2'] = format_rt_reading(data[52:56]) values['EM_Voltage_3'] = format_rt_reading(data[56:60]) values['EM_Current_1'] = format_rt_reading(data[60:64]) values['EM_Current_2'] = format_rt_reading(data[64:68]) values['EM_Current_3'] = format_rt_reading(data[68:72]) values['EM_Phase_1'] = format_rt_reading(data[72:76]) values['EM_Phase_2'] = format_rt_reading(data[76:80]) values['EM_Phase_3'] = format_rt_reading(data[80:84]) values['EM_Hz'] = format_rt_reading(data[84:88]) values['EM_PowerRelay'] = format_rt_reading(data[88:92]) values['WM_MeterValue'] = format_rt_reading(data[92:96]) values['WM_MeterPower'] = format_rt_reading(data[96:100]) values['HM_MeterValue'] = format_rt_reading(data[100:104]) values['HM_MeterPower'] = format_rt_reading(data[104:108]) values['GM_MeterValue'] = format_rt_reading(data[108:112]) values['GM_MeterPower'] = format_rt_reading(data[112:116]) values['CM_MeterValue'] = format_rt_reading(data[116:120]) values['CM_MeterPower'] = format_rt_reading(data[120:124]) self.update_rt_value(values) return except: numretries -= 1 raise
def send_request(self, request_obj, response_obj, wait_time=None, numretries=None): """API to devices to send a request object and wait for response devices may provide wait_time, retry_count else may use defaults provided by protocol """ if not self.is_running(): raise ENotRunning() if wait_time is None: wait_time = self.reply_timeout if numretries is None: numretries = self.retry_count #have to lock here to ensure, no one drains the port out if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'wait time and numretries are %s' % str((wait_time, numretries))) save_wait_time = wait_time self.lock.acquire() try: while numretries: try: self.conn.drain() wait_time = save_wait_time t0 = time.time() #loopback object res = self.lh.send_request_with_response(request_obj, request_obj, wait_time) if not res: #should not happen raise EWriteError() wait_time = wait_time - (time.time() - t0) if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'got loopback-resp:time left:%f' % wait_time) if wait_time < 0 : #can never be raise ETimeout() #wait until we get first byte of packet res = 0 while not res: t0 = time.time() res = self.lh.receive_response(self.stx_obj, wait_time) wait_time = wait_time - (time.time() - t0) if wait_time < 0 : raise ETimeout() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'got first byte. wait time:%f' % wait_time) res = self.lh.receive_response(response_obj, wait_time) if not res: raise EInvalidMessage() return except: numretries -= 1 finally: self.lock.release() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Exhausted no. of retries. Raising last exception') raise
def __callback(self, contextEngineId, contextName, varBinds): # V1 looks like this: # _sysUpTime = (1,3,6,1,2,1,1,3) # _snmpTrapOID = (1,3,6,1,6,3,1,1,4,1,0) # _snmpTrapEnterprise = (1,3,6,1,6,3,1,1,4,3,0) # _snmpTrapAddress = (1,3,6,1,6,3,18,1,3,0) # V2 looks like # _sysUpTime0 = (1,3,6,1,2,1,1,3,0) # _snmpTrapOID = (1,3,6,1,6,3,1,1,4,1,0) # [varbinds...] if len(varBinds) < 2: # @fixme Log the malformed trap to the message log. raise EInvalidMessage( "SNMP trap must contain at least the time-stamp/sysUpTime " "and the trap/snmpTrapOID") # # When we processed the trap for logging. # logtime = time.time() version = '2c' # Assumption until proven otherwise. context_engine_id = _hex_str(contextEngineId) context_name = str(contextName) # # varBinds[0] extract sysUpTime: # sysUpTimeVarBind = varBinds.pop(0) if sysUpTimeVarBind[0] == _sysUpTime: # Inserted by PySNMP 4.1.9a. version = '1' elif sysUpTimeVarBind[0] == _sysUpTime0: # As per RFC 3416, what about v3? version = '2c' else: raise EInvalidMessage( "Expected sysUpTime OID of %r, or %r, received %r" % (_sysUpTime, _sysUpTime0, sysUpTimeVarBind[0])) # @note It seems that v1toV2 uses _sysUpTime and that true v2 uses # _sysUpTime0 sysUpTimePrettyName, sysUpTimePrettyValue = ( self.trap_view.getPrettyOidVal(*sysUpTimeVarBind)) # # varBinds[1] extract the snmpTrap. # snmpTrapNameVarBind = varBinds.pop(0) if snmpTrapNameVarBind[0] != _snmpTrapOID: raise EInvalidMessage( "Expected snmpTrapOID OID of %r, received %r" % (_snmpTrapOID, snmpTrapNameVarBind[0])) try: snmpTrapName, snmpTrapValue = self.trap_view.getPrettyOidVal( *snmpTrapNameVarBind) except: snmpTrapName = ".".join(map(str, snmpTrapNameVarBind[0])) snmpTrapValue = ".".join(map(str, snmpTrapNameVarBind[1])) # # varBinds[2] MIGHT BE the snmpTrapAddress, if this was an # "upconverted" V1 Trap-PDU. # snmpTrapEnterpriseValue = '' if varBinds: snmpTrapEnterpriseVarBind = varBinds[0] if snmpTrapEnterpriseVarBind[0] == _snmpTrapEnterprise: varBinds.pop(0) try: snmpTrapEnterpriseName, snmpTrapEnterpriseValue = ( self.trap_view.getPrettyOidVal( *snmpTrapEnterpriseVarBind)) except: snmpTrapEnterpriseName = (".".join( map(str, snmpTrapNameVarBind[0]))) snmpTrapEnterpriseValue = (".".join( map(str, snmpTrapNameVarBind[1]))) # # varBinds[2|3] MIGHT BE the snmpTrapAddress, if this was an # "upconverted" V1 Trap-PDU, or the it is a "custom" trap # using the snmpTrapAddress-Hack to set the logged source # address. # snmpTrapAddressValue = '' if varBinds: snmpTrapAddressVarBind = varBinds[0] if snmpTrapAddressVarBind[0] == _snmpTrapAddress: varBinds.pop(0) try: snmpTrapAddressName, snmpTrapAddressValue = ( self.trap_view.getPrettyOidVal( *snmpTrapAddressVarBind)) except: snmpTrapAddressName = (".".join( map(str, snmpTrapNameVarBind[0]))) snmpTrapAddressValue = (".".join( map(str, snmpTrapNameVarBind[1]))) # # Accumulate the remaining varBinds for logging. # convertedVarBinds = [] while varBinds: varName, varValue = varBinds.pop(0) try: # Try to make it pretty. varName, varValue = self.trap_view.getPrettyOidVal( varName, varValue) except: varName = ".".join(map(str, varName)) varValue = ".".join(map(str, varValue)) convertedVarBinds.append(( varName, varValue, )) self.trap_log.log_trap(version, context_engine_id, context_name, snmpTrapAddressValue, sysUpTimePrettyValue, snmpTrapValue, snmpTrapEnterpriseValue, convertedVarBinds, logtime) return
def _read(self, wait_time=None, numretries=None): """Reads the device Sends the request packet, recieves the response packet, Parses it. Updates the current reading value Shouldn't be called by anyone. Use get_value_by_name instead """ if numretries is None: numretries = self.retry_count while numretries: try: self._send_request(self.request_obj, self.response_obj, wait_time, 1) resp_addr = self.response_obj.findChildByName('addr') resp_data = self.response_obj.findChildByName('data') resp_cs = self.response_obj.findChildByName('cs') addr = resp_addr.getValue() data = resp_data.getValue() cs = resp_cs.getValue() #relay variable included because of bug #CSCts88534 relay = 0 resp_relay = self.response_obj.findChildByName('relay') if resp_relay is not None: relay = resp_relay.getValue() + 1 checksum = (0xD2 + calc_sum(addr) + calc_sum(data) + relay) & 0xFF if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'checksum calculated %s Received %s' % (str(checksum), str(cs))) if checksum != cs: msglog.log("omnimeter", msglog.types.WARN, "Checksum didn't match %s" % self.address) raise EBadChecksum() if self.bin_addr != addr: #it's not me. don't think this would ever happen, but who knows msglog.log('omnimeter', msglog.types.WARN, "Got some other meter's response (Strange!!!) %s" % self.address) raise EInvalidMessage() #everything fine till here, get the reading and update self.value #Get the error status flag meter_reading = {} err_status = ord(data[24]) - 0x33 if not (err_status & 0x01): meter_reading['SP'] = format_reading(data[20:24]) if self.debug: msglog.log('omnimeter', msglog.types.INFO, "Got Reading SP:%s" % (meter_reading['SP'],)) else: meter_reading['SP'] = EConnectionError() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Did not get reading for SP') if not (err_status & 0x02): meter_reading['CM'] = format_reading(data[12:16]) if self.debug: msglog.log('omnimeter',msglog.types.INFO, "Got Reading CM:%s" % (meter_reading['CM'],)) else: meter_reading['CM'] = EConnectionError() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Did not get reading for CM') if not (err_status & 0x04): meter_reading['GM'] = format_reading(data[8:12]) if self.debug: msglog.log('omnimeter',msglog.types.INFO, "Got Reading GM:%s" % (meter_reading['GM'],)) else: meter_reading['GM'] = EConnectionError() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Did not get reading for GM') if not (err_status & 0x08): meter_reading['HM'] = format_reading(data[4:8]) if self.debug: msglog.log('omnimeter',msglog.types.INFO, "Got Reading HM:%s" % (meter_reading['HM'],)) else: meter_reading['HM'] = EConnectionError() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Did not get reading for HM') if not (err_status & 0x10): meter_reading['WM'] = format_reading(data[0:4]) if self.debug: msglog.log('omnimeter',msglog.types.INFO, "Got Reading WM:%s" % (meter_reading['WM'],)) else: meter_reading['WM'] = EConnectionError() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Did not get reading for WM') if not (err_status & 0x20): meter_reading['EM'] = format_reading(data[16:20]) if self.debug: msglog.log('omnimeter', msglog.types.INFO, "Got Reading EM:%s" % (meter_reading['EM'],)) else: meter_reading['EM'] = EConnectionError() if self.debug: msglog.log('omnimeter', msglog.types.INFO, 'Did not get reading for EM') self.update_value(meter_reading) return except: numretries -= 1 raise