Added support for 8RTD card

main
Jan Beníček 2024-12-07 07:01:52 +01:00
parent eb13f0bdd3
commit 5c1e3d3fac
9 changed files with 150 additions and 4 deletions

1
.env.sample Normal file
View File

@ -0,0 +1 @@
MODULE_RTD8_LEVELS=01234567 #number of stack level (0-7) not separated

View File

@ -1 +1 @@
C:/Users/jan00/Documents/Programovani/MyProjects/SequentMicrosystems_API/.venv/Scripts/python.exe /home/jbenicek/Programovani/SequentMicrosystems_API/.venv/bin/python

View File

@ -4,8 +4,11 @@
[metadata] [metadata]
groups = ["default"] groups = ["default"]
strategy = ["cross_platform", "inherit_metadata"] strategy = ["cross_platform", "inherit_metadata"]
lock_version = "4.4.1" lock_version = "4.5.0"
content_hash = "sha256:f1937df1c5cdc07e0f42993da0c629a6322e5f5ec15a7ddf5012135f4ce53009" content_hash = "sha256:f4f1e2189c6ffd6d794a2407d788e6716784556dfe8717566ece8e4c48e157e7"
[[metadata.targets]]
requires_python = ">=3.12"
[[package]] [[package]]
name = "annotated-types" name = "annotated-types"
@ -13,6 +16,9 @@ version = "0.7.0"
requires_python = ">=3.8" requires_python = ">=3.8"
summary = "Reusable constraint types to use with typing.Annotated" summary = "Reusable constraint types to use with typing.Annotated"
groups = ["default"] groups = ["default"]
dependencies = [
"typing-extensions>=4.0.0; python_version < \"3.9\"",
]
files = [ files = [
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
@ -25,8 +31,10 @@ requires_python = ">=3.9"
summary = "High level compatibility layer for multiple asynchronous event loop implementations" summary = "High level compatibility layer for multiple asynchronous event loop implementations"
groups = ["default"] groups = ["default"]
dependencies = [ dependencies = [
"exceptiongroup>=1.0.2; python_version < \"3.11\"",
"idna>=2.8", "idna>=2.8",
"sniffio>=1.1", "sniffio>=1.1",
"typing-extensions>=4.1; python_version < \"3.11\"",
] ]
files = [ files = [
{file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"},
@ -41,6 +49,7 @@ summary = "Composable command line interface toolkit"
groups = ["default"] groups = ["default"]
dependencies = [ dependencies = [
"colorama; platform_system == \"Windows\"", "colorama; platform_system == \"Windows\"",
"importlib-metadata; python_version < \"3.8\"",
] ]
files = [ files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
@ -90,6 +99,9 @@ version = "0.14.0"
requires_python = ">=3.7" requires_python = ">=3.7"
summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
groups = ["default"] groups = ["default"]
dependencies = [
"typing-extensions; python_version < \"3.8\"",
]
files = [ files = [
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
@ -181,6 +193,29 @@ files = [
{file = "pydantic_core-2.27.0.tar.gz", hash = "sha256:f57783fbaf648205ac50ae7d646f27582fc706be3977e87c3c124e7a92407b10"}, {file = "pydantic_core-2.27.0.tar.gz", hash = "sha256:f57783fbaf648205ac50ae7d646f27582fc706be3977e87c3c124e7a92407b10"},
] ]
[[package]]
name = "smbus2"
version = "0.5.0"
summary = "smbus2 is a drop-in replacement for smbus-cffi/smbus-python in pure Python"
groups = ["default"]
files = [
{file = "smbus2-0.5.0-py2.py3-none-any.whl", hash = "sha256:1a15c3b9fa69357beb038cc0b5d37939702f8bfde1ddc89ca9f17d8461dbe949"},
{file = "smbus2-0.5.0.tar.gz", hash = "sha256:4a5946fd82277870c2878befdb1a29bb28d15cda14ea4d8d2d54cf3d4bdcb035"},
]
[[package]]
name = "smrtd"
version = "1.0.1"
summary = "Library to control Sequent Microsystems rtd Card"
groups = ["default"]
dependencies = [
"smbus2",
]
files = [
{file = "SMrtd-1.0.1-py2.py3-none-any.whl", hash = "sha256:0c6c1708f2240b8e283445f9cd5d00be7e7405fc79cf3d96b8c3488d7fc4b3a7"},
{file = "smrtd-1.0.1.tar.gz", hash = "sha256:b9b1275f80a4f84091a10ae0cd41ad85ce39968f3f7ba989f2db07f732505fcc"},
]
[[package]] [[package]]
name = "sniffio" name = "sniffio"
version = "1.3.1" version = "1.3.1"
@ -200,6 +235,7 @@ summary = "The little ASGI library that shines."
groups = ["default"] groups = ["default"]
dependencies = [ dependencies = [
"anyio<5,>=3.4.0", "anyio<5,>=3.4.0",
"typing-extensions>=3.10.0; python_version < \"3.10\"",
] ]
files = [ files = [
{file = "starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7"}, {file = "starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7"},
@ -226,6 +262,7 @@ groups = ["default"]
dependencies = [ dependencies = [
"click>=7.0", "click>=7.0",
"h11>=0.8", "h11>=0.8",
"typing-extensions>=4.0; python_version < \"3.11\"",
] ]
files = [ files = [
{file = "uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e"}, {file = "uvicorn-0.32.1-py3-none-any.whl", hash = "sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e"},

View File

@ -9,6 +9,7 @@ dependencies = [
"fastapi>=0.115.5", "fastapi>=0.115.5",
"uvicorn>=0.32.1", "uvicorn>=0.32.1",
"dotenv>=0.0.5", "dotenv>=0.0.5",
"SMrtd>=1.0.1",
] ]
requires-python = ">=3.12" requires-python = ">=3.12"
readme = "README.md" readme = "README.md"

View File

@ -1,5 +1,7 @@
from fastapi import FastAPI from fastapi import FastAPI
from src.modules.router import router as modulesrouter
app = FastAPI(root_path="/api")
app = FastAPI() app.include_router(router=modulesrouter)

View File

@ -0,0 +1 @@
Card: RTD Data Acquisition 8-Layer Stackable HAT for Raspberry Pi - https://sequentmicrosystems.com/products/rtd-data-acquisition-card-for-rpi

View File

@ -0,0 +1,35 @@
import src.modules.RTD8.service as service
from fastapi import APIRouter
from typing import Dict
router = APIRouter(prefix="/RTD8", tags=["Modules --> RTD8 card"])
@router.get("/all", summary="Read all RTD8 cards values in Celsius", response_model=Dict[int, Dict[int, float]])
def get_all_celsius():
return service.read_temp_all()
@router.get("/{stack}", summary="Read specified RTD8 card values in Celsius", response_model=Dict[int, float])
def get_stack_celsius(stack: int):
return service.read_temp_stack(stack)
@router.get("/{stack}/{channel}", summary="Read specified RTD8 card value of specified channel in Celsius", response_model=float)
def get_channel_celsius(stack: int, channel: int):
return service.read_temp(stack, channel)
@router.get("/all/resistance", summary="Read all RTD8 cards values in Ohm", response_model=Dict[int, Dict[int, float]])
def get_all_celsius():
return service.read_resistance_all()
@router.get("/{stack}/resistance", summary="Read specified RTD8 card values in Ohm", response_model=Dict[int, float])
def get_stack_celsius(stack: int):
return service.read_resistance_stack(stack)
@router.get("/{stack}/{channel}/resistance", summary="Read specified RTD8 card value of specified channel in Ohm", response_model=float)
def get_channel_celsius(stack: int, channel: int):
return service.read_resistance(stack, channel)

View File

@ -0,0 +1,58 @@
import librtd, os
stacks = [int(h) for h in os.getenv("MODULE_RTD8_LEVELS", "")]
if not stacks:
print("MODULE_RTD8_LEVELS is not set or invalid")
def read_temp(stack: int, channel: int) -> float | str:
"""
Read specified channel in Celsius
"""
if stack in stacks and 1 <= channel <= 8:
try:
return librtd.get(stack, channel)
except Exception as e:
raise ValueError(f"Error read data from card {stack} on channel {channel} by error: {e}")
return -512
def read_temp_stack(stack: int) -> dict:
"""
Read all inputs data in Celsius
"""
return {ch: read_temp(stack=stack, channel=ch) for ch in range(1, 9)}
def read_temp_all() -> dict:
"""
Read all RTD8 cards inputs in Celsius
"""
return {stack: read_resistance_stack(stack=stack) for stack in stacks}
def read_resistance(stack: int, channel: int) -> float | str:
"""
Read specified channel in Ohm
"""
if stack in stacks and 1 <= channel <= 8:
try:
return librtd.getRes(stack, channel)
except Exception as e:
raise ValueError(f"Error read data from card {stack} on channel {channel} by error: {e}")
return -512
def read_resistance_stack(stack: int) -> dict:
"""
Read all inputs data in Ohm
"""
return {ch: read_resistance(stack=stack, channel=ch) for ch in range(1, 9)}
def read_resistance_all() -> dict:
"""
Read all RTD8 cards inputs in Ohm
"""
return {stack: read_resistance_stack(stack=stack) for stack in stacks}

11
src/modules/router.py Normal file
View File

@ -0,0 +1,11 @@
from fastapi import APIRouter
from src.modules.RTD8.router import router as RTD8Router
router = APIRouter(prefix="/modules")
router.include_router(router=RTD8Router)