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:
Eduardo 2024-04-23 11:15:23 +02:00
parent 414d8431c1
commit 85c1ec2d2d
6 changed files with 64 additions and 14 deletions

View File

@ -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

View File

@ -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

View File

@ -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
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):

View File

@ -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:

View File

@ -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()

View File

@ -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()