Serial Communication Framework for Raspberry PI
Project description
picmd
picmd is a framework for creating applications that request and respond to AT commands using serial communication.
Its main purpose is for use with Raspberry PI.
Quick Sample
Create an instance of PiCmd
with the create
method and register the command handler with the handler
decorator.
Start the application with the run
method and wait for a command request.
from picmd import PiCmd
import time
app = PiCmd.create('/dev/serial0')
@app.handler(0x01)
def greeting_handler() -> str:
return 'hello world'
@app.handler(0x02)
def file_receive_handler(data: bytes):
with open('./tmp/received-%s.bin' % int(time.time()), 'wb') as f:
f.write(data)
app.run()
AT Command Format
Command Request (Client -> Application)
Hexadecimal data starting with AT*PIC=
and ending with CRLF
.
The command type is specified by the first 8 bits.
The command parameter size is represented by the second 16 bits. Then there is the content of the command parameters.
The check parity is the XOR of the values from command type to command parameter.
AT*PIC=\x01\x04\x00\x01\x00\x00\x00\x04\r\n
<-----><--><------><--------------><--><-->
\ \ \ \ \ \_ command end delimiter (CRLF)
\ \ \ \ \_ check parity
\ \ \ \_ command data (The length changes depending on the value of "command data size")
\ \ \_ command data size (max 0xffff)
\ \_ command (max 0xff)
\_ command start prefix
Command Response (Application -> Client)
Hexadecimal data starting with *PIC:
and ending with CRLF
.
The response status is specified by the first 8 bits.
The response data size is represented by the second 16 bits. Then there is the content of the response datas.
The check parity is the XOR of the values from response status to response data.
OK
*PIC:\x01\x04\x00\x01\x00\x00\x00\x04\r\nOK\r\n
<---><--><------><--------------><--><-------->
\ \ \ \ \ \_ response end delimiter
\ \ \ \ \_ check parity
\ \ \ \_ response data (The length changes depending on the value of "response data size")
\ \ \_ response data size (max 0xffff)
\ \_ response status (0x01)
\_ response start prefix
ERROR
*PIC:\x07\x04\x00\x01\x00\x00\x00\x02\r\nERROR\r\n
<---><--><------><--------------><--><----------->
\ \ \ \ \ \_ response end delimiter
\ \ \ \ \_ check parity
\ \ \ \_ response data (The length changes depending on the value of "response data size")
\ \ \_ response data size (max 0xffff)
\ \_ response status (values from 0x02 to 0xff)
\_ response start prefix
Reserved value of response status
status | description |
---|---|
0x01 | No error |
0x02 | Invalid command format error |
0x03 | Invalid parity error |
0x04 | Command not found error |
0x05 | Invalid data length error |
0x06 | Command fail error |
How to confirm communication
Sends the following command.
AT\r\n
If the next message is received in the response, the communication confirmation is successful.
\r\n
OK
\r\n
Command Handler Interface
The command handler function receives the byte data of the command parameter in the first argument data
and the size of the command parameter in the second argument size
. It is also possible to omit either or both of these.
You can take a dependency set by the provide
function (see later) as an argument.
Examples of handlers' arguments
An example of a case where you want to receive both data and size.
@app.handler(0x01)
def handler(data: bytes, size: int):
....
An example of receiving data only.
@app.handler(0x01)
def handler(data: bytes):
....
Example of a case where both are not received.
@app.handler(0x01)
def handler():
....
An example of receiving data and dependencies.
@app.handler(0x01)
def handler(data: bytes, service1: Service1, service2: Service2):
....
When returning some kind of response
Returns a value of type bool
, int
, float
,str
, or bytes
.
@app.handler(0x01)
def handler(data: bytes, size: int) -> Union[bool, int, float, str, bytes]:
....
return response_data
When returning no response
Returns nothing.
@app.handler(0x01)
def handler(data: bytes, size: int):
....
# nothing return
If you want to return your domain error status
Raise an exception with the status_code
attribute.
If you want to return error message etc. as response data, add description
attribute.
class DomainException(Exception):
status_code = 0xff
description = 'any error message'
@app.handler(0x01)
def handler(data: bytes, size: int):
....
raise DomainException
API
PiCmd
PiCmd.create(serial_port: str) -> PiCmd
Take the serial port path as an argument and create an instance.
@handler(command: int)
Decorator that takes a command type as an argument and registers it as a handler.
provide(provided: Dict[str, Any])
Specifies the dependency to pass to the handler by dict. The handler will receive the same arguments as the key name.
for example.
app.provide({
'service1': service1,
'service2': service2
})
import_handler_register(handler_register: HandlerRegister)
Import the handlers registered in the HandlerRegister.
run()
Start accepting and responding to commands.
HandlerRegister
It is used to register handlers to be imported into PiCmd.
@handler(command: int)
Decorator that takes a command type as an argument and registers it as a handler.
Client library
The libraries for the client are as follows.
- node-picmd (node.js)
Change Log
0.7.0
Added HandlerRegister feature.
0.6.1
Fixed a response bug of the PING command.
0.6.0
Added a feature to confirm communication.
0.5.0
Added the feature to provide dependency.
0.4.0
Added support for omitting the arguments of the handler function.
0.3.0
Change the data format of the protocol.
0.2.0
Change request and resopnse prefix.
0.1.0
Initial release.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file picmd-0.7.0.tar.gz
.
File metadata
- Download URL: picmd-0.7.0.tar.gz
- Upload date:
- Size: 10.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.8.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1c484bbc6dd940a0c8972f13327c7441ce45efa0b781525484945287f538deec |
|
MD5 | d4281baff320d9699ea0fe515c1cdd8f |
|
BLAKE2b-256 | 3ef3a81972a94ed0809a90a64d532c64de6c22b44d8108aaf4d663cd202b68d5 |
File details
Details for the file picmd-0.7.0-py3-none-any.whl
.
File metadata
- Download URL: picmd-0.7.0-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.1 CPython/3.8.2
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 67a200b4112b43dda4f9b55ef31bbae20b21db2e808ff1defbd84fea8633c9e0 |
|
MD5 | 9f9ea6b6be44d40f652fa6509c0e488f |
|
BLAKE2b-256 | 60c583f5ea6ad129d8c9e39e98fac82be759819e602bdf8898ac455e5ea8078d |