A feature's guide now sits under the menu it is used from, read from the templates rather than from where somebody once put it: Header-Bar, All-Boards, Pages, Board-Header (search and every Board View), Board-Sidebar (Board Settings, Filter, Members, Labels, Archive), Rules, Swimlanes, Lists, Cards, Member-Settings, Admin-Panel and Login-Page. Topics used from several menus (editor, history, theme, translations, email, troubleshooting) are in General. - Each area has a README mapping its menu entries to their guides and to the template or server module that implements them. Board-Header/README.md lists all 40 Board View entries with the template boardBody.jade renders; five views (Table, Calendar Mode, Time, Timeline, Map) have no guide of their own yet and say so. - Board-View.md listed 25 views while BOARD_VIEWS has 40; it now lists all of them with their English labels. - Pages keep their file names. Where a released changelog links an old path, a "# Moved" page stays there and points to the new one; test-menu.sh skips folders holding only those. - Undo was filed under Login; it is General/Undo now. - Every link in docs, code comments, scripts and tests follows the move; docsLinksResolve checks them all. Tests that read a doc follow it to its new place. boardViewSettings now fails when Board-View.md or Board-Header/README.md differs from BOARD_VIEWS, or names a template boardBody.jade does not render. Thanks to xet7 !
3.2 KiB
RFID tags with WeKan's REST API
#1126. WeKan has no RFID support of its own, and needs none. A reader next to a door, a workbench or a shelf, and a short script, can use the REST API to move a card when a tagged thing is scanned. Examples: a tool going out moves its card to In use, a parcel arriving moves to Received, a person checking in adds a comment.
What you need
- WeKan with the REST API on (
WITH_API=true) and a WeKan user for the reader, member of the board with write access. That user's rights are all the script has. - An RFID reader. Most USB readers type the tag's number like a keyboard and
press Enter, so a script reads it from standard input. Serial readers (e.g.
RC522 or PN532 on a Raspberry Pi) are read with their own library; only
the line
tag = ...below changes. - On the board, a custom field called RFID, holding each card's tag number.
Find a card by its tag, move it
GET /api/boards/{board}/cardsByCustomField/{field}/{value} finds the cards
whose RFID field holds the tag, and PUT /api/boards/{board}/lists/{list}/cards/{card} with { "listId": ... } moves
one to another list of the board.
#!/usr/bin/env python3
# Moves the card whose RFID custom field holds the scanned tag to TARGET_LIST.
import json, sys, urllib.request
WEKAN = "https://wekan.example.com"
USER, PASSWORD = "rfid-reader", "a long password"
BOARD, RFID_FIELD, TARGET_LIST = "<board id>", "<RFID custom field id>", "<list id>"
def call(method, path, body=None, token=None):
req = urllib.request.Request(WEKAN + path, method=method,
data=None if body is None else json.dumps(body).encode(),
headers={"Content-Type": "application/json",
**({"Authorization": "Bearer " + token} if token else {})})
with urllib.request.urlopen(req) as res:
return json.load(res)
token = call("POST", "/users/login", {"username": USER, "password": PASSWORD})["token"]
for line in sys.stdin: # a USB reader types the tag + Enter
tag = line.strip()
if not tag:
continue
cards = call("GET", f"/api/boards/{BOARD}/cardsByCustomField/{RFID_FIELD}/{tag}", token=token)
for card in cards:
call("PUT", f"/api/boards/{BOARD}/lists/{card['listId']}/cards/{card['_id']}",
{"listId": TARGET_LIST}, token=token)
print(f"{tag}: moved {card['title']}")
if not cards:
print(f"{tag}: no card has this tag")
The ids are in the board's URL and in GET /api/boards/{board}/lists and
GET /api/boards/{board}/custom-fields.
Other actions
- Add a comment instead:
POST /api/boards/{board}/cards/{card}/commentswith{ "comment": "Checked in at the workshop" }. - Create a card for an unknown tag:
POST /api/boards/{board}/lists/{list}/cardswith{ "title": tag, "swimlaneId": ... }, then set its RFID field. - Let a Rule do the rest: "when a card is moved to In use, set the due date to 7 days later".
Keep the reader's WeKan password out of the script in shared places, for example in an environment variable, and give that user only the boards it needs.