uhppoted / uhppoted-dll

Shared library (DLL) for uhppote-core with bindings for C, C++, C#, Python and Clozure Common Lisp
MIT License
4 stars 1 forks source link

How to use? #6

Closed RofiMF closed 1 year ago

RofiMF commented 1 year ago

Hi, Sorry, I want to ask how to use this library in Python?

Can you use "pip install" or is there another way?

uhppoted commented 1 year ago

Hi,

Unfortunately it can't be pip installed - it uses a DLL generated from a Go library and that DLL has to be built on the target system which makes it difficult to package it up and put it on PyPI.

If you want to use it you have to clone the project, build it locally and then copy the DLL and the Python bindings to your own project. Which is not difficult but requires Go to be installed on your system - the steps are described under the installation section of the README. The Python bindings are documented here and there is an example of how to use them here.

You could also take a look at the generated bindings for Python which do not require you to build anything locally - just download the bindings from the Releases, unzip them and put them somewhere in your project folder.

I've added a TODO item to package the codegen'd bindings as a Python library and put it on PyPI but it's going to be a while before I get to it I'm afraid.

RofiMF commented 1 year ago

Hi, I have tried to do according to what is in the installation section but I get an error when running the build :

when using "Make" : image

and when using "Go": image

and this is the result of running it in Python: image

I hope there is another way you can provide?

Thank You

uhppoted commented 1 year ago

Hi,

It looks like your directory structure isn't correct. Lets start by getting the example project up and running and then we can take it from there - in a clean directory, try this:

  1. git clone https://github.com/uhppoted/uhppoted-dll.git

    > Cloning into 'uhppoted-dll'...
    > remote: Enumerating objects: 2027, done.
    > remote: Counting objects: 100% (262/262), done.
    > remote: Compressing objects: 100% (169/169), done.
    > remote: Total 2027 (delta 129), reused 171 (delta 84), pack-reused 1765
    > Receiving objects: 100% (2027/2027), 1.47 MiB | 3.70 MiB/s, done.
    > Resolving deltas: 100% (1291/1291), done.
  2. cd uhppoted-dll

  3. make build

    > go fmt ./go/...
    > go build -trimpath -buildmode=c-shared -o ./lib/libuhppoted.dylib go/devices.go go/cards.go go/events.go go/time_profiles.go go/tasks.go go/main.go 
    > go build -trimpath -buildmode=c-shared -tags debug -o ./lib/debug/libuhppoted.dylib go/devices_debug.go go/cards_debug.go go/events_debug.go go/time_profiles_debug.go go/tasks_debug.go go/main.go 
    > go build -trimpath -buildmode=c-shared -tags tests -o ./lib/tests/libuhppoted.dylib go/devices_tests.go go/cards_tests.go go/events_tests.go go/time_profiles_tests.go go/tasks_tests.go go/main.go 
  4. cd examples/python

  5. make build

    > yapf -ri .
    > yapf -ri ../../bindings/python
  6. make get-devices

    >  ... request
    >  ...          00000000  17 94 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    >  ...          00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    >  ...          00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    >  ...          00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    >  ...          
    > 
    >  ... sent 64 bytes to 255.255.255.255:60000
    > 
    >  ... received 64 bytes from 192.168.1.100:60000
    >  ...          00000000  17 94 00 00 41 78 1e 12  c0 a8 01 64 ff ff ff 00  |....Ax.....d....|
    >  ...          00000010  c0 a8 01 01 52 fd fc 07  21 82 08 92 20 19 08 15  |....R...!... ...|
    >  ...          00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    >  ...          00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    >  ...          
    >  ...          
    > get-devices(1)
    >     405419896

Let me know how it goes.

RofiMF commented 1 year ago

Hi, I got this when I did step 5, what should I do for this? image

for step 3 I have successfully run it and I did it on my laptop because the previous one I did on my PC and it still has the same problem so I think there is a problem with my PC.

uhppoted commented 1 year ago

Hi,

I suspect you don't have yapf installed - it's a Python code formatter and it's not an absolute requirement so you could just edit the Makefile to remove it, but at this stage it's probably easier to just install it:

pip install yapf

re. PC. It sounds like there is something wrong with your Go installation - or it's possibly a very old version. The DLL is developed against the latest version (1.20 at the moment). You can check the Go version with:

go version
RofiMF commented 1 year ago

Hi,

