swARM-at 0.0.4
Une bibliothèque pour la communication avec des modules LoRa via des commandes AT.
Keywords: LoRa AT command RAK3172

# swARM_at

https://docs.rakwireless.com/Product-Categories/WisDuo/RAK3172-Module/Deprecated-AT-Command/

## Class: RAK3172

This class provides an interface to interact with the RAK3172 module via serial communication for both LoRaWAN and P2P communications.

### init(self, port, baud_rate=9600, timeout=1)
Description: Initializes a new instance of the RAK3172 class.
Parameters:
port (str): The COM port where the module is connected.
baud_rate (int, optional): Baud rate for serial communication. Default is 9600.
timeout (int, optional): Timeout for serial communication in seconds. Default is 1.
Exceptions:
Raises InvalidCOMPortException if the provided COM port is not valid.
Raises InvalidBaudRateException if the provided baud rate is not valid.

### connect(self)
Description: Establishes a serial connection with the module.
Output: Prints a message indicating the success or failure of the connection.
### disconnect(self)
Description: Closes the serial connection with the module.
Output: Prints a message indicating that the module has been disconnected.

### set_network_mode(self, lorawan=True)

Description: Sets the network mode to either LoRaWAN or P2P.
Parameters:
lorawan (bool, optional): If True, sets the mode to LoRaWAN, otherwise to P2P. Default is True.
Output: Prints a message indicating the success or failure of the operation.
Returns: The current network mode.
### send_command(self, command)

Description: Sends a command to the module and reads the response.
Parameters:
command (str): The command to send.
Returns: Boolean indicating the success or failure of the command.
### set_app_key(self, app_key)

Description: Sets the application key for LoRaWAN.
Parameters:
app_key (str): The application key to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_app_key(self)

Description: Retrieves the current application key.
Returns: The application key or None if the operation fails.
### set_app_eui(self, app_eui)

Description: Sets the application EUI.
Parameters:
app_eui (str): The application EUI to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_app_eui(self)

Description: Retrieves the current application EUI.
Returns: The application EUI or None if the operation fails.

### is_only_hex(self, chaine)

Description: Utility method to check if a string contains only hexadecimal characters.
Parameters:
chaine (str): The string to check.
Returns: Boolean indicating whether the string contains only hexadecimal characters.
### set_dev_eui(self, dev_eui)

Description: Sets the device EUI.
Parameters:
dev_eui (str): The device EUI to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_dev_eui(self)

Description: Retrieves the current device EUI.
Returns: The device EUI or None if the operation fails.
### set_nwks_key(self, nwks_key)

Description: Sets the network session key for LoRaWAN.
Parameters:
nwks_key (str): The network session key to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_nwks_key(self)

Description: Retrieves the current network session key.
Returns: The network session key or None if the operation fails.
### set_apps_key(self, apps_key)

Description: Sets the application session key for LoRaWAN.
Parameters:
apps_key (str): The application session key to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_apps_key(self)

Description: Retrieves the current application session key.
Returns: The application session key or None if the operation fails.
### set_dev_addr(self, dev_addr)

Description: Sets the device address for LoRaWAN.
Parameters:
dev_addr (str): The device address to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_dev_addr(self)

Description: Retrieves the current device address.
Returns: The device address or None if the operation fails.
### set_join_mode(self, otaa=True)

Description: Sets the join mode to either OTAA or ABP for LoRaWAN.
Parameters:
otaa (bool, optional): If True, sets the mode to OTAA, otherwise to ABP. Default is True.
Output: Prints a message indicating the success or failure of the operation.
Returns: The current join mode.


### set_confirm_mode(self, confirmed=True)

Description: Sets the payload mode to either confirmed or unconfirmed for LoRaWAN.
Parameters:
confirmed (bool, optional): If True, sets the mode to confirmed, otherwise to unconfirmed. Default is True.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating the current payload mode.
### join_network(self, join=1, auto_join=0, reattempt_interval=8, join_attempts=0)

