Exemplo n.º 1
0
    def _transmit(self, request, retlen, last_try=False):
        response = ''
        try:
            self._connection.sendall(request)
            self.log.debug('request sent')

            for i in range(self.comtries):
                self.log.debug('waiting for response, try %d/%d', i,
                               self.comtries)
                p = select.select([self._connection], [], [], self.bustimeout)
                if self._connection in p[0]:
                    data = self._connection.recv(20)  # more than enough!
                    if not data:
                        raise CommunicationError(self, 'no reply from recv')
                    response += data
                    if response[-1] in (EOT, DC1, DC2, DC3, ACK, NAK):
                        return response
        except OSError as err:
            if last_try:
                raise CommunicationError(self, 'tcp connection failed: %s' %
                                         err) from err
            # try reopening connection
            self.log.warning('tcp connection failed, retrying', exc=1)
            self.doReset()
            return self._transmit(request, retlen, last_try=True)
        else:
            return response
Exemplo n.º 2
0
    def _HW_writeParameter(self, index, value, store2eeprom=False):
        if index not in self.HW_writeable_Params:
            raise UsageError('Writing not possible for parameter index %s' %
                             index)

        index = self.HW_writeable_Params.get(index, index)
        self.log.debug('writeParameter %d:0x%04x', index, value)

        if store2eeprom:
            if self._HW_readStatusWord() & (1 << 6) == 0:
                # target reached not set -> problem
                raise UsageError(
                    self, 'Param acces no possible until target '
                    'reached')
            self.log.warning('writeParameter stores to eeprom !')

        if self._readStatusWord() & (1 << 7):
            raise UsageError(
                self, 'Can not access Parameters while Motor is '
                'moving, please stop it first!')

        # wait for inactive ACK/NACK
        self.log.debug('Wait for idle ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) == 0:
                break
        else:
            raise CommunicationError(
                self, 'HW still busy, can not write '
                'Parameter, please retry later')

        self._writeDestination(value)
        if store2eeprom:
            # store to eeprom
            # index goes to bits 8..15, also set bit1 (2) = eeprom and
            # bit0 (1) = set_parameter
            self._writeUpperControlWord((index << 8) | 3)
        else:
            # store to volatile memory
            # index goes to bits 8..15, also set bit0 (1) = set_parameter
            self._writeUpperControlWord((index << 8) | 1)

        self.log.debug('Wait for ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) != 0:
                break
        else:
            raise CommunicationError(
                self, 'WritePar command not recognized '
                'by HW, please retry later....')

        if self._readStatusWord() & (1 << 14):
            raise CommunicationError(
                self, 'Writing of Parameter %r failed, '
                'got a NACK' % index)
        return self._readReturn()
Exemplo n.º 3
0
    def doSetPosition(self, value):
        for _ in range(100):
            if self._readStatusWord() & (1 << 7):
                continue
            break
        else:
            raise UsageError(
                self, 'Can not set position while motor is '
                'moving, please stop it first!')

        was_on = self._readControlBit(0)
        if was_on:
            self._HW_disable()

        # wait for inactive ACK/NACK
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) == 0:
                break
        else:
            raise CommunicationError(
                self, 'HW still busy, can not set '
                'position, please retry later.')

        loops = 10
        for loop in range(loops):
            self.log.debug('setPosition: loop %d of %d', loop, loops)
            self._writeDestination(self._phys2steps(value))
            # index=1: update current position
            self._writeUpperControlWord((1 << 8) | 1)

            # Wait for ACK/NACK bits
            for _ in range(100):
                last_sw = self._readStatusWord()
                if last_sw & (3 << 14) != 0:
                    break
            else:
                self.log.warning(
                    'SetPosition command not recognized, retrying')

            if last_sw & (2 << 14) != 0:
                self.log.debug('setPosition: got ACK')
                break
            elif last_sw & (1 << 14):
                self.log.debug('setPosition: got NACK')
                raise CommunicationError(
                    self, 'Setting position failed, '
                    'got a NACK!')
        else:
            raise CommunicationError(
                self, 'setPosition command not '
                'recognized by HW, please retry later.')

        if was_on:
            self._HW_enable()
Exemplo n.º 4
0
 def doRead(self, maxage=0):
     if self._cache:
         try:
             time, ttl, val = self._cache.get_explicit(self, 'value')
         except CacheError:
             raise CommunicationError(self, CACHE_NOVALUE_STRING)
         if time and ttl and time + ttl < currenttime():
             # Note: this will only be reached if self.maxage is expired as well
             self.log.warning('value timed out in cache, this should be '
                              'considered as an error!')
         return val
     raise CommunicationError(
         self, '%s: no cache found' % self.__class__.__name__)
Exemplo n.º 5
0
 def connect_pv(self, pvname, timeout):
     # Check pv is available
     try:
         _CONTEXT.get(pvname, timeout=timeout)
     except TimeoutError:
         raise CommunicationError(f'could not connect to PV {pvname}')
     return pvname
Exemplo n.º 6
0
 def _current(self):
     # return the current in Amperes
     resp = self._taco_guard(self._dev.communicate, 'I%d' % self.channel)
     # format is MMMM-E (mantissa/exponent)
     if len(resp) != 6:
         raise CommunicationError(self, 'invalid current readout %r' % resp)
     return float(resp[:4] + 'e' + resp[4:])
Exemplo n.º 7
0
    def _get_pv(self, pvparam, field='value', as_string=False):
        """
        Uses pvaccess to obtain a field from a PV. The default field is value,
        so that

            val = self._get_pv('readpv')

        retrieves the value of the PV. To obtain alarm or other status information,
        the field parameter can be specified:

            alarm = self._get_pv('readpv', field='alarm')

        Args:
            pvparam: The PV parameter to be queried. Is translated to a PV name internally.
            field: Field of the PV to obtain, default is value.

        Returns: Value of the queried PV field.
        """
        # result = self._pvs[pvparam].get(field).toDict().get(field)
        result = _pvget(self._pvs[pvparam], field, as_string)

        if result is None:  # timeout or channel not connected
            raise CommunicationError(self, 'timed out getting PV %r from EPICS'
                                     % self._get_pv_name(pvparam))

        return result
Exemplo n.º 8
0
 def _getRaw(self):
     if parse is None:
         raise NicosError(
             self, 'cannot parse web page, lxml is not '
             'installed on this system')
     url = 'http://%s/web?group=%d' % (self.hostname, self.group)
     try:
         tree = parse(url)
         names = [
             name.text.strip()
             for name in tree.findall('//font[@class="tagname"]')
         ]
         values = [
             value.text.strip()
             for value in tree.findall('//font[@class="pv"]')
         ]
         info = dict(zip(names, values))
         if self.valuename not in info:
             raise ConfigurationError(
                 self, 'value %r not found on '
                 'Memograph page (valid values are %s)' %
                 (self.valuename, ', '.join(map(repr, names))))
         return info[self.valuename]
     except ConfigurationError:  # pass through error raised above
         raise
     except Exception as err:
         raise CommunicationError(
             self, 'Memograph not responding or '
             'changed format: %s' % err)
Exemplo n.º 9
0
    def doPreinit(self, mode):
        # Don't create PVs in simulation mode
        self._pvs = {}
        self._pvctrls = {}
        if mode != SIMULATION:
            # in case we get started in a thread, make sure to use the global
            # CA context in that thread
            if epics.ca.current_context() is None:
                epics.ca.use_initial_context()

            # When there are standard names for PVs (see motor record), the PV
            # names may be derived from some prefix. To make this more flexible,
            # the pv_parameters are obtained via a method that can be overridden
            # in subclasses.
            pv_parameters = self._get_pv_parameters()
            for pvparam in pv_parameters:

                # Retrieve the actual PV-name from (potentially overridden) method
                pvname = self._get_pv_name(pvparam)
                if not pvname:
                    raise ConfigurationError(self, 'PV for parameter %s was '
                                                   'not found!' % pvparam)
                pv = self._pvs[pvparam] = epics.pv.PV(
                    pvname, connection_timeout=self.epicstimeout)
                pv.connect()
                if not pv.wait_for_connection(timeout=self.epicstimeout):
                    raise CommunicationError(self, 'could not connect to PV %r'
                                             % pvname)

                self._pvctrls[pvparam] = pv.get_ctrlvars() or {}
        else:
            for pvparam in self._get_pv_parameters():
                self._pvs[pvparam] = HardwareStub(self)
                self._pvctrls[pvparam] = {}
Exemplo n.º 10
0
    def _send_command(self, prefix, command, retry=None):
        try:
            # Connect once for each request to avoid problems with overlapping
            # commands/responses to/from the Serial->Ethernet device.
            ip, port = self.host.split(':')
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.connect((ip, int(port)))

            message = '{}{}{}\r'.format(prefix, self.index, command)
            self.log.debug('Sending message: ' + message)
            sock.send(message)
            self.log.debug('Message sent, waiting for reply')
            reply = sock.recv(1024)
            self.log.debug('Got reply: ' + str(len(reply)) + ' ' + str(reply))
            sock.close()
            try:
                if reply.endswith('\x06'):
                    return reply[:-1]
                return reply
            except TypeError:
                return None
        except OSError:
            if retry is not None:
                self.log.debug('Retry unsuccessful, raising error.')
                raise CommunicationError(
                    'Communication error with device.') from None

            self.log.debug('Socket error, retrying after 0.1 second sleep.')
            sleep(0.1)
            return self._send_command(prefix, command, True)
Exemplo n.º 11
0
 def doInit(self, mode):
     if mode != SIMULATION:
         if not self.comm('IVR').startswith('MCC'):
             raise CommunicationError(self, 'No Response from Phytron, '
                                      'please check!')
         self._pushParams()
         self.doReset()
Exemplo n.º 12
0
    def writeParameter(self, index, value, store2eeprom=False):
        self.log.debug('writeParameter %d:0x%04x', index, value)
        if store2eeprom:
            self.log.warning('writeParameter stores to eeprom !')
        try:
            index = int(self._paridx.get(index, index))
        except ValueError:
            UsageError(self, 'Unknown parameter %r' % index)
        if self._readStatusWord() & (1 << 7):
            raise UsageError(
                self, 'Can not access Parameters while Motor is '
                'moving, please stop it first!')
        if self.power == 'on':
            self.power = 'off'

        # wait for inactive ACK/NACK
        self.log.debug('Wait for idle ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) == 0:
                break
        else:
            raise CommunicationError(
                self, 'HW still busy, can not write '
                'Parameter, please retry later.')

        self._writeDestination(value)
        if store2eeprom:
            # store to eeprom
            self._writeUpperControlWord((index << 8) | 3)
        else:
            # store to volatile memory
            self._writeUpperControlWord((index << 8) | 1)

        self.log.debug('Wait for ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) != 0:
                break
        else:
            raise CommunicationError(
                self, 'WritePar command not recognized '
                'by HW, please retry later.')

        if self._readStatusWord() & (1 << 14):
            raise CommunicationError(
                self, 'Writing of Parameter %r failed, '
                'got a NACK' % index)
        return self._readReturn()
Exemplo n.º 13
0
 def doWriteRamp(self, ramp):
     ramp = int(ramp / 60.)
     if ramp == 0:
         raise ConfigurationError(
             self, 'ramp is too small; must be at '
             'least 60 V/min')
     resp = self._taco_guard(self._dev.communicate,
                             'V%d=%03d' % (self.channel, ramp))
     if resp:
         raise CommunicationError(
             self, 'could not write ramp, reply from '
             'device: %r' % resp)
     resp = self._taco_guard(self._dev.communicate, 'A%d=01' % self.channel)
     if resp:
         raise CommunicationError(
             self, 'could not save ramp, reply from '
             'device: %r' % resp)
     self.log.info('ramp set to %d V/min and stored in EEPROM', ramp * 60)
Exemplo n.º 14
0
    def _rest_request(self, endpoint):
        response = requests.get('http://{}/{}/{}'.format(
            self.host, endpoint, self.service))
        jsondata = response.json()

        if 'data' in jsondata:
            return jsondata['data']

        raise CommunicationError('Error: {}'.format(jsondata['error']))
Exemplo n.º 15
0
 def doRead(self, maxage=0):
     if epics.ca.current_context() is None:
         epics.ca.use_initial_context()
     result = self._pvs['readpv'].get(timeout=self.epicstimeout,
                                      count=self.count)
     if result is None:  # timeout
         raise CommunicationError(
             self, 'timed out getting PV %r from EPICS' %
             self._get_pv_name('readpv'))
     return result
Exemplo n.º 16
0
 def _execute(self, q, t=5, wait=0):
     try:
         os.write(self._io, q.encode() + b'\n')
     except OSError as err:
         if t == 0:
             raise CommunicationError(self, 'error executing: %s' % err)
         session.delay(0.5)
         self.doReset()
         self._execute(q, t - 1)
     session.delay(wait)
     self._check_status()
Exemplo n.º 17
0
    def doInit(self, mode):
        if mode == SIMULATION:
            return
        self._dev = serial.Serial(self.port)

        # sanity check: try to ask the device for its identification and
        # make sure a suitable string is received
        self._dev.write('*IDN?\n')
        reply = self._dev.readline()
        if not reply.startswith('<some string>'):
            raise CommunicationError('wrong identification: %r' % reply)
Exemplo n.º 18
0
 def _get_pv(self, pvparam, as_string=False):
     # since NICOS devices can be accessed from any thread, we have to
     # ensure that the same context is set on every thread
     if epics.ca.current_context() is None:
         epics.ca.use_initial_context()
     result = self._pvs[pvparam].get(timeout=self.epicstimeout,
                                     as_string=as_string)
     if result is None:  # timeout
         raise CommunicationError(self, 'timed out getting PV %r from EPICS'
                                  % self._get_pv_name(pvparam))
     return result
Exemplo n.º 19
0
    def readParameter(self, index):
        self.log.debug('readParameter %d', index)
        try:
            index = int(self._paridx.get(index, index))
        except ValueError:
            raise UsageError(
                self, 'Unknown parameter %r, try one of %s' %
                (index, ', '.join(self._paridx))) from None
        if self._readStatusWord() & (1 << 7):
            raise UsageError(
                self, 'Can not access Parameters while Motor is '
                'moving, please stop it first!')
        if self.power == 'on':
            self.power = 'off'

        # wait for inactive ACK/NACK
        self.log.debug('Wait for idle ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) == 0:
                break
        else:
            raise CommunicationError(
                self, 'HW still busy, can not read '
                'Parameter, please retry later.')

        self._writeUpperControlWord((index << 8) | 4)

        self.log.debug('Wait for ACK/NACK bits')
        for _ in range(1000):
            if self._readStatusWord() & (3 << 14) != 0:
                break
        else:
            raise CommunicationError(
                self, 'ReadPar command not recognized by '
                'HW, please retry later.')

        if self._readStatusWord() & (1 << 14):
            raise CommunicationError(
                self, 'Reading of Parameter %r failed, '
                'got a NACK' % index)
        return self._readReturn()
Exemplo n.º 20
0
def check_tango_host_connection(address, timeout=3.0):
    """Check pure network connection to the tango host."""
    tango_host = os.environ.get('TANGO_HOST', 'localhost:10000')

    if address.startswith('tango://'):
        tango_host = address.split('/')[2]

    try:
        with tcpSocketContext(tango_host, 10000, timeout=timeout):
            pass
    except socket.error as e:
        raise CommunicationError(str(e))
Exemplo n.º 21
0
 def _getRaw(self):
     url = 'http://%s/Single%s' % (self.hostname, self.port)
     try:
         response = urllib.request.urlopen(url)
         html = response.read()
         return html
     except ConfigurationError:  # pass through error raised above
         raise
     except Exception as err:
         raise CommunicationError(
             self,
             'wut-box not responding or changed format: %s' % err) from err
Exemplo n.º 22
0
 def _getRaw(self):
     url = 'http://%s/Single%s' % (self.hostname, self.port)
     try:
         response = urllib.request.urlopen(url) # pylint:disable=consider-using-with
         html = response.read().decode('utf-8')
         return str(html)
     except ConfigurationError:  # pass through error raised above
         raise
     except Exception as err:
         raise CommunicationError(
             self, 'wut-box not responding or changed format: %s' % err
         ) from err
Exemplo n.º 23
0
 def _get_value(maxage=None):
     # This is the original _get_pv. Unfortunately this class doesn't
     # derive from EpicsDevice, hence I can't use something like
     # EpicsDevice._get_pv(self, ...)
     if epics.ca.current_context() is None:
         epics.ca.use_initial_context()
     result = self._pvs[pvparam].get(timeout=self.epicstimeout,
                                     as_string=as_string)
     if result is None:  # timeout
         raise CommunicationError(
             self, 'timed out getting PV %r from '
             'EPICS' % self._get_pv_name(pvparam))
     return result
Exemplo n.º 24
0
    def _put_pv_blocking(self, pvparam, value, update_rate=0.1, timeout=60):
        if epics.ca.current_context() is None:
            epics.ca.use_initial_context()

        pv = self._pvs[pvparam]

        pv.put(value, use_complete=True)

        start = currenttime()
        while not pv.put_complete:
            if currenttime() - start > timeout:
                raise CommunicationError('Timeout in setting %s' % pv.pvname)
            session.delay(update_rate)
Exemplo n.º 25
0
 def _endatclearalarm(self):
     """Clear alarm for a binary-endat encoder."""
     if self._type is not None and 'endat-protocol' not in self._type:
         return
     try:
         self._attached_bus.send(self.addr, 155, 185, 3)
         session.delay(0.5)
         self._attached_bus.send(self.addr, 157, 0, 3)
         session.delay(0.5)
         self.doReset()
     except Exception as err:
         raise CommunicationError(self,
                                  'cannot clear alarm for encoder') from err
Exemplo n.º 26
0
 def communicate(self, msg, dest, expect_ok=False, expect_hex=0):
     msg = '%02X%02X%s' % (dest, self.source, msg)
     msg += self._crc(msg)
     ret = self._dev.communicate(msg)
     # check reply for validity
     crc = self._crc(ret[:-2])
     if (len(ret) < 7 or ret[4] != '>' or ret[-2:] != crc
             or ret[:2] != '%02X' % self.source
             or ret[2:4] != '%02X' % dest):
         raise CommunicationError(self, 'garbled reply: %r' % ret)
     resp = ret[5:-2]
     if expect_ok and resp != 'OK':
         raise CommunicationError(self, 'unexpected reply: %r' % resp)
     if expect_hex:
         if len(resp) != expect_hex:
             raise CommunicationError(self, 'response invalid: %r' % resp)
         try:
             value = int(resp, 16)
         except ValueError:
             raise CommunicationError(self, 'invalid hex number: %r' % resp)
         return value
     return resp
Exemplo n.º 27
0
 def _getRaw(self):
     if urlopen is None:
         raise NicosError(self, 'cannot parse web page, urllib2 is not '
                          'installed on this system')
     url = 'http://%s/Single%s' % (self.hostname, self.port)
     try:
         response = urlopen(url)
         html = response.read()
         return html
     except ConfigurationError:  # pass through error raised above
         raise
     except Exception as err:
         raise CommunicationError(self, 'wut-box not responding or '
                                  'changed format: %s' % err)
Exemplo n.º 28
0
 def _check_status(self, t=3):
     try:
         os.write(self._io, b'*STB?\n')
         status = os.read(self._io, 100).rstrip().decode()
     except OSError as err:
         if t == 0:
             raise CommunicationError(self, 'error getting status: %s' %
                                      err) from err
         session.delay(0.5)
         self.doReset()
         return self._check_status(t - 1)
     if status != '0':
         self.log.warning('status byte = %s, clearing', status)
         os.write(self._io, b'*CLS\n')
Exemplo n.º 29
0
    def doStart(self, value):
        url = 'http://%s/outputaccess%s?PW=sans1&State=%s&' % (
            self.hostname, self.port, value)
        try:
            response = urllib.request.urlopen(url, timeout=1)
            html = response.read()
            self.log.debug(html)

        except ConfigurationError:  # pass through error raised above
            raise
        except Exception as err:
            raise CommunicationError(
                self,
                'wut-box not responding or changed format: %s' % err) from err
Exemplo n.º 30
0
 def _transmit(self, request, retlen, last_try=False):
     response = ''
     self._dev.write(request)
     for _i in range(self.comtries):
         session.delay(self.bustimeout)
         try:
             data = self._dev.read()
         except Exception:
             data = ''
         if not data:
             continue
         response += data
         if response[-1] in (EOT, DC1, DC2, DC3, ACK, NAK):
             return response
     raise CommunicationError(self, 'no response')