Skip to content

Commit

Permalink
[smsmodem] Initial contribution (openhab#12250)
Browse files Browse the repository at this point in the history
* [smsmodem] Initial contribution

This binding connects to a USB serial GSM modem (or a network exposed one, a.k.a ser2net) and allows openHAB to send and receive SMS through it.

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] README fix

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] build/spotless fix

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] compliance with 3rd party license

And long running thread naming convention
And treated some code warning

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] i18n

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Small fixes

update channel
rename action to avoid colision with other binding and a too generic name

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Use of standard Thing properties

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Fix sender identifier error with special character

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Add encoding parameter

For non latin character in SMS

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Apply review

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Split local and remote modem in two thing-types

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Apply review

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Apply review

Signed-off-by: Gwendal Roulleau <[email protected]>

* [smsmodem] Apply code review (removing unnecessary method)

Signed-off-by: Gwendal Roulleau <[email protected]>

Signed-off-by: Gwendal Roulleau <[email protected]>
Co-authored-by: Gwendal Roulleau <[email protected]>
Signed-off-by: Andras Uhrin <[email protected]>
  • Loading branch information
2 people authored and andrasU committed Jan 5, 2024
1 parent 7d09984 commit ad2bb99
Show file tree
Hide file tree
Showing 23 changed files with 122 additions and 107 deletions.
94 changes: 49 additions & 45 deletions bundles/org.openhab.binding.smsmodem/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,100 +4,104 @@ This binding connects to a USB serial GSM modem (or a network exposed one, see s

Serial modem should all use the same communication protocol (AT message) and therefore this binding _should_ be compatible with every dongle.
However, there is a gap between theory and reality and success may vary.
The protocol stack is based on the no longer supported smslib project (more precisely a v4 fork), and all modems supported by this library should be OK.
The protocol stack is based on the no longer supported smslib project (more precisely a v4 fork), and all modems supported by this library should be OK.

The following devices have been reported functional :

- Huawei E180
- Huawei E180

## Supported Things

Two things are supported by this binding :

- A _smsmodembridge_, representing the dongle connected on the local computer
- A _smsmodemremotebridge_, representing the dongle exposed over the network (with ser2net or other similar software)
- A _smsconversation_, representing a conversation between one distant msisdn and the msisdn on the sim card in the dongle.
- A *smsmodembridge*, representing the dongle connected on the local computer
- A *smsmodemremotebridge*, representing the dongle exposed over the network (with ser2net or other similar software)
- A *smsconversation*, representing a conversation between one distant msisdn and the msisdn on the sim card in the dongle.

## Discovery

There is no discovery process for _smsmodembridge_ or _smsmodemremotebridge_ thing.
A _smsconversation_ thing will be discovered and added to the inbox everytime the modem should receive a SMS by a new sender.
There is no discovery process for *smsmodembridge* or *smsmodemremotebridge* thing.
A *smsconversation* thing will be discovered and added to the inbox everytime the modem should receive a SMS by a new sender.

## Thing Configuration

The _smsmodembridge_ or _smsmodemremotebridge_ things requires at least two parameters to work properly.
The *smsmodembridge* or *smsmodemremotebridge* things requires at least two parameters to work properly.

For local _smsmodembridge_:
For local *smsmodembridge*:

| Parameter Name | type | direct serial modem |
| -------------- | ------- | --------------------------------------------- |
| serialPort | text | The serial port to access (eg. /dev/tty/USBx) |
| baud | integer | Baud rate |
| Parameter Name | type | direct serial modem |
|----------------|-------|----------------------|
|serialPort| text | The serial port to access (eg. /dev/tty/USBx) |
|baud| integer | Baud rate |

For remote _smsmodemremotebridge_:
For remote *smsmodemremotebridge*:

| Parameter Name | type | serial over network |
|----------------|-------|----------------------|
|ip| text | IP address of the computer hosting the ser2net service|
|networkPort| integer | The network port of the ser2net service |

| Parameter Name | type | serial over network |
| -------------- | ------- | ------------------------------------------------------ |
| ip | text | IP address of the computer hosting the ser2net service |
| networkPort | integer | The network port of the ser2net service |

The other parameters are optional :

| Parameter Name | type | description |
| ---------------- | ------- | -------------------------------------------------------------------------------------------- |
| simPin | text | If your sim card is protected, fill this field with the PIN code |
| pollingInterval | integer | Delay between two checks for new message (in seconds) |
| delayBetweenSend | integer | Delay to wait between two messages post (in milliseconds, could be necessary for slow modem) |
| Parameter Name | type | description |
|-----------------|------|---------------------|
|simPin | text | If your sim card is protected, fill this field with the PIN code|
|pollingInterval| integer | Delay between two checks for new message (in seconds)|
|delayBetweenSend| integer | Delay to wait between two messages post (in milliseconds, could be necessary for slow modem)|

The *smsconversation* thing is just a shortcut to address/receive messages with a specific msisdn. It is not mandatory to use the binding, as you can use action and trigger channel to send/receive a message once the smsmodem bridge is configured.

| Parameter Name | type | description |
|------------|----------|----------|
| recipient | text | The msisdn of the phone you want to discuss with.|
| deliveryReport | boolean | If enabled, ask the network for a delivery report (default false)|
| encoding | text | The encoding to use when sending the message (either Enc7, Enc8, EncUcs2, EncCustom, default is Enc7). EncUcs2 is good for non latin character, but SMS character size limit is then reduced|

The _smsconversation_ thing is just a shortcut to address/receive messages with a specific msisdn. It is not mandatory to use the binding, as you can use action and trigger channel to send/receive a message once the smsmodem bridge is configured.

| Parameter Name | type | description |
| -------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| recipient | text | The msisdn of the phone you want to discuss with. |
| deliveryReport | boolean | If enabled, ask the network for a delivery report (default false) |
| encoding | text | The encoding to use when sending the message (either Enc7, Enc8, EncUcs2, EncCustom, default is Enc7). EncUcs2 is good for non latin character, but SMS character size limit is then reduced |

## Channels

The _smsconversation_ supports the following channels :
| channel | type | description |
| -------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| receive | String | The last message received |
| send | String | A message to send |
| deliverystatus | String | Delivery status (either UNKNOWN, QUEUED, SENT, PENDING, DELIVERED, EXPIRED, or FAILED). Several status are only possible if the delivery report parameter is enabled |
The *smsconversation* supports the following channels :
| channel | type | description |
|----------|--------|------------------------------|
| receive | String| The last message received |
| send | String| A message to send |
|deliverystatus| String| Delivery status (either UNKNOWN, QUEUED, SENT, PENDING, DELIVERED, EXPIRED, or FAILED). Several status are only possible if the delivery report parameter is enabled|

## Trigger channels

The _smsmodembridge_ and _smsmodemremotebridge_ has the following trigger channel :
| Channel ID | event |
| -------------- | ----------------------------------------------------------------------------------- |
| receivetrigger | The msisdn and message received (concatened with the '\|' character as a separator) |
The *smsmodembridge* and *smsmodemremotebridge* has the following trigger channel :
| Channel ID | event |
|---------------------|----------------------------|
|receivetrigger| The msisdn and message received (concatened with the '\|' character as a separator)|


## Rule action

This binding includes a rule action to send SMS.

```javascript
```
(Rule DSL)
val smsAction = getActions("smsmodem","smsmodem:smsmodembridge:<uid>")
```

```javascript
```
(javascript JSR)
var smsAction = actions.get("smsmodem","smsmodem:smsmodembridge:<uid>");
```

Where uid is the Bridge UID of the _smsmodembridge_ thing.
Where uid is the Bridge UID of the *smsmodembridge* thing.

Once this action instance is retrieved, you can invoke the 'send' method on it:

```java
```
smsAction.sendSMS("1234567890", "Hello world!")
```

Or with a special encoding:

```java
```
smsAction.sendSMS("1234567890", "Hello world!", "EncUcs2")
```

Expand All @@ -107,7 +111,7 @@ smsAction.sendSMS("1234567890", "Hello world!", "EncUcs2")

things/smsmodem.things:

```java
```
Bridge smsmodem:smsmodembridge:adonglename "USB 3G Dongle " [ serialPort="/dev/ttyUSB0", baud="19200" ] {
Thing smsconversation aconversationname [ recipient="XXXXXXXXXXX", deliveryReport="true" ]
}
Expand Down
8 changes: 4 additions & 4 deletions bundles/org.openhab.binding.smsmodem/pom.xml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
<version>4.1.0-SNAPSHOT</version>
<version>3.4.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.smsmodem</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ private ArrayList<InboundMessage> parsePDU(String data, String memLocation) thro
pduString = "00" + pduString;
}
Pdu pdu = parser.parsePdu(pduString);
if (pdu instanceof SmsDeliveryPdu deliveryPdu) {
if (pdu instanceof SmsDeliveryPdu) {
logger.debug("PDU = {}", pdu.toString());
InboundMessage msg = null;
if (pdu.isBinary()) {
msg = new InboundBinaryMessage(deliveryPdu, memLocation, memIndex);
msg = new InboundBinaryMessage((SmsDeliveryPdu) pdu, memLocation, memIndex);
} else {
msg = new InboundMessage(deliveryPdu, memLocation, memIndex);
msg = new InboundMessage((SmsDeliveryPdu) pdu, memLocation, memIndex);
}
msg.setGatewayId(this.modem.getGatewayId());
msg.setGatewayId(this.modem.getGatewayId());
Expand Down Expand Up @@ -153,9 +153,9 @@ private ArrayList<InboundMessage> parsePDU(String data, String memLocation) thro
mpMsgList.add(tmpList);
}
}
} else if (pdu instanceof SmsStatusReportPdu statusReportPdu) {
} else if (pdu instanceof SmsStatusReportPdu) {
DeliveryReportMessage msg;
msg = new DeliveryReportMessage(statusReportPdu, memLocation, memIndex);
msg = new DeliveryReportMessage((SmsStatusReportPdu) pdu, memLocation, memIndex);
msg.setGatewayId(this.modem.getGatewayId());
messageList.add(msg);
}
Expand Down Expand Up @@ -376,8 +376,8 @@ private void processMessage(InboundMessage message) {
String messageSignature = message.getSignature();
if (!this.modem.getReadMessagesSet().contains(messageSignature)) {
this.modem.getDeviceInformation().increaseTotalReceived();
if (message instanceof DeliveryReportMessage deliveryReportMessage) {
modem.processDeliveryReport(deliveryReportMessage);
if (message instanceof DeliveryReportMessage) {
modem.processDeliveryReport((DeliveryReportMessage) message);
} else {
modem.processMessage(message);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ public interface IDeviceInformationListener {

void setMode(String mode);

void setTotalSent(String totalSent);
public void setTotalSent(String totalSent);

void setTotalFailed(String totalFailed);
public void setTotalFailed(String totalFailed);

void setTotalReceived(String totalReceived);
public void setTotalReceived(String totalReceived);

void setTotalFailures(String totalFailure);
public void setTotalFailures(String totalFailure);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,21 @@ public interface IInboundOutboundMessageListener {
*
* @param message The inbound message received
*/
void messageReceived(InboundMessage message);
public void messageReceived(InboundMessage message);

/**
* Implement this method to get warned when
* a message is sent on the network
*
* @param message the message sent
*/
void messageSent(OutboundMessage message);
public void messageSent(OutboundMessage message);

/**
* Implement this method to get warned when
* a message previously sent is received by the recipient
*
* @param message the delivery report message
*/
void messageDelivered(DeliveryReportMessage message);
public void messageDelivered(DeliveryReportMessage message);
}
Original file line number Diff line number Diff line change
Expand Up @@ -194,30 +194,30 @@ public String toString() {
b.append(String.format("Recipient Address: %s%n", getRecipientAddress()));
b.append(String.format("Payload Type: %s%n", payload.getType()));
b.append(String.format("Text payload: %s%n", payload.getText() == null ? "null" : payload.getText()));
if (this instanceof InboundMessage message) {
if (this instanceof InboundMessage) {
b.append(String.format("Sent Date: %s%n", getSentDate()));
b.append(String.format("Memory Storage Location: %s%n", message.getMemLocation()));
b.append(String.format("Memory Index: %d%n", message.getMemIndex()));
b.append(String.format("Memory MP Index: %s%n", message.getMpMemIndex()));
b.append(String.format("Memory Storage Location: %s%n", ((InboundMessage) this).getMemLocation()));
b.append(String.format("Memory Index: %d%n", ((InboundMessage) this).getMemIndex()));
b.append(String.format("Memory MP Index: %s%n", ((InboundMessage) this).getMpMemIndex()));
}
if (this instanceof OutboundMessage message) {
if (this instanceof OutboundMessage) {
b.append(String.format("Sent Date: %s%n",
(message.getSentStatus() == SentStatus.Sent ? getSentDate() : "N/A")));
(((OutboundMessage) this).getSentStatus() == SentStatus.Sent ? getSentDate() : "N/A")));
String ids = "";
for (String opId : message.getOperatorMessageIds()) {
for (String opId : ((OutboundMessage) this).getOperatorMessageIds()) {
ids += (ids.length() == 0 ? opId : "," + opId);
}
b.append(String.format("Operator Message IDs: %s%n", ids));
b.append(String.format("Status: %s%n", message.getSentStatus().toString()));
b.append(String.format("Failure: %s%n", message.getFailureCause().toString()));
b.append(String.format("Status: %s%n", ((OutboundMessage) this).getSentStatus().toString()));
b.append(String.format("Failure: %s%n", ((OutboundMessage) this).getFailureCause().toString()));
b.append(String.format("Request Delivery Reports: %b%n",
message.getRequestDeliveryReport()));
((OutboundMessage) this).getRequestDeliveryReport()));
}
if (this instanceof DeliveryReportMessage message) {
if (this instanceof DeliveryReportMessage) {
b.append(String.format("Original Operator Message Id: %s%n",
message.getOriginalOperatorMessageId()));
b.append(String.format("Delivery Date: %s%n", message.getOriginalReceivedDate()));
b.append(String.format("Delivery Status: %s%n", message.getDeliveryStatus()));
((DeliveryReportMessage) this).getOriginalOperatorMessageId()));
b.append(String.format("Delivery Date: %s%n", ((DeliveryReportMessage) this).getOriginalReceivedDate()));
b.append(String.format("Delivery Status: %s%n", ((DeliveryReportMessage) this).getDeliveryStatus()));
}
b.append(String
.format("== MESSAGE END ========================================================================%n"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ protected void writeBCDAddress(String address, int addressType, int addressLengt
// ADDRESS TYPE
this.baos.write(addressType);
// ADDRESS NUMBERS
// if address.length is not even, pad the string with an F at the end
// if address.length is not even, pad the string an with F at the end
String myaddress = address;
if (myaddress.length() % 2 == 1) {
myaddress = myaddress + "F";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
Expand Down
Loading

0 comments on commit ad2bb99

Please sign in to comment.