Description: Sends a command to join the LoRaWAN network.
Parameters:
join (int): Join command, usually 1 to join.
auto_join (int): Auto join option, 1 for auto join, 0 for manual.
reattempt_interval (int): Interval in seconds for reattempting join.
join_attempts (int): Number of join attempts.
Output: Prints a message indicating the success, failure, or response of the join command.
Returns: Boolean indicating success, failure, or None for uncertain status.
### check_join_status(self)

Description: Checks if the module has joined the LoRaWAN network.
Returns: Boolean indicating if the module is joined to the network.
### send_lorawan_data(self, port, payload)

Description: Sends data over LoRaWAN.
Parameters:
port (int): The port number to send data on.
payload (str): The payload to send.
Output: Prints a message indicating the success or failure of sending data.
Returns: Boolean indicating success or failure of the data transmission.
### check_last_frame_status(self)

Description: Checks the status of the last frame sent over LoRaWAN.
Returns: Boolean indicating if the last frame was confirmed by the network, or None for uncertain status.
### receive_data(self)

Description: Retrieves data received by the module.
Returns: A tuple containing the port and payload of received data, or (None, None) if no data is received or in case of an error.
### set_adr(self, enable)

Description: Enables or disables Adaptive Data Rate (ADR).
Parameters:
enable (bool): Set to True to enable ADR, False to disable.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure of setting ADR.
### get_adr_status(self)

Description: Retrieves the current status of ADR.
Returns: Boolean indicating if ADR is enabled or disabled, or None for uncertain status.

### set_lorawan_class(self, lorawan_class)

Description: Sets the LoRaWAN class of the device.
Parameters:
lorawan_class (str): The class to set ('A', 'B', or 'C').
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_lorawan_class(self)

Description: Retrieves the current LoRaWAN class of the device.
Returns: A string indicating the current LoRaWAN class or None if the operation fails.
### set_duty_cycle(self, enable)

Description: Enables or disables the duty cycle.
Parameters:
enable (bool): Set to True to enable the duty cycle, False to disable.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_duty_cycle(self)

Description: Retrieves the current status of the duty cycle.
Returns: A string indicating if the duty cycle is enabled or disabled, or None if the operation fails.
### set_frequency_band(self, band)

Description: Sets the frequency band for LoRaWAN communication.
Parameters:
band (str): The frequency band to set.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_frequency_band(self)

Description: Retrieves the current frequency band for LoRaWAN communication.
Returns: A string indicating the current frequency band or None if the operation fails.
### set_link_check(self, mode)

Description: Sets the link check mode.
Parameters:
mode (int): The link check mode to set (0, 1, or 2).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_link_check(self)

Description: Retrieves the current link check mode.
Returns: An integer indicating the current link check mode or None if the operation fails.
### set_public_network_mode(self, mode)

Description: Sets the public network mode.
Parameters:
mode (str): '0' for private network mode, '1' for public network mode.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_public_network_mode(self)

Description: Retrieves the current public network mode.
Returns: A string indicating the current public network mode or None if the operation fails.
### get_local_time(self)

Description: Retrieves the local time in UTC format.
Returns: A string indicating the local time or None if the operation fails.

### get_rssi(self)

Description: Retrieves the RSSI (Received Signal Strength Indicator) of the last received packet.
Returns: An integer indicating the RSSI value in dBm, or None if the operation fails.
### get_snr(self)

Description: Retrieves the SNR (Signal-to-Noise Ratio) of the last received packet.
Returns: An integer indicating the SNR value, or None if the operation fails.
### request_utc_time(self)

Description: Sends a request for UTC time to the network.
Output: Prints a message indicating the success or failure of the request.
Returns: Boolean indicating success or failure of the UTC time request.
### set_p2p_frequency(self, frequency)

Description: Sets the frequency for P2P communication.
Parameters:
frequency (int): The frequency to set in Hz.
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_p2p_frequency(self)

Description: Retrieves the current frequency for P2P communication.
Returns: An integer indicating the current P2P frequency in Hz, or None if the operation fails.
### set_p2p_spreading_factor(self, sf)

