Files
Lauri Ojansivu b7589737f5 File docs/Features the way the WeKan menus are.
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 !
2026-10-16 23:45:35 +03:00

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}/comments with { "comment": "Checked in at the workshop" }.
  • Create a card for an unknown tag: POST /api/boards/{board}/lists/{list}/cards with { "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.