docs: def inspect_sensors(self, name=None, timeout=None):
          """Inspect all or one sensor on the device. Update sensors index.
  
          Parameters
          ----------
          name : str or None, optional
              Name of the sensor or None to get all sensors.
          timeout : float or None, optional
              Timeout for sensors inspection, None for no timeout
  
          Returns
          -------
          Tornado future that resolves with:
  
          changes : :class:`~katcp.core.AttrDict`
              AttrDict with keys ``added`` and ``removed`` (of type
              :class:`set`), listing the sensors that have been added or removed
              respectively.  Modified sensors are listed in both. If there are no
              changes, returns ``None`` instead.
  
          Example structure:
  
              {'added': set(['sens1', 'sens2']),
               'removed': set(['sens10', 'sens20'])}
  
          """
          if name is None:
              msg = katcp.Message.request('sensor-list')
          else:
              msg = katcp.Message.request('sensor-list', name)
  
          reply, informs = yield self.katcp_client.future_request(
              msg, timeout=timeout)
          self._logger.debug('{} received {} sensor-list informs, reply: {}'
              .format(self.bind_address_string, len(informs), reply))
          if not reply.reply_ok():
              # If an unknown sensor is specified the desired result is to return
              # an empty list, even though the request will fail
              if name is None or 'Unknown sensor' not in reply.arguments[1]:
                  raise SyncError('Error reply during sync process: {}'
                                  .format(reply))
  
  
          sensors_old = set(self._sensors_index.keys())
          sensors_updated = set()
          for msg in informs:
              sen_name = msg.arguments[0]
              sensors_updated.add(sen_name)
              sen = {'description': msg.arguments[1],
                     'units': msg.arguments[2],
                     'sensor_type': msg.arguments[3],
                     'params': msg.arguments[4:]}
              self._update_index(self._sensors_index, sen_name, sen)
  
          added, removed = self._difference(
              sensors_old, sensors_updated, name, self._sensors_index)
  
          for sensor_name in removed:
              if sensor_name in self._sensor_object_cache:
                  del self._sensor_object_cache[sensor_name]
  
          if added or removed:
              raise Return(AttrDict(added=added, removed=removed))