def _read_single_parameter(self, mid, pid, timeout=2): self._mutex.acquire() try: #key = (mid,pid,) packet, key = read_single_parameter_packet(mid,pid) for i in range(3): self.point_dictionary[key] = None if self.debug: print 'writing ccm to port: %s' % str(packet.tolist()) self.port.write(packet) _timeout = timeout t_end = time.time() + timeout while (self.point_dictionary[key] == None) \ and _timeout >= 0: try: self._wait_for_values(_timeout) if self.debug > 2: print 'notified' except ETimeout: if self.debug: print 'wait timed out' break _timeout = t_end - time.time() value = self.point_dictionary[key] if self.debug: print 'type(value) = %s' % type(value) del(self.point_dictionary[key]) if value != None: self._offline = 0 #allow retries next time since this point did respond return value if self._offline: #known bad point raise ETimeout() self._offline = 1 #don't wait around for retries on this point, it's not responding raise ETimeout() #fail after third timeout finally: self._mutex.release() pass pass
def get(self, skipCache=0): if self.result == None: if self.bad_crc_count: raise ETimeout('communications error for: %s' % self.as_node_url()) raise ETimeout('no data yet for: %s' % self.as_node_url()) return self.result # value is placed here by another thread
def get(self, skipCache=0): rslt = self._value # cache miss if (uptime.secs() - self._last_update) > self.group.ttl: # motes periodically push updates - if it's been silent for # too long force an update. @fixme: the first read will still # return stale data - add blocking call and ETimeout logic last = self._last_update self.__cv.acquire() try: try: self._force_update() except: # an error using the XCommand interface occured # raise an exception but do not cache the ETimeout msglog.exception() raise ETimeout() self.__cv.wait(self.timeout) if last != self._last_update: # an update has occurred rslt = self._value else: self._last_update = uptime.secs() # let ETimeouts affect our value caching as well, # if a better update comes from the mesh, great. rslt = self._value = ETimeout() finally: self.__cv.release() if isinstance(rslt, ETimeout): raise rslt return rslt
def _read_temperature_for(self, device): channel = self.id if channel < 1 or channel > 2: raise Exception('channel must be between 1 and 2') d = unpack('<Q', device.address)[0] command = 'dallas %d %d\r' % (channel, d) #t1 = time.time() dict = self._read_response(command) if dict['command'] != 'dallas': raise Exception('command mismatch: %s' % (dict['command'], )) #if dict['channel'] != channel: #raise Exception('channel mismatch: %s %d' % (str(dict['channel']), channel,)) # 0xBEAA004B46FFFF0C1087 of which AA00 is the temp in reverse order and 10 is the device type # isolate the temperature from the loooong result raw_value = dict['device_ids'].values()[0] # big honking interger if self.debug: print 'raw response value: %0X' % raw_value crc = raw_value & 0xFF scratchpad = pack('>Q', (raw_value >> 8) & 0xffffffffffffffff) # strip off BE and crc #print repr(scratchpad), crc crc2 = crc_of(scratchpad) if self.debug: print "crc: ", crc, crc2 if crc2 != crc: raise ETimeout('dallas crc error') if self.debug: print 'sratchpad: ', repr(scratchpad) if scratchpad == '\x00\x00\x00\x00\x00\x00\x00\x00': raise ETimeout('dallas crc error') result = unpack('<h', scratchpad[:2])[0] # get temp return float(result)
def get_synchronous(self, station, rqst): self._sync_get_lock.acquire() try: t = self._synchronous_transaction hdr = self._get_auth_header(station) hdr['Connection'] = 'close' t.build_request(rqst.url, None, hdr) self._cv.acquire() try: response = ETimeout() try: t.send_request() self._cv.wait(self.timeout) self._last_sync_get = uptime.secs() if t.is_expired(): t.cancel() else: response = t.get_response() except: t.cancel() finally: self._cv.release() return response finally: self._sync_get_lock.release() return
def destructive_read(self, count=2147483647, timeout=2147483647): """ A variant of read() that (by default) returns all available data and truncates the internal "data-stream" to avoid hemorrhaging memory when posting large files. """ self._lock.acquire() try: data = '' while not data and timeout > 0: data = self.datastream.read(count) if data or self._done_collecting or self._stream_closed: break else: start_time = time.time() self._condition.wait(timeout) timeout -= time.time() - start_time finally: if self.datastream.pos == self.datastream.len: self.datastream.truncate(0) else: self.datastream = StringIO.StringIO(self.datastream.read()) self._lock.release() if data or self._done_collecting: return data elif self._stream_closed: return '' else: raise ETimeout()
def send_request(host, post, action, soap_request, conn=None): header = {'SOAPAction': action, 'Content-Type': 'text/xml; charset=utf-8'} i = host.find('http://') if i >= 0: host = host[i + 7:] #remove leading http if present if host[-1] == '/': host = host[:-1] if post[0] != '/': #make sure post starts with / post = '/' + post if post[-1] == '/': post = post[:-1] #if debug: print host, post, action, soap_request close_conn = 0 if conn is None: conn = _HTTPConnection(host) close_conn = 1 conn._trace('instantiated') conn._continuations = 0 if conn is None: if debug: print 'host not found' raise ETimeout('host not found', (host, post, action, soap_request)) try: if debug > 2: conn.set_debuglevel(1) conn._trace('pre-request') conn.request('POST', post, soap_request, header) conn._trace('post-request') while 1: conn._trace('pre-getresponse') r = conn.getresponse() if debug: print r.status, r.reason conn._trace('post-getresponse') if r.status != 100: break _HTTPConnection._total_continuations += 1 conn._continuations += 1 # 2000-12-30 djf -- drop bogus 100 response # by kludging httplib conn._HTTPConnection__state = httplib._CS_REQ_SENT conn._HTTPConnection__response = None if r.status != 200: raise EInvalidResponse(str(r.status), 'expecting OK response', (host, post, action, soap_request)) conn._trace('pre: r.read()') response = r.read() conn._trace('post: r.read()') if response is None: raise EInvalidValue('expecting SOAP server response', (host, post, action, soap_request)) return response finally: try: if close_conn: conn._trace('pre.close()') conn.close() conn._trace('post.close()') else: conn._trace('keep open') except: pass pass
def _send_request(self, rqst, callback): self.__port_lock.acquire() try: self._port.write(rqst.encode()) errs = 0 rsp = ETimeout() while errs < 5: buff = array.array('B') try: self._port.read(buff, 1, 1) #1 char read, 1 sec timeout. cmd = buff[0] if not cmd in [0x90, 0x94]: errs += 1 print 'err' continue self._port.read(buff, 2, 1) p_len = (buff[2] << 8) | buff[1] - 3 self._port.read(buff, p_len, 1) rsp = self._get_rsp_obj(rqst._cmd, buff) break except: msglog.exception() break if callback: callback(rqst, rsp) else: return rsp finally: self.__port_lock.release()
def set(self, newval): # cmd = (str(newval).rsplit('.', 1)[1]).split('=', 1)[0] msglog.log('USAP', INFO, "Device:set() with %s (cmd=%s)" % (str(newval), str(cmd))) vData = string.join(['\x00\x00\x40', str(newval)], '') self.req_vData_obj.setValue(vData) # res = None needResponse = 0 if cmd == 'bACT' or cmd == 'bAAP': needResponse = 1 # self.lh.connection.drain() if self.unison_v1_9_0_or_prior == 1 and needResponse == 0: try: self.lh.send_request_without_response(self.request_obj, 30) self.value = str(newval) time.sleep(1) except Exception, e: msglog.log( 'USAP', WARN, "Device:set() - Got exception trying to send request") msglog.exception() raise ETimeout('Error sending USAP request')
def _trigger_cov(self): try: v = self.get() except: v = ETimeout() cov = ChangeOfValueEvent(self, self._last_value, v, time.time()) self.event_generate(cov) self._last_value = v
def _non_blocking_connect(self,args,timeout): try: self._socket.connect(args) except error,why: if why[0] != 115: raise why if not self._wait_writable(timeout): raise ETimeout('Connect timed out.')
def limited_apply(func, args=(), timeout=None, cleanup=None, c_args=()): thread = _ResultThread(func, args, cleanup, c_args) thread.start() try: return thread.result(timeout) except ETimeout: thread.expire() thread.minimize() raise ETimeout('Function call timed out. Warning, calls which ' + 'timeout may leave blocked threads in memory.')
def write(self,data,timeout=None): if ((timeout is not None or self._safety) and self._socket._connected): if not self._socket._wait_writable(timeout): raise ETimeout('Socket did not become writable') self._lock.acquire() try: return self._ssl.write(data) finally: self._lock.release()
def result(self, timeout=None): self.join(timeout) self._lock.acquire() try: if self._exception is not None: raise self._exception if self._complete: return self._result finally: self._lock.release() raise ETimeout()
def get(self, skipCache=0): line = self.parent.get_line(self.id,skipCache) if line is None: raise ETimeout() list = string.split(line) if not self.spaces: value = list[self.column] elif self.column >= 0 or (self.column + self.spaces + 1) < 0: value = string.join(list[self.column:self.column+self.spaces+1]) else: value = string.join(list[self.column:]) return self.conversion(value)
def get_response(self): if self.debug: print 'Waiting for Rx event' self.rx_event.wait(self.timeout) if self.debug: print 'Got RX event or timeout' if self.rx_event.isSet(): if self.debug: print 'RX event was set' self.rx_event.clear() return self.message if self.debug: '!!!!! %f get_response raise ETimeout' % (self.runtime()) raise ETimeout('Aerocomm driver command response Timeout', str(self), 'Aerocomm')
def get(self, skipCache=0): sub = self.get_subject() if sub is None: raise ETimeout() if self.parent.is_remote(): return sub.get(skipCache) if isinstance(sub, TemplateInstanceNode): ti_status = sub.get_child('_status').get().get('status', 0) else: ti_status = 0 return { 'value': self.parent.get(), 'status': self.parent.get_write_priority() or ti_status }
def _get_value(self, skipCache=0): if self.is_bound_proxy(): return self._value force = 0 #force retransmission of subscribe packet for i in range(3): value = self._line_handler.get_value(self.lan_address, self.id_number, force, self._cov_event_callback) self._value = value if not value is None: # @fixme later one, figure out how to get state info to user return value force = 1 print 'force rz point %s resubscription' % (self.name) return ETimeout()
def get(self, skipCache=0): vData = string.join(['\x00\x00\x40', self.path, '.', 'bACT'], '') self.req_vData_obj.setValue(vData) msglog.log('USAP', INFO, "Object:get() - Sending request: %s" % (str(vData))) # res = None # self.lh.connection.drain() try: res = self.lh.send_request_with_response(self.request_obj, self.response_obj, 30) except Exception, e: msglog.log('USAP', WARN, "Object:get() - Got exception trying to send request") msglog.exception() raise ETimeout('Error sending USAP request')
def update_cache(self, value): now = uptime.secs() if isinstance(value, ValueObj): value = value.get(self.prop_name) if value is None or isinstance(value, Exception): value = ETimeout() if value != self._cached_value: if self.event_has_subscribers(): self._trigger_cov(self._cached_value, value, time.time()) self._cached_value = value if self._cached_result is None: changes = 0 else: changes = self._cached_result.changes + 1 self._cached_result = Result(self._cached_value, self._last_rcvd, changes) self._last_rcvd = now return
class _ResultThread(Thread): def __init__(self, target, args, cleanup, c_args, group=None, name=None, kwargs=None, verbose=None, *vargs, **keywords): if kwargs is None: kwargs = {} self._cleanup = cleanup self._cleanup_args = c_args self._complete = 0 self._expired = 0 self._lock = Lock() self._exception = None self._result = None Thread.__init__(self, group, target, name, args, kwargs, verbose, *vargs, **keywords) def run(self): try: result = apply(self._Thread__target, self._Thread__args, self._Thread__kwargs) except Exception, e: self._exception = e raise self._lock.acquire() try: expired = self._expired if expired: self._exception = ETimeout('Action has been expired') else: self._result = result self._complete = 1 finally: self._lock.release() if expired and self._cleanup is not None: apply(self._cleanup, self._cleanup_args) return
def recycle_expired_transactions(self): cnt = 0 for t in self._transactions: if t.is_expired(): t.cancel() tid = t.tid try: s_id, callback = self.tm._callbacks.get(tid) except: # callback is gone callback = None if callback: try: callback(ETimeout()) except: msglog.exception(prefix='Handled') del self.tm._callbacks[tid] cnt += 1 self.put_transaction(t) return
def read(self, count=None, timeout=15.0): self._lock.acquire() try: data = '' while not data and timeout > 0: data = self.datastream.read(count) if data or self._done_collecting or self._stream_closed: break else: start_time = time.time() self._condition.wait(timeout) timeout -= time.time() - start_time finally: self._lock.release() if data or self._done_collecting: return data elif self._stream_closed: return '' else: raise ETimeout()
def set(self, newval): # newval = str(newval).split('.', 1)[0] if newval.isdigit(): newval = int(newval) if not command.has_key(newval): msglog.log('USAP', WARN, "Object:set() with invalid command - %s" % str(newval)) raise EInvalidValue( 'Invalid Command', str(newval), 'Valid commands are \'0:DACT\' or \'1:ACTI\'.') if self.value == command[newval]: msglog.log( 'USAP', INFO, "Object:set() - Current value is same as new value \'%s\', so no action required." % str(command[newval])) return vData = string.join( ['\x00\x00\x40', self.path, '.', str(command[newval])], '') msglog.log( 'USAP', INFO, "Object:set() - newval = %s, vData(%d) = %s" % (str(command[newval]), len(vData), str(vData))) self.req_vData_obj.setValue(vData) # res = None # self.lh.connection.drain() if self.unison_v1_9_0_or_prior == 1: try: self.lh.send_request_without_response(self.request_obj, 30) time.sleep(1) except Exception, e: msglog.log( 'USAP', WARN, "Object:set() - Got exception trying to send request") msglog.exception() raise ETimeout('Error sending USAP request')
def get(self, skipCache=0): rlst = None rslt = self.container.get_property(self.prop_id) if rslt is not None: #The WXT can be reconfigured to express properties #in different units on the fly - save the current unit self.__raw_units = rslt[-1] rslt = rslt[:-1] try: rslt = float(rslt) except: pass # in automatic mode, not all values update continuously. # precipitation data, f.e., only updates when it's raining. # in these instances, allow the user to simply return 0 # instead of raising a timeout. elif self.parent.timeout: raise ETimeout() else: rslt = 0 return rslt
def _do_poll(self): if self.debug: msglog.log('DRAS', INFO, 'Polling the demand response server') for soap_func, callback_list in self.__observers.items(): for obj in callback_list: args = obj.get_args() try: if args: value = soap_func(*args) else: value = soap_func() except: # SOAP errors live here if self.debug: msglog.log('DRAS', INFO, 'Error polling the demand response server') msglog.exception() value = ETimeout() obj.update(value) self._schedule() return
def __wait_for_port(self, timeout=10.0): chatter_timeout = now() + timeout last_character_time = self.__last_character_time silent_interval = self.__silent_interval silence_timeout = last_character_time + silent_interval chatter = self.port.drain() while now() < chatter_timeout: if len(chatter): chatter = self.port.drain() last_character_time = now() silence_timeout = last_character_time + silent_interval continue if now() > silence_timeout: # OK, there has been no "chatter" for the required interval self.__last_character_time = last_character_time return sleep_timeout = silence_timeout - now() if sleep_timeout > 0.0: sleep(sleep_timeout) chatter = self.port.drain() raise ETimeout('Failed to detect %.2d millisecond silent interval ' 'after %d seconds.' % (silent_interval / 1000.0, timeout))
def read(self,count=None,timeout=None): args = (count,) if count is None: args = () if ((self._safety or timeout is not None) and not self._socket._wait_readable(0)): blocking = self._socket.is_blocking() self._lock.acquire() try: self._socket.setblocking(0) try: return self._ssl.read(*args) except sslerror,why: if why[0] not in (2,11) and blocking: raise why finally: self._socket.setblocking(blocking) self._lock.release() else: return self._ssl.read(*args) if (self._socket._connected and not self._socket._wait_readable(timeout)): raise ETimeout('Socket did not become readable') return self._ssl.read(*args)
def command(self, cmd, ip=None): b = cmd.buffer timeout = cmd.timeout(self.timeout) # @fixme Caching monitors based on address could speed things up. monitor = self.device_manager.monitor_from_kw( ModbusDeviceIdentifier, device_class="modbus", port=self.port_url, address=cmd.slave_address) self.port.lock() try: self.__wait_for_port() self.port.write(b) self.port.flush() header = buffer() # All Modbus responses are at least five bytes in length. bytesleft = 5 discarded = 0 timeleft = timeout # If this is a Megatron RS485 port then consume echoed transmit characters if properties.HARDWARE_CODENAME == 'Megatron': megatron_485 = self.parent.name in ('com3', 'com4', 'com5', 'com6') if megatron_485: expiration = now() + timeout try: self.port.read(header, len(b), timeleft) # We can check the received data here. If it is not what we sent then we have a # transmit error. Might be a collision. if (header != b): msglog.log( 'MODBUS', msglog.types.WARN, 'Transmitted message corrupt: Collision?') del (header[:]) except: msglog.exception() expiration = now() + timeout while bytesleft: self.port.read(header, bytesleft, timeleft) bytesleft = 0 while header and not header[0]: header.pop(0) bytesleft += 1 if bytesleft: discarded += bytesleft timeleft = expiration - now() if self.debug: print "Modbus.LinHandler: Discard %d 0s" % bytesleft if timeleft <= 0: raise ETimeout("Timeout discarding %d 0s" % discarded) if header[1] & 0x80: self.__last_character_time = now() e = cmd.exception(exception.factory)(self, header) raise e resp = cmd.response(response.factory)(self, header, timeout) self.__last_character_time = now() if (resp.slave_address != cmd.slave_address or resp.function != cmd.function): # Not a response to this command, ignore it raise exception.EModbusMismatch() except Exception, e: monitor.notify_exception(e) raise # Reraise the exception for processing...
if id: if nr.hasattr('is_binary_pv'): if nr.is_binary_pv(): value = int(value) elif nr.hasattr('_is_binary_type'): if nr._is_binary_type(): value = int(value) answer[id] = Result(value, now) #print 'Answer:%s' % (str(answer),) if debug: print 'Batch Callback Time:%s %s' % (self.properties, time.time() - self.last_get_time,) return answer except BACnetException, e: #total rpm exception try: if isinstance(e,BACnetError): if e.npdu.data[1] == 5 and e.npdu.data[3] == 0: return ETimeout("Missing comme device") except Exception,ERROR: msglog.exception() pass if len(self.ids) == 1: #single propety rpms throw exceptions at this level return {self.ids[0]: e} self.total_rpm_error_counter += 1 #at this point this is a multiple property read that failed #msglog.exception() if debug: print 'rpm failed, trying rp', str(self.properties) answer = {} for id in self.ids: nr = self.map[id] nr.set_batch_manager(None) #turn off rpm for the offending property msglog.log('bacnet', nr.as_node_url(), 'cannot get multiple') if debug: msglog.exception()