Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5b50eb5

Browse files
committedSep 13, 2019
Merge branch 'develop'
2 parents 50b507e + 1b15c7e commit 5b50eb5

31 files changed

+1498
-59
lines changed
 

‎Example/Tests/LinuxMain.swift

-7
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
// swift-tools-version:4.2
1+
// swift-tools-version:5.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
7-
name: "SwiftyXBeeExample",
7+
name: "ATCommandExample",
88
dependencies: [
99
// Dependencies declare other packages that this package depends on.
10-
.package(url: "https://github.com/samco182/SwiftyXBee", from: "1.0.0"),
11-
10+
.package(url: "https://github.com/samco182/SwiftyXBee", from: "1.1.0"),
1211
],
1312
targets: [
1413
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
1514
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
1615
.target(
17-
name: "SwiftyXBeeExample",
16+
name: "ATCommandExample",
1817
dependencies: ["SwiftyXBee"]),
1918
.testTarget(
20-
name: "SwiftyXBeeExampleTests",
21-
dependencies: ["SwiftyXBeeExample"]),
19+
name: "ATCommandExampleTests",
20+
dependencies: ["ATCommandExample"]),
2221
]
2322
)

‎Examples/ATCommandExample/README.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# ATCommandExample
2+
3+
A simple example of how to use AT Command and AT Command Response API Frames. XBee (ZigBee Series 2) radios must be configured in API mode and **AP mode set to 2 (escape bytes)**.
4+
5+
:warning: For a complete list of available AT Commands, please refer to the [XBee's datasheet](https://www.digi.com/resources/documentation/digidocs/pdfs/90002002.pdf).
6+
7+
All the AT Commands that can be configured/queried with **SwiftyXBee** can be configured/queried using the [XCTU tool](https://www.digi.com/resources/documentation/digidocs/90001526/tasks/t_download_and_install_xctu.htm) as well.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import SwiftyXBee
2+
3+
// Initialize xbee instance
4+
let serialConnection = SerialConnection(speed: .S9600, bitsPerChar: .Eight, stopBits: .One, parity: .None)
5+
let xbee = SwiftyXBee(for: .RaspberryPi3, serialConnection: serialConnection)
6+
7+
// Writing AT Command
8+
print("Writing AT Command: Node Identifier(NI)...")
9+
10+
let nodeIdentifier = "XBee Test"
11+
xbee.sendATCommand(.addressing(.ni(.write(nodeIdentifier))), frameId: .sendNoACK)
12+
13+
// Reading AT Command
14+
xbee.sendATCommand(.addressing(.ni(.read)))
15+
16+
print("Reading AT Command: Node Identifier(NI)...")
17+
18+
do {
19+
let atCommandResponse = try xbee.readATCommandResponse()
20+
print("AT Command Response received: \(atCommandResponse.frameData.commandData) = \(atCommandResponse.frameData.commandData.string)")
21+
} catch let error {
22+
print("Error receiving packet: \(error)")
23+
}

‎Example/Tests/SwiftyXBeeExampleTests/SwiftyXBeeExampleTests.swift ‎Examples/ATCommandExample/Tests/ATCommandExampleTests/ATCommandExampleTests.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import XCTest
22
import class Foundation.Bundle
33

4-
final class SwiftyXBeeExampleTests: XCTestCase {
4+
final class ATCommandExampleTests: XCTestCase {
55
func testExample() throws {
66
// This is an example of a functional test case.
77
// Use XCTAssert and related functions to verify your tests produce the correct
@@ -12,7 +12,7 @@ final class SwiftyXBeeExampleTests: XCTestCase {
1212
return
1313
}
1414

15-
let fooBinary = productsDirectory.appendingPathComponent("SwiftyXBeeExample")
15+
let fooBinary = productsDirectory.appendingPathComponent("ATCommandExample")
1616

1717
let process = Process()
1818
process.executableURL = fooBinary

‎Example/Tests/SwiftyXBeeExampleTests/XCTestManifests.swift ‎Examples/ATCommandExample/Tests/ATCommandExampleTests/XCTestManifests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import XCTest
33
#if !canImport(ObjectiveC)
44
public func allTests() -> [XCTestCaseEntry] {
55
return [
6-
testCase(SwiftyXBeeExampleTests.allTests),
6+
testCase(ATCommandExampleTests.allTests),
77
]
88
}
99
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import XCTest
2+
3+
import ATCommandExampleTests
4+
5+
var tests = [XCTestCaseEntry]()
6+
tests += ATCommandExampleTests.allTests()
7+
XCTMain(tests)

‎Examples/RxTxExample/Package.swift

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// swift-tools-version:5.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
let package = Package(
7+
name: "RxTxExample",
8+
dependencies: [
9+
// Dependencies declare other packages that this package depends on.
10+
.package(url: "https://github.com/samco182/SwiftyXBee", from: "1.1.0"),
11+
],
12+
targets: [
13+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
14+
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
15+
.target(
16+
name: "RxTxExample",
17+
dependencies: ["SwiftyXBee"]),
18+
.testTarget(
19+
name: "RxTxExampleTests",
20+
dependencies: ["RxTxExample"]),
21+
]
22+
)

‎Example/README.md ‎Examples/RxTxExample/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# SwiftyXBeeExample
1+
# RxTxExample
22

3-
A simple example of how to communicate with XBee (ZigBee Series 2) radios in API mode.
3+
A simple example of how to use XBee Rx and Tx API Frames. XBee (ZigBee Series 2) radios must be configured in API mode and **AP mode set to 2 (escape bytes)**.
44

55
⚠️ If you want to run the example code, make sure to use an actual XBee serial number when defining:
66
```swift

‎Example/Sources/SwiftyXBeeExample/main.swift ‎Examples/RxTxExample/Sources/RxTxExample/main.swift

+1-6
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@ import SwiftyXBee
44
let serialConnection = SerialConnection(speed: .S9600, bitsPerChar: .Eight, stopBits: .One, parity: .None)
55
let xbee = SwiftyXBee(for: .RaspberryPi3, serialConnection: serialConnection)
66

7-
87
// Reading a Receive Packet API Frame
9-
108
print("Receiving packet...")
119

1210
do {
@@ -16,17 +14,14 @@ do {
1614
print("Error receiving packet: \(error)")
1715
}
1816

19-
2017
// Sending a Transmit Request API Frame
21-
2218
print("Sending packet...")
19+
2320
let deviceAddress = DeviceAddress(address: 0x0013A20012345678) // For the example to work, replace this for an actual XBee Serial number
2421
let networkAddress = NetworkAddress(address: 0xFFFE) // You can use this address if you don't know the destination's network address
2522
xbee.sendTransmitRequest(to: deviceAddress, network: networkAddress, message: "This is my message to send!")
2623

27-
2824
// Reading a Transmit Status API Frame
29-
3025
do {
3126
let readingPacket = try xbee.readTransmitStatus()
3227
print("Packet sent. Status: \(readingPacket.frameData.deliveryStatus!)")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import XCTest
2+
3+
import RxTxExampleTests
4+
5+
var tests = [XCTestCaseEntry]()
6+
tests += RxTxExampleTests.allTests()
7+
XCTMain(tests)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import XCTest
2+
import class Foundation.Bundle
3+
4+
final class RxTxExampleTests: XCTestCase {
5+
func testExample() throws {
6+
// This is an example of a functional test case.
7+
// Use XCTAssert and related functions to verify your tests produce the correct
8+
// results.
9+
10+
// Some of the APIs that we use below are available in macOS 10.13 and above.
11+
guard #available(macOS 10.13, *) else {
12+
return
13+
}
14+
15+
let fooBinary = productsDirectory.appendingPathComponent("RxTxExample")
16+
17+
let process = Process()
18+
process.executableURL = fooBinary
19+
20+
let pipe = Pipe()
21+
process.standardOutput = pipe
22+
23+
try process.run()
24+
process.waitUntilExit()
25+
26+
let data = pipe.fileHandleForReading.readDataToEndOfFile()
27+
let output = String(data: data, encoding: .utf8)
28+
29+
XCTAssertEqual(output, "Hello, world!\n")
30+
}
31+
32+
/// Returns path to the built products directory.
33+
var productsDirectory: URL {
34+
#if os(macOS)
35+
for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") {
36+
return bundle.bundleURL.deletingLastPathComponent()
37+
}
38+
fatalError("couldn't find the products directory")
39+
#else
40+
return Bundle.main.bundleURL
41+
#endif
42+
}
43+
44+
static var allTests = [
45+
("testExample", testExample),
46+
]
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import XCTest
2+
3+
#if !canImport(ObjectiveC)
4+
public func allTests() -> [XCTestCaseEntry] {
5+
return [
6+
testCase(RxTxExampleTests.allTests),
7+
]
8+
}
9+
#endif

‎Package.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:4.2
1+
// swift-tools-version:5.0
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription

‎README.md

+29-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
## Summary
1313
This is a [SwiftyGPIO](https://github.com/uraimo/SwiftyGPIO) based library for communicating with XBee radios in **API mode**, with support for Series 2 **only**.
1414

15-
This is a **work in progress**. I started coding the library for a project I am currently working on, so, as of now, it only supports RX/TX and Transmit Status API Frames. If you want to contribute to this noble cause, please submit a PR and I will be more than happy to review it and merge it :smile:.
15+
This is a **work in progress**. I started coding the library for a project I am currently working on, so, as of now, it only supports ATCommand, ATCommandResponse, Tx, Rx, and Transmit Status API Frames. If you want to contribute to this noble cause, please submit a PR and I will be more than happy to review it and merge it :smile:.
1616

1717
For more information regarding the RF module, you can consult its [datasheet](https://www.digi.com/resources/documentation/digidocs/pdfs/90002002.pdf).
1818

@@ -44,14 +44,14 @@ The UART pins on the RaspberryPi (pin 14 TXD, pin 15 RXD) need to be enabled via
4444
## Supported Boards
4545
Every board supported by [SwiftyGPIO](https://github.com/uraimo/SwiftyGPIO): RaspberryPis, BeagleBones, C.H.I.P., etc...
4646

47-
To use this library, you'll need a Linux ARM board running [Swift 4.x](https://github.com/uraimo/buildSwiftOnARM) 🚗.
47+
To use this library, you'll need a Linux ARM board running [Swift 5.x](https://github.com/uraimo/buildSwiftOnARM) 🚗.
4848

49-
The example below will use a Raspberry Pi 3B+ board, but you can easily modify the example to use one of the other supported boards. A full working demo project for the RaspberryPi3B+ is available in the **Example** directory.
49+
The examples below will use a Raspberry Pi 3B+ board, but you can easily modify the examples to use one of the other supported boards. Full working demo projects for the RaspberryPi3B+ are available under the **Examples** directory.
5050

5151
## Installation
52-
First of all, makes sure your board is running **Swift 4.x** ⚠️!
52+
First of all, makes sure your board is running **Swift 5.x** ⚠️!
5353

54-
Since Swift 4.x supports Swift Package Manager, you only need to add SwiftXBee as a dependency in your project's `Package.swift` file:
54+
Since Swift 5.x supports Swift Package Manager, you only need to add SwiftXBee as a dependency in your project's `Package.swift` file:
5555

5656
```swift
5757
let package = Package(
@@ -86,6 +86,30 @@ let xbee = SwiftyXBee()
8686
```
8787
This initializer defaults to `.RaspberryPi3` as the selected board and serial connection with `speed: .S9600`, `bitsPerChar: .Eight`, `stopBits: .One`, and `parity: .None)`.
8888

89+
### AT Command Packet
90+
AT-type commands can be sent via API frames to configure your local radio. They can query the settings on the local radio or set parameters. These are all the same commands you typed in transparent/command mode.
91+
92+
For this example, the local radio's *Node Identifier* parameter is been set and read.
93+
94+
Setting AT Command parameter:
95+
``` swift
96+
// The new Node Identifier
97+
let nodeIdentifier = "XBee Test"
98+
99+
xbee.sendATCommand(.addressing(.ni(.write(nodeIdentifier))), frameId: .sendNoACK)
100+
```
101+
Reading AT Command parameter:
102+
```swift
103+
xbee.sendATCommand(.addressing(.ni(.read)))
104+
105+
do {
106+
let atCommandResponse = try xbee.readATCommandResponse()
107+
print("AT Command Response received: \(atCommandResponse.frameData.commandData) = \(atCommandResponse.frameData.commandData.string)")
108+
} catch let error {
109+
print("Error receiving packet: \(error)")
110+
}
111+
```
112+
89113
### Transmit Packets
90114
There a several different types of transmit (TX) packets available. But as mentioned above, as of now, the library only allows **Transmit Request** packets to be sent. A list of all TX packets can be found in the API [documentation](https://www.digi.com/resources/documentation/digidocs/pdfs/90002002.pdf). All classes that end in "Request" are TX packets.
91115
```swift

‎Sources/SwiftyXBee/Helpers/Constants.swift

+12-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public enum FrameType: UInt8 {
3232
case transmitRequest = 0x10
3333
case transmitStatus = 0x8B
3434
case receivePacket = 0x90
35+
case atCommand = 0x08
36+
case atCommandResponse = 0x88
3537
}
3638

3739
// ZigBee Receive Packet Frame
@@ -55,7 +57,7 @@ public enum TransmissionOption: UInt8 {
5557
case extendedTransmissionTimeout = 0x40
5658
}
5759

58-
// ZigBee Transmit Status
60+
// ZigBee Transmit Status Frame
5961
public enum DeliveryStatus: UInt8 {
6062
case success = 0x00
6163
case macACKFailure = 0x01
@@ -83,3 +85,12 @@ public enum DiscoveryStatus: UInt8 {
8385
case addressAndRoute = 0x03
8486
case extendedTimeoutDiscovery = 0x40
8587
}
88+
89+
// AT Command Response Frame
90+
public enum ATCommandStatus: UInt8 {
91+
case ok = 0x00
92+
case error = 0x01
93+
case invalidCommand = 0x02
94+
case invalidParameter = 0x03
95+
case txFailure = 0x04
96+
}

‎Sources/SwiftyXBee/Helpers/Extensions/Array+Extensions.swift

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77

88
import Foundation
99

10-
extension Array where Element == UInt8 {
10+
public extension Array where Element == UInt8 {
11+
/// String representation of byte array
12+
var string: String {
13+
guard let string = String(bytes: self, encoding: .utf8) else { return "" }
14+
return string
15+
}
16+
1117
/// Adds up all the elements in an array of UInt8.
1218
///
1319
/// - Returns: The sum of all the elements
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// Bool+Extensions.swift
3+
// SwiftyXBee
4+
//
5+
// Created by Samuel Cornejo on 9/11/19.
6+
//
7+
8+
import Foundation
9+
10+
public extension Bool {
11+
var uint8: UInt8 {
12+
return self ? 0x01 : 0x00
13+
}
14+
}
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.