Skip to main content

A reimplementation of the FOCAS protocol using UNIX sockets.

Project description

pyfocas

This project is a barebones reimplementation of the FANUC FOCAS protocol for communicating with a CNC machine.

It only uses UNIX sockets and sends the proper messages / packets instead of relying on vendor libraries.

Sources / Based On

This project relies on the reverse engineering of the FANUC FOCAS protocol by diohpix. The relevant library is pyfanuc.

This reimplementation of the protocol is currently the only way of reliably using FOCAS on a 64bit ARM (aarch64) system as no library for that architecture exists.

Protocol

The protocol is a big endian request-response protocol via UNIX sockets. A full message (either request or response) will be called packet. A packet has headers and at least one subpacket, which in turn consist of multiple blocks detailing the purpose of the packet.

Header

The header looks similar for request and response. A typical header contains the following blocks, with a block being a part of the header or subpacket:

NAME Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
PURPOSE Start of each packet Server or Client Open, Close, Other Length of packet incl. subpackets Number of subpackets
LENGTH 4 bytes 2 bytes 2 bytes 2 bytes 2 bytes

Sync Prefix marks the start of a packet and is always A0 A0 A0 A0.

Packet Origin marks if the packet is a request to the FOCAS server (00 01) or a response from it (different from 00 01).

Packet Type differentiates the packets between:

  • Trying to open a connection to the FOCAS server:
    • Request: 01 01
    • Response: 01 02
  • Trying to close the connection:
    • Request: 02 01
    • Response: 02 02
  • Trying to execute a generic command:
    • Request: 21 01
    • Response: 21 02

There are other packet types as can be seen in diohpix/pyfanuc which are not covered in this project (yet).

Packet Length contains the total length of bytes coming after it, including the size of the Subpacket Count (2 bytes) and all the subpackets in bytes.

Note that this results in the Packet Length always being larger than the sum of all subpacket's Subpacket Length by exactly 2 bytes (size of the Subpacket Count).

Subpacket Count holds the number of subpackets in this packet.

Subpacket

Subpackets are of varying length and data types. There are some reused sizes and packing / types.

Default Payload: 5x 4-Byte INT32

The subpackets are always of length 1c / 28 bytes. They each contain three pieces of information about the subpacket totalling 8 bytes followed by a payload of 20 bytes which can be split into multiple regions.

NAME Subpacket Length Control Device Function Payload
PURPOSE Length of the subpacket CNC or PMC Command to execute or which was executed. Data transmittable via subpacket
LENGTH 2 bytes 2 bytes 4 bytes 20 bytes

Implemented Functions

Initialize Connection

This needs to be done to create the connection with the FOCAS server.

Request

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 01 01 01 00 02 (unclear reason) 00 02 (unclear reason)

Response

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 04 01 02 01 68 (unclear reason) 00 08 (unclear reason)

The response contains 360 Bytes of (as of yet) unclear subpacket content.

Status Info

Request

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 01 21 01 00 1E 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 1C 00 01 00 01 00 19 20 times 00

Response

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 04 21 02 00 20 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 1E 00 01 00 01 00 19 See _FOCAS_STATINFO_STRUCT

System Info

Request

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 01 21 01 00 1E 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 1C 00 01 00 01 00 18 20 times 00

Response

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 04 21 02 00 24 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 22 00 01 00 01 00 18 See _FOCAS_SYSINFO_STRUCT

Read Macro

Request

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 01 21 01 00 1E 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 1C 00 01 00 01 00 15 00 00 01 F6 00 00 01 F6 + 12x 00

This reads macro variable #502 (01 F6).

Response

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 04 21 02 00 1A 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 18 00 01 00 01 00 15 00 00 00 00 (Fill) 00 00 00 10 (#Bytes coming after this) 29 7C 1E 00 00 0A 00 06 (First 8-Byte Scaled Int) 05 F5 E1 00 00 0A 00 08 (Second 8-Byte Scaled Int)

Write Macro (Double)

Writes a macro variable with a double value (not scaled integer)

Request

Sync Prefix Packet Origin Packet Type Packet Length Subpacket Count
A0 A0 A0 A0 00 01 21 01 00 38 00 01

With the single subpacket being:

Subpacket Length Control Device Function Payload
00 24 00 01 00 01 00 A8 00 00 01 F6 (Var. 502) 00 (12x Filling Bytes) 00 00 00 08 (#Bytes coming after this) 40 59 00 00 00 00 00 00 (Value as double)

This writes 100.0 to #502.

Development

Release

In the steps below we assume that you

  • installed uv, and
  • execute commands in the root of the repository.

Please replace <VERSION> with the version number of the package that you want to release (e.g. 0.2.0).

PyPI

To release a new version on PyPI please use the commands below:

uv version <VERSION>
export pyfocas_version="$(uv version --short)"
git commit -a -m "Release: Release version $pyfocas_version"
git tag "$pyfocas_version"
git push && git push --tags

GitHub

Open the release notes for the latest version and create a new release:

  1. Paste the release notes into the main text of the release web page
  2. Insert the version number into the tag field
  3. For the release title use “Version ”, where <VERSION> specifies the version number (e.g. “Version 0.2”)
  4. Click on “Publish Release”

Note: Alternatively you can also use the gh command:

gh release create

to create the release.

Project details


Release history Release notifications | RSS feed

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyfocas-0.1.tar.gz (10.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyfocas-0.1-py3-none-any.whl (9.6 kB view details)

Uploaded Python 3

File details

Details for the file pyfocas-0.1.tar.gz.

File metadata

  • Download URL: pyfocas-0.1.tar.gz
  • Upload date:
  • Size: 10.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfocas-0.1.tar.gz
Algorithm Hash digest
SHA256 ec969298463e03c329d902a530a21a3d49a5ad46a190a5ab1c2cdaf6ac06a3ea
MD5 f86c88accd5caa6e48c03f2a907a551c
BLAKE2b-256 3c7cb70394d73b0838144c463413bb02f24e26ed0b5b20457b1d37466f566130

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfocas-0.1.tar.gz:

Publisher: publish.yaml on MyTooliT/pyfocas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyfocas-0.1-py3-none-any.whl.

File metadata

  • Download URL: pyfocas-0.1-py3-none-any.whl
  • Upload date:
  • Size: 9.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pyfocas-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1405982476c2da7e9cfb0bfb3c9299440af221932c95d94dc2e6591af9398e22
MD5 a6ffa6db85546da1fc281ab5854f59f7
BLAKE2b-256 ce7d9aa2b2ef009a41dd7f67f214c84a7df826541d007201fa0bb93e07f11fe0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyfocas-0.1-py3-none-any.whl:

Publisher: publish.yaml on MyTooliT/pyfocas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page