def uptime(self): """ Elapsed time in seconds since the simulation has been started. """ if not self._started: return 0.0 return seconds_since(self._start_time)
def process_pv_updates(self, force=False): """ Update PV values that have changed for PVs that are due to update according to their respective poll interval timers. :param force: If True, will force updates to all PVs regardless of timers. """ dt = seconds_since(self._last_update_call or datetime.now()) # Cache details of PVs that need to update value_updates = [] meta_updates = [] with self._device_lock: for pv, pv_object in iteritems(self._interface.bound_pvs): self._timers[pv] = self._timers.get(pv, 0.0) + dt if self._timers[pv] >= pv_object.poll_interval or force: try: if self.getParam(pv) != pv_object.value or force: value_updates.append((pv, pv_object.value)) pv_meta = pv_object.meta if self._get_param_info(pv, pv_meta.keys()) != pv_meta or force: meta_updates.append((pv, pv_meta)) except (AttributeError, TypeError): self.log.exception('An error occurred while updating PV %s.', pv) finally: self._timers[pv] = 0.0 self._process_value_updates(value_updates) self._process_meta_updates(meta_updates) self._last_update_call = datetime.now()
def handle(self, cycle_delay=0.1): """ Call this method to spend about ``cycle_delay`` seconds processing requests in the pcaspy server. Under load, for example when running ``caget`` at a high frequency, the actual time spent in the method may be much shorter. This effect is not corrected for. :param cycle_delay: Approximate time to be spent processing requests in pcaspy server. """ self._server.process(cycle_delay) self._driver.process_pv_updates(seconds_since(self._last_update)) self._last_update = datetime.now()
def _process_cycle(self, delta): """ Processes one cycle, which consists of one simulation cycle and processing of control server commands. The method measures how long all this takes and returns the elapsed time in seconds. :param delta: Elapsed time in last cycle, passed to simulation. :return: Elapsed time in this cycle. """ start = datetime.now() self._process_simulation_cycle(delta) delta = seconds_since(start) return delta
def process_pv_updates(self, force=False): """ Update PV values that have changed for PVs that are due to update according to their respective poll interval timers. :param force: If True, will force updates to all PVs regardless of timers. """ dt = seconds_since(self._last_update_call or datetime.now()) # Cache details of PVs that need to update value_updates = [] meta_updates = [] with self._device_lock: for pv, pv_object in self._interface.bound_pvs.items(): self._timers[pv] = self._timers.get(pv, 0.0) + dt if self._timers[pv] >= pv_object.poll_interval or force: try: if self.getParam(pv) != pv_object.value or force: value_updates.append((pv, pv_object.value)) pv_meta = pv_object.meta if self._get_param_info( pv, pv_meta.keys()) != pv_meta or force: meta_updates.append((pv, pv_meta)) except (AttributeError, TypeError): self.log.exception( "An error occurred while updating PV %s.", pv) finally: self._timers[pv] = 0.0 self._process_value_updates(value_updates) self._process_meta_updates(meta_updates) self._last_update_call = datetime.now()
def test_seconds_since_future(self, datetime_mock): datetime_mock.now.return_value = datetime(2016, 9, 1, 2, 0) self.assertEqual(seconds_since(datetime(2016, 9, 1, 3, 0)), -3600.0)