Add machine status tracking and update for ArchiveSynchronizer
The ArchiveSynchronizer now tracks machine status and sends updates about it. Options of status are tracked as "working", "logged-in", and "logged-out". This implementation includes configuration changes for the st-ten-10 machine and error reporting for failures during remote archive operations.
This commit is contained in:
parent
414d8431c1
commit
85c1ec2d2d
@ -8,3 +8,4 @@ st-ten-6: st-ten-6
|
||||
st-ten-7: st-ten-7
|
||||
st-ten-8: st-ten-8
|
||||
ST-TEN-9: st-ten-9
|
||||
st-ten-10: st-ten-10
|
||||
|
||||
@ -3,7 +3,7 @@ description = ST-TEN-10
|
||||
instruction_folder = st-ten-10
|
||||
|
||||
[hardware_config]
|
||||
archive_synchronizer: absent
|
||||
archive_synchronizer: present
|
||||
label_printer: present
|
||||
label_printer_2: present # Brother label printer used only in st-ten-10
|
||||
remote_api: absent
|
||||
@ -16,8 +16,8 @@ leak_disabled: active #disable the tecna_t3 and furness_controls from starting
|
||||
|
||||
[archive_synchronizer]
|
||||
archive_endpoint: https://satilportal.it/api/st-ten-save/
|
||||
poll_time: 60
|
||||
hold_time: 1
|
||||
poll_time: 10
|
||||
hold_time: 10
|
||||
|
||||
#[furness_controls]
|
||||
#port: COM3
|
||||
|
||||
@ -2,6 +2,9 @@ import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import requests
|
||||
import traceback
|
||||
|
||||
import requests
|
||||
@ -13,19 +16,22 @@ from requests.adapters import HTTPAdapter, Retry
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
from .component import Component
|
||||
|
||||
# Suppress insecure request warning
|
||||
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||
|
||||
|
||||
class ArchiveSynchronizer(Component):
|
||||
machine_status = "offline"
|
||||
def __init__(self, config=None, name=None, period=1, lazy=True, paused=False, threaded=True):
|
||||
super().__init__(config=config, name=name, period=period, lazy=lazy, paused=paused, threaded=threaded)
|
||||
self.simulate = "--sim-archiver" in sys.argv
|
||||
self.status= ArchiveSynchronizer.machine_status
|
||||
|
||||
def config_changed(self):
|
||||
self.machine_id = self.config.machine_id
|
||||
self.archive_endpoint = self.config[self.name]["archive_endpoint"]
|
||||
if "--dev-portal" in sys.argv:
|
||||
self.archive_endpoint =f"https://dev.r5portal.it/api/st-ten-save/"
|
||||
else:
|
||||
self.archive_endpoint = self.config[self.name]["archive_endpoint"]
|
||||
#self.status_endpoint = f"https://dev.r5portal.it/api/device-info-update?machine-id={self.machine_id_endpoint}&status={self.status}"
|
||||
# self.images_path = self.config[self.name]["images_path"]
|
||||
self._do_set_period({"period": float(self.config[self.name]["poll_time"])})
|
||||
self.hold_time = round(float(self.config[self.name]["hold_time"]) * 1000)
|
||||
@ -49,9 +55,48 @@ class ArchiveSynchronizer(Component):
|
||||
if self.hold_time > 0:
|
||||
QThread.msleep(self.hold_time)
|
||||
self.gcs_bucket = None
|
||||
if "--dev-portal" in sys.argv:
|
||||
self.update_machine_status()
|
||||
super()._get()
|
||||
|
||||
def update_machine_status(self):
|
||||
self.status = ArchiveSynchronizer.machine_status
|
||||
#print(f"machine_status_global: {ArchiveSynchronizer.machine_status}") # TESTING
|
||||
self.status_endpoint = f"https://dev.r5portal.it/api/device-info-update?machine-id={self.machine_id.upper()}&status={self.status}"
|
||||
|
||||
if self.status not in ["working", "logged-in", "logged-out"]:
|
||||
status_dict = {"last_status": "offline"}
|
||||
else:
|
||||
status_dict = {"last_status": self.status}
|
||||
|
||||
response = None
|
||||
try:
|
||||
if not self.simulate:
|
||||
with requests.Session() as s:
|
||||
s.mount("", HTTPAdapter(max_retries=Retry(total=0))) # this disables retries
|
||||
response = requests.post(self.status_endpoint, json=status_dict, timeout=5, verify=False)
|
||||
if response.status_code != 200:
|
||||
raise AssertionError("bad status response")
|
||||
except AssertionError as e:
|
||||
self.log.warning(
|
||||
f"Status: {self.status}: failed to update machine status: {str(e)}: {response.status_code if response else 'no response'}: {response.content if response else 'no response'}"
|
||||
)
|
||||
return False
|
||||
except (requests.ConnectionError, requests.Timeout) as e:
|
||||
self.log.warning(
|
||||
f"Status: {self.status}: failed to update machine status, archive_endpoint might be unreachable: {str(e)}"
|
||||
)
|
||||
return False
|
||||
except Exception:
|
||||
self.log.error(
|
||||
f"Status: {self.status}: failed to update machine status:\n{traceback.format_exc()}:\n{response.status_code if response else 'no response'}: {response.content if response else 'no response'}"
|
||||
)
|
||||
return False
|
||||
|
||||
self.log.info(f"Status: {self.status}: Machine Status Updated Successfully")
|
||||
return True
|
||||
def remote_archive(self, record):
|
||||
r = None
|
||||
try:
|
||||
if not self.simulate:
|
||||
with requests.Session() as s:
|
||||
@ -74,10 +119,6 @@ class ArchiveSynchronizer(Component):
|
||||
except (requests.ConnectionError, requests.Timeout) as e:
|
||||
self.log.warning(f"id: {record.id}: failed to archive remotely, archive_endpoint might be unreachable: {str(e)}")
|
||||
return False
|
||||
except Exception:
|
||||
self.log.error(f"id: {record.id}: failed to archive remotely:\n{traceback.format_exc()}:\n{r.status_code}: {r.content}")
|
||||
return False
|
||||
self.log.info(f"id: {record.id}: archived remotely")
|
||||
return True
|
||||
|
||||
def remote_store(self, record):
|
||||
|
||||
@ -80,7 +80,6 @@ try:
|
||||
|
||||
class Main(QObject):
|
||||
do = pyqtSignal(dict)
|
||||
|
||||
@staticmethod
|
||||
def _do(config):
|
||||
return config["f"](*config.get("a", []), **config.get("k", {}))
|
||||
@ -250,6 +249,7 @@ try:
|
||||
Recipe_Selection, Barcode_Recipe_Selection):
|
||||
# LOGOUT IMMEDIATELY IF NOT TESTING
|
||||
Users.logout()
|
||||
ArchiveSynchronizer.machine_status = "logged-out"
|
||||
self.open_login()
|
||||
else:
|
||||
if not self.main_window.centralWidget().autotesting:
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import platform
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from components import ArchiveSynchronizer
|
||||
from lib.db import Session, Users
|
||||
from PyQt5.QtCore import QTimer, pyqtSignal
|
||||
from PyQt5.QtGui import QKeySequence, QIcon
|
||||
@ -21,6 +21,9 @@ class Login(Widget):
|
||||
super().__init__()
|
||||
self.welcome_l.setText("BENVENUTO, PER INIZIARE IL COLLAUDO, EFFETTUA L'ACCESSO:")
|
||||
self.user_cb.addItems(Users.get_usernames())
|
||||
|
||||
ArchiveSynchronizer.machine_status = "logged-in"
|
||||
|
||||
QShortcut(QKeySequence("Return"), self).activated.connect(self.login_b.click)
|
||||
QShortcut(QKeySequence("Enter"), self).activated.connect(self.login_b.click)
|
||||
self.login_b.clicked.connect(self.try_login)
|
||||
@ -56,6 +59,7 @@ class Login(Widget):
|
||||
login_count += 1
|
||||
# /TESTING
|
||||
self.successful_login.emit()
|
||||
ArchiveSynchronizer.machine_status = "logged-in"
|
||||
|
||||
def show_osk(self):
|
||||
self.password_le.setFocus()
|
||||
|
||||
@ -4,7 +4,7 @@ import os
|
||||
import sys
|
||||
import weakref
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from components import ArchiveSynchronizer
|
||||
from PyQt5.QtCore import QTimer, pyqtSlot
|
||||
from PyQt5.QtWidgets import QMessageBox
|
||||
from lib.db import Archive, Steps, Users
|
||||
@ -245,6 +245,10 @@ class Test(Widget):
|
||||
self.log.info(f"cycle step: {model_to_dict(self.step)!r} action: {action!r} current index:{self.cycle_index}")
|
||||
else:
|
||||
self.log.info(f"cycle step: {self.step!r} action: {action!r} current index:{self.cycle_index}")
|
||||
|
||||
ArchiveSynchronizer.machine_status = "working"
|
||||
# print(f"{ArchiveSynchronizer.machine_status}")#testing
|
||||
|
||||
current_w = self.centralWidget
|
||||
if hasattr(current_w, "stop"):
|
||||
current_w.stop()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user