uhppoted / uhppote-simulator

Go simulator for the UHPPOTE UT0311-L0x TCP/IP Wiegand access controller boards
MIT License
1 stars 2 forks source link
access-control uhppote

build ghcr

uhppote-simulator

Software simulator for access control systems based on the UHPPOTE UT0311-L0x TCP/IP Wiegand access control boards.

Supported operating systems:


Contents


Release Notes

Current release

v0.8.9 - 2024-09-06

  1. Implemented controller TCP/IP interface emulation.
  2. Added REST put-card API to add/update simulated controller cards.
  3. Reworked event handling to use connected UDP socket to send events.
  4. Reworked put-card handler to return false if card from or to date is a zero value.
  5. Updated to Go 1.23.

Installation

Docker

A public Docker image is published to ghcr.io. The image:

docker compose

A sample Docker compose configuration is provided in the docker/compose folder.

To run the example, download and extract the zipped scripts and supporting files into folder of your choice and then:

cd <compose folder>
docker compose up

The emulated controllers can be managed using the REST API.

docker run

To start a simulator using Docker run:

docker pull ghcr.io/uhppoted/simulator:latest
docker run --detach --publish 8000:8000 --publish 60000:60000/udp --name simulator \
           --mount source=uhppoted,target=/usr/local/etc/uhppoted \
           --rm ghcr.io/uhppoted/simulator

The emulated controllers can be managed using the REST API REST API.

docker build

For inclusion in a Dockerfile:

FROM ghcr.io/uhppoted/simulator:latest

Building from source

Assuming you have Go and make installed:

git clone https://github.com/uhppoted/uhppote-simulator.git
cd uhppote-simulator
make build

If you prefer not to use make:

git clone https://github.com/uhppoted/uhppote-simulator.git
cd uhppote-simulator
mkdir bin
go build -trimpath -o bin ./...

uhppote-simulator

Supported uhppote functions:

Usage: uhppote-simulator \<command> --devices=\<dir>

Defaults to 'run' unless one of the commands below is specified:

Supported options:

REST API

The simulator provides a REST API to simulate user actions and manage controllers:

The actions may be invoked:

The default port is 8000.

swipe-card

Simulates a card swipe with optional keypad code.

URL: `http://localhost:8000/uhppote/simulator/{controller}/swipe`
Method: POST
Request:
{
    "door": <door>,
    "card-number: <card>,
    "direction": [1|2],
    "PIN": <passcode>
}

controller   controller serial number e.g. 405419896
door         door number [1..4] e.g. 3
direction    1: IN, 2: OUT
PIN          (optional) PIN code for keypad reader

swipe:

curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/swipe" -H "accept: application/json" -H "Content-Type: application/json" -d '{"door":1,"card-number":10058400,"direction":1,"PIN":1357}'

swipe-in:

curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/swipe" -H "accept: application/json" -H "Content-Type: application/json" -d '{"door":1,"card-number":10058400,"direction":1,"PIN":1357}'

swipe-out:

curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/swipe" -H "accept: application/json" -H "Content-Type: application/json" -d '{"door":1,"card-number":10058400,"direction":2,"PIN":1357}'

supervisor-passcode

Simulates a supervisor passcode entry on a keypad.

URL: `http://localhost:8000/uhppote/simulator/{controller}/code`
Method: POST
Request:
{
    "door": <door>,
    "PIN": <passcode>
}

controller   controller serial number e.g. 405419896
door         door number [1..4] e.g. 3
passcode     supervisor passcode
curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/code" -H "accept: application/json" -H "Content-Type: application/json" -d '{"door":1,"passcode":1357}'

open-door

Simulates opening a door - the door must be unlocked (e.g. by a card swipe or button press or supervisor passcode) to open. A door open event will generated if the door was closed.

URL: `http://localhost:8000/uhppote/simulator/{controller}/door/{door}`
Method: POST
Request:
{
    "action": "open",
}

controller   controller serial number e.g. 405419896
door         door number [1..4] e.g. 3
action       open
curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/door/1" -H "accept: application/json" -H "Content-Type: application/json" -d '{"action":"open"}'

close-door

Simulates closing a door - a door closed event will be generated if the door was open.

URL: `http://localhost:8000/uhppote/simulator/{controller}/door/{door}`
Method: POST
Request:
{
    "action": "close",
}

controller   controller serial number e.g. 405419896
door         door number [1..4] e.g. 3
action       close
curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/door/1" -H "accept: application/json" -H "Content-Type: application/json" -d '{"action":"close"}'

