Automate with the Onefinity Controller API

Hi Onefinitians!

My name’s Gary, and I’m a self-taught tech enthusiast working on a project for my Old Man. The goal is a common one here on the forums: turning on dust collection and router power based on the state of the machine. I’m throwing in a multi-camera timelapse setup as well, 'cause it’s cool.

I’ve seen several schemes take advantage of the Onefinity controller’s hardware comms pins for input. @SurfinGump has a great writeup here.

This is clean. If we had a breakout board, I probably wouldn’t be writing this. We do not, and I’m ankle-deep in Raspberry Pis, so we’re going with a software-based approach to monitoring the machine state.

This topic came up when I wishfully searched for “Onefinity machine state” on this very Discourse. @wanoo links to the Onefinity github - specifically this list of API endpoints. This is our golden ticket, but I’m getting ahead of myself.

I’m posting here to make this machine more accessible to anyone who wants to automate around it, regardless of programming experience. I’m a novice myself, so if I seem inept to any real live programmers, it’s because I am.

With that in mind, here are a few definitions as I understand them. Please let me know what I get wrong!


What is an API?

API stands for Application Programming Interface. What it is, is a tool programmers can use to allow other programs to send and receive messages from their program. It’s a little like adding a post office to your code.

The messages are sent using HTTP requests.

What’s an HTTP request?

HTTP stands for Hypertext Transfer Protocol. What it is, is a set of rules computers use to send text back and forth over a network to any other computer with an IP address.

What’s an IP address?

An IP address is a number that identifies a computer on a network. It’s analagous to a phone number. You can find the IP address of your machine in the Network settings.

What’s Node-RED?

Node-RED is a programming environment that almost keeps you from having to write any code. You drag and drop commands (represented as colored blocks) from a toolbox onto a “canvas,” and then draw “strings” between them to create a flowchart.


Why do I care?

The user interface that comes with the Onefinity controller is just a web page that listens for information from the API to show status information, and sends commands via the API to initiate actions.

Using a browser on a computer connected to the same network as our Onefinity controller, we can do things like:

Copying and pasting individual API endpoint URIs into a web browser isn’t terribly convenient, but it’s a ham-fisted way to see which endpoints do what in lieu of documentation.

However - we want to do more than manually send commands using our browser. We want to react when something changes. And for that, we’ll need to start our program.

Install Node-RED on something. I’m using a Raspberry Pi 4 'cause I have one handy, but you can run Node-RED on just about anything.

Once Node-RED is installed and you’ve got it up and running in a browser window, string together: websocket in >> debug

image

Double-click on the websocket node. Set “Type” to “Listen on”, and click the “+” button next to “Path.” Enter “/ws://xxx.xxx.xxx.xxx/websocket” without quotes, substituting your Onefinity controller’s IP address for the Xxes. Click “Add,” then click “Done.” Click “Deploy” in the upper right-hand corner. Congratulations - you’re a programmer!

Now we should start seeing raw messages from your controller as they come in to the websocket node from the Onefinity API over your network. The first packet contains all variable names and their values, and the following packets contain only name/value pairs that have changed since the last update cycle.

Here’s some data that came from our rig: websocket-trimmed.json - Google Drive

My comment on the post linked above has a more detailed example function that filters machine state data from the unfiltered deluge.


I’m bordering on a novel here. Before I lose all coherence, I’ve got to hop off.

Having so much fun with this machine. Hope you are, too.

5 Likes

Looking at your project I think your can do all of your list using a patch work of correct linux programs like the motion app for the camera support. debugging messages can be displayed on your http server using php script. a google search may turn up a script to run a switch for the dust collection.

1 Like

Oh heck yeah! If you follow that last link, you’ll see the function for parsing machine state into a flow-level context variable.

I wasn’t going to get into the timelapse capture setup, as that’s more of a Linux project for furry-toothed nerds such as myself. But I long to babble about Linux, so if I’m in good company…

Instead of motion, I use mjpg-streamer. Since the cameras are UVC based, they already send mjpeg data over serial. mjpg-streamer gives you an API endpoint to grab frames from the existing stream, so there’s no conversion overhead from running a codec per camera. It’s speedy.

With this, I can capture two 1280×720 streams at around 35fps before I start losing frames, which is more than I need for timelapse capture (and way better than I expected to pull from a pi4 by sending two GET requests for every frame!).

