package de.ph87.homeautomation.property; import de.ph87.homeautomation.channel.ChannelChangedEvent; import de.ph87.homeautomation.channel.ChannelService; import de.ph87.homeautomation.web.WebSocketService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.event.TransactionPhase; import org.springframework.transaction.event.TransactionalEventListener; import java.util.function.BiConsumer; @Slf4j @Service @Transactional @RequiredArgsConstructor public class PropertyWriteService { private static final String NAME_PREFIX = "NEU "; private final PropertyReadService propertyReadService; private final ChannelService channelService; private final PropertyMapper propertyMapper; private final WebSocketService webSocketService; private final PropertyRepository propertyRepository; public void write(final String name, final double value) { write(propertyReadService.getByName(name), value); } public void write(final Property property, final double value) { channelService.write(property, value); } @TransactionalEventListener(phase = TransactionPhase.BEFORE_COMMIT) public void channelChangedEventListener(final ChannelChangedEvent event) { propertyReadService.findAllByReadChannel_Id(event.getChannelId()) .forEach(property -> { property.setValue(property.getReadChannel().getValue()); property.setTimestamp(property.getReadChannel().getValueTimestamp()); log.debug("Updated Property from Channel: {}", property); webSocketService.send(propertyMapper.toDto(property), true); } ); } public PropertyDto create() { final Property entry = new Property(); entry.setTitle(generateUnusedName()); return propertyMapper.toDto(propertyRepository.save(entry)); } private String generateUnusedName() { int index = 0; String name = null; while (name == null || propertyRepository.existsByName(name)) { name = PropertyWriteService.NAME_PREFIX + ++index; } return name; } public PropertyDto set(final long id, final BiConsumer setter, final T value) { final Property property = propertyReadService.getById(id); setter.accept(property, value); return propertyMapper.toDto(property); } public void delete(final long id) { propertyRepository.deleteById(id); } }