Black Lives Matter. Please consider donating to Black Girls Code today.
Dash HoloViews is now available! Check out the docs.

Dash interacting with hardware

One of the advantages I see of Dash is its session-less/state-less backend, which allows Dash to scale well and keeps things simple. But I see examples of users (me included) using Dash to serve as a GUI front-end for a piece of hardware (e.g. serial port, lab equipment, etc). These programs necessarily need to use some kind of global instance for Dash to interact with. These state-full programs will break when more than one user interacts with the program simultaneously.

For my purposes, I’ll probably limit things to just 1 connected user somehow, but it’s limiting, and there are other possible solutions. I’m wondering if the Dash developers and/or community are addressing this. I haven’t seen discussion about it directly, but maybe I haven’t stumbled upon the it yet.

thanks!

Hey, fellow hardware hacker!

I used Dash a few months ago to build a web interface to several modems in our lab, and overall I found it to be a marvelous framework for interacting with a piece of hardware.

These programs necessarily need to use some kind of global instance for Dash to interact with.

This was true in my case too. The inputs received from the GUI need to be translated to the appropriate opcode and sent to the equipment via serial port. Only one process can bind to that port at a time, though, and I was a little unsure after reading the docs whether an application’s callback functions (which may run on a different thread than the main application) would play nicely with a shared, mutual resource.

It worked pretty well! I did protect mutable objects with a multithreading.Rlock semaphore to ensure thread safety, but I’m not sure it’s necessary.

For my purposes, I’ll probably limit things to just 1 connected user somehow, but it’s limiting, and there are other possible solutions. I’m wondering if the Dash developers and/or community are addressing this.

I’m not sure what your ideal control flow looks like, but I’ll share with you some implementation details that might be helpful. I opted to disregard several warnings in the documentation about writing to global variables, because it wasn’t particularly important to me that multiple people be able to interact with the hardware at the same time. Consequently the application state behaves almost identically to hardware state… meaning, basically, that if you configure it one way, then close the tab and navigate back to the page, it’ll be exactly the same as before.

I suspect the app would probably work with multiple users, just because I know that the way I structured my callback (of which there’s only one) it’s listening for state changes to any mutable property of the GUI. So then any time there’s a state update, the entire state of the GUI is sent to the server along with it in the POST request, and the application’s backend state is always synchronized with the interface that changed most recently. So in theory, it would probably work, sort of, but the modem would just oscillate between two completely different configuration profiles depending on which user most recently modified an input field.

Nice! Thanks for sharing Kevin. Your experiences are familiar!

I think Dash is compelling in several ways, but what got me interested – I could write a front-end for my device that I could bring up on my desktop locally, my mobile device locally, or either device remotely. And I can do so exclusively with Python code. We’ve heard of the Internet of Things. It’s a bunch of hype, but Dash makes it pretty dang easy!

Here is a Dash program we wrote that runs on a Raspberry Pi with a Pi camera.

It works great. (We wrote a Dash WebRTC component that handles live video.) Since it’s written exclusively in Python, we can expect that lots of programmers can understand the code and write their own programs for computer vision, image processing, etc. These programs will have the same flexibility – local and remote interactability, etc. No need to attach a physical screen to the device. It’s compelling!

Things can go awry when more than 1 user interacts with the program though…

Imagine a simple dash app with a single slider. The slider is programmatically attached to an RC-servo. Move the slider and the RC-servo moves. You can write such a program in Dash and when 2 or more users interact with it, it works for the most part. The servo moves to the position of the most recently commanded position.

But what would be cool – when 1 user drags the slider the other users see the slider move. In addition to being cool, I think it’s “correct”.

I may be full of it, but here’s what I see: Dash is currently a data visualization toolkit. The data is read-only. The controls are write-only. If the data can be modified by or if the controls can be “state-full”, things get funky. Problems arise. Solutions are piecemeal.