Skip to content

Commit

Permalink
feat: add Chacon 54662 support
Browse files Browse the repository at this point in the history
  • Loading branch information
fcrespel committed May 9, 2024
1 parent 9f0b62e commit 8d5c0e7
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Remote Control REST API

REST API to use an RF 433 MHz transmitter as a remote control. It currently only supports the Chacon DIO 1.0 protocol.
REST API to use an RF 433 MHz transmitter as a remote control. It currently only supports the Chacon DIO 1.0 and Chacon 54662 protocols.

It has only been tested on an ODROID-C4 board and uses an ODROID-specific WiringPi version. It should be easy to adapt it for other boards (e.g. Raspberry Pi).

Expand Down
Empty file added app/chacon54662/__init__.py
Empty file.
28 changes: 28 additions & 0 deletions app/chacon54662/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import argparse

import odroid_wiringpi as wiringpi

from .protocol import transmit


def parse_args():
parser = argparse.ArgumentParser(description="Chacon 54662 remote control")
parser.add_argument("-g", "--gpio", help="GPIO WiringPi pin number (default: 0)", type=int, choices=range(0, 30), metavar="[0-29]", default=0)
parser.add_argument("-w", "--word", help="24-bit code word", type=int, required=True)
parser.add_argument("-r", "--repeat", help="Number of times to repeat the message (default: 1)", type=int, default=1)
return parser.parse_args()


def main():
args = parse_args()

if wiringpi.wiringPiSetup() == -1:
raise Exception("Failed to initialize WiringPi")
wiringpi.pinMode(args.gpio, wiringpi.OUTPUT)

for _ in range(args.repeat):
transmit(args.gpio, args.word)


if __name__ == "__main__":
main()
46 changes: 46 additions & 0 deletions app/chacon54662/protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import odroid_wiringpi as wiringpi

TIME_HIGH_LOCK = 290
TIME_LOW_LOCK = 2400

TIME_HIGH_0 = 1070
TIME_LOW_0 = 470

TIME_HIGH_1 = 290
TIME_LOW_1 = 1250


def sendBit(pin: int, b: bool):
if b:
wiringpi.digitalWrite(pin, wiringpi.HIGH)
wiringpi.delayMicroseconds(TIME_HIGH_1)
wiringpi.digitalWrite(pin, wiringpi.LOW)
wiringpi.delayMicroseconds(TIME_LOW_1)
else:
wiringpi.digitalWrite(pin, wiringpi.HIGH)
wiringpi.delayMicroseconds(TIME_HIGH_0)
wiringpi.digitalWrite(pin, wiringpi.LOW)
wiringpi.delayMicroseconds(TIME_LOW_0)


def sendWord(pin: int, word: int, bits: int):
for bit in reversed(range(bits)):
if word & (1 << bit):
sendBit(pin, True)
else:
sendBit(pin, False)


def transmit(pin: int, word: int):
for _ in range(4):
# Code word (24 bits)
sendWord(pin, word, 24)

# End lock
wiringpi.digitalWrite(pin, wiringpi.HIGH)
wiringpi.delayMicroseconds(TIME_HIGH_LOCK)
wiringpi.digitalWrite(pin, wiringpi.LOW)
wiringpi.delayMicroseconds(TIME_LOW_LOCK)

# Delay before next transmission
wiringpi.delay(10)
24 changes: 24 additions & 0 deletions app/chacon54662/routes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from fastapi import APIRouter, Body, Path, Query, Request

from .protocol import transmit

router = APIRouter(prefix="/chacon54662", tags=["chacon54662"])


@router.get("/state/{stateKey}", summary="Get button state")
async def get_state(request: Request, stateKey: str = Path(pattern="[a-z0-9-]")):
"""Get the current state for a given stateKey"""
if stateKey in request.app.state.chacon54662:
return request.app.state.chacon54662[stateKey]
else:
return 0


@router.put("/word", summary="Send 24-bit code word")
async def put_word(request: Request, word: str = Body(pattern="[01]{24}"), repeat: int = 3,
stateKey: str = Query(default=None, pattern="[a-z0-9-]"), stateValue: int = Query(default=None, ge=0, le=1)):
"""Send a 24-bit code word and optionally save state in a given stateKey"""
if stateKey is not None and stateValue is not None:
request.app.state.chacon54662[stateKey] = stateValue
for _ in range(repeat):
transmit(request.app.state.gpio, int(word, 2))
3 changes: 3 additions & 0 deletions app/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import odroid_wiringpi as wiringpi
import uvicorn
from chacon54662.routes import router as chacon54662_router
from chacondio10.routes import router as chacondio10_router
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
Expand All @@ -22,8 +23,10 @@ async def lifespan(app: FastAPI):
yield

app = FastAPI(title="Remote Control REST API", description="REST API to use an RF 433 MHz transmitter as a remote control", version="1.0", lifespan=lifespan)
app.include_router(chacon54662_router)
app.include_router(chacondio10_router)
app.state.gpio = 0
app.state.chacon54662 = {}
app.state.chacondio10 = {}


Expand Down

0 comments on commit 8d5c0e7

Please sign in to comment.