Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
89065e3
Update sas.py
dedalgr May 20, 2021
6f03c4f
Update sas.py
dedalgr Jun 6, 2022
9bc98af
ported to python3 and formatted
zacharytomlinson Dec 14, 2023
ad461cf
Game machine ID function does not return financial data
zacharytomlinson Jan 19, 2024
2844126
Removed artifacts
zacharytomlinson Jan 19, 2024
f9edf92
Fixed CRC issues with python3
zacharytomlinson Jan 23, 2024
8255684
Initial passover and cleanup of code
zacharytomlinson Jan 23, 2024
367540f
Formatted with black
zacharytomlinson Jan 23, 2024
a9bf015
Fixed some name cases
zacharytomlinson Jan 24, 2024
86dc186
Merge pull request #4 from zacharytomlinson/name-fix
zacharytomlinson Jan 24, 2024
f2b78d5
Merge branch 'master' into black-format
zacharytomlinson Jan 24, 2024
71798dd
Merge pull request #3 from zacharytomlinson/black-format
zacharytomlinson Jan 24, 2024
50e14c5
chore: fix typo, var/func naming confusion, restructure of the projec…
Jan 24, 2024
cc8bfba
chore: forgot to check if self.trasaction is populated before using it
Jan 24, 2024
8452a79
chore: black reformatting
Jan 24, 2024
b9d9e30
chore: test case skeleton
Jan 24, 2024
754ee7d
chore: test case skeleton
Jan 24, 2024
0289aaa
chore: detached config file from library. It's a lib and not a program
Jan 24, 2024
35a9f90
chore: updated test case skeleton
Jan 24, 2024
1e699a5
Merge remote-tracking branch 'origin/cleaning-and-restructure' into c…
Jan 24, 2024
7462a17
chore: reformatted with black
Jan 24, 2024
4bb9397
Merge pull request #5 from zacharytomlinson/cleaning-and-restructure
zacharytomlinson Jan 24, 2024
844b7a4
Update example.py
dedalgr Jan 26, 2024
f2a2187
Transfered dictionaries to dataclasses
zacharytomlinson Jan 26, 2024
5448647
Added instructions for getting RPI 3 running and stubbed out for RPI …
zacharytomlinson Jan 27, 2024
76c0d98
Added clarification of logic level converter so people don't fry thei…
zacharytomlinson Jan 27, 2024
d6c8af0
Merge pull request #7 from zacharytomlinson/rpi-3-instructions
well-it-wasnt-me Jan 28, 2024
39e1a05
Merge pull request #6 from dedalgr/patch-3
well-it-wasnt-me Jan 28, 2024
504168f
chore: requirements update
Jan 28, 2024
ac1e2e5
chore: requirements update
Jan 28, 2024
beb7427
chore: code reformatting, use of models, remnoved dictionaries, added…
Jan 28, 2024
7813d65
chore: test case to be done
Jan 28, 2024
210aaa6
chore: gitignore update to not push around the benchmark folder
Jan 28, 2024
1c2f245
chore: docs, first draft
Jan 28, 2024
f9a2360
Merge pull request #8 from zacharytomlinson/models-comments-tests
well-it-wasnt-me Jan 29, 2024
ce40a2d
chore: readme update
well-it-wasnt-me Jan 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,8 @@ venv.bak/

# mypy
.mypy_cache/

# IDEs
.idea

.benchmark
32 changes: 32 additions & 0 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the OS, Python version and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.12"
# You can also specify other tool versions:
# nodejs: "19"
# rust: "1.64"
# golang: "1.19"

# Build documentation in the "docs/" directory with Sphinx
sphinx:
configuration: docs/source/conf.py

# Optionally build your docs in additional formats such as PDF and ePub
# formats:
# - pdf
# - epub

# Optional but recommended, declare the Python requirements required
# to build your documentation
# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: requirements.txt
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 thomas-pythonas
Copyright (c) 2024 thomas-pythonas | zacharytomlinson | well-it-wasnt-me

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
83 changes: 75 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,80 @@
# saspy
Slots accounting system protocol based on Python for arm architecture
# SASPY
<p align="center">
<img src="https://github.com/zacharytomlinson/saspy/assets/15037424/e8a8efc8-e83f-44f9-9ca1-7543a280e6b3" width="300" height="auto">
</p>
Slots Accounting System (SAS) Protocol is a standard when comes to Slot Machine and VLTs. And because we were bored and with not enough things to do we decided to build this library

The SAS library was made using python and can be used for linux-based single-board computers (Raspberry, Orange PI, Banana Pi).
The Library is used for connecting to EGM by RS-232 protocol and for receiving and processing some data of SAS-protocol.
## How To
```bash
$ git clone https://github.com/zacharytomlinson/saspy.git
$ cd saspy
$ pip install -r requirements.txt
$ nano config.yml # Adjust according your needs
$ python example.py
```

SAS (Slot Accounting System) protocol is the de facto casino communications standards designed to automate slot machine meter reporting and event logging, player tracking, bonusing, ticketing and cashless gaming.
# Notes
## Raspberry Hardware Limitation
As per SAS documentation, for the connection, you need:
> 19.2 KBaud in a "wakeup" mode. The 11-bit data packet consists of one start bit, eight data bits, a
> ninth ‘wakeup’ bit, and one stop bit.