For yapf is already installed and Go is using version 1.20, but it still doesn't work when running Make build on examples/python. image

Is there still something I'm missing?

uhppoted commented 1 year ago

Ah, ok - I think the problem may be that your yapf is not installed as an executable. Try this command:

python3 yapf -ri .

or (depending how you have it installed):

python yapf -ri .

If that works then just edit the Makefile to use that command (possibly installing yapf using chocolatey might also work but it's not something I've tried).

re. Go. Is that the version on your laptop or desktop? If it's on your desktop then try this next in the root of the uhppoted-dll directory:

go fmt ./go/...
RofiMF commented 1 year ago

that is version on my laptop.

I try this on my laptop : image

I try this on my desktop : image

RofiMF commented 1 year ago

Hi, I can already use this library for my project.

Thank you for the help. I was very helped, especially with the response, which was quite fast and very detailed in giving instructions.

uhppoted commented 1 year ago

Oh! Great .. was just trying to think of what else to try, but that's good news!

RofiMF commented 1 year ago

Hi, I want to ask how to set the interlock and how to remove the interlock?

uhppoted commented 1 year ago

The set-interlock function is in the extended functions set which hasn't been completely implemented yet (it mostly only happens when somebody requests something from it).

I've added it to the current dev-cycle (ref. https://github.com/uhppoted/uhppote-core/issues/14) - give me a couple of days?

RofiMF commented 1 year ago

Okay I'll wait and while waiting I'll try the existing functions

Thank you

uhppoted commented 1 year ago

Hi,

Just a quick note to let you know the set-interlock API implementation has been pushed to the main branch - you'll have to do a git pull --rebase and then rebuild your local DLL to get it.

The implementation is provisional, pending more testing and release (sometime in June probably) but it's such a simple function it's unlikely to change.

RofiMF commented 1 year ago

Hi, First, I would like to thank you for completing the interlock function.

I've tried this interlock function and this is the result I got:

0 = None (Can open all doors) 1 = Door 1,2 Locked (can't be opened), Door 3,4 (can be opened) 2 = Door 3,4 Locked (can't be opened), Door 1,2 (can be opened) 3 = Doors 1,2,3,4 Locked (can't be opened) 4 = Door 1,2,3 Locked (can't be opened), Door 4 (can be opened)

what do you think about this?

uhppoted commented 1 year ago

Mmmm, it works according to spec on my controller - maybe double check your test methodology? It sounds like you possibly have the door switches or relays mislabelled.

Two things you can try:

  1. Use the example implementation with debug enabled - you should see something like:

    make set-interlock CONTROLLER=405419896 INTERLOCK=3
    
    ... sent 64 bytes to 255.255.255.255:60000
    
    ... request
    ...          00000000  17 a2 00 00 78 37 2a 18  03 00 00 00 00 00 00 00  |....-U9.........|
    ...          00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    ...          00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    ...          00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    ...          
    
    ... received 64 bytes from 192.168.1.101:60000
    ... response
    ...          00000000  17 a2 00 00 2d 55 39 19  01 00 00 00 00 00 00 00  |....-U9.........|
    ...          00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    ...          00000020  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    ...          00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    ...          
    set-interlock
    ID         423187757
    interlock  3
  2. Use the CLI listen command you can record the controller status and events and verify that what you think you are doing matches what the controller is seeing.

uhppoted commented 1 year ago

Ok, I did some more extensive testing and it appears the documentation I have is completely wrong and you were right and I was wrong. There appear to be 5 modes:

This is the updated interlock implementation as I have it currently mapped:

Interlock S1 S2 S3 S4 PB1 PB2 PB3 PB4
0 CLOSED CLOSED CLOSED CLOSED OK OK OK OK
0 OPEN OPEN OPEN OPEN OK OK OK OK
1 CLOSED CLOSED CLOSED CLOSED OK OK OK OK
1 OPEN CLOSED CLOSED CLOSED OK -- OK OK
1 CLOSED OPEN CLOSED CLOSED -- OK OK OK
1 CLOSED CLOSED OPEN CLOSED OK OK OK OK
1 CLOSED CLOSED CLOSED OPEN OK OK OK OK
2 CLOSED CLOSED CLOSED CLOSED OK OK OK OK
2 OPEN CLOSED CLOSED CLOSED OK OK OK OK
2 CLOSED OPEN CLOSED CLOSED OK OK OK OK
2 CLOSED CLOSED OPEN CLOSED OK OK OK --
2 CLOSED CLOSED CLOSED OPEN OK OK -- OK
3 CLOSED CLOSED CLOSED CLOSED OK OK OK OK
3 OPEN CLOSED CLOSED CLOSED OK -- OK OK
3 CLOSED OPEN CLOSED CLOSED -- OK OK OK
3 CLOSED CLOSED OPEN CLOSED OK OK OK --
3 CLOSED CLOSED CLOSED OPEN OK OK -- OK
4 CLOSED CLOSED CLOSED CLOSED OK OK OK OK
4 OPEN CLOSED CLOSED CLOSED OK -- -- OK
4 CLOSED OPEN CLOSED CLOSED -- OK -- OK
4 CLOSED CLOSED OPEN CLOSED -- -- OK OK
4 CLOSED CLOSED CLOSED OPEN OK OK OK OK
8 CLOSED CLOSED CLOSED CLOSED OK OK OK OK
8 OPEN CLOSED CLOSED CLOSED OK -- -- --
8 CLOSED OPEN CLOSED CLOSED -- OK -- --
8 CLOSED CLOSED OPEN CLOSED -- -- OK --
8 CLOSED CLOSED CLOSED OPEN -- -- -- --

I've pushed the changes to the repo but please treat them as provisional, pending more testing and validation.

RofiMF commented 1 year ago

Hi, I have tried the last update from you which is 5 interlock mode and I get the result like this : 0 = None (Can open all doors) 1 = Door 1,2 Locked (can't be opened), Door 3,4 (can be opened) 2 = Door 3,4 Locked (can't be opened), Door 1,2 (can be opened) 3 = Doors 1,2,3,4 Locked (can't be opened) 4 = Door 1,2,3 Locked (can't be opened), Door 4 (can be opened) 8 = Doors 1,2,3,4 Locked (can't be opened)

uhppoted commented 1 year ago

That looks more or less correct - if you want an interlocked door to be opened you have to bridge out the door sensor contact, e.g. in mode 1, if you want to open door 1 then door 2 must be closed.

If you're working with a bare board (i.e. not connected to an actual door sensor) then you can simulate that by connecting a wire between the two screw contacts of S2.

RofiMF commented 1 year ago

Oh right, I just realized it

I get results like that because the default board status of all doors is open, right?

so I have to use a sensor to make the status close in order to get a more suitable interlock result

CMIIW

uhppoted commented 1 year ago

Sort of suspected as much :-).

But yeah, the door contacts are sensed as closed when the two terminals are shorted together and sensed as open when they are open circuited. The reasoning is that if a wire breaks then the door will be sensed as open which is what you want. If it was the other way around then somebody could just break the wire, open the door and then walk in and out as they please without you being aware of it.

RofiMF commented 1 year ago

ok, I'll try first to install the sensor on my board and try the interlock function again

uhppoted commented 1 year ago

Am going to mark this as closed - haven't found any further issues while testing and the set-interlock function has been included in the v0.8.5 release.

Feel free to reopen if you need to though.

RofiMF commented 1 year ago

Hi, Previously, I would like to thank you for the help with the interlock function, the interlock function works fine without any problems.

What I want to ask now is whether it has a function to provide a password/PIN for each door?

uhppoted commented 1 year ago

Hi,

The PIN is (optionally) included in the put-card request - it somehow slipped through the cracks when I was updating the documentation for reader keypad support, but there's an example of how to do it in examples.py:

def put_card(u, args):
    device_id = args.controller
    card_number = args.card
    start = '2023-01-01'
    end = '2023-12-31'
    doors = [0, 1, 31, 75]
    PIN = 7531

    card = u.put_card(device_id, card_number, start, end, doors, PIN)

    display('put-card', [
        ('ID', device_id),
        ('card-number', card_number),
        ('     from', start),
        ('     to', end),
        ('     door[1]', doors[0]),
        ('     door[2]', doors[1]),
        ('     door[3]', doors[2]),
        ('     door[4]', doors[3]),
        ('     PIN', PIN),
    ])

You'll also need to invoke the activate-keypads function to enable/disable the reader keypads:

def activate_keypads(u, args):
    device_id = args.controller
    reader1 = True
    reader2 = True
    reader3 = False
    reader4 = True

    u.activate_keypads(device_id, reader1, reader2, reader3, reader4)

    display('activate-keypads', [
        ('ID', device_id),
        ('reader 1', reader1),
        ('reader 2', reader2),
        ('reader 3', reader3),
        ('reader 4', reader4),
    ])