press-button

Simulates pressing the 'door open' button - a button pressed event will be generated if the button was not already pressed.

URL: `http://localhost:8000/uhppote/simulator/{controller}/door/{door}`
Method: POST
Request:
{
    "action": "button",
    "duration": 10
}

controller   controller serial number e.g. 405419896
door         door number [1..4] e.g. 3
action       button
duration     seconds to press the button e.g. 10
curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/door/1" -H "accept: application/json" -H "Content-Type: application/json" -d '{"action":"button", "duration":10}'

list-controllers

Lists the configured controllers.

URL: `http://localhost:8000/uhppote/simulator`
Method: GET
curl -X GET "http://127.0.0.1:8000/uhppote/simulator" -H "accept: application/json"

create-controller

Adds a new controller to the simulator.

URL: `http://localhost:8000/uhppote/simulator`
Method: POST
Request:
{
    "device-id": <controller>,
    "device-type": <manufacturer-code>,
    "compressed": [true|false]
}

controller          controller serial number e.g. 405419896
manufacturer-code   UT0311-L02 for a 2 door controller, UT0311-L04 for a 4 door controller
compressed          store controller in compressed (true) or human-readable form (false)
curl -X POST "http://127.0.0.1:8000/uhppote/simulator" -H "accept: */*" -H "Content-Type: application/json" -d '{"device-id":405419896,"device-type":"UT0311-L04","compressed":false}'

delete-controller

Delets a controller from the simulator.

URL: `http://localhost:8000/uhppote/simulator/<controller>`
Method: DELETE

controller   controller serial number e.g. 405419896
curl -X DELETE "http://127.0.0.1:8000/uhppote/simulator/405419896" -H "accept: */*"

put-card

Adds or updates a card on a simulated controller. Unlike the controller put-card API, the REST API does not require a valid start/end date (for testing purposes).

URL: `http://localhost:8000/uhppote/simulator/<controller>/cards/<card>`
Method: PUT
Request:
{
    "start-date": <start-date>,
    "end-date": <end-date>,
    "doors": <doors>,
    "PIN": <uint32>
}

controller     controller serial number e.g. 405419896
start-date     card 'valid from' date e.g 2024-01-01
end-date       card 'valid until' date e.g 2024-12-31
doors          list of doors the card for which the card has access e.g. [1,2,4]
PIN            card PIN e.g.7531
curl -X POST "http://127.0.0.1:8000/uhppote/simulator/405419896/cards/10058400" -H "accept: */*" -H "Content-Type: application/json" -d '{"start-date": "2024-01-01", "end-date": "2024-12-31", "doors": [1,2,4], "PIN": 7531}'

Postman

Python

NOTES

put-card

  1. The UHPPOTE access controller has a weird behaviour around the PIN field. According to the SDK documentation, valid PINs are in the range 0 to 999999. However the controller will accept a PIN number out of that range and only keep the lower 7 nibbles of the 32-bit unsigned value. e.g:
PIN Hex value Stored as (hex) Retrieved as (hex) Retrieved as (decimal)
0 0x000000 0x000000 0x000000 0
999999 0x0f423f 0x0f423f 0x0f423f 999999
1000000 0x0f4240 0x000000 0x000000 0
1000001 0x0f4241 0x000000 0x000000 0
1048576 0x100000 0x000000 0x000000 0
1048577 0x100001 0x000000 0x000001 1
1999999 0x1E847F 0x0E847F 0x000001 951423

Note that by design, the simulator does not emulate this behaviour, on the grounds that it is probably a version specific bug.

  1. The emulated controller does not accept cards with a 'zero' start or end date - the REST put-card API can be used to add cards without valid start/end dates for testing.

restore-default-parameters

restore-default-parameters has (for practical reasons) NOT been validated against an actual controller. Resetting the simulator:

passcode

  1. If a supervisor passcode is entered for a door that is normally closed, the UHPPOTE controller will unlock the door and then immediately relock it. This seems anomalous and in this case the simulator unlocks the door on the assumption that the supervisor code is intended to be an override.

Events

tl;dr; The UHPPOTE controller does not 'rollover' when the onboard event store is filled.

From experimentation, it appears that the UHPPOTE controller has an event store for approximately 200 000 events (the user manual says 100 000, so possibly varies varies with model/version). On filling the event buffer the controller seems to discard a chunk of about 2048 events from the start of the event buffer to make space for new events. The event index continues to increment monotonically.