@Override
 public void unregisterDeviceListener(DeviceStatusListener deviceListener) {
   if (deviceListener != null) {
     String id = deviceListener.getDeviceStatusListenerID();
     if (id.equals(DeviceStatusListener.DEVICE_DISCOVERY)) {
       this.deviceDiscovery = null;
     } else {
       Device intDevice = strucMan.getDeviceByDSID(deviceListener.getDeviceStatusListenerID());
       if (intDevice != null) {
         intDevice.unregisterDeviceStateListener();
       }
     }
   }
 }
 @Override
 public void registerDeviceListener(DeviceStatusListener deviceListener) {
   if (deviceListener != null) {
     String id = deviceListener.getDeviceStatusListenerID();
     logger.debug("register DeviceListener with id: " + id);
     if (id.equals(DeviceStatusListener.DEVICE_DISCOVERY)) {
       this.deviceDiscovery = deviceListener;
       for (Device device : strucMan.getDeviceMap().values()) {
         deviceDiscovery.onDeviceAdded(device);
       }
     } else {
       Device intDevice = strucMan.getDeviceByDSID(deviceListener.getDeviceStatusListenerID());
       if (intDevice != null) {
         intDevice.registerDeviceStateListener(deviceListener);
       } else {
         deviceListener.onDeviceRemoved(null);
       }
     }
   }
 }
    @Override
    public void run() {
      if (connMan.checkConnection()) {
        if (!getManagerState().equals(ManagerStates.RUNNING)) {
          logger.debug("Thread started");
          if (devicesLoaded) {
            stateChanged(ManagerStates.RUNNING);
          } else {
            stateChanged(ManagerStates.INITIALIZING);
          }
        }
        HashMap<DSID, Device> tempDeviceMap;
        if (strucMan.getDeviceMap() != null) {
          tempDeviceMap = (HashMap<DSID, Device>) strucMan.getDeviceMap();
        } else {
          tempDeviceMap = new HashMap<DSID, Device>();
        }

        List<Device> currentDeviceList =
            digitalSTROMClient.getApartmentDevices(connMan.getSessionToken(), false);

        // update the current total power consumption
        if (totalPowerConsumptionListener != null
            && nextSensorUpdate <= System.currentTimeMillis()) {
          meters = digitalSTROMClient.getMeterList(connMan.getSessionToken());
          totalPowerConsumptionListener.onTotalPowerConsumptionChanged(getTotalPowerConsumption());
          totalPowerConsumptionListener.onEnergyMeterValueChanged(getTotalEnergyMeterValue());
          nextSensorUpdate = System.currentTimeMillis() + config.getTotalPowerUpdateInterval();
        }

        while (!currentDeviceList.isEmpty()) {
          Device currentDevice = currentDeviceList.remove(0);
          DSID currentDeviceDSID = currentDevice.getDSID();
          Device eshDevice = tempDeviceMap.remove(currentDeviceDSID);

          if (eshDevice != null) {
            checkDeviceConfig(currentDevice, eshDevice);

            if (eshDevice.isPresent()) {
              // check device state updates
              while (!eshDevice.isDeviceUpToDate()) {
                DeviceStateUpdate deviceStateUpdate = eshDevice.getNextDeviceUpdateState();
                if (deviceStateUpdate != null) {
                  switch (deviceStateUpdate.getType()) {
                    case DeviceStateUpdate.UPDATE_BRIGHTNESS:
                    case DeviceStateUpdate.UPDATE_SLAT_ANGLE_INCREASE:
                    case DeviceStateUpdate.UPDATE_SLAT_ANGLE_DECREASE:
                      filterCommand(deviceStateUpdate, eshDevice);
                      break;
                    case DeviceStateUpdate.UPDATE_SCENE_CONFIG:
                    case DeviceStateUpdate.UPDATE_SCENE_OUTPUT:
                      updateSceneData(eshDevice, deviceStateUpdate);
                      break;
                    case DeviceStateUpdate.UPDATE_OUTPUT_VALUE:
                      readOutputValue(eshDevice);
                      break;
                    default:
                      sendComandsToDSS(eshDevice, deviceStateUpdate);
                  }
                }
              }
            }

          } else {
            logger.debug("Found new device!");
            if (trashDevices.isEmpty()) {
              currentDevice.setConfig(config);
              strucMan.addDeviceToStructure(currentDevice);
              logger.debug(
                  "trashDevices are empty, add Device with dSID "
                      + currentDevice.getDSID().toString()
                      + " to the deviceMap!");
            } else {
              logger.debug("Search device in trashDevices.");
              TrashDevice foundTrashDevice = null;
              for (TrashDevice trashDevice : trashDevices) {
                if (trashDevice != null) {
                  if (trashDevice.getDevice().equals(currentDevice)) {
                    foundTrashDevice = trashDevice;
                    logger.debug(
                        "Found device in trashDevices, add TrashDevice with dSID {} to the StructureManager!",
                        currentDeviceDSID);
                  }
                }
              }
              if (foundTrashDevice != null) {
                trashDevices.remove(foundTrashDevice);
                strucMan.addDeviceToStructure(foundTrashDevice.getDevice());
              } else {
                strucMan.addDeviceToStructure(currentDevice);
                logger.debug(
                    "Can't find device in trashDevices, add Device with dSID: {} to the StructureManager!",
                    currentDeviceDSID);
              }
            }
            if (deviceDiscovery != null) {
              if (currentDevice.isDeviceWithOutput()) {
                deviceDiscovery.onDeviceAdded(currentDevice);
                logger.debug(
                    "inform DeviceStatusListener: {} about removed device with dSID {}",
                    DeviceStatusListener.DEVICE_DISCOVERY,
                    currentDevice.getDSID().getValue());
              }
            } else {
              logger.debug(
                  "The device discovery is not registrated, can't inform device discovery about found device.");
            }
          }
        }

        if (!devicesLoaded && strucMan.getDeviceMap() != null) {
          if (!strucMan.getDeviceMap().values().isEmpty()) {
            logger.debug("Devices loaded");
            devicesLoaded = true;
            stateChanged(ManagerStates.RUNNING);
          }
        }

        if (!sceneMan.scenesGenerated()
            && !sceneMan.getManagerState().equals(ManagerStates.GENERATING_SCENES)) {
          logger.debug(sceneMan.getManagerState().toString());
          sceneMan.generateScenes();
        }

        for (Device device : tempDeviceMap.values()) {
          logger.debug("Found removed devices.");

          trashDevices.add(new TrashDevice(device));
          DeviceStatusListener listener = device.unregisterDeviceStateListener();
          if (listener != null) {
            listener.onDeviceRemoved(null);
          }
          strucMan.deleteDevice(device);
          logger.debug("Add device with dSID {} to trashDevices", device.getDSID().getValue());

          if (deviceDiscovery != null) {
            deviceDiscovery.onDeviceRemoved(device);
            logger.debug(
                "inform DeviceStatusListener: {} about removed device with dSID {}",
                DeviceStatusListener.DEVICE_DISCOVERY,
                device.getDSID().getValue());
          } else {
            logger.debug(
                "The device-Discovery is not registrated, can't inform device discovery about removed device.");
          }
        }

        if (!trashDevices.isEmpty()
            && (lastBinCheck + config.getBinCheckTime() < System.currentTimeMillis())) {
          for (TrashDevice trashDevice : trashDevices) {
            if (trashDevice.isTimeToDelete(Calendar.getInstance().get(Calendar.DAY_OF_YEAR))) {
              logger.debug("Found trashDevice that have to delete!");
              trashDevices.remove(trashDevice);
              logger.debug("Delete trashDevice: " + trashDevice.getDevice().getDSID().getValue());
            }
          }
          lastBinCheck = System.currentTimeMillis();
        }
      }
    }