Description: Sets the spreading factor for P2P communication.
Parameters:
sf (int): The spreading factor to set (between 6 and 12).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_p2p_spreading_factor(self)

Description: Retrieves the current spreading factor for P2P communication.
Returns: An integer indicating the current spreading factor, or None if the operation fails.
### set_p2p_bandwidth(self, bw)

Description: Sets the bandwidth for P2P communication.
Parameters:
bw (int): The bandwidth to set in kHz (125, 250, or 500).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_p2p_bandwidth(self)

Description: Retrieves the current bandwidth for P2P communication.
Returns: An integer indicating the current bandwidth in kHz, or None if the operation fails.
### set_p2p_coding_rate(self, cr)

Description: Sets the coding rate for P2P communication.
Parameters:
cr (int): The coding rate to set (0 for 4/5, 1 for 4/6, 2 for 4/7, or 3 for 4/8).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_p2p_coding_rate(self)

Description: Retrieves the current coding rate for P2P communication.
Returns: An integer indicating the current coding rate, or None if the operation fails.

### set_p2p_parameters(self, freq, sf, bw, cr, preamble, power)

Description: Sets multiple P2P parameters at once.
Parameters:
freq (int): Frequency in Hz.
sf (int): Spreading factor (between 6 and 12).
bw (int): Bandwidth in kHz (125, 250, or 500).
cr (int): Coding rate (0 for 4/5, 1 for 4/6, 2 for 4/7, or 3 for 4/8).
preamble (int): Preamble length (between 2 and 65535).
power (int): Transmit power (between 5 and 22 dBm).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### get_p2p_parameters(self)

Description: Retrieves the current P2P parameters.
Returns: A list containing the current P2P parameters (frequency, spreading factor, bandwidth, coding rate, preamble length, and power) or None if the operation fails.
### send_p2p_data(self, payload)

Description: Sends data in P2P mode.
Parameters:
payload (str): The payload to send (maximum 255 bytes).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.
### set_p2p_receive_window(self, timeout)

Description: Sets the P2P receive window timeout.
Parameters:
timeout (int): Timeout in milliseconds (0 for no timeout, up to 65535).
Output: Prints a message indicating the success or failure of the operation.
Returns: Boolean indicating success or failure.

## Examples

A simple example to join a LoRaWAN Network using OTAA method.

```python
from swARM_at.RAK3172 import RAK3172, VALID_BAUD_RATE, VALID_COM_PORT, VALIDE_BAND
from swARM_at.exceptions import InvalidBaudRateException, InvalidCOMPortException
rak = RAK3172("COM3")
rak.connect()
rak.set_network_mode()
rak.set_join_mode()
rak.join_network(1, 0, 10, 8)
rak.check_join_status()
rak.send_lorawan_data(20,"112233445566778899")
```


A simple example to display LoRaWAN device infos 

```python
from swARM_at.RAK3172 import RAK3172, VALID_BAUD_RATE, VALID_COM_PORT, VALIDE_BAND
from swARM_at.exceptions import InvalidBaudRateException, InvalidCOMPortException
rak = RAK3172("COM3")
rak.connect()
devEUI=rak.get_dev_eui()
AppEUI=rak.get_app_eui()
AppKey=rak.get_app_key()
print(f'DevEUI={devEUI}\r\nAppEUI={AppEUI}\r\nAppKey={AppKey}')
```

A simple example to send somehtin in LoRa Mode and set a RX Window

```python
from swARM_at.RAK3172 import RAK3172, VALID_BAUD_RATE, VALID_COM_PORT, VALIDE_BAND
from swARM_at.exceptions import InvalidBaudRateException, InvalidCOMPortException
rak = RAK3172("COM3")
rak.connect()
rak.set_network_mode(False)
rak.send_p2p_data("FF112233")
rak.set_p2p_receive_window(5000)
print(rak.read_response())
```

## Class: RAK4270

This class provides an interface to interact with the RAK4270 module via serial communication for both LoRaWAN and P2P communications using the `at+set_config` and `at+get_config` command format.

