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

RC 0.9.2 #114

Open
wants to merge 81 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
d889dfc
Add Github Actions
DomAmato Mar 3, 2020
889b1b9
Update issue templates
DomAmato Mar 18, 2020
ccc06fb
wait for the process to be terminated (#17)
DomAmato Jan 3, 2020
50e7d2b
Properly handle when parsing other types of SMS PDUs (#16)
DomAmato Jan 3, 2020
22074be
Add chunking for messeages over 512 bytes (#15)
DomAmato Jan 3, 2020
6b36f54
Update test_Modem.py
DomAmato Jan 3, 2020
eeca8f9
check python and pip versions (#19)
DomAmato Jan 7, 2020
1ee0189
simplify version check
DomAmato Jan 7, 2020
cdddf6c
check python and pip version for update too
DomAmato Jan 7, 2020
4b6e2a2
call super.disconnect instead of connect (ensures event network.disco…
akumlehn Mar 3, 2020
cde545a
remove extraneous parenthesis (#24)
DomAmato Mar 24, 2020
a63eaba
include token
DomAmato Mar 24, 2020
b41028b
remove extraneous parenthesis (#26)
DomAmato Mar 25, 2020
e8fcaed
remove travis and rename actions
DomAmato Mar 24, 2020
4dbbb14
use pytest instead of coverage
DomAmato Mar 25, 2020
3996463
only test on 3.7 for now
DomAmato Mar 25, 2020
535e359
Allow sending raw AT commands to the modem (#28)
DomAmato Apr 3, 2020
ce138c8
Fix PPP Errors with disconnect and routing (#32)
DomAmato Apr 23, 2020
477e711
Concat to bytes not str (#33)
DomAmato May 4, 2020
bd52942
properly convert bytestring ascii value
DomAmato May 9, 2020
cfef0f5
convert from ascii int value to int
DomAmato May 20, 2020
0566314
make it possible to renable at sockets (#36)
DomAmato Jun 6, 2020
7c45b17
include support for Huawei Modem E372 (#21)
HectorMendez Jul 10, 2020
653481d
Add BG96 Support (#37)
DomAmato Jul 10, 2020
12f485e
try adding config on develop
DomAmato Jul 10, 2020
82affa9
add some more github actions (#41)
DomAmato Jul 11, 2020
0a53d69
add dependency label to config
DomAmato Jul 11, 2020
a52ecae
Dont encode buffer (#39)
DomAmato Jul 14, 2020
aa97656
add more info to release
DomAmato Jul 14, 2020
26e2421
Bump actions/setup-python from v1 to v2.0.2 (#51)
dependabot[bot] Jul 18, 2020
52ae291
Update psutil requirement from ~=5.6.3 to ~=5.7.2 (#50)
dependabot[bot] Jul 18, 2020
56a8f03
Update hjson requirement from ~=3.0.0 to ~=3.0.1 (#48)
dependabot[bot] Jul 18, 2020
fe7c9a4
Update pyudev requirement from ~=0.21.0 to ~=0.22.0 (#45)
dependabot[bot] Jul 18, 2020
1cac5d5
Update requests requirement from ~=2.22.0 to ~=2.24.0 (#44)
dependabot[bot] Jul 18, 2020
7d59380
add section for dependencies
DomAmato Jul 18, 2020
94e0d59
fix broken python actions
DomAmato Jan 5, 2021
19b1a04
Update psutil requirement from ~=5.7.2 to ~=5.8.0 (#70)
dependabot[bot] Jan 5, 2021
96c3468
Update pyusb requirement from ~=1.0.2 to ~=1.1.0 (#59)
dependabot[bot] Jan 5, 2021
2f92ec8
Update requests requirement from ~=2.24.0 to ~=2.25.1 (#67)
dependabot[bot] Jan 5, 2021
7157d82
Update pyserial requirement from ~=3.4.0 to ~=3.5 (#72)
dependabot[bot] Jan 5, 2021
99dde7a
Strip AT command result prefix when issued command ends with ? or % (#6)
TomPethtel Jan 17, 2021
e205937
Fix type for BG96 (#77)
rbalik Mar 9, 2021
bacbf38
allow setting APN (#79)
DomAmato Apr 27, 2021
582c8dc
properly handle bytes when reading from an open socket (#74)
DomAmato Apr 30, 2021
a622ee1
Update pyusb requirement from ~=1.1.0 to ~=1.1.1 (#75)
dependabot[bot] Apr 30, 2021
3b7ede4
Fix actions and bump version
DomAmato Apr 30, 2021
1c40eeb
Update install script to check for python 3.9
DomAmato Mar 30, 2022
3990905
Also update update script to use python 3.9
DomAmato Mar 30, 2022
5733bdf
Tear down PDP context after sending socket messages (#90)
DomAmato Nov 2, 2022
01ffd91
Clean up unused and test dependencies (#73)
DomAmato Nov 2, 2022
9d98eab
Update pyusb requirement from ~=1.1.1 to ~=1.2.1 (#88)
dependabot[bot] Nov 2, 2022
dacca2a
Bump python-pppd from 1.0.3 to 1.0.4 (#83)
dependabot[bot] Nov 2, 2022
a281cd7
fix setup.py so that installing isnt broken
DomAmato Nov 3, 2022
a52de20
update action file
DomAmato Nov 3, 2022
a3bf1cb
Add EC21 to supported modems (#109)
DomAmato Nov 10, 2022
71c4bde
raise an authentication error if its unable to get keys, consolidate …
HologramInterview Nov 16, 2022
053f319
Add support for providing a specific modem name
parker-hologram Aug 29, 2023
6a1fcc9
Allow passing of modem from hologram cloud
parker-hologram Aug 29, 2023
964ea05
Add in the ability to pass modem to network manager
parker-hologram Aug 30, 2023
c53ed00
Allow users to scan for usable modems and set specific modems
parker-hologram Aug 30, 2023
ff6fa66
Change python sdk auth to match pattern
parker-hologram Aug 30, 2023
5e2aecd
Add send sms functionality
parker-hologram Aug 31, 2023
99e73a3
Use the timeout provided in the function definition
parker-hologram Aug 31, 2023
bcbb825
Refactor how to autodetect a modem
parker-hologram Aug 31, 2023
a8c19d3
Update comment at andrews request
parker-hologram Sep 5, 2023
1c8d9ef
Update documentation to point to python 3.9 instead of 3.7
parker-hologram Sep 5, 2023
5cd1788
Add updates to changelog
parker-hologram Sep 5, 2023
63b2ca1
Fix 3.9 to 3.7
parker-hologram Sep 5, 2023
d2e4059
Add more concrete example to the changelog
parker-hologram Sep 5, 2023
1ded340
Make users aware that sending smss may result in extra charges
parker-hologram Sep 5, 2023
641acdb
Merge pull request #118 from hologram-io/feature/multi-modem-support
parker-hologram Sep 5, 2023
e5f5770
Fix the regex that breaks the install script
parker-hologram Sep 5, 2023
c015677
Merge pull request #119 from hologram-io/bugfix/update-install-regex
parker-hologram Sep 5, 2023
2d69457
Update version number
parker-hologram Sep 5, 2023
b646628
Merge pull request #120 from hologram-io/bugfix/update-install-regex
parker-hologram Sep 5, 2023
4fafac3
Widen supported requests packages
parker-hologram Sep 15, 2023
45f1f4a
Merge pull request #121 from hologram-io/feature/widen-supported-requ…
parker-hologram Sep 15, 2023
fe9b619
Add a imei check around modem detection loop
parker-hologram Sep 15, 2023
47006d8
Merge pull request #122 from hologram-io/bugfix/ensure-detected-modem…
parker-hologram Sep 15, 2023
a9b9359
Allow different PDP contexts
lalo-hologram Dec 20, 2023
053c484
Merge pull request #124 from hologram-io/feature/allow-different-pdp-…
lalo-hologram Dec 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.7
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: '3.7'
python-version: '3.9'

- name: Install dependencies
run: |
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/testlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.7]
python-version: [3.9]

steps:
- uses: actions/checkout@v2
Expand All @@ -20,6 +20,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-test.txt
pip install -r requirements.txt

- name: Lint with flake8
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# What's New in Hologram Python SDK

## v0.10.0
2023-09-05 Hologram <[email protected]>
* targets python version 3.9
* Allow setting a specific modem when initializing a network. This can be done by passing the modem into the `HologramCloud` intializing method for example: `HologramCloud({}, authentication_type='totp', network='cellular', modem=modem)`. Initialize a modem using one of the following methods:
1. Initialize a modem object with a known good port using a supported modem class in `Hologram.Network.Modem` for example: `EC21(device_name="/dev/ttyUSB4")` This initializes a Quectel EC21 on port `/dev/ttyUSB4`
2. Scan for all available modems through the new `Cellular.scan_for_all_usable_modems()` method at `Hologram.Network.Cellular`. This returns a list of accessible intialized modem objects. Just pass one of these in as a modem.
* Allow modems to send SMS messages through the modem interface. For example: `hologram.network.modem.send_sms_message("+80112", "Hi dashboard!")`. *Note: Extra charges for sending SMS with this method may apply*

## v0.9.1
2021-04-30 Hologram <[email protected]>
includes the following bug fixes
Expand Down
10 changes: 6 additions & 4 deletions Hologram/Cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import logging
from logging import NullHandler
from Hologram.Event import Event
from typing import Union
from Hologram.Network.Modem.Modem import Modem
from Hologram.Network import NetworkManager
from Hologram.Authentication import *

Expand All @@ -21,7 +23,7 @@ def __repr__(self):
return type(self).__name__

def __init__(self, credentials, send_host = '', send_port = 0,
receive_host = '', receive_port = 0, network = ''):
receive_host = '', receive_port = 0, network = '', modem: Union[None, Modem] = None):

# Logging setup.
self.logger = logging.getLogger(__name__)
Expand All @@ -33,21 +35,21 @@ def __init__(self, credentials, send_host = '', send_port = 0,
self.__initialize_host_and_port(send_host, send_port,
receive_host, receive_port)

self.initializeNetwork(network)
self.initializeNetwork(network, modem)

def __initialize_host_and_port(self, send_host, send_port, receive_host, receive_port):
self.send_host = send_host
self.send_port = send_port
self.receive_host = receive_host
self.receive_port = receive_port

def initializeNetwork(self, network):
def initializeNetwork(self, network, modem):

self.event = Event()
self.__message_buffer = []

# Network Configuration
self._networkManager = NetworkManager.NetworkManager(self.event, network)
self._networkManager = NetworkManager.NetworkManager(self.event, network, modem=modem)

# This registers the message buffering feature based on network availability.
self.event.subscribe('network.connected', self.__clear_payload_buffer)
Expand Down
7 changes: 5 additions & 2 deletions Hologram/CustomCloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import sys
import threading
import time
from typing import Union
from Hologram.Network.Modem.Modem import Modem
from Hologram.Cloud import Cloud
from Exceptions.HologramError import HologramError

Expand All @@ -25,14 +27,15 @@ class CustomCloud(Cloud):

def __init__(self, credentials, send_host='', send_port=0,
receive_host='', receive_port=0, enable_inbound=False,
network=''):
network='', modem: Union[None, Modem] = None):

super().__init__(credentials,
send_host=send_host,
send_port=send_port,
receive_host=receive_host,
receive_port=receive_port,
network=network)
network=network,
modem=modem)

# Enforce that the send and receive configs are set before using the class.
if enable_inbound and (receive_host == '' or receive_port == 0):
Expand Down
11 changes: 8 additions & 3 deletions Hologram/HologramCloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import binascii
import json
import sys
from typing import Union
from Hologram.Network.Modem.Modem import Modem
from Hologram.CustomCloud import CustomCloud
from HologramAuth import TOTPAuthentication, SIMOTPAuthentication
from Hologram.Authentication import CSRPSKAuthentication
from Exceptions.HologramError import HologramError
from Exceptions.HologramError import HologramError, AuthenticationError

DEFAULT_SEND_MESSAGE_TIMEOUT = 5
HOLOGRAM_HOST_SEND = 'cloudsocket.hologram.io'
Expand Down Expand Up @@ -60,14 +62,16 @@ class HologramCloud(CustomCloud):
}

def __init__(self, credentials, enable_inbound=False, network='',
authentication_type='totp'):
authentication_type='totp', modem: Union[None, Modem] = None):
super().__init__(credentials,
send_host=HOLOGRAM_HOST_SEND,
send_port=HOLOGRAM_PORT_SEND,
receive_host=HOLOGRAM_HOST_RECEIVE,
receive_port=HOLOGRAM_PORT_RECEIVE,
enable_inbound=enable_inbound,
network=network)
network=network,
modem=modem
)

self.setAuthenticationType(credentials, authentication_type=authentication_type)

Expand Down Expand Up @@ -125,6 +129,7 @@ def __populate_totp_credentials(self):
self.authentication.credentials['private_key'] = self.network.imsi
except Exception as e:
self.logger.error('Unable to fetch device id or private key')
raise AuthenticationError('Unable to fetch device id or private key for TOTP authenication')

def __populate_sim_otp_credentials(self):
nonce = self.request_hex_nonce()
Expand Down
59 changes: 38 additions & 21 deletions Hologram/Network/Cellular.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
from Hologram.Event import Event
from Exceptions.HologramError import NetworkError
from Hologram.Network.Route import Route
from Hologram.Network.Modem import Modem, E303, MS2131, E372, BG96, Nova_U201, NovaM, DriverLoader
from Hologram.Network.Modem import Modem, E303, MS2131, E372, BG96, EC21, Nova_U201, NovaM, DriverLoader
from Hologram.Network import Network, NetworkScope
import time
from typing import Union
from serial.tools import list_ports

# Cellular return codes.
Expand All @@ -32,6 +33,7 @@ class Cellular(Network):
'ms2131': MS2131.MS2131,
'e372': E372.E372,
'bg96': BG96.BG96,
'ec21': EC21.EC21,
'nova': Nova_U201.Nova_U201,
'novam': NovaM.NovaM,
'': Modem
Expand All @@ -47,10 +49,10 @@ def __init__(self, event=Event()):

def autodetect_modem(self):
# scan for a modem and set it if found
dev_devices = self._scan_for_modems()
if dev_devices is None:
first_modem_handler = Cellular._scan_and_select_first_supported_modem()
if first_modem_handler is None:
raise NetworkError('Modem not detected')
self.modem = dev_devices[0]
self.modem = first_modem_handler(event=self.event)

def load_modem_drivers(self):
self._load_modem_drivers()
Expand Down Expand Up @@ -207,27 +209,45 @@ def _load_modem_drivers(self):
dl.force_driver_for_device(syspath, vid_pid[0], vid_pid[1])



def _scan_for_modems(self):
res = None
for (modemName, modemHandler) in self._modemHandlers.items():
if self._scan_for_modem(modemHandler):
res = (modemName, modemHandler)
break
return res
@staticmethod
def _scan_and_select_first_supported_modem() -> Union[Modem, None]:
for (_, modemHandler) in Cellular._modemHandlers.items():
modem_exists = Cellular._does_modem_exist_for_handler(modemHandler)
if modem_exists:
return modemHandler
return None


def _scan_for_modem(self, modemHandler):
@staticmethod
def _does_modem_exist_for_handler(modemHandler):
usb_ids = modemHandler.usb_ids
for vid_pid in usb_ids:
if not vid_pid:
continue
self.logger.debug('checking for vid_pid: %s', str(vid_pid))
for dev in list_ports.grep("{0}:{1}".format(vid_pid[0], vid_pid[1])):
self.logger.info('Detected modem %s', modemHandler.__name__)
for _ in list_ports.grep("{0}:{1}".format(vid_pid[0], vid_pid[1])):
return True
return False

@staticmethod
def scan_for_all_usable_modems() -> list[Modem]:
modems = []
unique_imeis = set()
for (_, modemHandler) in Cellular._modemHandlers.items():
modem_exists = Cellular._does_modem_exist_for_handler(modemHandler)
if modem_exists:
try:
test_handler = modemHandler()
usable_ports = test_handler.detect_usable_serial_port(stop_on_first=False)
for port in usable_ports:
modem = modemHandler(device_name=port)
imei = modem.imei
if imei not in unique_imeis:
unique_imeis.add(imei)
modems.append(modem)
except Exception:
# Any exception already logged up the chain
pass
return modems



Expand All @@ -236,11 +256,8 @@ def modem(self):
return self._modem

@modem.setter
def modem(self, modem):
if modem not in self._modemHandlers:
raise NetworkError('Invalid modem type: %s' % modem)
else:
self._modem = self._modemHandlers[modem](event=self.event)
def modem(self, modem: Union[None, Modem] = None):
self._modem = modem

@property
def localIPAddress(self):
Expand Down
Loading
Loading