When timelapse capture is triggered, the flow requests frames, stitches them together side-by-side using imagemagick, and caches them in a ramdisk that gets flushed every 500MB to reduce disk writes. When the capture ends, a custom version of ffmpeg compiled to take advantage of the pi4’s hardware encoder renders the frames into a timelapse. If the render exits without an error code (and auto cleanup is enabled), the frames are deleted, and you’ve got a timelapse waiting for you in a samba share.

I’ve been waiting to update this topic until I get the relay board built. That’ll be an intro to Arduino, firmata, the significance of the l293d, etc.

If anyone’s interested in more detail on the timelapse, I can absolutely get into that first!

1 Like

I am also a Linux gear head. In the long run I think we would be happier with a LinuxCNC based system. It can do everything the Buildbotics and Masso controllers can do.

I would also include Samba and Pure-FTPd. Would also be nice to build a web page that would output dmesg, df -h, and top. Great to help users debug problems.

I would live to see dmesg and top for some of the strange movement reports.

Not a big fan of Camera support on CNC controller. Cameras use disk space quickly. I run ZoneMinder on proxmox server.

2 Likes

Though the impressive AVR bit diddling by the folks at Buildbotics does result in a step rate above its price peers, I would like to play with LinuxCNC one day. I just don’t want to pay for a new stepper controller.

This all runs on a separate rpi4. I want to leave the 1F’s rpi3 alone entirely, so it could be reflashed to the factory image without losing ground. This should work with any unmodified 1F or BB controller with network access.

1 Like

I want to dump the rpi3 for a rpi5 or x86 box. Just want it to be plug and play. For 1F hardware no splicing. Looking for help because of the amount of time this will take. A working proof of of concept may be enough for a kick starter. I want to do more testing on the 1F box before I start.

The rpi3 embedded in the 1F controller, you mean? Why would you want to upgrade that? It’s not bottlenecking anything; it’s idle most of the time.

The actual firmware firmware lives on the AVR, and is the cleverest bit of the BB/1F controller. The aforementioned bit-diddling, abusing timing registers to achieve repeatable step rates of 250k per channel, in my opinion, is what puts the controller in competition with the next price tier.

The pi3 runs the webhost portion and communicates with the AVR over i2c using an outdated kernel module you won’t find in current repos (and is incompatible with current Linux kernel versions). Upgrading to a pi5 would mean at minimum reworking the python side of the firmware to use a different i2c library, and physically modifying the hardware (pi3 and pi5 have totally different layouts).

Then, every time a firmware update was released, we’d have to re-rework the code with the new communications library.

For all this effort, we would get identical performance from the machine. The pi5 wouldn’t improve step rates, but it might render the user interface faster locally. A little?

That said, we can already lighten the load on the rpi3 by accessing the UI through a web browser on a different device. The pi3 should have even less to do if we unplug the monitor. That could theoretically improve API response times, but they’re already so fast as to be negligible.

I’m all for expending effort if there’s a payoff, but upgrading the rpi3 to an rpi5 seems to me like replacing an F-150 with an F-350 to continue hauling the same groceries. Is there something your controller isn’t doing that you envision might be solved with more computing horsepower?

I was looking at the M.2 SSD support so users can stop messing with flash drives. Going to look at the needs of LinuxCNC before making final choice.

You can already avoid flash drives entirely, my friend.

  1. Open up a web browser on the computer you do your CAD on. Type your machine’s IP address into the address bar.

  2. Click “Upload File.” Navigate to the gcode file you want to run.

  3. Run the file.

Nary a flash drive touched.

2 Likes

Going to invest time to understand the Onefinity Controller before reinventing the wheel.

When you say “turning on dust collection and router power based on the state of the machine.” Are you talking about adding any missing M code support? Or would it be a relay triggered on some action. Buttons added in the GUI?

1 Like

We’re doing it without modifying the machine or controller one bit. No custom g-codes or breakout boards needed!

We’re tapping into information from the firmware the same way the GUI on the touchscreen does. I’m not a techie by trade, so I’ll walk you through the train of thought that got me here.

When I first saw the 1F controller boot up, I noticed the GUI is just a webpage loaded in Chromium. You can’t see the address bar, but if you could, it would say “127.0.0.1” or “localhost” - both of which mean, “the IP address assigned to me” in IPv4.

The next thing I did was try to open the GUI from a computer on the same network. When I typed in the machine’s IP address like any other web page in a new tab, BAM, there it was! Homed it from the laptop and giggled like a doofus.

That let me know that somehow, machine state data was being sent to the browser. Traipsing through the Buildbotics github led me to the list of API endpoints in my first post.

When you load the GUI in a browser (whether on the touchscreen, locally, or on another device on your network), the browser starts receiving information to fill up the blank fields from:

your.machine's.ip.address/websocket

That’s where all the changing information (from “READY” to the x/y positions to the currently running file, etc.) on the GUI comes from.

In our Node-RED flow, we open that same socket, so we have access to all that information in our program.

I TeamViewered into my Old Man’s rig and hastily made a screen recording - sorry for the quality - but this video shows what the data from the websocket coming in looks like. Makes for a boring video, but it gets the point across.

The really important bit is that the data is in Node-RED - because Node-RED can talk to just about anything else. From here, it’s kind of “choose your own adventure” depending on how comfortable you are with a soldering iron.

I’ve seen people purchase a WiFi connected smart plug for their router and dust collection, and use Node-RED to trigger those. That’s a slick way to go. One of my goals is eliminating wireless communications wherever possible, though. When able, run cable.

I’m going to roll my own “smart outlets.” There’s a library called Firmata that lets Node-RED directly control the pins on an Arduino plugged into a USB port on the computer running Node-RED.

I’m going to use an Arduino Nano to control an L293d H-bridge driving the relay coils.

1 Like

We have a nice onefinity breakout board now :slight_smile:

Closed loop steppers and homing switches could work with auxiliary I/O box. New I/O box is listed on ATC order form.

We got ATC, rotary, and spindle all in one shot. Going to buy automated vacuum switch and call it good.

3 Likes

Heck yeah! This week has been a whirlwind of cool announcements!

I’m on tenterhooks for the impending firmware updates. The update I’m hoping for hasn’t been announced, but it’ll probably come from BB upstream if it comes at all.

I’m curious to see how the Y-slaving works in firmware, and I’ll be combing the headers in the AVR code for implementation of live speed and feed overrides. Right now those API endpoints are dead ends, unfortunately.

1 Like

Neurotransmitter method
Of turning on the dust collector.

Purchase a remote control fob for the dust collector and double tape it close to working controls of the cnc.

The brain will send out a faint neural electrical charge through thousands (maybe millions) of synapses causing the index finger to go erect. Press the green button for on, press the red button for stop.

(Not making fun, just wish I had the capacity to understand this post…jealous)

1 Like

I do not think this is worth coding. Double tape makes more since this time.

Do you have access to M code pre and post actions? I am looking at digging into the M6 tool change.

The new Rapid change ATC needs more motion control than a normal ATC. Something like the PwnCNC ATC could work with less code. All the lego blocks are in place we only have to rearrange them.

Heh, I appreciate your build log!

All jokes aside, tool for the job and all that - this does the trick with a low likelihood of crashing.

I’d say you’ve got a linearly oriented waterfowl arrangement.

1 Like

Do you have a file with those codes I could dry-run? Not sure when I’ll get to it with Thanksgiving ‘n’ stuff, but I can pipe the output of the websocket to a file, run the file, and then comb through for something to latch onto.

Do you have Node-RED installed on something yet? I can walk you through it; just let me know what we’d be installing it on and I’ll get you started.

It’s fun to see the output live, and really shortens the experimentation cycle =]

Do not have Node-RED reading the code base trying to understand how the system works. Do not see the rapid ATC code in 1.4.2. Select people have access 1.5. Think the code hack will be in src/resources/onefinity_defaults.json

Hi all…perhaps time for a pseudo-clueless OF newb to chime in (first post, woot!) I have gotten to the point of my build where the “basics” are working and I have a few projects under my belt. Perhaps more importantly for this discussion, I successfully got my wifi connection to be strong and stable.

The reason this hobbyist is watching this thread is because I am planning to use an ESP32 to monitor/control peripheral components and also provide a visual indication of their status using color LED strips around the shop. To me, the appeal of using the webocket API is that I could easily isolate all other electronics from the BB controller, stay away from pesky work-arounds like coolant gcode, and also keep the [inevitable] wires for this endeavor out of my primary working area.

First up is automatically opening/closing my existing [and awesome] 3d-printed, ESP32/Arduino-controlled blast gates and turning on/off the dust collector (with delays even).

I have played a little with the API - trying [all of the] ESP32 websocket demos I could find. Some connected but none actually returned any useful data - but then serial input (and wifi) in the C++/Arduino world baffles me*. I am not using node red and would prefer to stick with just the Arduino IDE libraries initially.

So now my question(s). Anyone have any insight into connecting an ESP32 on the Arduino IDE without node red? Will the JSON libraries work to parse the BB stream? Any specific BB codes that might work for this initial application and that folks have already had success with?

Of course, other insight and ramblings would be appreciated. Cheers!

  • = self-taught programmer hobbyist