text: '''
  RotorHazard Helper and utility functions
  '''
  
  import os
  import logging
  import platform
  import subprocess
  import glob
  
  logger = logging.getLogger(__name__)
  
  FREQUENCY_ID_NONE = 0       # indicator value for node disabled
  IS_SYS_RASPBERRY_PI = True  # set by 'idAndLogSystemInfo()'
  
  def time_format(millis):
      '''Convert milliseconds to 00:00.000'''
      if millis is None:
          return None
  
      millis = int(round(millis, 0))
      minutes = millis // 60000
      over = millis % 60000
      seconds = over // 1000
      over = over % 1000
      milliseconds = over
      return '{0:01d}:{1:02d}.{2:03d}'.format(minutes, seconds, milliseconds)
  
  def phonetictime_format(millis):
      '''Convert milliseconds to phonetic'''
      millis = int(millis + 50)  # round to nearest tenth of a second
      minutes = millis // 60000
      over = millis % 60000
      seconds = over // 1000
      over = over % 1000
      tenths = over // 100
  
      if minutes > 0:
          return '{0:01d} {1:02d}.{2:01d}'.format(minutes, seconds, tenths)
      else:
          return '{0:01d}.{1:01d}'.format(seconds, tenths)
  
  def idAndLogSystemInfo():
      global IS_SYS_RASPBERRY_PI
      IS_SYS_RASPBERRY_PI = False
      try:
          modelStr = None
          try:
              fileHnd = open("/proc/device-tree/model", "r")
              modelStr = fileHnd.read()
              fileHnd.close()
          except:
              pass
          if modelStr and "raspberry pi" in modelStr.lower():
              IS_SYS_RASPBERRY_PI = True
              logger.info("Host machine: " + modelStr.strip('\0'))
          logger.info("Host OS: {0} {1}".format(platform.system(), platform.release()))
      except Exception:
          logger.exception("Error in 'idAndLogSystemInfo()'")
  
  # Checks if given file or directory is owned by 'root' and changes owner to 'pi' user if so.
  # Returns True if owner changed to 'pi' user; False if not.
  def checkSetFileOwnerPi(fileNameStr):
      try:
          if IS_SYS_RASPBERRY_PI:
              # check that 'pi' user exists, file/dir exists, and owner is 'root'
              if os.path.isdir("/home/pi") and os.path.exists(fileNameStr) and os.stat(fileNameStr).st_uid == 0:
                  subprocess.check_call(["sudo", "chown", "pi:pi", fileNameStr])
                  if os.stat(fileNameStr).st_uid != 0:
                      if os.path.isdir(fileNameStr):  # if dir then also apply to files in dir
                          file_list = list(filter(os.path.isfile, glob.glob(fileNameStr + "/*.*")))
                          for chk_path in file_list:
                              checkSetFileOwnerPi(chk_path, logger)
                      return True
                  logger.info("Unable to change owner in 'checkSetFileOwnerPi()': " + fileNameStr)
      except Exception:
          logger.exception("Error in 'checkSetFileOwnerPi()'")
      return False
  