### Key Differences from RAK3172:
- Uses `at+set_config` format instead of direct AT commands
- Different command syntax for configuration parameters
- Same functionality but adapted command structure

### Examples for RAK4270

A simple example to join a LoRaWAN Network using OTAA method with RAK4270:

```python
from swARM_at.RAK4270 import RAK4270, VALID_BAUD_RATE, VALID_COM_PORT, VALID_BAND
from swARM_at.exceptions import InvalidBaudRateException, InvalidCOMPortException
rak = RAK4270("COM3")
rak.connect()
rak.set_network_mode()  # LoRaWAN mode
rak.set_join_mode(True)  # OTAA mode
rak.set_lora_class("A")
rak.set_region("EU868")
rak.set_dev_eui("1133557799224466")
rak.set_app_eui("1000000000000009")
rak.set_app_key("04FA4E626EF5CF227C969601176275C2")
rak.join_network()
rak.send_lorawan_data(2, "112233445566778899")
```

A simple example to display RAK4270 device infos:

```python
from swARM_at.RAK4270 import RAK4270, VALID_BAUD_RATE, VALID_COM_PORT, VALID_BAND
from swARM_at.exceptions import InvalidBaudRateException, InvalidCOMPortException
rak = RAK4270("COM3")
rak.connect()
devEUI = rak.get_dev_eui()
AppEUI = rak.get_app_eui()
AppKey = rak.get_app_key()
print(f'DevEUI={devEUI}\r\nAppEUI={AppEUI}\r\nAppKey={AppKey}')
```

A simple example to send something in P2P Mode:

```python
from swARM_at.RAK4270 import RAK4270, VALID_BAUD_RATE, VALID_COM_PORT, VALID_BAND
from swARM_at.exceptions import InvalidBaudRateException, InvalidCOMPortException
rak = RAK4270("COM3")
rak.connect()
rak.set_network_mode(False)  # P2P mode
rak.set_p2p_config(869525000, 7, 0, 1, 5, 5)  # freq, sf, bw, cr, preamble, power
rak.send_p2p_data("FF112233")
```


# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- **RAK4270 Module Support**: New `RAK4270` class for students using RAK4270 LoRaWAN modules
  - Complete AT command interface using `at+set_config`/`at+get_config` format
  - Support for LoRaWAN communication (OTAA/ABP modes, all frequency bands)
  - Support for P2P (peer-to-peer) communication
  - Comprehensive parameter validation and error handling
  - Cross-platform serial port support (Windows COM, Linux/macOS /dev/tty*)

- **Enhanced Documentation**
  - Added `CLAUDE.md` with development guidelines and architecture documentation
  - Extended `README.md` with RAK4270 usage examples and comparisons
  - Added comprehensive docstrings to RAK4270 class and key methods
  - Provided practical examples for educational use (LoRaWAN OTAA, P2P, device info)

- **Robust Test Coverage**
  - 83 comprehensive test cases for RAK4270 (92% code coverage)
  - Error handling and edge case validation
  - Mock-based testing for reliable CI/CD without hardware dependencies
  - Both success and failure scenario testing

### Changed
- Updated package `__init__.py` to export both `RAK3172` and `RAK4270` classes
- Enhanced README.md with side-by-side comparison of RAK3172 vs RAK4270 usage

### Technical Details
- RAK4270 class follows same architecture patterns as existing RAK3172 for consistency
- Uses `unittest.mock` for comprehensive testing without hardware dependencies  
- Validates hex parameters, port ranges, and AT command responses
- Supports all LoRaWAN frequency bands (EU433, EU868, US915, AU915, etc.)
- Thread-safe serial communication with proper exception handling

### For Educators
- Students can now work with both RAK3172 (newer) and RAK4270 (legacy) modules
- Consistent API design allows easy transition between module types
- Comprehensive examples and documentation support learning objectives
- Robust error handling provides clear feedback for debugging

## [0.0] - Previous Release
- Initial implementation with RAK3172 module support
- Basic LoRaWAN and P2P communication functionality
- Core AT command interface and serial communication