Difficulty connecting to an external device (cooler) via serial port

What is the problem?

I have a 'cooler' attached to the extruder, and i'm trying to connect to the port i pluged the cooler in via USB cable in order to send/receive data.

I developed an Octoprint plugin that is supposed to control the fan speed of the cooler and some other features, this is my plugin struture:

  • assistant_plugin
    -- /init.py
    -- /templates/pluginGUI.jinja2
    -- /static/js/gui_functions.js

I'm trying to implement the connection logic in the 'gui_functions.js' JavaScript file, i have done some research and what i found is, to connect to the port there are three main steps:
1- in my Raspberry Pi run "npm install serialport"
2- at the top of my javascript add "const { SerialPort } = require('serialport')"
3- then create a port "const port = new SerialPort({ path: '/dev/ttyUSB0', baudRate: 115200 });"

but all my tries are failing so far, it keeps showing this error in the console tab: "caught ReferenceError: require is not defined". I'm kinda new to this whole thing so my developing knowledge is little. any help is appreciated! :slight_smile:

this is my JS code snippet for reference:
__
const { SerialPort } = require('serialport');
function PortConnectionViewModel(parameters) {
var self = this;

    self.connect = function() {
  const serialPort = new SerialPort({ path: '/dev/ttyUSB0', baudRate: 115200 });
  serialPort.open(function(error) {
            if (error) {
                console.log(error);
                return;
            }
            console.log("Connected to serial port");
        });

        serialPort.on('data', function(data) {
            console.log('Received data:', data);
        });
}

    self.disconnect = function() {
        if (serialPort) {
            serialPort.close(function(error) {
                if (error) {
                    console.error('Error closing port:', error.message);
                } else {
                    console.log('Port is closed');
                }
            });
        } else {
            console.error('Serial port not open or not available');
        }
    }
}

__

What did you already try to solve it?

WRITE HERE

Have you tried running in safe mode?

yes

Did running in safe mode solve the problem?

no since safe mode disables plugins.

Systeminfo Bundle

You can download this in OctoPrint's System Information dialog ... no bundle, no support!)

WRITE HERE

Additional information about your setup

What kind of hardware precisely, OctoPrint version, OctoPi version, printer, firmware, browser, operating system, ... as much data as possible

WRITE HERE

Making the connection in JavaScript implies you only need to talk to the device when you are looking at it in a browser. Is that the case?

If not, you could look at my Plugin. SIOControl. I implemented a connection as a class that might point you in the right direction. A lot of what I started with was I think gleaned from the enclosure plugin so that might also be a good reference. But keep in mind these both do the connection, communication and storage on the server side not the client(browser)

1 Like

Thank you for your respond.

I decided to implement the port connection logic in my Python file, and it worked fine. Now all I need is to be able to pass strings correctly from my JS file to my python file in order to send it to the port (cooler). I am struggling to do so and I get this error in the console tab every time “POST 400 (BAD REQUEST)”, which might mean that there is something wrong with the communication between the JS and Python files.

My goal is actually straightforward, I want when I press the ‘sendFanData’ button to pass the string ‘controlString’ to my backend (init.py) and then forward it to the cooler from there. i tried “OctoPrint.simpleApiCommand” and “$.ajax” and some other ways but it seems like there’s still something missing.

Here’s the ‘sendFanData’ section and the string i want to pass from my JS (gui_functions.js):

function FanSpeedViewModel(parameters) {

	// code 

	self.sendFanData = function() {

		 // the controlString below is what I am trying to pass, it looks like this for e.g “x_2_255_255_7_1_x”

         var controlString = "x_2_" + actualValueHot + "_" + actualValueCold + "_" + selectedIndex + "_" + isActive + "_x";
		
		 // should I write the code that sends it to the python file here?
	}
}

let me know if i need to provide the full file code. Appreciate the help!

Using the OctoPrint.simpleApiCommand method requires some supporting boiler plate. But it seems the best way for you to go.

I use this method in in my SIOControl to issue commands where needed. First review the documentation.
https://docs.octoprint.org/en/master/jsclientlib/base.html?highlight=simpleapicommand#OctoPrintClient.simpleApiCommand

Then take a look at the __init__.py
There are 2 methods that are needed. One defines the calls that are possible(get_api_commands) the other handles the requests (on_api_command).

If you look at the definition for "toggleSio" command, you can then look at the siocontrol.js file and find the call to the on_api_command for that command "simpleApiCommand".

            OctoPrint.simpleApiCommand("siocontrol", "toggelSio", { pin: sioPin }).then(function (state) {
               
            });