157 lines
5.9 KiB
Python
157 lines
5.9 KiB
Python
#!/usr/bin/env python3
|
|
import json
|
|
|
|
with open('/home/mdares/.node-red/flows.json', 'r') as f:
|
|
flows = json.load(f)
|
|
|
|
# HTML for resume/restart prompt modal
|
|
resume_prompt_html = '''
|
|
<!-- Resume/Restart Prompt Modal -->
|
|
<div id="resume-modal" class="modal" ng-show="resumePrompt.show">
|
|
<div class="modal-card">
|
|
<h2>Work Order Already In Progress</h2>
|
|
<p class="wo-info">{{ resumePrompt.id }}</p>
|
|
<p class="wo-summary">
|
|
<strong>{{ resumePrompt.goodParts }}</strong> of <strong>{{ resumePrompt.targetQty }}</strong> parts completed
|
|
({{ resumePrompt.progressPercent }}%)
|
|
</p>
|
|
<p class="wo-summary">Cycle Count: <strong>{{ resumePrompt.cycleCount }}</strong></p>
|
|
|
|
<div style="margin-top: 1.5rem; display: flex; flex-direction: column; gap: 0.75rem;">
|
|
<button class="prompt-continue" ng-click="resumeWorkOrder()">
|
|
Resume from {{ resumePrompt.goodParts }} parts
|
|
</button>
|
|
<button class="prompt-yes" ng-click="confirmRestart()">
|
|
Restart from 0 (Warning: Progress will be lost!)
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
'''
|
|
|
|
# JavaScript for handling resume prompt
|
|
resume_prompt_js = '''
|
|
// Resume/Restart Prompt State
|
|
scope.resumePrompt = {
|
|
show: false,
|
|
id: '',
|
|
sku: '',
|
|
cycleCount: 0,
|
|
goodParts: 0,
|
|
targetQty: 0,
|
|
progressPercent: 0,
|
|
order: null
|
|
};
|
|
|
|
scope.resumeWorkOrder = function() {
|
|
if (!scope.resumePrompt.order) {
|
|
console.error('No order data for resume');
|
|
return;
|
|
}
|
|
|
|
scope.send({
|
|
action: 'resume-work-order',
|
|
payload: scope.resumePrompt.order
|
|
});
|
|
|
|
scope.resumePrompt.show = false;
|
|
scope.hasActiveOrder = true;
|
|
};
|
|
|
|
scope.confirmRestart = function() {
|
|
if (!confirm('Are you sure you want to restart? All progress (' + scope.resumePrompt.goodParts + ' parts) will be lost!')) {
|
|
return;
|
|
}
|
|
|
|
if (!scope.resumePrompt.order) {
|
|
console.error('No order data for restart');
|
|
return;
|
|
}
|
|
|
|
scope.send({
|
|
action: 'restart-work-order',
|
|
payload: scope.resumePrompt.order
|
|
});
|
|
|
|
scope.resumePrompt.show = false;
|
|
scope.hasActiveOrder = true;
|
|
};
|
|
'''
|
|
|
|
# Watch handler for resume prompt
|
|
resume_watch_handler = '''
|
|
// Handle resume prompt
|
|
if (msg.topic === 'resumePrompt' && msg.payload) {
|
|
scope.resumePrompt.show = true;
|
|
scope.resumePrompt.id = msg.payload.id || '';
|
|
scope.resumePrompt.sku = msg.payload.sku || '';
|
|
scope.resumePrompt.cycleCount = msg.payload.cycleCount || 0;
|
|
scope.resumePrompt.goodParts = msg.payload.goodParts || 0;
|
|
scope.resumePrompt.targetQty = msg.payload.targetQty || 0;
|
|
scope.resumePrompt.progressPercent = msg.payload.progressPercent || 0;
|
|
scope.resumePrompt.order = msg.payload.order || null;
|
|
return;
|
|
}
|
|
'''
|
|
|
|
# Find Home Template node and update it
|
|
for node in flows:
|
|
if node.get('id') == '1821c4842945ecd8' and node.get('name') == 'Home Template':
|
|
template = node.get('format', '')
|
|
|
|
# Add resume modal HTML before the closing </div> of #oee or before scrap modal
|
|
if '<div id="scrap-modal"' in template:
|
|
# Insert before scrap modal
|
|
template = template.replace('<div id="scrap-modal"', resume_prompt_html + '<div id="scrap-modal"')
|
|
else:
|
|
# Insert before closing body tag or at end
|
|
template = template.replace('</div>\n<script>', '</div>\n' + resume_prompt_html + '\n<script>')
|
|
|
|
# Add resume prompt JS functions before the $watch section
|
|
if '(function(scope) {' in template and 'scope.$watch' in template:
|
|
# Find the first scope.$watch and insert before it
|
|
watch_idx = template.find('scope.$watch')
|
|
if watch_idx != -1:
|
|
# Find the start of the watch function (go back to find opening of scope function containing it)
|
|
# Insert resume JS right after "(function(scope) {" and before renderDashboard or other functions
|
|
|
|
# Better approach: insert before the closing })(scope); at the very end
|
|
closing_idx = template.rfind('})(scope);')
|
|
if closing_idx != -1:
|
|
template = template[:closing_idx] + resume_prompt_js + '\n ' + template[closing_idx:]
|
|
|
|
# Add watch handler for resumePrompt topic
|
|
# Find the $watch('msg' section and add handler
|
|
if "scope.$watch('msg'" in template:
|
|
# Find where msg.topic handlers are (look for "if (msg.topic ==" patterns)
|
|
# Insert our handler before the closing of the watch function
|
|
|
|
# Find the watch function and add handler inside it
|
|
# Look for the pattern where other topic handlers are
|
|
if "if (msg.topic === 'machineStatus')" in template:
|
|
# Insert before machineStatus handler
|
|
template = template.replace(
|
|
"if (msg.topic === 'machineStatus')",
|
|
resume_watch_handler + "\n if (msg.topic === 'machineStatus')"
|
|
)
|
|
elif 'scope.$watch' in template:
|
|
# Add at the beginning of the watch function
|
|
watch_start = template.find("scope.$watch('msg', function(msg) {")
|
|
if watch_start != -1:
|
|
# Find the first if statement after the watch declaration
|
|
insert_pos = template.find('if (!msg)', watch_start)
|
|
if insert_pos != -1:
|
|
# Insert after the "if (!msg) { return; }" block
|
|
after_null_check = template.find('}', insert_pos) + 1
|
|
template = template[:after_null_check] + '\n ' + resume_watch_handler + template[after_null_check:]
|
|
|
|
node['format'] = template
|
|
print("Updated Home Template with resume/restart prompt")
|
|
break
|
|
|
|
# Write back
|
|
with open('/home/mdares/.node-red/flows.json', 'w') as f:
|
|
json.dump(flows, f, indent=4)
|
|
|
|
print("Home Template updated successfully")
|