ACE Auto Refill toggle feature
This commit is contained in:
@@ -453,6 +453,7 @@ class KobraXBridge:
|
||||
self._ams_loaded_slot: int = -1 # global slot index of currently loaded slot
|
||||
self._pending_load_slot: int = -1 # global slot index requested via /api/ams/feed type=1
|
||||
self._ace_box_ids: list[int] = [] # detected ACE unit IDs (0..3)
|
||||
self._ace_auto_feed: dict[int, int] = {} # per-box auto_feed state (0/1)
|
||||
self._head_tools_model: int = -1
|
||||
self._filament_mode: str = "toolhead"
|
||||
self._last_uploaded_file: str = ""
|
||||
@@ -821,6 +822,10 @@ class KobraXBridge:
|
||||
global_slots, global_loaded = self._aggregate_slots(boxes, self._filament_mode)
|
||||
self._ams_loaded_slot = global_loaded
|
||||
self._update_ace_drying_state(data, boxes)
|
||||
for box in boxes:
|
||||
bid = int(box.get("id", -1))
|
||||
if 0 <= bid <= 3 and "auto_feed" in box:
|
||||
self._ace_auto_feed[bid] = int(box["auto_feed"])
|
||||
if self._pending_load_slot >= 0 and global_loaded == self._pending_load_slot:
|
||||
self._pending_load_slot = -1
|
||||
activity_map = self._slot_activity_map(boxes, global_loaded)
|
||||
@@ -3218,7 +3223,11 @@ function applyState(){
|
||||
if(!show)continue;
|
||||
var ud=unitMap[i]||dry;
|
||||
var refillToggle=document.getElementById('ace-auto-refill-toggle-'+i);
|
||||
if(refillToggle)refillToggle.checked=_aceAutoRefillGet(i);
|
||||
var autoFeedMap=s.ace_auto_feed||{};
|
||||
if(refillToggle&&!_aceAutoFeedPending[i]){
|
||||
var afVal=autoFeedMap.hasOwnProperty(String(i))?Number(autoFeedMap[String(i)]):(_aceAutoRefillGet(i)?1:0);
|
||||
refillToggle.checked=afVal===1;
|
||||
}
|
||||
var dryToggle=document.getElementById('ace-dry-enable-toggle-'+i);
|
||||
if(dryToggle)dryToggle.checked=Number(ud.status||0)>0;
|
||||
var hh=document.getElementById('d-ace-dry-humidity-'+i);
|
||||
@@ -3755,11 +3764,19 @@ function aceDryStart(aceId){
|
||||
.catch(function(e){clog('ACE-Fehler: '+e,'msg-err');});
|
||||
}
|
||||
|
||||
var _aceAutoFeedPending={};
|
||||
function aceAutoRefillToggle(aceId){
|
||||
aceId=(typeof aceId==='number'&&aceId>=0)?aceId:0;
|
||||
var on=!!((document.getElementById('ace-auto-refill-toggle-'+aceId)||{}).checked);
|
||||
_aceAutoRefillSet(aceId,on);
|
||||
clog('ACE '+(aceId+1)+' - '+(T.ace_dry_auto_refill||'Auto Refill')+': '+(on?'ON':'OFF')+' '+(T.ace_dry_ui_pending||'(UI only, backend next)'),'msg-info');
|
||||
_aceAutoFeedPending[aceId]=true;
|
||||
fetch('/api/ace/auto_feed',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({ace_id:aceId,on:on?1:0})})
|
||||
.then(function(r){return r.json();})
|
||||
.then(function(d){
|
||||
delete _aceAutoFeedPending[aceId];
|
||||
if(d.error){clog('Auto Refill error: '+d.error,'msg-err');var t=document.getElementById('ace-auto-refill-toggle-'+aceId);if(t)t.checked=!on;return;}
|
||||
clog('ACE '+(aceId+1)+' - '+(T.ace_dry_auto_refill||'Auto Refill')+': '+(on?'ON':'OFF'),'msg-ok');
|
||||
})
|
||||
.catch(function(e){delete _aceAutoFeedPending[aceId];clog('Auto Refill error: '+e,'msg-err');var t=document.getElementById('ace-auto-refill-toggle-'+aceId);if(t)t.checked=!on;});
|
||||
}
|
||||
|
||||
function openAceDryDialog(aceId){
|
||||
@@ -4764,6 +4781,36 @@ function loadPrinterTab(){
|
||||
await loop.run_in_executor(None, _send)
|
||||
return web.json_response({"result": "ok"})
|
||||
|
||||
async def handle_api_ace_auto_feed(self, request):
|
||||
try:
|
||||
body = await request.json()
|
||||
except Exception:
|
||||
body = {}
|
||||
|
||||
ace_id_raw = body.get("ace_id", None)
|
||||
on_raw = body.get("on", None)
|
||||
if ace_id_raw is None or on_raw is None:
|
||||
return web.json_response({"error": "ace_id and on are required"}, status=400)
|
||||
try:
|
||||
ace_id = int(ace_id_raw)
|
||||
on = int(bool(on_raw))
|
||||
except Exception:
|
||||
return web.json_response({"error": "invalid parameters"}, status=400)
|
||||
if not (0 <= ace_id <= 3):
|
||||
return web.json_response({"error": "ace_id must be 0-3"}, status=400)
|
||||
|
||||
payload = {"multi_color_box": [{"id": ace_id, "auto_feed": on}]}
|
||||
loop = asyncio.get_event_loop()
|
||||
# Fire-and-forget: setAutoFeed ACK arrives via multiColorBox/report callback.
|
||||
# Waiting for a response on that busy push topic causes false "code:0" rejections.
|
||||
await loop.run_in_executor(
|
||||
None,
|
||||
lambda: self.client.publish("multiColorBox", "setAutoFeed", payload, timeout=0)
|
||||
)
|
||||
self._ace_auto_feed[ace_id] = on
|
||||
self._state_dirty = True
|
||||
return web.json_response({"result": "ok", "ace_id": ace_id, "auto_feed": on})
|
||||
|
||||
async def handle_api_ace_dry(self, request):
|
||||
try:
|
||||
body = await request.json()
|
||||
@@ -5087,6 +5134,7 @@ function loadPrinterTab(){
|
||||
"filament_mode": s.get("filament_mode", self._filament_mode),
|
||||
"ace_drying": s.get("ace_drying", {"status": 0, "target_temp": 0, "duration": 0, "remain_time": 0, "humidity": None, "current_temp": None}),
|
||||
"ace_units": list(self._ace_box_ids),
|
||||
"ace_auto_feed": dict(self._ace_auto_feed),
|
||||
"ace_dry_presets": self._ace_dry_presets,
|
||||
"thumbnail": self._thumbnail_b64,
|
||||
"connection_error": s["connection_error"],
|
||||
@@ -5822,6 +5870,7 @@ def build_app(bridge: KobraXBridge) -> web.Application:
|
||||
r.add_post("/api/speed", bridge.handle_api_speed)
|
||||
r.add_post("/api/ams/feed", bridge.handle_api_ams_feed)
|
||||
r.add_post("/api/ams/set_slot", bridge.handle_api_ams_set_slot)
|
||||
r.add_post("/api/ace/auto_feed", bridge.handle_api_ace_auto_feed)
|
||||
r.add_post("/api/ace/dry", bridge.handle_api_ace_dry)
|
||||
r.add_post("/api/axis", bridge.handle_api_axis)
|
||||
r.add_post("/api/temperature", bridge.handle_api_temperature)
|
||||
|
||||
Reference in New Issue
Block a user