101 lines
3.3 KiB
Java
101 lines
3.3 KiB
Java
package de.ph87.home.device;
|
|
|
|
import de.ph87.home.area.Area;
|
|
import de.ph87.home.area.AreaService;
|
|
import de.ph87.home.common.crud.CrudAction;
|
|
import de.ph87.home.common.crud.EntityNotFound;
|
|
import de.ph87.home.property.*;
|
|
import jakarta.annotation.Nullable;
|
|
import lombok.NonNull;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.context.ApplicationEventPublisher;
|
|
import org.springframework.context.event.EventListener;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
@Slf4j
|
|
@Service
|
|
@Transactional
|
|
@RequiredArgsConstructor
|
|
public class DeviceService {
|
|
|
|
private final PropertyService propertyService;
|
|
|
|
private final DeviceRepository deviceRepository;
|
|
|
|
private final ApplicationEventPublisher applicationEventPublisher;
|
|
|
|
private final AreaService areaService;
|
|
|
|
@NonNull
|
|
public DeviceDto create(@NonNull final String areaUuid, @NonNull final String name, @NonNull final String slug, @NonNull final String stateProperty) {
|
|
final Area area = areaService.getByUuid(areaUuid);
|
|
return publish(deviceRepository.save(new Device(area, name, slug, stateProperty)), CrudAction.UPDATED);
|
|
}
|
|
|
|
public void setState(@NonNull final String uuidOrSlug, final boolean state) throws PropertyNotFound, PropertyNotWritable, PropertyTypeMismatch {
|
|
log.debug("setState: uuidOrSlug={}, state={}", uuidOrSlug, state);
|
|
final Device device = getByUuidOrSlug(uuidOrSlug);
|
|
propertyService.write(device.getStatePropertyId(), state, Boolean.class);
|
|
}
|
|
|
|
@NonNull
|
|
public DeviceDto getByUuidOrSlugDto(final @NonNull String uuidOrSlug) {
|
|
return toDto(getByUuidOrSlug(uuidOrSlug));
|
|
}
|
|
|
|
@NonNull
|
|
private Device getByUuidOrSlug(@NonNull final String uuidOrSlug) {
|
|
return deviceRepository.findByUuidOrSlug(uuidOrSlug, uuidOrSlug).orElseThrow(() -> new EntityNotFound("uuidOrSlug", uuidOrSlug));
|
|
}
|
|
|
|
@NonNull
|
|
public DeviceDto toDto(@NonNull final Device device) {
|
|
final PropertyDto<Boolean> state = propertyService.dtoByIdAndTypeOrNull(device.getStatePropertyId(), Boolean.class);
|
|
return new DeviceDto(device, state);
|
|
}
|
|
|
|
@NonNull
|
|
private Device getByUuid(@NonNull final String uuid) {
|
|
return deviceRepository.findById(uuid).orElseThrow(() -> new EntityNotFound("uuid", uuid));
|
|
}
|
|
|
|
@NonNull
|
|
public List<DeviceDto> list(@Nullable final DeviceFilter filter) throws PropertyTypeMismatch {
|
|
final List<DeviceDto> all = deviceRepository.findAll().stream().map(this::toDto).toList();
|
|
if (filter == null) {
|
|
return all;
|
|
}
|
|
final List<DeviceDto> results = new ArrayList<>();
|
|
for (final DeviceDto dto : all) {
|
|
if (filter.filter(dto)) {
|
|
results.add(dto);
|
|
}
|
|
}
|
|
return results;
|
|
}
|
|
|
|
@EventListener(PropertyDto.class)
|
|
public void onPropertyChange(@NonNull final PropertyDto<?> dto) {
|
|
deviceRepository.findAllByStatePropertyId(dto.getId()).forEach(device -> publish(device, CrudAction.CREATED));
|
|
}
|
|
|
|
@NonNull
|
|
private DeviceDto publish(@NonNull final Device device, @NonNull final CrudAction action) {
|
|
final DeviceDto dto = toDto(device);
|
|
log.info("Device {}: {}", action, dto);
|
|
applicationEventPublisher.publishEvent(dto);
|
|
return dto;
|
|
}
|
|
|
|
@NonNull
|
|
public DeviceDto getByUuidDto(@NonNull final String uuid) {
|
|
return toDto(getByUuid(uuid));
|
|
}
|
|
|
|
}
|