11import os
22import time
3+ import unicodedata
4+
35import yaml
46
7+ from octoprint_mrbeam .iobeam .iobeam_handler import IoBeamValueEvents
58from octoprint_mrbeam .mrb_logger import mrb_logger
69from octoprint .events import Events as OctoPrintEvents
710from octoprint_mrbeam .mrbeam_events import MrBeamEvents
@@ -18,7 +21,6 @@ def usageHandler(plugin):
1821
1922
2023class UsageHandler (object ):
21- MAX_DUST_FACTOR = 2.0
2224 MIN_DUST_FACTOR = 0.5
2325 MAX_DUST_VALUE = 0.5
2426 MIN_DUST_VALUE = 0.2
@@ -40,12 +42,6 @@ def __init__(self, plugin):
4042 self .start_ntp_synced = None
4143
4244 self ._last_dust_value = None
43- self ._dust_mapping_m = (self .MAX_DUST_FACTOR - self .MIN_DUST_FACTOR ) / (
44- self .MAX_DUST_VALUE - self .MIN_DUST_VALUE
45- )
46- self ._dust_mapping_b = (
47- self .MIN_DUST_FACTOR - self ._dust_mapping_m * self .MIN_DUST_VALUE
48- )
4945
5046 analyticsfolder = os .path .join (
5147 self ._settings .getBaseFolder ("base" ),
@@ -78,12 +74,26 @@ def _on_mrbeam_plugin_initialized(self, event, payload):
7874 self ._laser_head_serial = self ._lh ["serial" ]
7975 else :
8076 self ._laser_head_serial = "no_serial"
81-
77+ self . _calculate_dust_mapping ()
8278 self ._init_missing_usage_data ()
8379 self .log_usage ()
8480
8581 self ._subscribe ()
8682
83+ def _calculate_dust_mapping (self ):
84+ max_dust_factor = self ._laserhead_handler .current_laserhead_max_dust_factor
85+ self ._dust_mapping_m = (max_dust_factor - self .MIN_DUST_FACTOR ) / (
86+ self .MAX_DUST_VALUE - self .MIN_DUST_VALUE
87+ )
88+ self ._dust_mapping_b = (
89+ self .MIN_DUST_FACTOR - self ._dust_mapping_m * self .MIN_DUST_VALUE
90+ )
91+ self ._logger .debug (
92+ "new dust mapping -> {} - {} - {}" .format (
93+ max_dust_factor , self ._dust_mapping_m , self ._dust_mapping_b
94+ )
95+ )
96+
8797 def log_usage (self ):
8898 self ._logger .info (
8999 "Usage: total_usage: {}, pre-filter: {}, main filter: {}, current laser head: {}, mechanics: {}, compressor: {} - {}" .format (
@@ -117,6 +127,9 @@ def _subscribe(self):
117127 self ._event_bus .subscribe (
118128 MrBeamEvents .LASER_HEAD_READ , self .event_laser_head_read
119129 )
130+ self ._plugin .iobeam .subscribe (
131+ IoBeamValueEvents .LASERHEAD_CHANGED , self ._event_laserhead_changed
132+ )
120133
121134 def event_laser_head_read (self , event , payload ):
122135 # Update laser head info if necessary --> Only update if there is a serial number different than the previous
@@ -164,6 +177,17 @@ def event_stop(self, event, payload):
164177
165178 self .write_usage_analytics (action = "job_finished" )
166179
180+ def _event_laserhead_changed (self , event ):
181+ """
182+ will be triggered if the laser head changed,
183+ refreshes the laserhead max dust factor that will be used for the new laser head
184+
185+ Returns:
186+
187+ """
188+ self ._logger .debug ("Laserhead changed recalculate dust mapping" )
189+ self ._calculate_dust_mapping ()
190+
167191 def _set_time (self , job_duration ):
168192 if job_duration is not None and job_duration > 0.0 :
169193
@@ -356,36 +380,66 @@ def _load_usage_data(self):
356380 "Trying to recover from _backup_file file: %s" , self ._backup_file
357381 )
358382 recovery_try = True
359- if os .path .isfile (self ._backup_file ):
383+ try :
384+ with open (self ._backup_file , "r" ) as stream :
385+ data = yaml .safe_load (stream )
386+ if self ._validate_data (data ):
387+ data ["restored" ] = (
388+ data ["restored" ] + 1 if "restored" in data else 1
389+ )
390+ self ._usage_data = data
391+ self ._write_usage_data ()
392+ success = True
393+ self ._logger .info ("Recovered from _backup_file file. Yayy!" )
394+ except yaml .constructor .ConstructorError :
360395 try :
361- data = None
362- with open (self ._backup_file , "r" ) as stream :
363- data = yaml .safe_load (stream )
364- if self ._validate_data (data ):
365- data ["restored" ] = (
366- data ["restored" ] + 1 if "restored" in data else 1
367- )
368- self ._usage_data = data
369- success = True
370- self ._write_usage_data ()
371- self ._logger .info ("Recovered from _backup_file file. Yayy!" )
372- except :
373- self ._logger .error ("Can't read _backup_file file." )
396+ success = self ._repair_backup_usage_data ()
397+ except Exception :
398+ self ._logger .error ("Repair of the _backup_file failed." )
399+ except OSError :
400+ self ._logger .error ("There is no _backup_file file." )
401+ except yaml .YAMLError :
402+ self ._logger .error ("There was a YAMLError with the _backup_file file." )
403+ except :
404+ self ._logger .error ("Can't read _backup_file file." )
374405
375406 if not success :
376407 self ._logger .warn ("Resetting usage data. (marking as incomplete)" )
377408 self ._usage_data = self ._get_usage_data_template ()
378409 if recovery_try :
379410 self ._write_usage_data ()
380411
412+ def _repair_backup_usage_data (self ):
413+ """
414+ repairs a broken usage backup file, where the version is saved in unicode
415+
416+ Returns:
417+ boolean: successfull
418+ """
419+ success = False
420+ with open (self ._backup_file , "r" ) as stream :
421+ data = yaml .load (stream )
422+ if self ._validate_data (data ):
423+ #checks if the version is saved in unicode and converts it into a string see SW-1269
424+ if isinstance (data ["version" ], unicode ):
425+ data ["version" ] = unicodedata .normalize ('NFKD' , data ["version" ]).encode ('ascii' , 'ignore' )
426+ data ["restored" ] = (
427+ data ["restored" ] + 1 if "restored" in data else 1
428+ )
429+ self ._usage_data = data
430+ success = True
431+ self ._write_usage_data ()
432+ self ._logger .info ("Could repair _backup_file file. Yayy!" )
433+ return success
434+
381435 def _write_usage_data (self , file = None ):
382436 self ._usage_data ["version" ] = self ._plugin_version
383437 self ._usage_data ["ts" ] = time .time ()
384438 self ._usage_data ["serial" ] = self ._device_serial
385439 file = self ._storage_file if file is None else file
386440 try :
387441 with open (file , "w" ) as outfile :
388- yaml .dump (self ._usage_data , outfile , default_flow_style = False )
442+ yaml .safe_dump (self ._usage_data , outfile , default_flow_style = False )
389443 except :
390444 self ._logger .exception ("Can't write file %s due to an exception: " , file )
391445
0 commit comments