# Module `lib.tools.sdcard`

Sdcard management class

Expand source code

    # Distributed under Pycameresp License
    # Copyright (c) 2023 Remi BERTHOLET
    # pylint:disable=consider-using-f-string

    """ Sdcard management class """
    try:
            import machine
    except:
            pass
    import uos
    import tools.logger
    import tools.filesystem
    import tools.info

    class SdCard:
            """ Manage the sdcard """
            opened = [False]
            mountpoint = [""]
            slot = [{}]

            @staticmethod
            def set_slot(**slot):
                    """ Set the default sdcard slot
                    - slot  :  selects which of the available interfaces to use. Leaving this unset will select the default interface.
                    - width : selects the bus width for the SD/MMC interface.
                    - cd    : can be used to specify a card-detect pin.
                    - wp    : can be used to specify a write-protect pin.
                    - sck   : can be used to specify an SPI clock pin.
                    - miso  : can be used to specify an SPI miso pin.
                    - mosi  : can be used to specify an SPI mosi pin.
                    - cs    : can be used to specify an SPI chip select pin.
                    - freq  : selects the SD/MMC interface frequency in Hz (only supported on the ESP32).
                    (look doc http://docs.micropython.org/en/latest/library/machine.SDCard.html?highlight=sdcard) """
                    SdCard.slot[0] = slot

            @staticmethod
            def get_max_size():
                    """ Return the maximal size of sdcard """
                    if SdCard.is_mounted():
                            status = uos.statvfs(SdCard.get_mountpoint())
                            if tools.filesystem.ismicropython():
                                    return status[1]*status[2]
                            else:
                                    return status.f_frsize*status.f_blocks
                    else:
                            return 0

            @staticmethod
            def get_free_size():
                    """ Return the free size of sdcard """
                    if SdCard.is_mounted():
                            status = uos.statvfs(SdCard.get_mountpoint())
                            if tools.filesystem.ismicropython():
                                    return status[0]*status[3]
                            else:
                                    return status.f_bsize * status.f_bfree
                    else:
                            return 0

            @staticmethod
            def is_mounted():
                    """ Indicates if the sd card is mounted """
                    return SdCard.opened[0]

            @staticmethod
            def is_available():
                    """ Indicates if the sd card is available on device """
                    if "slot" in SdCard.slot[0]:
                            if SdCard.slot[0]["slot"] is None:
                                    return False
                    return True

            @staticmethod
            def get_mountpoint():
                    """ Return the mount point """
                    return SdCard.mountpoint[0]

            @staticmethod
            def formatsd(fs="FAT"):
                    """ Format the sd card (erase all data) """
                    result = False
                    if SdCard.is_mounted() is False:
                            try:
                                    # pylint:disable=redefined-outer-name

                                    import os
                                    import machine
                                    sd = machine.SDCard(**(SdCard.slot[0]))
                                    if fs== "FAT":
                                            # pylint:disable=no-member
                                            os.VfsFat.mkfs(sd)
                                            os.VfsFat(sd)
                                            result = True
                                    elif fs== "LFS":
                                            # pylint:disable=no-member
                                            os.VfsLfs2.mkfs(sd)
                                            os.VfsLfs2(sd)
                                    result = True
                            except Exception as err:
                                    tools.logger.syslog(err)
                    return result

            @staticmethod
            def umount(mountpoint = "/sd"):
                    """ Umount sd card """
                    result = False
                    if SdCard.is_mounted() is True and mountpoint != "/" and mountpoint != "":
                            if SdCard.is_available():
                                    if tools.filesystem.ismicropython():
                                            try:
                                                    uos.umount(mountpoint)
                                                    SdCard.mountpoint[0] = ""
                                                    SdCard.opened[0]= False
                                                    result = True
                                            except Exception as err:
                                                    tools.logger.syslog(err, "Cannot umount %s"%mountpoint)
                                    else:
                                            SdCard.mountpoint[0] = ""
                                            SdCard.opened[0] = False
                                            result = True
                            else:
                                    tools.logger.syslog("SdCard disabled")
                                    SdCard.mountpoint[0] = ""
                                    SdCard.opened[0] = False
                                    result = True
                    elif SdCard.is_mounted() is False:
                            result = True
                    return result

            @staticmethod
            def mount(mountpoint = "/sd"):
                    """ Mount sd card """
                    result = False
                    if SdCard.is_mounted() is False and mountpoint != "/" and mountpoint != "":
                            if SdCard.is_available():
                                    if tools.filesystem.ismicropython():

                                            try:
                                                    # If the sdcard not already mounted
                                                    if uos.statvfs("/") == uos.statvfs(mountpoint):
                                                            uos.mount(machine.SDCard(**(SdCard.slot[0])), mountpoint)
                                                            SdCard.mountpoint[0] = mountpoint
                                                            SdCard.opened[0]= True
                                                            result = True
                                            except Exception as err:
                                                    tools.info.increase_issues_counter()
                                                    tools.logger.syslog("Cannot mount %s"%mountpoint)
                                    else:
                                            SdCard.mountpoint[0] = mountpoint[1:]
                                            SdCard.opened[0] = True
                                            result = True
                            else:
                                    tools.logger.syslog("SdCard disabled")
                                    if tools.filesystem.ismicropython():
                                            SdCard.mountpoint[0] = "/data"
                                    else:
                                            from os import getcwd
                                            SdCard.mountpoint[0] = "%s/data"%getcwd()
                                    SdCard.opened[0] = True
                                    tools.filesystem.makedir(SdCard.mountpoint[0], True)
                                    result = True
                    elif SdCard.is_mounted():
                            if tools.filesystem.ismicropython():
                                    if SdCard.is_available():
                                            if mountpoint == SdCard.get_mountpoint():
                                                    result = True
                                    else:
                                            result = True
                            else:
                                    result = True
                    return result

            @staticmethod
            def create_file(directory, filename, mode="w"):
                    """ Create file with directory """
                    result = None
                    filepath = directory + "/" + filename
                    directories = [directory]
                    direct = directory
                    while 1:
                            parts = tools.filesystem.split(direct)

                            if parts[1] == "" or parts[0] == "":
                                    break
                            directories.append(parts[0])
                            direct = parts[0]

                    if "/" in directories:
                            directories.remove("/")
                    if SdCard.mountpoint[0] in directories:
                            directories.remove(SdCard.mountpoint[0])

                    newdirs = []
                    for l in range(len(directories)):
                            part = directories[:l]
                            part.reverse()
                            newdirs.append(part)
                    directories.reverse()
                    newdirs.append(directories)

                    for directories in newdirs:
                            for direct in directories:
                                    try:
                                            uos.mkdir(direct)
                                    except OSError as err:
                                            if err.args[0] not in [2,17]:
                                                    tools.logger.syslog(err)
                                                    break
                            try:
                                    # pylint:disable=unspecified-encoding
                                    result = open(filepath,mode)
                                    break
                            except OSError as err:
                                    if err.args[0] not in [2,17]:
                                            tools.logger.syslog(err)
                                            break
                    return result

            @staticmethod
            def is_not_enough_space(low):
                    """ Indicates if remaining space is not sufficient """
                    free = SdCard.get_free_size()
                    total = SdCard.get_max_size()
                    if low:
                            if SdCard.is_available():
                                    threshold = 5
                            else:
                                    threshold = 5
                    else:
                            if SdCard.is_available():
                                    threshold = 8
                            else:
                                    threshold = 25

                    if free < 0 or total < 0:
                            return True

                    if free < 32*1024*4:
                            return True
                    else:
                            return ((free * 100 // total) <= threshold)

            @staticmethod
            def save(directory, filename, data):
                    """ Save file on sd card """
                    result = False
                    if SdCard.is_mounted():
                            file = None
                            if SdCard.is_not_enough_space(low=True) is False:
                                    try:
                                            file = SdCard.create_file(SdCard.get_mountpoint() + "/" + directory, filename, "w")
                                            file.write(data)
                                            file.close()
                                            result = True
                                    except OSError as err:
                                            tools.logger.syslog(err, "Cannot save %s/%s/%s"%(SdCard.get_mountpoint(), directory, filename))
                                            # If sd card not responding properly
                                            if err.errno == 2:
                                                    tools.info.increase_issues_counter()
                                    except Exception as err:
                                            tools.logger.syslog(err, "Cannot save %s/%s/%s"%(SdCard.get_mountpoint(), directory, filename))
                                    finally:
                                            if file is not None:
                                                    file.close()
                            else:
                                    if SdCard.is_available() is False:
                                            result = True
                    return result

## Classes

`class SdCard`

  Manage the sdcard

  Expand source code

      class SdCard:
              """ Manage the sdcard """
              opened = [False]
              mountpoint = [""]
              slot = [{}]

              @staticmethod
              def set_slot(**slot):
                      """ Set the default sdcard slot
                      - slot  :  selects which of the available interfaces to use. Leaving this unset will select the default interface.
                      - width : selects the bus width for the SD/MMC interface.
                      - cd    : can be used to specify a card-detect pin.
                      - wp    : can be used to specify a write-protect pin.
                      - sck   : can be used to specify an SPI clock pin.
                      - miso  : can be used to specify an SPI miso pin.
                      - mosi  : can be used to specify an SPI mosi pin.
                      - cs    : can be used to specify an SPI chip select pin.
                      - freq  : selects the SD/MMC interface frequency in Hz (only supported on the ESP32).
                      (look doc http://docs.micropython.org/en/latest/library/machine.SDCard.html?highlight=sdcard) """
                      SdCard.slot[0] = slot

              @staticmethod
              def get_max_size():
                      """ Return the maximal size of sdcard """
                      if SdCard.is_mounted():
                              status = uos.statvfs(SdCard.get_mountpoint())
                              if tools.filesystem.ismicropython():
                                      return status[1]*status[2]
                              else:
                                      return status.f_frsize*status.f_blocks
                      else:
                              return 0

              @staticmethod
              def get_free_size():
                      """ Return the free size of sdcard """
                      if SdCard.is_mounted():
                              status = uos.statvfs(SdCard.get_mountpoint())
                              if tools.filesystem.ismicropython():
                                      return status[0]*status[3]
                              else:
                                      return status.f_bsize * status.f_bfree
                      else:
                              return 0

              @staticmethod
              def is_mounted():
                      """ Indicates if the sd card is mounted """
                      return SdCard.opened[0]

              @staticmethod
              def is_available():
                      """ Indicates if the sd card is available on device """
                      if "slot" in SdCard.slot[0]:
                              if SdCard.slot[0]["slot"] is None:
                                      return False
                      return True

              @staticmethod
              def get_mountpoint():
                      """ Return the mount point """
                      return SdCard.mountpoint[0]

              @staticmethod
              def formatsd(fs="FAT"):
                      """ Format the sd card (erase all data) """
                      result = False
                      if SdCard.is_mounted() is False:
                              try:
                                      # pylint:disable=redefined-outer-name

                                      import os
                                      import machine
                                      sd = machine.SDCard(**(SdCard.slot[0]))
                                      if fs== "FAT":
                                              # pylint:disable=no-member
                                              os.VfsFat.mkfs(sd)
                                              os.VfsFat(sd)
                                              result = True
                                      elif fs== "LFS":
                                              # pylint:disable=no-member
                                              os.VfsLfs2.mkfs(sd)
                                              os.VfsLfs2(sd)
                                      result = True
                              except Exception as err:
                                      tools.logger.syslog(err)
                      return result

              @staticmethod
              def umount(mountpoint = "/sd"):
                      """ Umount sd card """
                      result = False
                      if SdCard.is_mounted() is True and mountpoint != "/" and mountpoint != "":
                              if SdCard.is_available():
                                      if tools.filesystem.ismicropython():
                                              try:
                                                      uos.umount(mountpoint)
                                                      SdCard.mountpoint[0] = ""
                                                      SdCard.opened[0]= False
                                                      result = True
                                              except Exception as err:
                                                      tools.logger.syslog(err, "Cannot umount %s"%mountpoint)
                                      else:
                                              SdCard.mountpoint[0] = ""
                                              SdCard.opened[0] = False
                                              result = True
                              else:
                                      tools.logger.syslog("SdCard disabled")
                                      SdCard.mountpoint[0] = ""
                                      SdCard.opened[0] = False
                                      result = True
                      elif SdCard.is_mounted() is False:
                              result = True
                      return result

              @staticmethod
              def mount(mountpoint = "/sd"):
                      """ Mount sd card """
                      result = False
                      if SdCard.is_mounted() is False and mountpoint != "/" and mountpoint != "":
                              if SdCard.is_available():
                                      if tools.filesystem.ismicropython():

                                              try:
                                                      # If the sdcard not already mounted
                                                      if uos.statvfs("/") == uos.statvfs(mountpoint):
                                                              uos.mount(machine.SDCard(**(SdCard.slot[0])), mountpoint)
                                                              SdCard.mountpoint[0] = mountpoint
                                                              SdCard.opened[0]= True
                                                              result = True
                                              except Exception as err:
                                                      tools.info.increase_issues_counter()
                                                      tools.logger.syslog("Cannot mount %s"%mountpoint)
                                      else:
                                              SdCard.mountpoint[0] = mountpoint[1:]
                                              SdCard.opened[0] = True
                                              result = True
                              else:
                                      tools.logger.syslog("SdCard disabled")
                                      if tools.filesystem.ismicropython():
                                              SdCard.mountpoint[0] = "/data"
                                      else:
                                              from os import getcwd
                                              SdCard.mountpoint[0] = "%s/data"%getcwd()
                                      SdCard.opened[0] = True
                                      tools.filesystem.makedir(SdCard.mountpoint[0], True)
                                      result = True
                      elif SdCard.is_mounted():
                              if tools.filesystem.ismicropython():
                                      if SdCard.is_available():
                                              if mountpoint == SdCard.get_mountpoint():
                                                      result = True
                                      else:
                                              result = True
                              else:
                                      result = True
                      return result

              @staticmethod
              def create_file(directory, filename, mode="w"):
                      """ Create file with directory """
                      result = None
                      filepath = directory + "/" + filename
                      directories = [directory]
                      direct = directory
                      while 1:
                              parts = tools.filesystem.split(direct)

                              if parts[1] == "" or parts[0] == "":
                                      break
                              directories.append(parts[0])
                              direct = parts[0]

                      if "/" in directories:
                              directories.remove("/")
                      if SdCard.mountpoint[0] in directories:
                              directories.remove(SdCard.mountpoint[0])

                      newdirs = []
                      for l in range(len(directories)):
                              part = directories[:l]
                              part.reverse()
                              newdirs.append(part)
                      directories.reverse()
                      newdirs.append(directories)

                      for directories in newdirs:
                              for direct in directories:
                                      try:
                                              uos.mkdir(direct)
                                      except OSError as err:
                                              if err.args[0] not in [2,17]:
                                                      tools.logger.syslog(err)
                                                      break
                              try:
                                      # pylint:disable=unspecified-encoding
                                      result = open(filepath,mode)
                                      break
                              except OSError as err:
                                      if err.args[0] not in [2,17]:
                                              tools.logger.syslog(err)
                                              break
                      return result

              @staticmethod
              def is_not_enough_space(low):
                      """ Indicates if remaining space is not sufficient """
                      free = SdCard.get_free_size()
                      total = SdCard.get_max_size()
                      if low:
                              if SdCard.is_available():
                                      threshold = 5
                              else:
                                      threshold = 5
                      else:
                              if SdCard.is_available():
                                      threshold = 8
                              else:
                                      threshold = 25

                      if free < 0 or total < 0:
                              return True

                      if free < 32*1024*4:
                              return True
                      else:
                              return ((free * 100 // total) <= threshold)

              @staticmethod
              def save(directory, filename, data):
                      """ Save file on sd card """
                      result = False
                      if SdCard.is_mounted():
                              file = None
                              if SdCard.is_not_enough_space(low=True) is False:
                                      try:
                                              file = SdCard.create_file(SdCard.get_mountpoint() + "/" + directory, filename, "w")
                                              file.write(data)
                                              file.close()
                                              result = True
                                      except OSError as err:
                                              tools.logger.syslog(err, "Cannot save %s/%s/%s"%(SdCard.get_mountpoint(), directory, filename))
                                              # If sd card not responding properly
                                              if err.errno == 2:
                                                      tools.info.increase_issues_counter()
                                      except Exception as err:
                                              tools.logger.syslog(err, "Cannot save %s/%s/%s"%(SdCard.get_mountpoint(), directory, filename))
                                      finally:
                                              if file is not None:
                                                      file.close()
                              else:
                                      if SdCard.is_available() is False:
                                              result = True
                      return result

  ### Class variables

  `var mountpoint`
  `var opened`
  `var slot`

  ### Static methods

  `def create_file(directory, filename, mode='w')`

    Create file with directory

    Expand source code

        @staticmethod
        def create_file(directory, filename, mode="w"):
                """ Create file with directory """
                result = None
                filepath = directory + "/" + filename
                directories = [directory]
                direct = directory
                while 1:
                        parts = tools.filesystem.split(direct)

                        if parts[1] == "" or parts[0] == "":
                                break
                        directories.append(parts[0])
                        direct = parts[0]

                if "/" in directories:
                        directories.remove("/")
                if SdCard.mountpoint[0] in directories:
                        directories.remove(SdCard.mountpoint[0])

                newdirs = []
                for l in range(len(directories)):
                        part = directories[:l]
                        part.reverse()
                        newdirs.append(part)
                directories.reverse()
                newdirs.append(directories)

                for directories in newdirs:
                        for direct in directories:
                                try:
                                        uos.mkdir(direct)
                                except OSError as err:
                                        if err.args[0] not in [2,17]:
                                                tools.logger.syslog(err)
                                                break
                        try:
                                # pylint:disable=unspecified-encoding
                                result = open(filepath,mode)
                                break
                        except OSError as err:
                                if err.args[0] not in [2,17]:
                                        tools.logger.syslog(err)
                                        break
                return result

  `def formatsd(fs='FAT')`

    Format the sd card (erase all data)

    Expand source code

        @staticmethod
        def formatsd(fs="FAT"):
                """ Format the sd card (erase all data) """
                result = False
                if SdCard.is_mounted() is False:
                        try:
                                # pylint:disable=redefined-outer-name

                                import os
                                import machine
                                sd = machine.SDCard(**(SdCard.slot[0]))
                                if fs== "FAT":
                                        # pylint:disable=no-member
                                        os.VfsFat.mkfs(sd)
                                        os.VfsFat(sd)
                                        result = True
                                elif fs== "LFS":
                                        # pylint:disable=no-member
                                        os.VfsLfs2.mkfs(sd)
                                        os.VfsLfs2(sd)
                                result = True
                        except Exception as err:
                                tools.logger.syslog(err)
                return result

  `def get_free_size()`

    Return the free size of sdcard

    Expand source code

        @staticmethod
        def get_free_size():
                """ Return the free size of sdcard """
                if SdCard.is_mounted():
                        status = uos.statvfs(SdCard.get_mountpoint())
                        if tools.filesystem.ismicropython():
                                return status[0]*status[3]
                        else:
                                return status.f_bsize * status.f_bfree
                else:
                        return 0

  `def get_max_size()`

    Return the maximal size of sdcard

    Expand source code

        @staticmethod
        def get_max_size():
                """ Return the maximal size of sdcard """
                if SdCard.is_mounted():
                        status = uos.statvfs(SdCard.get_mountpoint())
                        if tools.filesystem.ismicropython():
                                return status[1]*status[2]
                        else:
                                return status.f_frsize*status.f_blocks
                else:
                        return 0

  `def get_mountpoint()`

    Return the mount point

    Expand source code

        @staticmethod
        def get_mountpoint():
                """ Return the mount point """
                return SdCard.mountpoint[0]

  `def is_available()`

    Indicates if the sd card is available on device

    Expand source code

        @staticmethod
        def is_available():
                """ Indicates if the sd card is available on device """
                if "slot" in SdCard.slot[0]:
                        if SdCard.slot[0]["slot"] is None:
                                return False
                return True

  `def is_mounted()`

    Indicates if the sd card is mounted

    Expand source code

        @staticmethod
        def is_mounted():
                """ Indicates if the sd card is mounted """
                return SdCard.opened[0]

  `def is_not_enough_space(low)`

    Indicates if remaining space is not sufficient

    Expand source code

        @staticmethod
        def is_not_enough_space(low):
                """ Indicates if remaining space is not sufficient """
                free = SdCard.get_free_size()
                total = SdCard.get_max_size()
                if low:
                        if SdCard.is_available():
                                threshold = 5
                        else:
                                threshold = 5
                else:
                        if SdCard.is_available():
                                threshold = 8
                        else:
                                threshold = 25

                if free < 0 or total < 0:
                        return True

                if free < 32*1024*4:
                        return True
                else:
                        return ((free * 100 // total) <= threshold)

  `def mount(mountpoint='/sd')`

    Mount sd card

    Expand source code

        @staticmethod
        def mount(mountpoint = "/sd"):
                """ Mount sd card """
                result = False
                if SdCard.is_mounted() is False and mountpoint != "/" and mountpoint != "":
                        if SdCard.is_available():
                                if tools.filesystem.ismicropython():

                                        try:
                                                # If the sdcard not already mounted
                                                if uos.statvfs("/") == uos.statvfs(mountpoint):
                                                        uos.mount(machine.SDCard(**(SdCard.slot[0])), mountpoint)
                                                        SdCard.mountpoint[0] = mountpoint
                                                        SdCard.opened[0]= True
                                                        result = True
                                        except Exception as err:
                                                tools.info.increase_issues_counter()
                                                tools.logger.syslog("Cannot mount %s"%mountpoint)
                                else:
                                        SdCard.mountpoint[0] = mountpoint[1:]
                                        SdCard.opened[0] = True
                                        result = True
                        else:
                                tools.logger.syslog("SdCard disabled")
                                if tools.filesystem.ismicropython():
                                        SdCard.mountpoint[0] = "/data"
                                else:
                                        from os import getcwd
                                        SdCard.mountpoint[0] = "%s/data"%getcwd()
                                SdCard.opened[0] = True
                                tools.filesystem.makedir(SdCard.mountpoint[0], True)
                                result = True
                elif SdCard.is_mounted():
                        if tools.filesystem.ismicropython():
                                if SdCard.is_available():
                                        if mountpoint == SdCard.get_mountpoint():
                                                result = True
                                else:
                                        result = True
                        else:
                                result = True
                return result

  `def save(directory, filename, data)`

    Save file on sd card

    Expand source code

        @staticmethod
        def save(directory, filename, data):
                """ Save file on sd card """
                result = False
                if SdCard.is_mounted():
                        file = None
                        if SdCard.is_not_enough_space(low=True) is False:
                                try:
                                        file = SdCard.create_file(SdCard.get_mountpoint() + "/" + directory, filename, "w")
                                        file.write(data)
                                        file.close()
                                        result = True
                                except OSError as err:
                                        tools.logger.syslog(err, "Cannot save %s/%s/%s"%(SdCard.get_mountpoint(), directory, filename))
                                        # If sd card not responding properly
                                        if err.errno == 2:
                                                tools.info.increase_issues_counter()
                                except Exception as err:
                                        tools.logger.syslog(err, "Cannot save %s/%s/%s"%(SdCard.get_mountpoint(), directory, filename))
                                finally:
                                        if file is not None:
                                                file.close()
                        else:
                                if SdCard.is_available() is False:
                                        result = True
                return result

  `def set_slot(**slot)`

    Set the default sdcard slot - slot : selects which of the available interfaces to use. Leaving this unset will select the default interface. - width : selects the bus width for the SD/MMC interface. - cd : can be used to specify a card-detect pin. - wp : can be used to specify a write-protect pin. - sck : can be used to specify an SPI clock pin. - miso : can be used to specify an SPI miso pin. - mosi : can be used to specify an SPI mosi pin. - cs : can be used to specify an SPI chip select pin. - freq : selects the SD/MMC interface frequency in Hz (only supported on the ESP32). (look doc http://docs.micropython.org/en/latest/library/machine.SDCard.html?highlight=sdcard)

    Expand source code

        @staticmethod
        def set_slot(**slot):
                """ Set the default sdcard slot
                - slot  :  selects which of the available interfaces to use. Leaving this unset will select the default interface.
                - width : selects the bus width for the SD/MMC interface.
                - cd    : can be used to specify a card-detect pin.
                - wp    : can be used to specify a write-protect pin.
                - sck   : can be used to specify an SPI clock pin.
                - miso  : can be used to specify an SPI miso pin.
                - mosi  : can be used to specify an SPI mosi pin.
                - cs    : can be used to specify an SPI chip select pin.
                - freq  : selects the SD/MMC interface frequency in Hz (only supported on the ESP32).
                (look doc http://docs.micropython.org/en/latest/library/machine.SDCard.html?highlight=sdcard) """
                SdCard.slot[0] = slot

  `def umount(mountpoint='/sd')`

    Umount sd card

    Expand source code

        @staticmethod
        def umount(mountpoint = "/sd"):
                """ Umount sd card """
                result = False
                if SdCard.is_mounted() is True and mountpoint != "/" and mountpoint != "":
                        if SdCard.is_available():
                                if tools.filesystem.ismicropython():
                                        try:
                                                uos.umount(mountpoint)
                                                SdCard.mountpoint[0] = ""
                                                SdCard.opened[0]= False
                                                result = True
                                        except Exception as err:
                                                tools.logger.syslog(err, "Cannot umount %s"%mountpoint)
                                else:
                                        SdCard.mountpoint[0] = ""
                                        SdCard.opened[0] = False
                                        result = True
                        else:
                                tools.logger.syslog("SdCard disabled")
                                SdCard.mountpoint[0] = ""
                                SdCard.opened[0] = False
                                result = True
                elif SdCard.is_mounted() is False:
                        result = True
                return result