fix: HA sync uses per-printer autocommit connections to prevent database locked
Deploy via Portainer / deploy (push) Successful in 1s
Deploy via Portainer / deploy (push) Successful in 1s
This commit is contained in:
@@ -2040,21 +2040,26 @@ def _ha_sync_once():
|
|||||||
states = _ha_fetch_all_states(ha_url, ha_token)
|
states = _ha_fetch_all_states(ha_url, ha_token)
|
||||||
if not states:
|
if not states:
|
||||||
return
|
return
|
||||||
# Ouvrir la connexion d'écriture APRÈS l'appel HTTP (qui peut être long)
|
# Lire les imprimantes avec une connexion courte (lecture seule)
|
||||||
conn = sqlite3.connect(DATABASE, timeout=30)
|
_rc = sqlite3.connect(DATABASE, timeout=15)
|
||||||
conn.row_factory = sqlite3.Row
|
_rc.row_factory = sqlite3.Row
|
||||||
conn.execute('PRAGMA journal_mode=WAL')
|
printers = _rc.execute(
|
||||||
printers = conn.execute(
|
|
||||||
"SELECT id, name, ha_entity_prefix FROM printers "
|
"SELECT id, name, ha_entity_prefix FROM printers "
|
||||||
"WHERE ha_entity_prefix IS NOT NULL AND ha_entity_prefix != ''"
|
"WHERE ha_entity_prefix IS NOT NULL AND ha_entity_prefix != ''"
|
||||||
).fetchall()
|
).fetchall()
|
||||||
|
_rc.close()
|
||||||
|
|
||||||
now_iso = datetime.now(timezone.utc).replace(tzinfo=None).isoformat()
|
now_iso = datetime.now(timezone.utc).replace(tzinfo=None).isoformat()
|
||||||
window = (datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(minutes=30)).isoformat()
|
window = (datetime.now(timezone.utc).replace(tzinfo=None) + timedelta(minutes=30)).isoformat()
|
||||||
for p in printers:
|
for p in printers:
|
||||||
prefix = p['ha_entity_prefix']
|
prefix = p['ha_entity_prefix']
|
||||||
ha_status = states.get(f'sensor.{prefix}_etat_de_l_impression', 'unknown')
|
ha_status = states.get(f'sensor.{prefix}_etat_de_l_impression', 'unknown')
|
||||||
ha_error = states.get(f'binary_sensor.{prefix}_erreur_d_impression', 'off')
|
ha_error = states.get(f'binary_sensor.{prefix}_erreur_d_impression', 'off')
|
||||||
slot = conn.execute(
|
# Connexion courte par imprimante : on lit, on écrit, on commit, on ferme
|
||||||
|
wc = sqlite3.connect(DATABASE, timeout=15, isolation_level=None)
|
||||||
|
wc.row_factory = sqlite3.Row
|
||||||
|
try:
|
||||||
|
slot = wc.execute(
|
||||||
"SELECT id, status FROM print_slots "
|
"SELECT id, status FROM print_slots "
|
||||||
"WHERE printer_id=? AND status IN ('planned','running') "
|
"WHERE printer_id=? AND status IN ('planned','running') "
|
||||||
"AND planned_start <= ? AND planned_end >= ? "
|
"AND planned_start <= ? AND planned_end >= ? "
|
||||||
@@ -2071,15 +2076,13 @@ def _ha_sync_once():
|
|||||||
elif ha_status == 'running' and slot['status'] == 'planned':
|
elif ha_status == 'running' and slot['status'] == 'planned':
|
||||||
new_status = 'running'
|
new_status = 'running'
|
||||||
if new_status:
|
if new_status:
|
||||||
conn.execute('UPDATE print_slots SET status=? WHERE id=?',
|
wc.execute('UPDATE print_slots SET status=? WHERE id=?',
|
||||||
(new_status, slot['id']))
|
(new_status, slot['id']))
|
||||||
if ha_ignored > 0:
|
if ha_ignored > 0:
|
||||||
conn.execute('UPDATE print_slots SET pieces_ignored=? WHERE id=?',
|
wc.execute('UPDATE print_slots SET pieces_ignored=? WHERE id=?',
|
||||||
(ha_ignored, slot['id']))
|
(ha_ignored, slot['id']))
|
||||||
try:
|
|
||||||
conn.commit()
|
|
||||||
finally:
|
finally:
|
||||||
conn.close()
|
wc.close()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'[HA sync] {e}')
|
print(f'[HA sync] {e}')
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user