Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[smsmodem] Initial contribution #12250

Merged
merged 14 commits into from
Dec 3, 2022
Merged
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1476,6 +1476,11 @@
<artifactId>org.openhab.binding.smhi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.smsmodem</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.sncf</artifactId>
Expand Down
24 changes: 24 additions & 0 deletions bundles/org.openhab.binding.smsmodem/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-addons

== Third-party Content
This binding includes code (under the org.smslib package) from the SMSlib project
The code have been slighly modified to use the serial library provided by the openHAB runtime (amongst small other fixes, and code compliance for openHAB)

smslib
* license Apache 2.0 License
* https://github.com/tdelenikas/smslib

PduUtils Library
* license Apache 2.0 License
146 changes: 146 additions & 0 deletions bundles/org.openhab.binding.smsmodem/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
# SMSModem Binding

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

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 following devices have been reported functional :

- 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.

## 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.

## Thing Configuration

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

For local *smsmodembridge*:

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

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 |


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)|

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|

## 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)|
fwolter marked this conversation as resolved.
Show resolved Hide resolved


## Rule action

This binding includes a rule action to send SMS.

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

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

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

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

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

Or with a special encoding:

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

## Full Example

### Thing configuration

things/smsmodem.things:

```
Bridge smsmodem:smsmodembridge:adonglename "USB 3G Dongle " [ serialPort="/dev/ttyUSB0", baud="19200" ] {
Thing smsconversation aconversationname [ recipient="XXXXXXXXXXX", deliveryReport="true" ]
}
```

### Send SMS

`sms.rules` for DSL:

```java
rule "Alarm by SMS"
when
Item Alarm changed
then
val smsAction = getActions("smsmodem","smsmodem:smsmodembridge:dongleuid")
smsAction.sendSMS("33123456789", "Alert !")
end
```

### Receive and forward SMS

`sms.py` with the python helper library :

```python
@rule("smscommand.receive", description="Receive SMS and resend it")
@when("Channel smsmodem:smsmodembridge:dongleuid:receivetrigger triggered")
def smscommand(event):
sender_and_message = event.event.split("|")
sender = sender_and_message[0]
content = sender_and_message[1]
actions.get("smsmodem", "smsmodem:smsmodembridge:dongleuid").send("336123456789", sender + " just send the following message: " + content)
```
39 changes: 39 additions & 0 deletions bundles/org.openhab.binding.smsmodem/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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>3.4.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.smsmodem</artifactId>

<name>openHAB Add-ons :: Bundles :: SMSModem Binding</name>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>add-source</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<sources>
<source>src/3rdparty/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.smslib;

import java.util.BitSet;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Extracted from SMSLib
*/
@NonNullByDefault
public class Capabilities {
BitSet caps = new BitSet();

public enum Caps {
CanSendMessage,
CanSendBinaryMessage,
CanSendUnicodeMessage,
CanSendWapMessage,
CanSendFlashMessage,
CanSendPortInfo,
CanSetSenderId,
CanSplitMessages,
CanRequestDeliveryStatus,
CanQueryDeliveryStatus,
CanQueryCreditBalance,
CanQueryCoverage,
CanSetValidityPeriod
}

public void set(Caps c) {
this.caps.set(c.ordinal());
}

public BitSet getCapabilities() {
return (BitSet) this.caps.clone();
}

@Override
public String toString() {
BitSet bs = (BitSet) getCapabilities().clone();
StringBuffer b = new StringBuffer();
for (Caps c : Caps.values()) {
b.append(String.format("%-30s : ", c.toString()));
b.append(bs.get(c.ordinal()) ? "YES" : "NO");
b.append("\n");
}
return b.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.smslib;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Wrapper for communication exception
*/
@NonNullByDefault
public class CommunicationException extends Exception {

private static final long serialVersionUID = -5175636461754717860L;

public CommunicationException(String message, Exception cause) {
super(message, cause);
}

public CommunicationException(String message) {
super(message);
}
}
Loading