Skip to content

Commit

Permalink
Merge pull request #7 from Sensirion/add-sensor-type-interface
Browse files Browse the repository at this point in the history
Add sensor type interface
  • Loading branch information
psachs authored Apr 10, 2024
2 parents 6b3475a + 6f582f9 commit 81516c5
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Build and Publish Package to pypi.org
on:
create:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
name: Define a cache for the virtual environment based on the dependencies lock file
with:
path: ./.venv
key: venv-${{ hashFiles('poetry.lock') }}
key: venv-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }}
- name: Install the project dependencies
run: poetry install --with test
- name: Verify style with flake8
Expand Down
13 changes: 11 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.1.0] - 2024-4-10

### Added

- Interface to get and set sensor type
- Interface to scan for i2c addresses
- Interface to get/set i2c address

## [1.0.0] - 2024-2-14

### Added

- Provide initial version of this repository containing a driver for the Sensirion SCC1-USB cable.

[Unreleased]: https://github.com/Sensirion/python-uart-scc1/compare/1.0.0...HEAD
[1.0.0]: https://github.com/Sensirion/python-uart-scc1/releases/tag/1.0.0
[Unreleased]: https://github.com/Sensirion/python-uart-scc1/compare/1.1.0...HEAD
[1.1.0]: https://github.com/Sensirion/python-uart-scc1/compare/1.0.0...1.1.0
[1.0.0]: https://github.com/Sensirion/python-uart-scc1/releases/tag/1.0.0
1 change: 1 addition & 0 deletions examples/scc1_slf3x_example/slf3x_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

with ShdlcSerialPort(port=args.serial_port, baudrate=115200) as port:
device = Scc1ShdlcDevice(ShdlcConnection(port), slave_address=0)
device.set_sensor_type(Scc1Slf3x.SENSOR_TYPE)
sensor = Scc1Slf3x(device)
print("serial_number:", sensor.serial_number)
print("product id:", sensor.product_id)
Expand Down
2 changes: 2 additions & 0 deletions examples/scc1_usb_to_i2c/scc1_usb_2_i2c_usage.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@

with ShdlcSerialPort(port='COM5', baudrate=115200) as port:
bridge = Scc1ShdlcDevice(ShdlcConnection(port), slave_address=0)
bridge.set_sensor_type(3) # SF06 devices

channel = I2cChannel(bridge.get_i2c_transceiver(),
slave_address=0x08,
crc=CrcCalculator(8, 0x31, 0xff, 0x0))

sensor = Sf06LfDevice(channel)

try:
sensor.stop_continuous_measurement()
time.sleep(0.1)
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "sensirion-uart-scc1"
version = "1.0.0"
version = "1.1.0"
description = "Driver for Sensirion SCC1 USB cable"
authors = ["Pascal Sachs"]
license = "BSD-3-Clause"
Expand Down Expand Up @@ -28,6 +28,7 @@ testpaths = [
"tests"
]


[tool.poetry.group.docs]
optional = true

Expand Down
87 changes: 78 additions & 9 deletions sensirion_uart_scc1/scc1_shdlc_device.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-

import logging
from typing import Optional, Iterable, Union
from struct import unpack
from typing import Optional, Iterable, Union, List

from packaging.version import Version
from sensirion_shdlc_driver import ShdlcDevice, ShdlcConnection
Expand All @@ -15,7 +16,7 @@

class Scc1ShdlcDevice(ShdlcDevice):
"""
The Scc1 Shdlc device is used to communicate with various sensor using the Sensirion SCC1 sensor cable.
The Scc1 SHDLC device is used to communicate with various sensors using the Sensirion SCC1 sensor cable.
"""

def __init__(self, connection: ShdlcConnection, slave_address: int = 0) -> None:
Expand All @@ -27,12 +28,15 @@ def __init__(self, connection: ShdlcConnection, slave_address: int = 0) -> None:
super().__init__(connection, slave_address)
self._version = self.get_version()
self._serial_number = self.get_serial_number()
self._sensor_type = self.get_sensor_type()
self._i2c_address = self.get_sensor_address()
self._connected_i2c_addresses: List[int] = []

def __str__(self):
def __str__(self) -> str:
return f"SCC1-{self.serial_number}@{self.com_port}"

@property
def com_port(self):
def com_port(self) -> str:
return self.connection.port.description.split('@')[0]

@property
Expand All @@ -43,10 +47,75 @@ def serial_number(self) -> str:
def firmware_version(self) -> Version:
return Version(str(self._version.firmware))

@property
def connected_i2c_addresses(self) -> List[int]:
"""Returns the connected I2C addresses. You need to call find_chips to fill this attribute."""
return self._connected_i2c_addresses

def perform_i2c_scan(self) -> List[int]:
"""
Looks for i2c devices within a certain range on a certain port
:return: List of i2c addresses that responded to the scan
"""
result = self.transceive(0x29, [0x01], timeout=0.025)
return list(unpack('>{cnt}B'.format(cnt=len(result)), result))

def find_chips(self) -> List[int]:
"""
Looking for chips on all ports and sets the _connected_i2c_addresses attribute
:return: List of connected addresses
"""
self._connected_i2c_addresses = self.perform_i2c_scan()
return self._connected_i2c_addresses

def get_sensor_type(self) -> Optional[int]:
"""
:return: the configured sensor type
"""
result = self.transceive(0x24, [], timeout=0.025)
if result:
return int(unpack('>B', result)[0])
return None

def set_sensor_type(self, sensor_type: int):
"""
Set sensor type
0: Flow Sensor (SF04 based products)
1: Humidity Sensor (SHTxx products)
2: Flow Sensor (SF05 based products)
3: Flow Sensor (SF06 based products) (Firmware ≥1.7)
4: Reserved
:param sensor_type: One of the supported sensor types 0-4
"""
if sensor_type not in range(5):
raise ValueError('Sensor type not supported')
self.transceive(0x24, [sensor_type], timeout=0.01)
self._sensor_type = sensor_type

def get_sensor_address(self) -> Optional[int]:
"""
:return: the configured i2c address
"""
result = self.transceive(0x25, [], timeout=0.025)
if result:
return int(unpack('>B', result)[0])
return None

def set_sensor_address(self, i2c_address: int) -> None:
"""
Configure the sensors i2c address and write it to EEPROM
:param i2c_address: the i2c address
"""
if i2c_address not in range(128):
raise ValueError('I2C address out of range. Address has to be within the range 0...127')
self.transceive(0x25, [i2c_address], timeout=0.01)
self._i2c_address = i2c_address

def sensor_reset(self) -> None:
"""
Execute a hard reset on the sensor and check for correct response. Active
continuous/single measurement is stopped and the sensor is left in idle state.
Execute a hard reset on the sensor and check for the correct response.
Active continuous/single measurement is stopped, and the sensor is left in idle state.
"""
self.transceive(0x66, [], 0.3)

Expand Down Expand Up @@ -74,8 +143,8 @@ def get_i2c_transceiver(self) -> I2cTransceiver:
"""
An I2cTransceiver object is required in or der to use the cable with public python i2c drivers.
In general all functionality of the sensors are available in the public python drivers as well. The
throughput of the public python driver will be lower than the throughput that can be achieved with
the sensor specific api of the SCC1 sensor cable.
In general, all functionality of the sensors is available in the public python drivers as well.
The throughput of the public python driver will be lower than the throughput that can be achieved with
the sensor-specific api of the SCC1 sensor cable.
"""
return Scc1I2cTransceiver(self)

0 comments on commit 81516c5

Please sign in to comment.