Hologram's Python SDK is an easy-to-use interface for communicating with the Hologram cloud, other cloud services, and SMS destinations.
It's designed to be run on small Linux devices such as Raspberry Pi, which are connected to the internet using a USB Cellular Modem. Source code is available on GitHub.
Hologram CLI
Don't want to have to write your own scripts? Just need to send data from your device to your apps?
Hologram's Command-Line Interface (CLI) is takes the most useful features of the Python SDK and provides one-line commands you can use from your console.
Installation
Requirements
- Python 3.9
We recommend using the SDK with a Raspberry Pi running Raspbian Buster. If you want to use other Linux distributions, make sure to stop the modem manager or other tools that might interfere with the serial port.
Procedure
We wrote scripts to ease the installation process.
Please run this command to download the script that installs the Python SDK:
curl -L hologram.io/python-install | bash
Please run this command to download the script that updates the Python SDK:
curl -L hologram.io/python-update | bash
If everything goes well, you're done and ready to use the SDK.
Using with Python 2
Older versions of the SDK that work with Python 2 are still available on PyPI. You can install these directly with pip:
bash sudo pip install hologram-python~=0.8.3
You might be missing some dependencies that would normally get installed by our install script above. If you get any errors, try installing some more packages:
bash sudo apt install python pip ppp libpython2.7-dev
And then try running the pip install command again.
Credentials
The credentials dictionary can be used to specify the 8 character device key of your Hologram Device. This is generally used for HologramCloud purposes and is explained in more detail below. You shouldn't need to specify the devicekey
parameter unless you're using CSRPSK Authentication. This is described in detail below.
Credentials dictionary keys:
- devicekey (string) — The 8 character device key obtained from your dashboard.
Example:
from Hologram.HologramCloud import HologramCloud
credentials = {'devicekey': '12345a7b'}
Cloud
Cloud is a base class that acts as a fundamental interface in which CustomCloud and HologramCloud is built on.
Properties:
- version (string) — A formatted Hologram SDK version string.
- network_type (string) — A formatted string of the current network type.
Example:
cloud = HologramCloud(dict(), network='cellular')
print cloud.version
# Prints 0.7.0
print cloud.network_type
# Prints either 'Network Agnostic Mode' or 'Cellular'
HologramCloud
HologramCloud
is a subclass of CustomCloud
and is the main way to use our cloud via the SDK. The Hologram cloud parameters/configs are used to populate properties in CustomCloud
. In other words, the HologramCloud
property values are:
- send_host —
'cloudsocket.hologram.io'
- send_port —
9999
- receive_host —
'0.0.0.0'
- receive_port —
4010
Note: The HologramCloud
inbound functionality, which utilizes both receive_host
and receive_port
, will only work if the SDK is used in a Hologram cellular connected device. Please use with caution.
Properties:
- credentials (dict()) — The dictionary stores the credentials required to make remote calls to the Hologram Cloud.
HologramCloud(credentials, network='', authentication_type='totp')
The HologramCloud constructor is responsible for initializing many of SDK components selected by the user.
Parameters:
- credentials (dict()) — The dictionary used to store the keys for authentication purposes.
- network (string) — The Network interface that you intend to use for this HologramCloud instance. Default to '', which is to set up non-network mode.
- authentication_type (string) — The Authentication type used by HologramCloud. This can be either csrpsk or totp. Default to totp.
Network interface options:
These are cellular network interfaces (strings) that you can use to choose which Network interface you want to use for the connectivity layer in the Hologram SDK.
cellular
— Cellular interface.''
— Empty string for network agnostic (non-network) mode.
Example:
from Hologram.HologramCloud import HologramCloud
credentials = {'devicekey': '1234abcd'}
hologram = HologramCloud(credentials, network='cellular') # 1st example with cellular network interface.
.sendMessage(message, topics=None, timeout=5)
This method sends a message to the specified host. This will also broadcast the message.sent event if the message is sent successfully.
Parameters:
- message (string) — The message that will be sent.
- topics (string array, optional) — The topic(s) that will be sent.
- timeout (int) — A timeout period in seconds for when the socket should close if it doesn't receive any response. The default timeout is 5 seconds.
Returns: A Hologram response code (int).
There are specific error codes that will be returned:
ERR_OK
(0
) — The message has been sent successfully.ERR_CONNCLOSED
(1
) — Connection was closed so we couldn't read the whole message.ERR_MSGINVALID
(2
) — Failed to parse the message.ERR_AUTHINVALID
(3
) — Auth section of the message was invalid.ERR_PAYLOADINVALID
(4
) — Payload type was invalid.ERR_PROTINVALID
(5
) — Protocol type was invalid.ERR_INTERNAL
(6
) — Internal error in Hologram Cloud.ERR_UNKNOWN
(-1
) — Unknown error.
# Send message with topics. This has a 5 sec socket timeout
recv = cloud.sendMessage("hi there!", topics=["TOPIC1","TOPIC2"])
# recv will be 0 if message is sent successfully
# Send message with a timeout of 7 seconds
recv2 = cloud.sendMessage("hi again!", topics=["TOPIC1","TOPIC2"], timeout=7)
Cloud messages are buffered if the network is down (on a network.disconnected event). Once the network is reestablished (a broadcast on network.connected), these messages that failed to send initially will be sent to the cloud again.
.sendSMS(destination_number, message)
Parameters:
- destination_number (string) — The destination number. This must be a E.164 formatted string with a '+' sign.
- message (string) — The SMS body. This SMS must be less than or equal to 160 characters in length
Returns: A message response description (string)
Example:
recv = cloud.sendSMS("+11234567890", "Hello, Python!") # Send SMS to destination number
Note: The sendSMS interface only works when the authentication type is set to CSRPSK.
.enableSMS()
Start listening on incoming SMS and buffer them internally.
Parameters: None
Returns: None
.disableSMS()
Stops listening to incoming SMS.
Parameters: None
Returns: None
.popReceivedSMS()
Whenever the inbound SMS feature is enabled and SMS(es) are received, they will be appended to a SMS received buffer. This receive buffer acts as a queue for inbound SMS, and a .popReceivedSMS() call will pop and return the oldest SMS payload that is still currently in the queue. Returns None if the received buffer is empty.
Parameters: None
Returns: A SMS payload (SMS)
The SMS object contains the following properties:
Properties:
- sender (string) — The sender's number. This must be a E.164 formatted string with a '+' sign.
- timestamp (Timestamp) — Timestamp of when the SMS was received.
- message (string) — The SMS body. This SMS must be less than or equal to 160 characters in length.
The Timestamp object contains the following properties:
Properties:
- year (int) — Year
- month (int) — Month.
- day (int) — Day.
- hour (int) — Hour.
- minute (int) — Minute.
- second (int) — Second.
- tzquarter (int) — Timezone in 15 min offsets from UTC. For example, if you're in Chicago, this will be -20 = (-20 * 15 mins) = -300 mins = -5 hours from UTC.
Example:
# 1. someone sends a "hey there!" SMS
# After a while...
# 2. someone sends another "bye!" SMS
sms_obj = hologramCloud.popReceivedSMS()
print sms_obj.message # prints "hey there!"
sms_obj = hologramCloud.popReceivedSMS()
print sms_obj.message # prints "bye!"
sms_obj = hologramCloud.popReceivedSMS() # trying to pop more returned SMS.
print sms_obj # prints None because the receive buffer is empty.
You can also subscribe to when messages are being received via sms.received. This event will get broadcasted whenever an inbound SMS has been received, and you can choose to have event handlers/callback functions registered to it. This is explained in more detail under the Event section below.
Note: Since we utilize Python threads within the inbound SMS receive feature, your callback function needs to be thread safe to avoid race conditions in your application. In addition to that, we can only guarantee that the 'sms.received' broadcast happens after a message is received but not exactly when since those are decoupled and handled in separate threads. If you're doing multiple sends at the same time, we also can't guarantee that the first broadcast that happens come from the first received message (once again, since it's threaded)
Example:
1st Example:
def sayHelloReceived():
print "hello! I received something!"
# ...
hologramCloud.event.subscribe('sms.received', sayHelloReceived)
# someone sends a "this is the payload" SMS
# "hello! I received something!" is printed here
# Note that the received buffer still contains "this is a payload"
2nd Example:
The user can choose to pop the message within his/her event handler function too.
# this function now pops the received message and prints it out.
def sayHelloReceivedAndPopMessage():
print "hello! I received something!"
sms_obj = hologramCloud.popReceivedSMS()
print sms_obj.message
# ...
hologramCloud.event.subscribe('sms.received', sayHelloReceivedAndPopMessage)
# someone sends a "this is the payload" message
# prints "hello! I received something!"
# prints "this is the payload"
sleep(100)
sms_obj = hologramCloud.popReceivedSMS() # prints None
.getResultString(result_code)
This method takes in a result code and prints the appropriate description.
Parameters:
- result_code (int) — The Hologram result code. See section below for a full list of compatible result codes.
Returns: A message response description (string).
These are specific error descriptions that will be returned based on the given result_code:
ERR_OK
(0
) — Message sent successfully.ERR_CONNCLOSED
(1
) — Connection was closed so we couldn't read the whole message.ERR_MSGINVALID
(2
) — Failed to parse the message.ERR_AUTHINVALID
(3
) — Auth section of the message was invalid.ERR_PAYLOADINVALID
(4
) — Payload type was invalid.ERR_PROTINVALID
(5
) — Protocol type was invalid.ERR_INTERNAL
(6
) — Internal error in Hologram Cloud.ERR_UNKNOWN
(-1
) — Unknown error.
# Send message with topics. This has a 5 sec socket timeout
recv1 = cloud.sendMessage("hi there!", topics=["TOPIC1","TOPIC2"])
# This will print 'Message sent successfully' if recv1 is 0.
print 'RESPONSE MESSAGE: ' + cloud.getResultString(recv1)
# Send message with a timeout of 7 seconds
recv2 = cloud.sendMessage("hi again!", topics=["TOPIC1","TOPIC2"], timeout=7)
print 'RESPONSE MESSAGE: ' + cloud.getResultString(recv2)
CustomCloud
CustomCloud
is a subclass of Cloud
, and it allows the user to make inbound and outbound connections via the SDK by specifying the host
and port
parameters.
If you would like to use the Hologram cloud, please check out the HologramCloud
subclass instead as it'll populate the appropriate host
, port
and any other required parameters for you.
CustomCloud(credentials, send_host, send_port, receive_host, receive_port)
The CustomCloud
constructor is responsible for initializing many of SDK components selected by the user.
Parameters:
- credentials (dict()) — Credentials are required to make remote calls to the custom cloud of your choice. If you don't support credentials at all, you can set this to None.
- send_host (string) — The remote host that data will be sent to via this TCP outbound socket connection.
- send_port (int) — The remote port that data will be sent to via this TCP outbound socket connection.
- receive_host (string) — The server host used to listen for a TCP inbound socket connection.
- receive_port (int) — The server port used to listen for a TCP inbound socket connection.
- network (string) — The Network interface that you intend to use for this CustomCloud instance. Default to
''
, which is to set up non-network mode.
Note: You must set send_host
and send_port
if you choose to use the CustomCloud class to send messages (make outbound connection) in your application. Likewise, receive_host
and receive_port
must be set if you plan to enable inbound connection.
Network interface options:
These are cellular network interfaces (strings) that you can use to choose which Network interface you want to use for the connectivity layer in the Hologram SDK.
- cellular — Cellular interface
- '' — Empty string for network agnostic (non-network) mode.
Example:
from Hologram.CustomCloud import CustomCloud
# send example
customCloud1 = CustomCloud(dict(), send_host='my.example.host.com', send_port=9999)
# receive example with cellular network interface
customCloud2 = CustomCloud(dict(), receive_host='0.0.0.0', receive_port=57750, network='cellular')
.sendMessage(message, timeout=5)
This method sends a message to the specified host. This will also broadcast the message.sent event if the message is sent successfully.
Parameters:
- message (string) — The message that will be sent.
- timeout (int) — A timeout period in seconds for when the socket should close if it doesn't receive any response. The default timeout is 5 seconds.
Returns: The response from the remote host (string)
Example:
recv = customCloud.sendMessage("hello")
recv2 = customCloud.sendMessage("hello again with 7 sec timeout", timeout = 7)
Cloud messages are buffered if the network is down (on a network.disconnected
event). Once the network is reestablished (a broadcast on network.connected
), these messages that failed to send initially will be sent to the cloud again.
.sendPeriodicMessage(interval, message, topics=None, timeout=5)
This method sends periodic message(s) every interval seconds to the specified host. This will also broadcast the message.sent
event if each message is sent successfully. You cannot have more than 1 periodic message at once.
Parameters:
- interval (int) — The interval between periodic sends in seconds. This needs to be at least 1 second if totp authentication is used.
- message (string) — The message that will be sent.
- topics (list) — List of topics (optional).
- timeout (int) — A timeout period in seconds for when the socket should close if it doesn't receive any response. The default timeout is 5 seconds.
Returns: None
Example:
recv = customCloud.sendPeriodicMessage(10, 'This is a periodic message', topics=['PERIODIC MESSAGES'], timeout=6)
print 'sleeping for 20 seconds...'
time.sleep(20)
customCloud.stopPeriodicMessage()
.stopPeriodicMessage()
Disables and stop sending background periodic messages.
Parameters: None
Returns: None
.openReceiveSocket()
Initializes, opens and binds an inbound TCP socket connection. This method is also responsible for spinning up another thread for the blocking socket accept call, which is used to process incoming connections.
Parameters: None
Example:
inboundCloud = CustomCloud(dict(), send_host = 'my.example.host.com', send_port = 9999, receive_host = '0.0.0.0', receive_port = 57750)
inboundCloud.openReceiveSocket()
hologram = HologramCloud(dict(), network='cellular')
hologram.openReceiveSocket()
.closeReceiveSocket()
Closes the inbound TCP socket connection.
Parameters: None
Example:
# Closes the inbound socket connection. You can reopen this again via the .openReceiveSocket()
# call.
inboundCloud = CustomCloud(dict(), send_host = 'my.example.host.com', send_port = 9999, receive_host = '0.0.0.0', receive_port = 57750)
# Open and then close the socket connection.
inboundCloud.openReceiveSocket()
# do something...
inboundCloud.closeReceiveSocket()
# Reopen the socket connection.
inboundCloud.openReceiveSocket()
hologram = HologramCloud(dict(), network='cellular')
hologram.openReceiveSocket()
# do something...
hologram.closeReceiveSocket()
.popReceivedMessage()
Whenever the inbound message feature is enabled and message(s) are received, they will be appended to a received buffer. This receive buffer acts as a queue for inbound data, and a .popReceivedMessage()
call will pop and return the oldest data payload that is still currently in the queue. Returns None if the received buffer is empty.
Parameters: None
Returns: A received data payload (string)
Example:
# 1. someone sends a "hey there!" message # 2. someone sends another "bye!" message
recv = customCloud.popReceivedMessage() print recv
# prints "hey there!"
recv = customCloud.popReceivedMessage()
print recv
# prints "bye!"
recv = customCloud.popReceivedMessage()
# trying to pop more returned responses.
print recv
# prints None because the receive buffer is empty.
You can also subscribe to when messages are being received via message.received
. This event will get broadcasted whenever an inbound message has been received, and you can choose to have event handlers/callback functions registered to it. This is explained in more detail under the Event section below.
Note: Since we utilize Python threads within the inbound message receive feature, your callback function needs to be thread safe to avoid race conditions in your application. In addition to that, we can only guarantee that the message.received
broadcast happens after a message is received but not exactly when since those are decoupled and handled in separate threads. If you're doing multiple sends at the same time, we also can't guarantee that the first broadcast that happens come from the first received message (once again, since it's threaded).
Example:
1st Example:
def sayHelloReceived():
print "hello! I received something!"
# ...
customCloud.event.subscribe('message.received', sayHelloReceived)
# someone sends a "this is the payload" message
# "hello! I received something!" is printed here
# Note that the received buffer still contains "this is a payload"
2nd Example:
The user can choose to pop the message within his/her event handler function too.
# this function now pops the received message and prints it out.
def sayHelloReceivedAndPopMessage():
print "hello! I received something!"
recv = customCloud.popReceivedMessage()
print recv
# ...
customCloud.event.subscribe('message.received', sayHelloReceivedAndPopMessage)
# someone sends a "this is the payload" message
# prints "hello! I received something!"
# prints "this is the payload"
sleep(100)
recv = customCloud.popReceivedMessage()
# prints None
Note: Although you can have multiple event handlers subscribed to the message.received
event, we cannot guarantee which event handler will run first. Hence, you might run into a race condition and cause undefined behavior, especially so when your event handler function(s) are not thread safe. Once again, we highly recommend that you keep them thread safe so you don't run into an undefined behavior like this.
NetworkManager
The NetworkManager
class is responsible for defining and managing the networking interfaces of Hologram SDK. There are interfaces here that allow you to, for example, connect and disconnect from a network of your choice. This NetworkManager
interface lives within a Cloud instance. The NetworkManager
is responsible for picking the right interface based on the argument set in the Cloud constructors.
Note: The NetworkManager
interface is in beta, and the interface may change in the future.
Note: The networking functionality has only been tested on a Raspberry Pi 3 running Raspbian Jessie. It should work on other Debian-based Linux installations. Please post in our community forum if you have any issues.
We also provide a non-network mode that can be used to disable the Hologram SDK networking functionality. You may want to do this if you just want to interact with the interfaces in the Hologram SDK, but not deal with the details on how to connect/disconnect the device itself via the SDK.
Example:
customCloud = CustomCloud(dict(), send_host = 'my.example.host.com', send_port = 9999)
The NetworkManager
interface allows you to choose between 2 different network options: 1. Cellular 2. None(non-network mode)
Non-network mode allows you to use the Python SDK independent of the network used by your machine. This assumes that you have figured out the network connectivity layer required by the SDK.
.connect(timeout=200)
Connects to the specified network by establishing a PPP session. This will also broadcast the network.connectedevent if sucessful. Default timeout is 200 seconds.
Parameters:
- timeout (int) — A timeout period in seconds for when the connection should close if it fails to connect. Default timeout is 200 seconds.
Returns: Bool — True
if successful, False
otherwise.
Note: You shouldn't have to make .connect()
and .disconnect()
calls unless one or more of these is true: 1) You want to send messages/SMS via PPP. 2) You are sending messages/SMS with the E303 or MS2131 modem.
.disconnect()
Disconnect from an active network by tearing down an existing PPP session. This will also broadcast the network.disconnected event. This is meant to be called by a subclass that implements the Network interface, and not to be called directly.
Parameters: None
.reconnect()
Reconnects to the specified network. This is meant to be called by a subclass that implements the Network interface, and not to be called directly.
Parameters: None
.listAvailableInterfaces()
Returns a list of available network interfaces supported by the Python SDK. This will be a subset of the following strings:
cellular
— Cellular interface.''
— Empty string for network agnostic (non-network) mode.
Returns: List of available interfaces (list())
Example:
print 'Available network interfaces:'
print hologram.network.listAvailableInterfaces() # ['cellular']
Cellular
The Cellular
interface allows you to use the Hologram SDK to connect/disconnect from the network. We currently support two modes of operation, which are PPP and Serial mode. The operation modes used varies with the cellular modem that you're using. For example, in PPP mode, you can use the Hologram Nova (U201/R404), Huawei E303 or MS2131 modems as part of your cellular connectivity solution.
The Cellular
interface requires root permissions to connect/disconnect from a given address. We strongly recommend running your scripts with sudo
privileges.
- PPP Mode supported devices: Hologram Nova (U201/R404), Huawei E303, MS2131 modems
Properties:
modem
(Modem) — Holds the Modem instance that will be responsible for establishing a cellular connection.localIPAddress
(string) — The local IP address. It'll be None if the cell network is inactive.remoteIPAddress
(string) — The remote IP address. It'll be None if the cell network is inactive.signal_strength
(string) — The Received Signal Strength Indication (RSSI) value of the modem.imsi
(string) — The international mobile subscriber identification (IMSI) value.iccid
(string) — The integrated circuit card identifier (ICCID) value.operator
(string) — The operator name.location
(Location) — The approximate location of the modem.active_modem_interface
(string) — The name of the attached modem. Will be None if the modem isn't supported.
The Location object has the following properties:
Properties:
date
(string) — The date.time
(string) — The time.latitude
(string) — Approximate latitude value.longitude
(string) — Approximate longitude value.altitude
(string) — Approximate altitude in meters (m).uncertainty
(string) — Uncertainty in meters (m).operator
(string) — The operator name.
.connect(timeout=200)
Connect to a cellular connection by establishing a PPP session. This will also broadcast the cellular.connectedevent.
Parameters:
- timeout (int) — A timeout period in seconds for when the connection should close if it fails to connect. Default timeout is 200 seconds.
Returns: Bool — True
if successful, False
otherwise.
Note: You shouldn't have to make .connect()
and .disconnect()
calls unless one or more of these is true: 1) You want to send messages/SMS via PPP. 2) You are sending messages/SMS with the E303 or MS2131 modem.
Example:
hologram.network.connect(timeout=7) # Connect with 7 second timeout.
.disconnect()
Disconnect from an active cellular connection by tearing down a PPP session. This will also broadcast thecellular.disconnected event.
Parameters: None
Returns: Bool — True
if successful, False
otherwise.
.getConnectionStatus()
Returns the cell network connection status. This is represented by the following return codes:
Connection Status Code:
CLOUD_DISCONNECTED
—0
CLOUD_CONNECTED
—1
CLOUD_ERR_SIM
—3
CLOUD_ERR_SIGNAL
—5
CLOUD_ERR_CONNECT
—12
Parameters: None
Returns: Int — The connection status codes.
Example:
# prints 1 if there's an active connection.
print 'CONNECTION STATUS: ' + str(hologram.network.getConnectionStatus())
Modem
The Modem
interface allows you to interact directly with the modem. This is a base class for the Hologram Nova (U201/R404), Huawei MS2131 and E303 modem interfaces.
Properties:
localIPAddress
(string) — The local IP address. It'll be None if the cell network is inactive.remoteIPAddress
(string) — The remote IP address. It'll be None if the cell network is inactive.signal_strength
(string) — The Received Signal Strength Indication (RSSI) value of the modem.imsi
(string) — The international mobile subscriber identification (IMSI) value.iccid
(string) — The integrated circuit card identifier (ICCID) value.operator
(string) — The operator name.location
(Location) — The approximate location of the modem.active_modem_interface
(string) — The name of the attached modem. Will be None if the modem isn't supported.
Nova
The Nova
class implements the Modem interface and is designed to interact with a Hologram Nova U201 modem.
Properties: with the SDK. We only support 'ppp' for now.
localIPAddress
(string) — The local IP address. It'll be None if the cell network is inactive.remoteIPAddress
(string) — The remote IP address. It'll be None if the cell network is inactive.
Nova(device_name=None, baud_rate='9600', chatscript_file=None)
Parameters:
- device_name (string) — The device name.
- baud_rate (string) — The baud rate of the serial line.
- chatscript_file (string) — Path to chatscript file.
You can obtain a sample chatscript that works with the Nova here
Note: The chatscript file must be an executable for the SDK to load it. You can do this by running:
sudo chmod +x <file></file>
.connect(timeout=200)
Connect to a cellular connection by establishing a PPP session.
Parameters:
- timeout (int) — A timeout period in seconds for when the connection should close if it fails to connect. Default is 200 seconds.
Returns: Bool — True
if successful, False
otherwise.
Note: You shouldn't have to make .connect()
and .disconnect()
calls unless one or more of these is true: 1) You want to send messages/SMS via PPP. 2) You are sending messages/SMS with the E303 or MS2131 modem.
.disconnect()
Disconnect from an active cellular connection by tearing down a PPP session.
Parameters: None
Returns: Bool — True
if successful, False
otherwise.
NovaM_R404
The NovaM_R404
class implements the Modem interface and is designed to interact with a Hologram Nova R404 modem.
Properties:
- localIPAddress (string) — The local IP address. It'll be
None
if the cell network is inactive. - remoteIPAddress (string) — The remote IP address. It'll be
None
if the cell network is inactive.
If you're using a R404 modem, you might need to run the following commands whenever your machine is rebooted:
sudo modprobe option
sudo sh -c 'echo -n 05c6 90b2 > /sys/bus/usb-serial/drivers/option1/new_id'
NovaM_R404(device_name=None, baud_rate='9600', chatscript_file=None)
Parameters:
- device_name(string) — The device name.
- baud_rate(string) — The baud rate of the serial line.
- chatscript_file(string) — Path to chatscript file.
You can obtain a sample chatscript that works with the Nova here.
Note: The chatscript file must be an executable for the SDK to load it. You can do this by running:
sudo chmod +x <file></file>
.connect(timeout=200)
Connect to a cellular connection by establishing a PPP session.
Parameters:
- timeout (int) — A timeout period in seconds for when the connection should close if it fails to connect. Default is 200 seconds.
Returns: Bool — True
if successful, False
otherwise.
Note: You shouldn't have to make .connect()
and .disconnect()
calls unless one or more of these is true: 1) You want to send messages/SMS via PPP. 2) You are sending messages/SMS with the E303 or MS2131 modem.
.disconnect()
Disconnect from an active cellular connection by tearing down a PPP session.
Parameters: None
Returns: Bool — True
if successful, False
otherwise.
E303
The E303 class implements the Modem interface and is designed to interact with a Huawei E303 modem.
Properties: with the SDK. We only support 'ppp' for now.
- localIPAddress (string) — The local IP address. It'll be None if the cell network is inactive.
- remoteIPAddress (string) — The remote IP address. It'll be None if the cell network is inactive.
E303(device_name=None, baud_rate='9600', chatscript_file=None)
Parameters:
- device_name (string) — The device name.
- baud_rate (string) — The baud rate of the serial line.
- chatscript_file (string) — Path to chatscript file.
You can obtain a sample chatscript that works with the E303here
Note: The chatscript file must be an executable for the SDK to load it. You can do this by running
sudo chmod +x <file>.</file>
.connect(timeout=200)
Connect to a cellular connection by establishing a PPP session.
Parameters:
- timeout (int) — A timeout period in seconds for when the connection should close if it fails to connect. Default is 200 seconds.
Returns: Bool — True
if successful, False
otherwise.
Note: You shouldn't have to make .connect()
and .disconnect()
calls unless one or more of these is true: 1) You want to send messages/SMS via PPP. 2) You are sending messages/SMS with the E303 or MS2131 modem.
.disconnect()
Disconnect from an active cellular connection by tearing down a PPP session.
Parameters: None
Returns: Bool — True
if successful, False
otherwise.
MS2131
The MS2131
class implements the Modem interface and is designed to interact with a Huawei MS2131 modem.
Properties:
- localIPAddress (string) — The local IP address. It'll be
None
if the cell network is inactive. - remoteIPAddress (string) — The remote IP address. It'll be
None
if the cell network is inactive.
MS2131(device_name=None, baud_rate='9600', chatscript_file=None)
Parameters:
- device_name (string) — The device name.
- baud_rate (string) — The baud rate of the serial line.
- chatscript_file (string) — Path to chatscript file.
You can obtain a sample chatscript that works with the MS2131here
Note: The chatscript file must be an executable for the SDK to load it. You can do this by running:
sudo chmod +x <file></file>
.connect(timeout=200)
Connect to a cellular connection by establishing a PPP session.
Parameters:
- timeout (int) — A timeout period in seconds for when the connection should close if it fails to connect. Default is 200 seconds.
Returns: Bool — True
if successful, False
otherwise.
Note: You shouldn't have to make .connect()
and .disconnect()
calls unless one or more of these is true: 1) You want to send messages/SMS via PPP. 2) You are sending messages/SMS with the E303 or MS2131 modem.
.disconnect()
Disconnect from an active cellular connection by tearing down a PPP session.
Parameters: None
Returns: Bool — True
if successful, False
otherwise.
Event
This Hologram SDK allows the developer to publish/subscribe to certain events via the Event interface. Registered event handlers based on predefined strings below will get executed when the event occurs. Some of these predefined strings are as follows:
message.sent
— A message has just been sent.message.received
— A message has been received.sms.received
— A SMS has been received.
.subscribe(event, callback)
Registers an event handler function to the specific event.
Parameters:
- event (string) — Choose from one of the predefined event strings listed above.
- callback (function) — Callback function.
Example:
def message_sent():
print 'hurray!'
# do something
def temp():
# message_sent() will execute whenever a broadcast happens on message.sent
# (or whenever a message is sent)
cloud.event.subscribe('message.sent', message_sent)
.unsubscribe(event, callback)
Unregisters an event handler function to the specific event.
Parameters:
- event (string) — Choose from one of the predefined event strings listed above.
- callback (function) — Callback function.
Example:
# message_sent() will no longer be executed when a message is sent.
cloud.event.unsubscribe('message.sent', message_sent)
Log
We use the standard Python logger framework to report all SDK internal messages. We also define custom exceptions such as HologramError
, PPPError
and AuthenticationError
for SDK specific errors.
Note: You must define a custom Python handler in order to see the raised exceptions. This can be done using the Python logging framework by calling something such as logging.basicConfig()
. Check the Python logging framework documentation for more information.
Tests
We use the pytest testing framework, and unit tests can be found under the /tests
folder.
To run them from the top level directory, go ahead and type make test
via the Makefile we provided. This will run all unit tests under /tests
.
Multi-factor Authentication (MFA)
Overview
Hologram's multi-factor authentication (MFA) helps developers and businesses verify IoT device identity, maintain privacy, and re-issue security keys to restore trust with devices following a security incident or breach. Currently available via Hologram secure SIMs with the Hologram Python SDK or CLI, Hologram multi-factor authentication enables key rotation, signing, and message authentication codes, such as Time-based One-Time Password for Machines (TOTP-M), all through a few lines code.
Available now in private beta. To get started, simply request more information by contacting our sales team.
Hologram MFA
- Nonce and Challenge-Response Scheme
Hologram SDK generates a nonce which is input to a challenge-response scheme embedded within secure memory in all Hologram secure IoT SIMs. - Serial and time-based One-time Password for Machines (OTP-M) Generation
Hologram secure IoT SIM returns Serial and Time-based One-time Password for Machines (OTP-M) for authentication for message payload. - Serial and OTP-M Key Submission
Message payload and serial+OTP-M key submitted to Hologram authentication server. - Hologram MFA Validation
Hologram authentication server symmetrically reproduces nonce and challenge scheme for validation of device identity and payload then returns confirmation/success in real-time.
Setup
The HologramCloud
constructor initializes the authentication type used for message validation in the Python SDK. By default, a single factor One-time Password (OTP) based on time is used. Enabling multi-factor authentication through a combination of the default OTP and Hologram MFA element in Hologram's secure IoT SIMs requires only initializing the authentication type parameter with authentication_type='sim-otp'
.
Example:
from Hologram.HologramCloud import HologramCloud
credentials = {'devicekey': '1234abcd'}
hologram = HologramCloud(credentials, network='cellular', authentication_type='sim-otp')