(you may need to update your DLL - activate-keypads was added in v0.8.6)

uhppoted commented 1 year ago

BTW, apropos of your first query on this issue - there is now a pure Python package which you can pip install:

The API is slightly different to the DLL so if you've already done a lot of development with the DLL you may not want to switch - the Python package has also only just been released (last week) so it's not nearly as battle tested as the DLL :-).

RofiMF commented 1 year ago

sorry, I mean just set a password/PIN without having to put_card

this is needed for certain people who are not given a card but are allowed to enter

and thank you for providing that can be installed via pip

uhppoted commented 1 year ago

I'm afraid I haven't any idea at how to do that - all the systems I've worked with use cards! It would probably depend on what the reader was doing... do you have any documentation for the reader/keypad?

You could try looking at the events while entering a PIN on the keypad - it might give you some idea of what the reader is sending through.

RofiMF commented 1 year ago

because on the board/controller that I use I have deleted all the cards listed but it still has a PIN, so I think this board/controller can only be set a password/PIN without the need for a card

uhppoted commented 1 year ago

Mmmm, that doesn't sound right - which model controller and reader are you using?

I've been through the (very minimal) documentation that I have and the only thing I can find that may be related is that the controller allows for up to four supervisor passwords - is it possible that you are using those?

RofiMF commented 1 year ago

image

sorry if I explain it too complicated, what I mean is like the Controller's Password feature in the Access Control application if you know the application

and it's true that the password can be set on each door in the controller

uhppoted commented 1 year ago

Ok, having done some more reading - your keypads are probably working in Wiegand-26 emulation mode which means that the card number you need to program is

| facility code | 5 digit PIN |

e.g. if your facility code is 67 and the PIN is 1234, the card number would be 6701234

If your reader came with any documentation it may have more detail otherwise this might have some useful information:

If all else fails you could try downloading uhppote-cli and use it to listen to the controller swipe events which include the card number you would need to program.

However, that doesn't explain why your PIN codes work if you have deleted all the cards - the only explanation for that I can think of is that you are using the supervisor PINs. If you've downloaded uhppote-cli it may be worth running the get-all-cards command to see what is actually on your system.

RofiMF commented 1 year ago

How do you set the supervisor PIN that you mean?

uhppoted commented 1 year ago

Ah, ok - what you're calling the controller password is what the documentation calls the supervisor password.

That hasn't been implemented yet - give me a couple of days?

RofiMF commented 1 year ago

Okay, thank you very much

I will patiently wait for it

uhppoted commented 1 year ago

Thanks :-) ... it's going to have to be added to all the projects but I'll post a note here when the DLL bit is done.

uhppoted commented 1 year ago

Hi,

If you're feeling adventurous, there's a provisional implementation of set-super-passwords in the main branch - it seems to work but it's the first iteration and has only been very superficially tested so YMMV.

(BTW, I won't be available for the next couple of days so expect replies to be a bit delayed)

RofiMF commented 1 year ago

Coincidentally, in the next few days I will also be on another project, so maybe I won't be able to try the set-super-password that has been implemented.

So maybe I can wait for the final set-super-password.

uhppoted commented 1 year ago

Hi - am going to close this issue.

The set-door-passcodes function has been implemented across the board (cf. https://github.com/uhppoted/uhppoted/issues/40) and seems to work as expected. It will be included in the next release (v0.8.7) which is still some time away so if you need the functionality, please use the code from the main branch.

Feel free to reopen if you need to :-).

RofiMF commented 1 year ago

Thank you very much for providing the set-door-passcodes. I will try to apply this feature first.

image

I suddenly got an error like this in a function that I had created. can I ask for help with this problem? what happened so that I can get an error like this?

uhppoted commented 1 year ago

Hi,

I've created a new issue to look at this: Error in devices.go line 137

RofiMF commented 1 year ago

okay, I hope this issue can be resolved

uhppoted commented 1 year ago

Uh .. can you please take a look at that issue? I need the debug output :-)

RofiMF commented 1 year ago

I have 121 controllers and put get_status inside forloop, then the issue appears

uhppoted commented 1 year ago

I'm afraid I can't do much without the debug output - Error in devices.go line 137 describes how to get it.