The EGM and SMIB communicate each other in SAS protocol standards, whereas communication between the SMIB and host is not standardized, which interoperability and standards issue is resolved by new standards, G2S (Game to System) protocol. SMIB also provides touch screen and card readers for AFT and player tracking service.
### Connecting with RPI 3 B+:
1) Update your machine:
```
user@host> sudo apt-get update
user@host> sudo apt-get dist-upgrade
user@host> sudo apt-get clean
```
2) Enable UART in config and disable bluetooth
```
sudo echo "enable_uart=1" >> /boot/config.txt
sudo echo "dtoverlay=pi3-disable-bt" >> /boot/config.txt
```
3) Reboot for changes to take effect
```
sudo echo reboot
```
4) Configure serial connection to "serial0" port in config.yml
```
connection:
serial_port: /dev/serial0
```

The System architecture of SAS Protocol: SAS protocol is used for communication between EGM and SMIB. SAS protocol consists of 3 layers of physical layer, link layer, and application layer. The physical layer leverages RS-232 at 9.2kbps of 1 start bit, 8 data bits, and 1wakeup bit and 1 stop bit. The wakeup bit is used for signaling the frame start byte and needs special care in implementation (described later). Master-slave polling mechanism is used for the medium access control similar to USB and traditional remote terminal system. Each EGM is assigned a link address of 1 to 127. ‘0’ is used for broadcasting. The polling rate ranges from 200ms to 5s but can be reduced to 40ms when EGM support RTE (real time event) mode. SMIB uses two different types of polls, GP (general poll) and LP (long poll). GP is one byte EGM address with wakeup bit set, and polls events generated in the receiving EGM system. The receiving EGM should respond with 1 byte event code, which is called ‘exception’ in the specification. The exceptions include non-priority exceptions such as no event, game start, game end, system tilt, and priority exceptions such as handpay condition, ticket out, ticket in, and fund-transfer request. LP is used for SMIB to send command to EGMs and classified into R(read)-type, S(set)-type, M(multi-game)-type, and G (global)-type. LP starts with 1 byte command value with wakeup bit set, and the lengths of LP are fixed or variable depending on the command. All LP except R-type contains CRC-16 (cyclic redundancy check) for bit error detection. The response frame uses the similar format but with wakeup bit off. SMIB use implied ACK mechanism for confirming the receipt.
5) **NOTE** To avoid frying your Pi, you are still going to need a rs-232 to TTL logic level converter. I used the [MAX3323](https://www.mouser.com/ProductDetail/Analog-Devices-Maxim-Integrated/MAX3323EEPE%2b?qs=CDqwynd4ZNoRwc1iI5RFww%3D%3D)

SAS Protocol Application Functions: ROM signature request, Metric, Progressive broadcast, Tournament operation, RTE (real time event), Bonus Controller, Jackpot hand-pay, TITO(Ticket in/out), Multi-denomination, AFT, Component Authentication
### Alternative to MAX3323 and Pi UART
Connecting with USB to serial adapter, use a usb rs232 cable.....I used this [one](https://www.amazon.com/USB-Serial-Adapter-Prolific-PL-2303/dp/B00GRP8EZU/ref=sr_1_1_sspa?dib=eyJ2IjoiMSJ9.eT7IwLbFTyi5P6wiZqvnXrIsQpdtfPz_M46xtQa_S1I6h-lpFonAvq5YC5xJqm4vO8e3APmv6ZveRIHnEk3JvZ7RPORl8CFQWSUM226Dz0JssJAFQzWxU_Rk-YZaVXY5yPT9ZX-bqG0CDKUEzPruTJWEFg-ITUZtUOwr8KLTrvxvVg-ounmiZNAaizmQvxjrTdVozOF4iRbI5UF54oqfyn1obbD9whyaS_eGnl-TRcU.CRPZSqj6-D9E9pUJExtcBxGZd89oO6OAewGmvDxATTU&dib_tag=se&keywords=prolific%2Busb%2Bto%2Bserial&qid=1705598420&sr=8-1-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&th=1).

## Good to know
### Event Reporting
Basically you have 2 ways: ***Standard event poll*** and ***real time event poll***.

The **standard event poll** works with a FIFO memory and in real world use cases is kinda useless (unless you need to store the history of this machine status). You can call this event simply using the `event_poll` method in the code.

When you start the **real time event reporting** the machine, no matter what you ask, will always reply with the current event in the machine...leading to badcrc error and whatnot...plus the real time event responses are not mapped in the code (don't worry...im working on it). The function, in the code, to enable this is `en_dis_rt_event_reporting`.

Of course i needed the real time event reporting (to bind some actions) and at same time use some of the `aft_*` functions in the code.

To solve this issues i had to use the operator page on the machine to enable a second channel and buy a second prolific usb rs232 cable....

In this way on a channel i enabled the real time event reporting and on the second channel i could use the script normally (and the AFT functions) without problems.....

Of course...this is a way created out of "no time"....if somebody has a better idea im all ear !

## Dictionaries Notes
### GPOLL
**"4f": "Bill accepted"**
- Non-RTE mode: use this for all bills without explicit denomination.
- RTE mode: use for all bill denominations.

**"50": "$200.00 bill accepted"**
- Non-RTE only

# Authors
This project was initiated by [thomas-pythonas](https://github.com/thomas-pythonas) in 2018 and has no update since then.

Current author and mantainer are:

- [zacharytomlinson](https://github.com/zacharytomlinson)
- [well-it-wasnt-me](https://github.com/well-it-wasnt-me)
20 changes: 20 additions & 0 deletions config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
connection:
serial_port: /dev/ttyUSB0
timeout: 2
baudrate: 19200

events:
poll_timeout: 0.2
poll_address: 0x80

debug:
level: DEBUG # CRITICAL | ERROR | WARNING | INFO | DEBUG | NOTSET

security:
key: 44

machine:
pos_id: B374A402
reg_key: 0000000000000000000000000000000000000000
asset_number: 01000000
denomination: 0.01
17 changes: 17 additions & 0 deletions config_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import yaml


class ConfigHandler:
def __init__(self, file_path="config.yml"):
self.config_file_path = file_path
self.config = None

def read_config_file(self):
with open(self.config_file_path, "r") as yaml_file:
self.config = yaml.safe_load(yaml_file)

def get_config_value(self, section, key):
if self.config:
return self.config.get(section, {}).get(key)
else:
raise ValueError("Configuration not loaded. Call read_config_file first.")
13 changes: 13 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# docs/conf.py

# Add the following content
import os
import sys
sys.path.insert(0, os.path.abspath('..'))

project = 'SASPy'
author = 'Zachary Tomlinson, Antonio D\'Angelo'

extensions = [
'sphinx.ext.autodoc',
]
20 changes: 20 additions & 0 deletions docs/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
connection:
serial_port: /dev/ttyUSB0
timeout: 2
baudrate: 19200

events:
poll_timeout: 0.2
poll_address: 0x80

debug:
level: DEBUG # CRITICAL | ERROR | WARNING | INFO | DEBUG | NOTSET

security:
key: 44

machine:
pos_id: B374A402
reg_key: 0000000000000000000000000000000000000000
asset_number: 01000000
denomination: 0.01
7 changes: 7 additions & 0 deletions docs/config_handler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
config\_handler module
======================

.. automodule:: config_handler
:members:
:undoc-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/error_handler.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error\_handler module
=====================

.. automodule:: error_handler
:members:
:undoc-members:
:show-inheritance:
7 changes: 7 additions & 0 deletions docs/example.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
example module
==============

.. automodule:: example
:members:
:undoc-members:
:show-inheritance:
20 changes: 20 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.. sas documentation master file, created by
sphinx-quickstart on Tue Jan 25 12:34:56 2024.

Welcome to the SASpy documentation!
====================================

.. toctree::
:maxdepth: 2

config_handler
error_handler
sas
models

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
109 changes: 109 additions & 0 deletions docs/models.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
models package
==============

Submodules
----------

models.AftLockStatus module
---------------------------

.. automodule:: models.AftLockStatus
:members:
:undoc-members:
:show-inheritance:

models.AftReceiptStatus module
------------------------------

.. automodule:: models.AftReceiptStatus
:members:
:undoc-members:
:show-inheritance:

models.AftRegistrationStatus module
-----------------------------------

.. automodule:: models.AftRegistrationStatus
:members:
:undoc-members:
:show-inheritance:

models.AftStatements module
---------------------------

.. automodule:: models.AftStatements
:members:
:undoc-members:
:show-inheritance:

models.AftTransferStatus module
-------------------------------

.. automodule:: models.AftTransferStatus
:members:
:undoc-members:
:show-inheritance:

models.AftTransferType module
-----------------------------

.. automodule:: models.AftTransferType
:members:
:undoc-members:
:show-inheritance:

models.Denomination module
--------------------------

.. automodule:: models.Denomination
:members:
:undoc-members:
:show-inheritance:

models.EftStatement module
--------------------------

.. automodule:: models.EftStatement
:members:
:undoc-members:
:show-inheritance:

models.GPoll module
-------------------

.. automodule:: models.GPoll
:members:
:undoc-members:
:show-inheritance:

models.GameFeatures module
--------------------------

.. automodule:: models.GameFeatures
:members:
:undoc-members:
:show-inheritance:

models.Meters module
--------------------

.. automodule:: models.Meters
:members:
:undoc-members:
:show-inheritance:

models.TitoStatement module
---------------------------

.. automodule:: models.TitoStatement
:members:
:undoc-members:
:show-inheritance:

Module contents
---------------

.. automodule:: models
:members:
:undoc-members:
:show-inheritance:
12 changes: 12 additions & 0 deletions docs/modules.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
saspy
=====

.. toctree::
:maxdepth: 4

config_handler
error_handler
example
models
sas
tests
7 changes: 7 additions & 0 deletions docs/sas.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sas module
==========

.. automodule:: sas
:members:
:undoc-members:
:show-inheritance:
Loading