Skip to content

Conversation

@scooterthedev
Copy link
Contributor

@scooterthedev scooterthedev commented Jun 12, 2024

This will be the pr for webUI that @christophergault198 and I are making. I will be changing/adding/removing lots of stuff within the next couple of days. We are hoping to have a pr ready by Sunday or Monday at the latest. This will hopefully have a x1plusd command built in for starting/stopping, and we will try to use aiohttp instead of flask @jwise.

@bani6809
Copy link
Contributor

we can't PR binary zip blobs, and PRs should not be placeholders. you should PR when you have something ready for actual review.

@RaySajuuk
Copy link

Mistake?

@jwise
Copy link
Member

jwise commented Jun 12, 2024

IMO it's OK for PRs to be placeholders for early review -- that's fine and useful for architectural commentary early, as well as filing issues to describe what you plan to implement -- but absolutely not binary zip blobs

@scooterthedev
Copy link
Contributor Author

IMO it's OK for PRs to be placeholders for early review -- that's fine and useful for architectural commentary early, as well as filing issues to describe what you plan to implement -- but absolutely not binary zip blobs

Yah, sorry about that. I just wanted to have something to start the pr. I have added the necessary files for it to run to this pr, and will hopefully add a x1plusd command to start/stop it, and a maybe a UI to enable/disable it.

Copy link
Member

@jwise jwise left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am excited by the idea of a web UI!

Broadly, this needs a lot more work to fit into the X1Plus world. I left a bunch of comments for where I'd like to see it go. Maybe a good first start would be to put up a PR that integrates an aiohttpd into x1plusd (controlled by x1plus.settings), which just served a novnc? That seems like the simplest possible thing that woudl be making positive architectural steps, and we can do one thing at a time there -- then we can iterate on adding WebHMI features from there.

Comment on lines +15 to +16
# Script to be executed:
DAEMON="python3 /usr/etc/system/webhmi/little_webhmi.py"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WebHMI needs to be part of x1plusd, not running in the background as its own python service

Comment on lines +5 to +11
function set_heatbed_temp() {
temp=$1
json="{ \
\"print\":{\"command\":\"gcode_line\", \"sequence_id\":\"2002\", \"param\":\"M140 S$temp\"} \
}"
mqtt_pub "$json"
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use x1plus.client commands to do this? Or pull in a MQTT client into x1plusd (I think @jphannifan was talking about an asyncio wrapper for paho)? I would like to avoid spawning shell scripts to the degree possible -- it seems like most of this stuff should really live in the x1plus.client library.

import os

# Print the current working directory for debugging
print("Current working directory:", os.getcwd())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NB: X1Plus packages live in the /opt/x1plus/lib/python/ directory. So this probably should be x1plus.services.x1plusd.webhmi or something.

Comment on lines +20 to +30
async def update_current_job():
global current_job_name
while True:
try:
with open('/userdata/print_ctx.json', 'r') as file:
data = json.load(file)
subtask_name = data['subtask_name']
current_job_name = subtask_name
except Exception as e:
print(f"Error reading or parsing JSON file: {e}")
await asyncio.sleep(10)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get these data either from DBus or MQTT instead of having to poll? Are these data broadcast on DBus as a signal?

Comment on lines +46 to +62
async def home_xyz_func(request):
global latest_message
subprocess.run(["/usr/bin/home_xyz.sh"], shell=False)
latest_message = 'Home XYZ'
raise web.HTTPFound('/')

async def preheat_100c(request):
global latest_message
subprocess.run(["/usr/bin/heatbed_set.sh", "-s", "100"], shell=False)
latest_message = 'Preheat Activated - 100c'
raise web.HTTPFound('/')

async def preheat_0c(request):
global latest_message
subprocess.run(["/usr/bin/heatbed_set.sh", "-s", "0"], shell=False)
latest_message = 'Preheat Deactivated'
raise web.HTTPFound('/')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I am thinking about is that I would rather have a generic interface to the printer -- with logic run in a SPA in the browser -- than having one HTTP endpoint for each of a million little things. I was thinking that the generic interface to the printer really wanted to be a WebSocket with generic interfaces like 'submit Gcode', or 'submit MQTT request', or 'execute DBus RPC', with all the smarts on the client side.

Comment on lines +64 to +71
async def start_bbl_screen_vnc(request):
global latest_message
try:
latest_message = 'VNC Started'
subprocess.run(["/usr/bin/start_bbl_screen_vnc.sh"], shell=True, timeout=3)
except subprocess.TimeoutExpired:
latest_message = 'VNC Started'
raise web.HTTPFound('/')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not correct for running vnc now

Comment on lines +111 to +112
if __name__ == '__main__':
web.run_app(app, host='0.0.0.0', port=5001) No newline at end of file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be configured by x1plus.settings

Comment on lines +108 to +109
# Start the background thread for updating the current job
threading.Thread(target=lambda: asyncio.run(update_current_job()), daemon=True).start()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this a Thread, not an asyncio task?

var img = document.getElementById('modelImage');
img.src = '/current_model_image?' + new Date().getTime();
}
setInterval(refreshModelImage, 180000); // Refresh every 180000 milliseconds (3 minutes)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah this is a primo example of why one might want to use a websocket to push updates :)


app.router.add_get('/', printer_hmi)
app.router.add_post('/home_xyz_func', home_xyz_func)
app.router.add_post('/preheat_100c', preheat_100c)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a very scary endpoint to have on the network with absolutely no authentication

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a very scary endpoint to have on the network with absolutely no authentication

Something that could be set to disabled by default and enabled by those on secure networks. I understand the concern, but for many (like myself) this would be a non-issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants