def main(): print(" +--------------------------------------+") print(" | XBee Python Library Send Data Sample |") print(" +--------------------------------------+\n") device = XBeeDevice(PORT, BAUD_RATE) # 这部分可选,传输Timeout # Retrieving the configured timeout for synchronous operations. print("Current timeout: %d seconds" % device.get_sync_ops_timeout()) # 默认是4s # Configuring the new timeout (in seconds) for synchronous operations. device.set_sync_ops_timeout(NEW_TIMEOUT_FOR_SYNC_OPERATIONS) try: device.open() # Obtain the remote XBee device from the XBee network. xbee_network = device.get_network() remote_device = xbee_network.discover_device(REMOTE_NODE_ID) if remote_device is None: print("Could not find the remote device") exit(1) print("Sending data to %s >> %s..." % (remote_device.get_64bit_addr(), DATA_TO_SEND)) device.send_data(remote_device, DATA_TO_SEND) print("Success") finally: if device is not None and device.is_open(): device.close()
def run(): global device #dev_logger = utils.enable_logger("digi.xbee.devices", logging.DEBUG) dev_logger = utils.disable_logger("digi.xbee.devices") ################################################################################################### # Look for XBee USB port, to avoid conflicts with other USB devices ################################################################################################### rospy.init_node('fleetCoordinator', anonymous=True) rospy.loginfo("Looking for XBee...") context = pyudev.Context() usbPort = 'No XBee found' for device in context.list_devices(subsystem='tty'): if 'ID_VENDOR' in device and device['ID_VENDOR'] == 'FTDI': usbPort = device['DEVNAME'] device = XBeeDevice(usbPort, 57600) #device = XBeeDevice("/dev/ttyUSB0", 57600) device.open() print("Current timeout: %d seconds" % device.get_sync_ops_timeout()) device.set_sync_ops_timeout(0.1) ################################################################################################### # Get local XBee ID (should be 0, convention for Coordinator) ################################################################################################### ID = utils.bytes_to_int(device.get_16bit_addr().address) if ID == 0: rospy.loginfo("\nHello,\nI am Coordinator " + str(ID)+'\n') else: raise Exception("This XBee device is not the coordinator of the network,\nlook for the XBee device stamped with 'C'.") ################################################################################################### # Initialisation ################################################################################################### #Variables storing the data received by the subscribers global remote_devices, pubGps, pubEuler, pubLB, pubLE, lastDataStr, lastData remote_devices = {} lastDataStr = {} lastData = {} pubGps = [] pubEuler = [] pubLB = [] pubLE = [] xnet = device.get_network() xnet.add_device_discovered_callback(network_callback) xnet.add_discovery_process_finished_callback(network_finished) device.add_data_received_callback(data_received) rate = rospy.Rate(10) GPSdata = GPSFix() eulerAnglesData = Vector3() lineStartData, lineEndData = Pose2D(), Pose2D() global chosen, mode, cmd mode = 0 chosen = 0 cmd = Twist() pygame.init() screen = pygame.display.set_mode( (640,480) ) pygame.display.set_caption('Python numbers') ################################################################################################### # Transmission Loop ################################################################################################### while not rospy.is_shutdown(): if(xnet.is_discovery_running() is False): xnet.start_discovery_process() display(screen) send_command() rate.sleep() if(xnet.is_discovery_running()): xnet.stop_discovery_process() device.close()
def main(): class ReadAD: def __init__(self, start=0): self.lock = threading.Lock() self.value = start def read_AD(self, indice): logging.debug('Waiting for lock') self.lock.acquire() try: self.timeout = False logging.debug('Acquired lock') vcc = nodos_activos[indice].get_parameter("%V") vcc = int(utils.hex_to_string(vcc).replace(' ', ''), 16) # Leemos el valor crudo de las entradas analógicas raw_value_1 = nodos_activos[indice].get_adc_value(IOLINE_IN_0) raw_value_2 = nodos_activos[indice].get_adc_value(IOLINE_IN_1) raw_value_3 = nodos_activos[indice].get_adc_value(IOLINE_IN_2) raw_value_4 = nodos_activos[indice].get_adc_value(IOLINE_IN_3) # Calculamos el valor de temperatura en cada entrada en función de la tensión de alimentación y del tntc_1 = ntc10k_calculate_temp(raw_value_1, vcc) tntc_2 = ntc10k_calculate_temp(raw_value_2, vcc) tntc_3 = ntc10k_calculate_temp(raw_value_3, vcc) tntc_4 = ntc10k_calculate_temp(raw_value_4, vcc) # ************************************************************************ # ESTA ES LA PARTE DE TELEGRAF send_data_to_telegraf.main(REMOTE_NODES_ID[indice], tntc_1, tntc_2, tntc_3, tntc_4, float(vcc)) except TimeoutException: self.timeout = True logging.debug('ADC error') local_device.reset() finally: self.lock.release() return self.timeout # función que realiza las tareas de lectura de las entradas en los nodos timeouts = [] def worker(c, i): #La petición se hace con tiempo variable, si no responde, esto es si da timeout se hacen más rápidas para ver #si el nodo estaba en una secuencia de sueño, si sobre pasa el límite de timeouts cortos ya no se le pregunta más timeouts.append(0) try: while True and (timeouts[i] < MAX_INTENTOS_LEER_DATOS): logging.debug('Stamp: %s', str(datetime.now())) if c.read_AD(i): timeouts[i] += 1 logging.debug("Timeouts %s", timeouts) pause = SHORT_WAIT else: timeouts[i] = 0 #reseteamos la cuenta de timeouts pause = LONG_WAIT logging.debug('Sleeping %0.02f', pause) time.sleep(pause) except ValueError: logging.debug('Worker error') # función que realiza el procedimiento de descubrimiento de los nodos listado en el archivo list_of_nodes.ini nodos_activos = [] def descubre_nodos(): index_devices = 0 try: for index in range(0, len(REMOTE_NODES_ID)): nodo_descubierto = False intentos_descubir = 0 while (nodo_descubierto != True ) and intentos_descubir < MAX_INTENTOS_DESCUBRIMIENTO: remote_device = (xbee_network.discover_device( REMOTE_NODES_ID[index])) if remote_device is None: logging.debug('Could not find the remote device: %s', REMOTE_NODES_ID[index]) intentos_descubir += 1 logging.debug("Nodo: %s", (REMOTE_NODES_ID[index])) logging.debug( 'Intentos descubrimiento restantes: %s', (MAX_INTENTOS_DESCUBRIMIENTO - intentos_descubir)) time.sleep(1) else: nodos_activos.append(remote_device) index_devices += 1 logging.debug('Descubierto: %s', remote_device) nodo_descubierto = True except: logging.debug('Error proceso descubrimiento') # Configuracíon de la salida del log logging.basicConfig( level=logging.DEBUG, format='(%(threadName)-10s) %(message)s', ) # Conexión al nodo local local_device = XBeeDevice(port, baud_rate) xbee_network = local_device.get_network() local_device.open() #descubre_nodos() print(local_device.get_sync_ops_timeout()) local_device.set_sync_ops_timeout(10) print(local_device.get_sync_ops_timeout())
class Device: PORT = '' BAUD_RATE = '' # Grupo de parametros que podem ser setados, nota-se que não são necessariamente os mesmo que podem ser obtidos do xbee.------ PARAM_NODE_ID = "NI" PARAM_PAN_ID = "ID" PARAM_DEST_ADDRESS_H = "DH" PARAM_DEST_ADDRESS_L = "DL" # Valores exemplo PARAM_VALUE_NODE_ID = "Yoda" PARAM_VALUE_PAN_ID = utils.hex_string_to_bytes("1234") PARAM_VALUE_DEST_ADDRESS_H = utils.hex_string_to_bytes("00") PARAM_VALUE_DEST_ADDRESS_L = utils.hex_string_to_bytes("FFFF") # ------------- local_xbee = None remote_xbee = None SixFourBitAddress = "" def __init__(self): super(Device, self).__init__() # Precisa ser chamado toda vez que um xbee remoto for criado. O endereço deve ser previamente conhecido. Pode ser que haja uma maneira melhor. def set_64bitaddres(self, adress): self.SixFourBitAddress = adress def set_port(self, porta): self.PORT = porta def get_port(self): return self.PORT def set_baudrate(self, baud): self.BAUD_RATE = baud def get_baudrate(self): return self.BAUD_RATE def create_nodes(self, numero): self.local_xbee = XBeeDevice(PORT, BAUND_RATE) for x in range(0, numero - 2): self.remote_xbee[x] = RemoteXBeeDevice( local_xbee, XBee64BitAddress.from_hex_string(SixFourBitAddress)) def open_connection(self): self.local_xbee.open() # retorna uma lista com os parâmetros def get_Device_Information(self, xbee): addr_64 = xbee.get_64bit_addr() node_id = xbee.get_node_id() hardware_version = xbee.get_hardware_version() firmware_version = xbee.get_firmware_version() protocol = xbee.get_protocol() operating_mode = xbee.get_operating_mode() dest_addr = xbee.get_dest_address() pan_id = xbee.get_pan_id() power_lvl = xbee.get_power_level() lista_result = [ addr_64, node_id, hardware_version, firmware_version, protocol, operating_mode, dest_addr, pan_id, power_lvl ] return lista_result # Recebe um dicionário com parâmetros def set_Device_Information(self, xbee, dicionario_paramentros): for key in dicionario_parametros: if key == 'PARAM_VALUE_NODE_ID': self.PARAM_VALUE_NODE_ID = dicionario_parametros.get( 'PARAM_VALUE_NODE_ID') if key == 'PARAM_VALUE_PAN_ID': self.PARAM_VALUE_PAN_ID = dicionario_parametros.get( 'PARAM_VALUE_PAN_ID') if key == 'PARAM_VALUE_DEST_ADDRESS_H': self.PARAM_VALUE_DEST_ADDRESS_H = dicionario_parametros.get( 'PARAM_VALUE_DEST_ADDRESS_H') if key == 'PARAM_VALUE_DEST_ADDRESS_L': self.PARAM_VALUE_DEST_ADDRESS_L = dicionario_parametros.get( 'PARAM_VALUE_DEST_ADDRESS_L') xbee.set_parameter(self.PARAM_NODE_ID, bytearray(self.PARAM_VALUE_NODE_ID, 'utf8')) xbee.set_parameter(self.PARAM_PAN_ID, self.PARAM_VALUE_PAN_ID) xbee.set_parameter(self.PARAM_DEST_ADDRESS_H, self.PARAM_VALUE_DEST_ADDRESS_H) xbee.set_parameter(self.PARAM_DEST_ADDRESS_L, self.PARAM_VALUE_DEST_ADDRESS_L) def close_connection(self): self.local_xbee.close() def reset_device(self, xbee): self.xbee.reset() def discover_network(self): xnet = self.local_xbee.get_network() xnet.set_discovery_options({ DiscoveryOptions.APPEND_DD, DiscoveryOptions.DISCOVERY_MYSELF, DiscoveryOptions.APEND_RSSI }) xnet.set_discovery_timeout(15) xnet.start_discovery_process() while xnet.is_discovery_running(): time.sleep(0.5) devices = xnet.get_devices() iterator = iter(devices) lista_nos while iterator.next() is not None: lista_nos.append(get_Device_Information(iterator.next())) return lista_nos def send_synchronous_data(self, remote_xbee, string): self.local_xbee.send_data(remote_xbee, string) # timeout está em segundos. def set_timeout_synchronous_data(self, timeout): self.local_xbee.set_sync_ops_timeout(timeout) def get_timeout_synchronous_data(self): return self.local_xbee.get_sync_ops_timeout() def send_broadcast_data(self, string): self.local_xbee.send_data_broadcast(string) # Definição do callback para recepção de mensagem. def my_data_received_callback(self, xbee_message, remote_xbee): address = xbee_message.remote_xbee.get_64bit_addr() data = xbee_message.data.decode("utf8") print("Received data from %s: %s" % (address, data)) # recebe mensagens por <timer> segundos def receive_data(self, timer): for y in range(0, timer - 1): self.local_xbee.add_data_received_callback( my_data_received_callback) self.local_xbee.del_data_received_callback(my_data_recived_callback) # Precisa de testes para ver como é a saída dos dados e como isso será passado para interface. # Há uma maneira alternativa de se fazer, ver documentação. def log(self): # enable log dev_logger = enable_logger(digi.xbee.devices.__name__, logging.INFO)
def run(): global device, modeV modeV = 0 #dev_logger = utils.enable_logger("digi.xbee.devices", logging.DEBUG) dev_logger = utils.disable_logger("digi.xbee.devices") ################################################################################################### # Look for XBee USB port, to avoid conflicts with other USB devices ################################################################################################### rospy.init_node('fleetEndPoint', anonymous=True) rospy.loginfo("Looking for XBee...") context = pyudev.Context() usbPort = 'No XBee found' for device in context.list_devices(subsystem='tty'): if 'ID_VENDOR' in device and device['ID_VENDOR'] == 'FTDI': usbPort = device['DEVNAME'] device = XBeeDevice(usbPort, 57600) #device = XBeeDevice("/dev/ttyUSB1", 57600) device.open() print("Current timeout: %d seconds" % device.get_sync_ops_timeout()) device.set_sync_ops_timeout(0.1) ################################################################################################### # Get local XBee ID (should be 0, convention for Coordinator) ################################################################################################### ID = utils.bytes_to_int(device.get_64bit_addr().address) if ID == 0: raise Exception("\nThis Shouldn't be a Coordinator" + '\n') else: print("Hello This is " + str(ID)) ################################################################################################### # Initialisation ################################################################################################### #Variables storing the data received by the subscribers global windForceString, windDirectionString, gpsString, eulerAnglesString, posString, beginString, endString, lastData, lastDataStr, pub_send_u_rudder_sail, pub_send_control_mode windForceData, windDirectionData, GPSdata, eulerAnglesData, lineStartData, lineEndData = Float32( ), Float32(), String(), Vector3(), Pose2D(), Pose2D() remote_devices = {} lastDataStr = '' lastData = {} lastData["NMEA"] = '' lastData["windF"] = 0.0 lastData["windT"] = 0.0 lastData["eulerx"] = 0.0 lastData["eulery"] = 0.0 lastData["eulerz"] = 0.0 #xnet = device.get_network() #xnet.add_device_discovered_callback(network_callback) #xnet.add_discovery_process_finished_callback(network_finished) device.add_data_received_callback(data_received) rate = rospy.Rate(10) rospy.Subscriber('/sailboat/GPS/NMEA', String, sub_GPS) rospy.Subscriber('/sailboat/wind', Pose2D, sub_WIND) rospy.Subscriber('/sailboat/IMU', Imu, sub_IMU) rospy.Subscriber('regulator_send_lineBegin', Pose2D, sub_lineBegin) rospy.Subscriber('regulator_send_lineEnd', Pose2D, sub_lineEnd) pub_send_u_rudder_sail = rospy.Publisher('xbee/sailboat_cmd', Twist, queue_size=2) pub_send_control_mode = rospy.Publisher('xbee/mode', Float32, queue_size=2) ################################################################################################### # Transmission Loop ################################################################################################### while not rospy.is_shutdown(): #if(xnet.is_discovery_running() is False): # xnet.start_discovery_process() try: device.send_data( RemoteXBeeDevice(device, XBee64BitAddress.from_hex_string("00")), data_to_bytearray(lastData)) except TimeoutException: #print("timeout") pass except XBeeException: pass if (modeV == 1): pub_send_u_rudder_sail.publish(rudder_sail) mode = Float32(data=0.) mode.data = modeV pub_send_control_mode.publish(mode) rate.sleep() #if(xnet.is_discovery_running()): # xnet.stop_discovery_process() device.close()
def shutdown_cleanly(xbee: XBeeDevice) -> Error: """ Helper function to attempt to cleanly shut down the XBee. Note that only XBee 3 Cellular devices require a clean shutdown; this function behaves as a NOP for XBee 3 Zigbee/802.15.4/DigiMesh devices. You should invoke this function prior to issuing the ATFR command or removing power to the XBee. Otherwise, you risk corrupting/bricking the XBee's cell modem chip. For more info, see the "Clean shutdown" page in the XBee3 Cellular User Guide: https://www.digi.com/resources/documentation/Digidocs/90002258/#Reference/r_clean_shutdown.htm This function assumes that the XBee is currently in API Mode Without Escapes. The clean shutdown is performed by issuing the XBee 3 Cellular ATSD (Shutdown) command to the XBee module. Note that on XBee 3 Zigbee and 802.15.4 devices, the ATSD command does something completely different (SD = Scan Duration). Note that ATSD command does NOT put the XBee 3 Cellular device to sleep. Rather, it simply puts the XBee module (particularly its cell modem chip) into a state in which it is safe to power off. The XBee will continue to respond to API Frames messages even after it is in this shutdown state. Note that the XBee 3 Cellular ATSD command takes a long time to respond, usually somewhere between 6 and 12 seconds, but it could be longer, so give it a nice long timeout, say 30 seconds, since that is what the user guide recommends for alternate airplane mode shutdown approach. We don't retry the shutdown command in a loop because a failure is highly unlikely. If the shutdown command fails, we report the error, but we don't do anything else-- chances are you're still going to turn off the power no matter what, but at least we tried to shut down so gracefully. If the XBee 3 Cellular ATSD fails, we do attempt an alternate, fallback shutdown approach. Note that the shutdown command (ATSD) was not introduced until the August 2019 release of the XBee3 Cellular firmware, so older versions of firmware will need to rely upon this alternate approach. One approach mentioned on the [Clean shutdown page of the User Guide]( https://www.digi.com/resources/documentation/Digidocs/90002258/#Reference/r_clean_shutdown.htm) is to de-assert the DTR_n/SLEEP_REQUEST pin and wait until the SLEEP_STATUS pin goes low. However, if your XBee carrier board hardware was not designed with this in mind, you won't be able to monitor this. Instead, we just wait for a specific reasonable amount of time, say 30 seconds. After all, this is a fallback shutdown approach, and this is better than nothing. However, there is another, bigger issue with the DTR_n/SLEEP_REQUEST approach: this pin might not be configured as a sleep request input! In other words, the XBee register "D8" might instead have it configured as a general-purposes digital I/O pin, in which case strobing this pin won't work. Since I don't want to make any assumptions about how the XBee is configured, I'm going to avoid the pin-based approach. So instead, we will use the third shutdown approach described in the User Guide: send the ATAM (Airplane Mode) command to put the device into airplane mode. Then we wait 30 seconds as prescribed in the User Guide to give it plenty of time to shut down. Note that the ATAM (Airplane Mode) command gets applied immediately; no need to subsequently send ATAC (Apply Configuration) to apply the changes. """ proto = xbee.get_protocol() if proto not in (XBeeProtocol.CELLULAR, XBeeProtocol.CELLULAR_NBIOT): log("%s: Device is not an XBee 3 Cellular; no need for clean shutdown. Bypassing clean shutdown." % func()) return Success xbee_atsd_timeout_sec = 30 xbee_time_to_wait_in_airplane_mode_sec = 30 log("%s: Adjusting the xbee-python command timeout value..." % func()) try: default_timeout_sec = xbee.get_sync_ops_timeout( ) # Store default value so that we can put it back. xbee.set_sync_ops_timeout( xbee_atsd_timeout_sec ) # ATSD takes longer than most commands so give it extra time. except Exception as ex: return Error( "%s: Failed to adjust the xbee-python command timeout value. Reason: " % (func(), ex)) log("%s: Attempting to cleanly shut down the XBee. Sending shutdown command (ATSD)..." % func()) try: xbee.execute_command("SD") log("%s: XBee shutdown command (ATSD) succeeded. Now safe to remove power from the module." % func()) return Success except Exception as ex: log("%s: XBee shutdown command (ATSD) failed. Reason: %s. Will attempt fallback approach." % (func(), ex)) finally: xbee.set_sync_ops_timeout(default_timeout_sec) log("%s: Attempting fallback approach to cleanly shut down. Sending ATAM command and waiting for %s seconds." % (func(), xbee_time_to_wait_in_airplane_mode_sec)) try: xbee.set_parameter("AM", b"\x01") except Exception as ex: return Error("%s: XBee ATAM command failed. Reason: %s" % (func(), ex)) time.sleep(xbee_time_to_wait_in_airplane_mode_sec) log("%s: Done waiting for XBee to enter airplane mode. You may now remove power from the module." % func()) return Success