def _send_poll_request(self): # Merge all poll items into one set. # Note: This does not try to merge any overlapping ranges. Those will # lead to parameters being read multiple times. items = functools.reduce(lambda x, y: x.union(y), self._poll_subscriptions.values(), set()) self.log.debug("_send_poll_request: request contains %d items", len(items)) m = proto.Message() m.type = proto.Message.REQ_SET_POLL_ITEMS for bus, dev, item in items: proto_item = m.request_set_poll_items.items.add() proto_item.bus = bus proto_item.dev = dev try: lower, upper = item proto_item.par = lower proto_item.count = (upper - lower) + 1 except TypeError: proto_item.par = item proto_item.count = 1 assert len(items) == len(m.request_set_poll_items.items) return self.connection.queue_request(m)
def set_rc(self, bus, device, on_off): m = proto.Message() m.type = proto.Message.REQ_RC m.request_rc.bus = bus m.request_rc.dev = device m.request_rc.rc = on_off return self.connection.queue_request(m)
def set_parameter(self, bus, device, address, value): """Set the parameter at (bus, device, address) to the given value. Returns a basic_model.ResultFuture containing a basic_model.SetResult instance on success. """ ret = bm.ResultFuture() def on_response_received(f): try: if not f.cancelled(): ret.set_result( bm.SetResult(bus, device, address, f.result().response.set_result.val, value)) except Exception as e: if not ret.done(): ret.set_exception(e) m = proto.Message() m.type = proto.Message.REQ_SET m.request_set.bus = int(bus) m.request_set.dev = int(device) m.request_set.par = int(address) m.request_set.val = int(value) m.request_set.mirror = False request_future = self.connection.queue_request(m).add_done_callback( on_response_received) def cancel_request(f): if f.cancelled(): request_future.cancel() ret.add_done_callback(cancel_request) return ret
def scanbus(self, bus): def on_bus_scanned(f): try: self._handle_scanbus_result(f.result().response) except Exception: self.log.exception("%s: scanbus error" % self) m = proto.Message() m.type = proto.Message.REQ_SCANBUS m.request_scanbus.bus = bus return self.connection.queue_request(m).add_done_callback( on_bus_scanned)
def _socket_readyRead(self): if self._read_size <= 0 and self._socket.bytesAvailable() >= 2: # Note: added the bytes() conversion when porting to PySide2. # Without it the struct.unpack() call would lead to a segmentation # fault. data = bytes(self._socket.read(2)) self._read_size = struct.unpack('!H', data)[0] self.log.debug("_socket_readyRead: incoming msg size = %d", self._read_size) if self._read_size > 0 and self._socket.bytesAvailable() >= self._read_size: message_data = bytes(self._socket.read(self._read_size)) self.log.debug("_socket_readyRead: read %u bytes from socket", len(message_data)) try: message = proto.Message() message.ParseFromString(message_data) self.log.debug("_socket_readyRead: received %s", message) except proto_message.DecodeError as e: self.log.error("Could not deserialize incoming message: %s.", e) self.disconnectClient() return self._read_size = 0 self.message_received.emit(message) if proto.is_response(message): request, future = self._current_request if proto.is_error_response(message): future.set_exception(proto.MessageError( message=message, request=request)) self.error_received.emit(message) else: future.set_result(RequestResult(request, message)) self.response_received.emit(request, message, future) self._current_request = None if self.get_queue_size() > 0: self._start_write_request() else: self.queue_empty.emit() elif proto.is_notification(message): self.notification_received.emit(message) if self._socket.bytesAvailable() >= 2: # Handle additional available data. self._socket_readyRead()
def disconnectMrc(self): self.log.debug("disconnectMrc") ret = Future() if self.server.is_running(): def handle_quit_response(f): self.log.info( f"disconnectMrc.handle_quit_response result: {f.result().response.response_bool}" ) r = f.result() if r.response.response_bool: def on_server_stopped(stopFuture): self.log.debug( f"disconnectMrc.on_server_stopped {stopFuture}") self._is_connected = False self._is_connecting = False ret.set_result(True) def stop_server(disconnectFuture): self.log.debug( f"disconnectMrc.stop_server {disconnectFuture}") self.server.stop().add_done_callback(on_server_stopped) self.connection.disconnectMrc().add_done_callback( stop_server) else: self.log.debug( "disconnectMrc.handle_quit_response: quit response was False!" ) ret.set_result(False) req = proto.Message() req.type = proto.Message.REQ_QUIT self.queue_request(req).add_done_callback(handle_quit_response) else: ret.set_result(True) return ret
def _start_write_request(self): if not self.is_connected(): self.log.debug("_start_write_request: not connected") return if self._current_request is not None: self.log.debug("_start_write_request: request in progress") return while len(self._queue): str_request, future = self._queue.pop(False) # FIFO order request = proto.Message() request.ParseFromString(str_request) self._current_request = (request, future) self.queue_size_changed.emit(len(self._queue)) if future.set_running_or_notify_cancel(): break if future.cancelled(): self._current_request = None return self.log.debug("_start_write_request: request=%s, str_request=%s, len(str_request)=%d", request, str_request, len(str_request)); data = str_request data = struct.pack('!H', len(data)) + data # prepend message size self.log.debug("_start_write_request: writing %s (len=%d)", request, len(data)) if self._socket.write(bytes(data)) == -1: future.set_exception(util.SocketError(self._socket.error(), self._socket.errorString())) else: def bytes_written(): self.log.debug("_start_write_request: request %s sent", request) self._socket.bytesWritten.disconnect(bytes_written) self.request_sent.emit(request, future) self._socket.bytesWritten.connect(bytes_written)
def read_parameter(self, bus, device, address): """Read the parameter at (bus, device address). Returns a basic_model.ResultFuture containing a basic_model.ReadResult instance on success. """ ret = bm.ResultFuture() def on_response_received(f): #self.log.warning("read_parameter: ret(%s)._callbacks=%s", # ret, ret._callbacks) try: ret.set_result( bm.ReadResult(bus, device, address, f.result().response.response_read.val)) except Exception as e: ret.set_exception(e) m = proto.Message() m.type = proto.Message.REQ_READ m.request_read.bus = bus m.request_read.dev = device m.request_read.par = address m.request_read.mirror = False request_future = self.connection.queue_request(m).add_done_callback( on_response_received) #self.log.warning("read_parameter: request_future(%s)._callbacks=%s", # request_future, request_future._callbacks) def cancel_request(f): if f.cancelled(): request_future.cancel() ret.add_done_callback(cancel_request) return ret
def set_silenced(self, silenced): m = proto.Message() m.type = proto.Message.REQ_SET_SILENCED m.request_set_silenced.silenced = silenced return self.connection.queue_request(m)
def release_write_access(self): m = proto.Message() m.type = proto.Message.REQ_RELEASE_WRITE_ACCESS return self.connection.queue_request(m)
def acquire_write_access(self, force=False): m = proto.Message() m.type = proto.Message.REQ_ACQUIRE_WRITE_ACCESS m.request_acquire_write_access.force = force return self.connection.queue_request(m)