#3 FIX Property- & Device updates

+ Devices in Property::usages
+ code clean
This commit is contained in:
Patrick Haßel 2022-10-26 21:04:13 +02:00
parent 818145e38b
commit 0b146b5972
26 changed files with 202 additions and 114 deletions

View File

@ -1,4 +1,4 @@
import {validateDateAllowNull, validateListOrEmpty, validateNumberAllowNull, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
import {validateListOrEmpty, validateNumberNotNull, validateStringNotEmptyNotNull} from "../validators";
import {Channel} from "../channel/Channel";
import {SearchResult} from "../SearchResult";
@ -8,8 +8,6 @@ export class Property {
public id: number,
public type: string,
public title: string,
public value: number | null,
public timestamp: Date | null,
public readChannel: Channel | null,
public writeChannel: Channel | null,
public usages: SearchResult[],
@ -29,8 +27,6 @@ export class Property {
validateNumberNotNull(json['id']),
validateStringNotEmptyNotNull(json['type']),
validateStringNotEmptyNotNull(json['title']),
validateNumberAllowNull(json['value']),
validateDateAllowNull(json['timestamp']),
Channel.fromJsonAllowNull(json['readChannel']),
Channel.fromJsonAllowNull(json['writeChannel']),
validateListOrEmpty(json['usages'], SearchResult.fromJson),

View File

@ -74,7 +74,7 @@ export class DeviceListComponent implements OnInit {
}
getSwitchClassList(device: Device): object {
const value: number | null | undefined = (device as DeviceSwitch).stateProperty?.value;
const value: number | null | undefined = (device as DeviceSwitch).stateProperty?.readChannel?.value;
return {
switchOn: value === 1,
switchOff: value === 0,
@ -87,7 +87,7 @@ export class DeviceListComponent implements OnInit {
}
getShutterClassList(device: Device): object {
const value: number | null | undefined = (device as DeviceShutter).positionProperty?.value;
const value: number | null | undefined = (device as DeviceShutter).positionProperty?.readChannel?.value;
return {
shutterOpen: value === 0,
shutterBetween: value !== null && value !== undefined && value > 0 && value < 100,

View File

@ -36,29 +36,29 @@
</select>
</td>
<ng-container *ngIf="property.value !== null else empty">
<td *ngIf="property.type === 'BOOLEAN'" class="boolean" [class.true]="property.value" [class.false]="!property.value" (click)="edit(property, 'value', property.value > 0 ? 0 : 1)">
{{property.value ? "An" : "Aus"}}
<ng-container *ngIf="property.readChannel?.value !== null else empty">
<td *ngIf="property.type === 'BOOLEAN'" class="boolean" [class.true]="property.readChannel?.value" [class.false]="!property.readChannel?.value" (click)="edit(property, 'value', property.readChannel?.value > 0 ? 0 : 1)">
{{property.readChannel?.value ? "An" : "Aus"}}
</td>
<td *ngIf="property.type === 'SHUTTER'" class="number" [class.true]="property.value === 0" [class.false]="property.value === 100" [class.tristate]="0 < property.value && property.value < 100">
{{property.value}} %
<td *ngIf="property.type === 'SHUTTER'" class="number" [class.true]="property.readChannel?.value === 0" [class.false]="property.readChannel?.value === 100" [class.tristate]="0 < property.readChannel?.value && property.readChannel?.value < 100">
{{property.readChannel?.value}} %
</td>
<td *ngIf="property.type === 'BRIGHTNESS_PERCENT'" class="number">
{{property.value}} %
{{property.readChannel?.value}} %
</td>
<td *ngIf="property.type === 'COLOR_TEMPERATURE'" class="number">
{{property.value}} K
{{property.readChannel?.value}} K
</td>
<td *ngIf="property.type === 'LUX'" class="number">
{{property.value | number:'0.0-0'}} lux
{{property.readChannel?.value | number:'0.0-0'}} lux
</td>
<td *ngIf="property.type === 'SCENE'">
{{findScene(property)?.title || "Unbekannt: " + property.value}}
{{findScene(property)?.title || "Unbekannt: " + property.readChannel?.value}}
</td>
</ng-container>
<td *ngIf="property.timestamp !== null else empty">
{{property.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}
<td *ngIf="property.readChannel?.timestamp !== null else empty">
{{property.readChannel?.timestamp | date:'yyyy-MM-dd HH:mm:ss'}}
</td>
<td class="full">

View File

@ -72,7 +72,7 @@ export class PropertyListComponent implements OnInit {
}
findScene(property: Property): Scene | undefined {
return this.scenes.find(s => s.id === property.value);
return this.scenes.find(s => s.id === property.readChannel?.value);
}
set(property: Property, key: string, value: any): void {

View File

@ -1,7 +1,7 @@
package de.ph87.homeautomation;
import de.ph87.homeautomation.knx.group.KnxGroupImportService;
import de.ph87.homeautomation.property.PropertyWriteService;
import de.ph87.homeautomation.property.PropertyWriter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.event.ApplicationStartedEvent;
@ -17,13 +17,13 @@ public class StartupService {
private final DemoDataService demoDataService;
private final PropertyWriteService propertyWriteService;
private final PropertyWriter propertyWriter;
@EventListener(ApplicationStartedEvent.class)
public void startup() {
knxGroupImportService.importGroups();
demoDataService.insertDemoData();
propertyWriteService.updateAllProperties();
propertyWriter.updateAllProperties();
}
}

View File

@ -1,6 +1,6 @@
package de.ph87.homeautomation.bulk;
import de.ph87.homeautomation.property.PropertyWriteService;
import de.ph87.homeautomation.property.PropertyWriter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -12,7 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor
public class BulkExecutor {
private final PropertyWriteService propertyWriteService;
private final PropertyWriter propertyWriter;
public void execute(final Bulk bulk) {
if (!bulk.isEnabled()) {
@ -20,7 +20,7 @@ public class BulkExecutor {
return;
}
log.info("Executing Bulk: {}", bulk);
bulk.getEntries().forEach(entry -> propertyWriteService.writeToChannel(entry.getProperty(), entry.getValue()));
bulk.getEntries().forEach(entry -> propertyWriter.writeToChannel(entry.getProperty(), entry.getValue()));
log.debug("Finished executing Bulk: {}", bulk);
}

View File

@ -13,23 +13,23 @@ import java.util.List;
@RequiredArgsConstructor
public class ChannelController implements ISearchController {
private final ChannelService channelService;
private final ChannelReader channelReader;
@GetMapping("findAll")
public List<? extends ChannelDto> findAll() {
return channelService.findAllDto();
return channelReader.findAllDto();
}
@Override
@GetMapping("searchById/{id}")
public SearchResult searchById(@PathVariable final long id) {
return channelService.findDtoById(id).map(this::toSearchResult).orElseThrow(() -> new NotFoundException("Channel.id=" + id));
return channelReader.findDtoById(id).map(this::toSearchResult).orElseThrow(() -> new NotFoundException("Channel.id=" + id));
}
@Override
@PostMapping("searchLike")
public List<SearchResult> searchLike(@RequestBody final String term) {
return channelService.findAllDtoLike(term).stream().map(this::toSearchResult).toList();
return channelReader.findAllDtoLike(term).stream().map(this::toSearchResult).toList();
}
private SearchResult toSearchResult(final ChannelDto dto) {

View File

@ -15,7 +15,7 @@ import java.util.Optional;
@Service
@Transactional
@RequiredArgsConstructor
public class ChannelService {
public class ChannelReader {
private final List<IChannelOwner> channelOwners;
@ -29,12 +29,12 @@ public class ChannelService {
return findByChannel(channel).orElseThrow(RuntimeException::new);
}
public void write(final Property property, final double value) {
final Channel channel = property.getWriteChannel();
public Double read(final Property property) {
final Channel channel = property.getReadChannel();
if (channel == null) {
return;
return null;
}
getByChannel(channel).write(property.getWriteChannel().getId(), value);
return getByChannel(channel).read(property.getReadChannel().getId());
}
public ChannelDto toDtoAllowNull(final Channel channel) {

View File

@ -0,0 +1,36 @@
package de.ph87.homeautomation.channel;
import de.ph87.homeautomation.property.Property;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class ChannelWriter {
private final List<IChannelOwner> channelOwners;
public Optional<IChannelOwner> findByChannel(final Channel channel) {
return channelOwners.stream().filter(owner -> channel.getChannelOwnerClass().isInstance(owner)).findFirst();
}
public IChannelOwner getByChannel(final Channel channel) {
return findByChannel(channel).orElseThrow(RuntimeException::new);
}
public void write(final Property property, final double value) {
final Channel channel = property.getWriteChannel();
if (channel == null) {
return;
}
getByChannel(channel).write(property.getWriteChannel().getId(), value);
}
}

View File

@ -6,6 +6,8 @@ public interface IChannelOwner {
void requestUpdate(final Channel channel);
Double read(final long id);
void write(final long id, final double value);
ChannelDto toDto(final long id);

View File

@ -15,60 +15,60 @@ import static de.ph87.homeautomation.shared.Helpers.mapOrNull;
@RequiredArgsConstructor
public class DeviceController {
private final DeviceReadService deviceReadService;
private final DeviceReader deviceReader;
private final DeviceWriteService deviceWriteService;
private final DeviceWriter deviceWriter;
private final PropertyReader propertyReader;
@GetMapping("findAll")
public List<DeviceDto> findAll() {
return deviceReadService.findAll();
return deviceReader.findAll();
}
@GetMapping("searchById/{id}")
public DeviceDto getById(@PathVariable final long id) {
return deviceReadService.getDtoById(id);
return deviceReader.getDtoById(id);
}
@PostMapping("create")
public DeviceDto create(@RequestBody final String typeString) {
return deviceWriteService.create(typeString);
return deviceWriter.create(typeString);
}
@GetMapping("delete/{id}")
public void delete(@PathVariable final long id) {
deviceWriteService.delete(id);
deviceWriter.delete(id);
}
@PostMapping("set/{id}/enabled")
public DeviceDto setEnabled(@PathVariable final long id, @RequestBody final boolean enabled) {
return deviceWriteService.set(id, Device::setEnabled, enabled);
return deviceWriter.set(id, Device::setEnabled, enabled);
}
@PostMapping("set/{id}/title")
public DeviceDto setName(@PathVariable final long id, @RequestBody final String title) {
return deviceWriteService.set(id, Device::setTitle, title);
return deviceWriter.set(id, Device::setTitle, title);
}
@PostMapping("set/{id}/DeviceSwitch/stateProperty")
public DeviceDto setDeviceSwitchStateProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
return deviceWriteService.setDeviceSwitch(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReader::getById)), propertyId);
return deviceWriter.setDeviceSwitch(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReader::getById)), propertyId);
}
@PostMapping("set/{id}/DeviceStateScene/stateProperty")
public DeviceDto setDeviceStateSceneStateProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReader::getById)), propertyId);
return deviceWriter.setDeviceStateScene(id, (device, v) -> device.setStateProperty(mapOrNull(v, propertyReader::getById)), propertyId);
}
@PostMapping("set/{id}/DeviceStateScene/sceneProperty")
public DeviceDto setDeviceStateSceneSceneProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
return deviceWriteService.setDeviceStateScene(id, (device, v) -> device.setSceneProperty(mapOrNull(v, propertyReader::getById)), propertyId);
return deviceWriter.setDeviceStateScene(id, (device, v) -> device.setSceneProperty(mapOrNull(v, propertyReader::getById)), propertyId);
}
@PostMapping("set/{id}/DeviceShutter/positionProperty")
public DeviceDto setDeviceShutterPositionProperty(@PathVariable final long id, @RequestBody(required = false) final Long propertyId) {
return deviceWriteService.setDeviceShutter(id, (device, v) -> device.setPositionProperty(mapOrNull(v, propertyReader::getById)), propertyId);
return deviceWriter.setDeviceShutter(id, (device, v) -> device.setPositionProperty(mapOrNull(v, propertyReader::getById)), propertyId);
}
}

View File

@ -16,7 +16,7 @@ import static de.ph87.homeautomation.shared.Helpers.mapOrNull;
@Service
@Transactional
@RequiredArgsConstructor
public class DeviceReadService {
public class DeviceReader {
private final DeviceRepository deviceRepository;
@ -27,14 +27,11 @@ public class DeviceReadService {
}
public DeviceDto toDto(final Device device) {
if (device instanceof DeviceSwitch) {
final DeviceSwitch deviceSwitch = (DeviceSwitch) device;
if (device instanceof final DeviceSwitch deviceSwitch) {
return new DeviceSwitchDto(deviceSwitch, mapOrNull(deviceSwitch.getStateProperty(), propertyMapper::toDto));
} else if (device instanceof DeviceStateScene) {
final DeviceStateScene deviceStateScene = (DeviceStateScene) device;
} else if (device instanceof final DeviceStateScene deviceStateScene) {
return new DeviceStateSceneDto(deviceStateScene, mapOrNull(deviceStateScene.getStateProperty(), propertyMapper::toDto), mapOrNull(deviceStateScene.getSceneProperty(), propertyMapper::toDto));
} else if (device instanceof DeviceShutter) {
final DeviceShutter deviceShutter = (DeviceShutter) device;
} else if (device instanceof final DeviceShutter deviceShutter) {
return new DeviceShutterDto(deviceShutter, mapOrNull(deviceShutter.getPositionProperty(), propertyMapper::toDto));
}
throw new RuntimeException();

View File

@ -0,0 +1,13 @@
package de.ph87.homeautomation.device;
import de.ph87.homeautomation.device.devices.DeviceShutter;
import de.ph87.homeautomation.property.Property;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface DeviceShutterRepository extends JpaRepository<DeviceShutter, Long> {
List<DeviceShutter> findDistinctByPositionProperty(Property property);
}

View File

@ -0,0 +1,13 @@
package de.ph87.homeautomation.device;
import de.ph87.homeautomation.device.devices.DeviceStateScene;
import de.ph87.homeautomation.property.Property;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface DeviceStateSceneRepository extends JpaRepository<DeviceStateScene, Long> {
List<DeviceStateScene> findDistinctByStatePropertyOrSceneProperty(Property state, Property scene);
}

View File

@ -0,0 +1,13 @@
package de.ph87.homeautomation.device;
import de.ph87.homeautomation.device.devices.DeviceSwitch;
import de.ph87.homeautomation.property.Property;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface DeviceSwitchRepository extends JpaRepository<DeviceSwitch, Long> {
List<DeviceSwitch> findDistinctByStateProperty(Property property);
}

View File

@ -2,6 +2,7 @@ package de.ph87.homeautomation.device;
import de.ph87.homeautomation.device.devices.*;
import de.ph87.homeautomation.property.Property;
import de.ph87.homeautomation.property.PropertyDto;
import de.ph87.homeautomation.scene.SceneDto;
import de.ph87.homeautomation.schedule.ScheduleWriter;
import de.ph87.homeautomation.web.BadRequestException;
@ -10,22 +11,32 @@ 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.Arrays;
import java.util.function.BiConsumer;
import static de.ph87.homeautomation.shared.Helpers.getCurrentTransactionName;
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class DeviceWriteService {
public class DeviceWriter {
private final DeviceRepository deviceRepository;
private final DeviceReadService deviceReadService;
private final DeviceReader deviceReader;
private final WebSocketService webSocketService;
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMPLETION)
public void onPropertyChanged(final PropertyDto dto) {
log.debug("Listen [{}]: {}", getCurrentTransactionName(), dto.getTitle());
// TODO
}
public DeviceDto createDeviceSwitch(final Property stateProperty) {
return createDeviceSwitch(null, stateProperty);
}
@ -65,13 +76,13 @@ public class DeviceWriteService {
}
public <T> DeviceDto set(final long id, final BiConsumer<Device, T> setter, final T value) {
final Device device = deviceReadService.getById(id);
final Device device = deviceReader.getById(id);
setter.accept(device, value);
return publish(device, true);
}
public <T> DeviceDto setDeviceSwitch(final long id, final BiConsumer<DeviceSwitch, T> setter, final T value) {
final Device device = deviceReadService.getById(id);
final Device device = deviceReader.getById(id);
if (!(device instanceof DeviceSwitch)) {
throw new BadRequestException("Not a DeviceSwitch: %s", device);
}
@ -80,7 +91,7 @@ public class DeviceWriteService {
}
public <T> DeviceDto setDeviceStateScene(final long id, final BiConsumer<DeviceStateScene, T> setter, final T value) {
final Device device = deviceReadService.getById(id);
final Device device = deviceReader.getById(id);
if (!(device instanceof DeviceStateScene)) {
throw new BadRequestException("Not a DeviceStateScene: %s", device);
}
@ -89,7 +100,7 @@ public class DeviceWriteService {
}
public <T> DeviceDto setDeviceShutter(final long id, final BiConsumer<DeviceShutter, T> setter, final T value) {
final Device device = deviceReadService.getById(id);
final Device device = deviceReader.getById(id);
if (!(device instanceof DeviceShutter)) {
throw new BadRequestException("Not a DeviceShutter: %s", device);
}
@ -98,7 +109,7 @@ public class DeviceWriteService {
}
public void delete(final long id) {
final Device device = deviceReadService.getById(id);
final Device device = deviceReader.getById(id);
deviceRepository.delete(device);
publish(device, false);
}
@ -118,7 +129,7 @@ public class DeviceWriteService {
}
private DeviceDto publish(final Device device, final boolean existing) {
return publish(deviceReadService.toDto(device), existing);
return publish(deviceReader.toDto(device), existing);
}
private DeviceDto publish(final DeviceDto dto, final boolean existing) {

View File

@ -1,7 +1,7 @@
package de.ph87.homeautomation.knx;
import de.ph87.homeautomation.knx.group.KnxGroupLinkService;
import de.ph87.homeautomation.knx.group.KnxGroupWriteService;
import de.ph87.homeautomation.knx.group.KnxGroupWriter;
import de.ph87.homeautomation.knx.group.KnxThreadWakeUpEvent;
import de.ph87.homeautomation.knx.router.Router;
import de.ph87.homeautomation.shared.AbstractThreadService;
@ -33,7 +33,7 @@ public class KnxThreadService extends AbstractThreadService implements NetworkLi
public static final Duration RESPONSE_TIMEOUT = Duration.ofMillis(500);
private final KnxGroupWriteService knxGroupWriteService;
private final KnxGroupWriter knxGroupWriter;
private final KnxGroupLinkService knxGroupLinkService;
@ -135,14 +135,14 @@ public class KnxThreadService extends AbstractThreadService implements NetworkLi
@Override
public void groupReadResponse(final ProcessEvent processEvent) {
synchronized (databaseAccessLock) {
knxGroupWriteService.setReceivedData(processEvent.getDestination(), processEvent.getASDU(), processEvent.getSourceAddr());
knxGroupWriter.setReceivedData(processEvent.getDestination(), processEvent.getASDU(), processEvent.getSourceAddr());
}
}
@Override
public void groupWrite(final ProcessEvent processEvent) {
synchronized (databaseAccessLock) {
knxGroupWriteService.setReceivedData(processEvent.getDestination(), processEvent.getASDU(), processEvent.getSourceAddr());
knxGroupWriter.setReceivedData(processEvent.getDestination(), processEvent.getASDU(), processEvent.getSourceAddr());
}
}

View File

@ -15,23 +15,28 @@ import java.util.List;
@RequiredArgsConstructor
public class KnxGroupChannelOwnerService implements IChannelOwner {
private final KnxGroupWriteService knxGroupWriteService;
private final KnxGroupWriter knxGroupWriter;
private final KnxGroupReadService knxGroupReadService;
private final KnxGroupReader knxGroupReader;
@Override
public void requestUpdate(final Channel channel) {
knxGroupWriteService.requestRead((KnxGroup) channel);
knxGroupWriter.requestRead((KnxGroup) channel);
}
@Override
public Double read(final long id) {
return knxGroupReader.getById(id).getValue();
}
@Override
public void write(final long id, final double value) {
knxGroupWriteService.requestWrite(knxGroupReadService.getById(id), value);
knxGroupWriter.requestWrite(knxGroupReader.getById(id), value);
}
@Override
public KnxGroupDto toDto(final long id) {
return toDto(knxGroupReadService.getById(id));
return toDto(knxGroupReader.getById(id));
}
public KnxGroupDto toDto(final KnxGroup knxGroup) {
@ -40,12 +45,12 @@ public class KnxGroupChannelOwnerService implements IChannelOwner {
@Override
public List<KnxGroupDto> findAllDto() {
return knxGroupReadService.findAll().stream().map(this::toDto).toList();
return knxGroupReader.findAll().stream().map(this::toDto).toList();
}
@Override
public List<KnxGroupDto> findAllDtoLikeIgnoreCase(final String like) {
return knxGroupReadService.findAllLike(like).stream().map(this::toDto).toList();
return knxGroupReader.findAllLike(like).stream().map(this::toDto).toList();
}
}

View File

@ -13,7 +13,7 @@ import java.util.Optional;
@Service
@Transactional
@RequiredArgsConstructor
public class KnxGroupReadService {
public class KnxGroupReader {
private final KnxGroupRepository knxGroupRepository;

View File

@ -21,7 +21,7 @@ import java.util.function.Function;
@Service
@Transactional
@RequiredArgsConstructor
public class KnxGroupWriteService {
public class KnxGroupWriter {
private final KnxGroupRepository knxGroupRepository;
@ -43,7 +43,7 @@ public class KnxGroupWriteService {
if (translator instanceof DPTXlatorBoolean) {
((DPTXlatorBoolean) translator).setValue(value == 1.0);
} else if (translator instanceof DPTXlator8BitUnsigned) {
((DPTXlator8BitUnsigned) translator).setValue((int) value);
translator.setValue((int) value);
} else if (translator instanceof DPTXlatorSceneNumber) {
((DPTXlatorSceneNumber) translator).setValue((int) value - 1);
} else { // TODO implement all DPTXlator...

View File

@ -4,7 +4,6 @@ import de.ph87.homeautomation.channel.Channel;
import lombok.*;
import javax.persistence.*;
import java.time.ZonedDateTime;
@Getter
@Setter
@ -25,11 +24,6 @@ public final class Property {
@Column(nullable = false, unique = true)
private String title;
private ZonedDateTime timestamp;
@Column(name = "value_")
private Double value;
@ManyToOne
private Channel readChannel;

View File

@ -1,6 +1,6 @@
package de.ph87.homeautomation.property;
import de.ph87.homeautomation.channel.ChannelService;
import de.ph87.homeautomation.channel.ChannelReader;
import de.ph87.homeautomation.shared.ISearchController;
import de.ph87.homeautomation.shared.SearchResult;
import lombok.RequiredArgsConstructor;
@ -13,15 +13,15 @@ import java.util.List;
@RequiredArgsConstructor
public class PropertyController implements ISearchController {
private final PropertyWriteService propertyWriteService;
private final PropertyWriter propertyWriter;
private final PropertyReader propertyReader;
private final ChannelService channelService;
private final ChannelReader channelReader;
@GetMapping("create")
public PropertyDto create() {
return propertyWriteService.create();
return propertyWriter.create();
}
@GetMapping("findAll")
@ -31,42 +31,42 @@ public class PropertyController implements ISearchController {
@PostMapping("set/{id}/type")
public PropertyDto setPropertyType(@PathVariable final long id, @RequestBody final String propertyType) {
return propertyWriteService.set(id, Property::setType, PropertyType.valueOf(propertyType));
return propertyWriter.set(id, Property::setType, PropertyType.valueOf(propertyType));
}
@PostMapping("set/{id}/title")
public PropertyDto setPropertyTitle(@PathVariable final long id, @RequestBody final String propertyTitle) {
return propertyWriteService.set(id, Property::setTitle, propertyTitle);
return propertyWriter.set(id, Property::setTitle, propertyTitle);
}
@PostMapping("set/{id}/value")
public PropertyDto setValue(@PathVariable final long id, @RequestBody final double value) {
return propertyWriteService.set(id, propertyWriteService::writeToChannel, value);
return propertyWriter.set(id, propertyWriter::writeToChannel, value);
}
@PostMapping("set/{id}/readChannel")
public PropertyDto setReadChannel(@PathVariable final long id, @RequestBody(required = false) final Long channelId) {
return propertyWriteService.set(id, (p, v) -> p.setReadChannel(channelId == null ? null : channelService.getById(v)), channelId);
return propertyWriter.set(id, (p, v) -> p.setReadChannel(channelId == null ? null : channelReader.getById(v)), channelId);
}
@PostMapping("set/{id}/writeChannel")
public PropertyDto setWriteChannel(@PathVariable final long id, @RequestBody(required = false) final Long channelId) {
return propertyWriteService.set(id, (p, v) -> p.setWriteChannel(channelId == null ? null : channelService.getById(v)), channelId);
return propertyWriter.set(id, (p, v) -> p.setWriteChannel(channelId == null ? null : channelReader.getById(v)), channelId);
}
@DeleteMapping("{id}")
public void delete(@PathVariable final long id) {
propertyWriteService.delete(id);
propertyWriter.delete(id);
}
@PostMapping("toggle/{id}")
public PropertyDto setValue(@PathVariable final long id) {
final boolean oldState = getOldStateBoolean(id, false);
return propertyWriteService.set(id, propertyWriteService::writeToChannel, oldState ? 0.0 : 1.0);
return propertyWriter.set(id, propertyWriter::writeToChannel, oldState ? 0.0 : 1.0);
}
private boolean getOldStateBoolean(final long id, final boolean orElse) {
final Double oldValue = propertyReader.getDtoById(id).getValue();
final Double oldValue = channelReader.read(propertyReader.getById(id));
if (oldValue == null || oldValue.isNaN()) {
return orElse;
}

View File

@ -5,7 +5,6 @@ import de.ph87.homeautomation.shared.SearchResult;
import lombok.Data;
import java.io.Serializable;
import java.time.ZonedDateTime;
import java.util.List;
@Data
@ -17,10 +16,6 @@ public final class PropertyDto implements Serializable {
private final String title;
private final Double value;
private final ZonedDateTime timestamp;
private final ChannelDto readChannel;
private final ChannelDto writeChannel;
@ -31,8 +26,6 @@ public final class PropertyDto implements Serializable {
this.id = property.getId();
this.type = property.getType();
this.title = property.getTitle();
this.value = property.getValue();
this.timestamp = property.getTimestamp();
this.readChannel = readChannel;
this.writeChannel = writeChannel;
this.usages = usages;

View File

@ -2,7 +2,11 @@ package de.ph87.homeautomation.property;
import de.ph87.homeautomation.bulk.Bulk;
import de.ph87.homeautomation.bulk.BulkRepository;
import de.ph87.homeautomation.channel.ChannelService;
import de.ph87.homeautomation.channel.ChannelReader;
import de.ph87.homeautomation.device.DeviceShutterRepository;
import de.ph87.homeautomation.device.DeviceStateSceneRepository;
import de.ph87.homeautomation.device.DeviceSwitchRepository;
import de.ph87.homeautomation.device.devices.Device;
import de.ph87.homeautomation.schedule.Schedule;
import de.ph87.homeautomation.schedule.ScheduleRepository;
import de.ph87.homeautomation.shared.SearchResult;
@ -20,18 +24,24 @@ import java.util.List;
@RequiredArgsConstructor
public class PropertyMapper {
private final ChannelService channelService;
private final ChannelReader channelReader;
private final ScheduleRepository scheduleRepository;
private final BulkRepository bulkRepository;
private final DeviceSwitchRepository deviceSwitchRepository;
private final DeviceShutterRepository deviceShutterRepository;
private final DeviceStateSceneRepository deviceStateSceneRepository;
public PropertyDto toDto(final Property property) {
final List<SearchResult> usages = findUsages(property);
return new PropertyDto(
property,
channelService.toDtoAllowNull(property.getReadChannel()),
channelService.toDtoAllowNull(property.getWriteChannel()),
channelReader.toDtoAllowNull(property.getReadChannel()),
channelReader.toDtoAllowNull(property.getWriteChannel()),
usages
);
}
@ -39,6 +49,9 @@ public class PropertyMapper {
private List<SearchResult> findUsages(final Property property) {
final List<SearchResult> searchResults = new ArrayList<>();
searchResults.addAll(scheduleRepository.findDistinctByEntries_Property(property).stream().map(this::toSearchResult).toList());
searchResults.addAll(deviceSwitchRepository.findDistinctByStateProperty(property).stream().map(this::toSearchResult).toList());
searchResults.addAll(deviceShutterRepository.findDistinctByPositionProperty(property).stream().map(this::toSearchResult).toList());
searchResults.addAll(deviceStateSceneRepository.findDistinctByStatePropertyOrSceneProperty(property, property).stream().map(this::toSearchResult).toList());
searchResults.addAll(bulkRepository.findDistinctByEntries_Property(property).stream().map(this::toSearchResult).toList());
return searchResults;
}
@ -54,6 +67,10 @@ public class PropertyMapper {
return new SearchResult(Schedule.class, schedule.getId(), schedule.getTitle());
}
private SearchResult toSearchResult(final Device device) {
return new SearchResult(Device.class, device.getId(), device.getTitle());
}
private SearchResult toSearchResult(final Bulk bulk) {
return new SearchResult(Bulk.class, bulk.getId(), bulk.getName());
}

View File

@ -1,7 +1,7 @@
package de.ph87.homeautomation.property;
import de.ph87.homeautomation.channel.ChannelDto;
import de.ph87.homeautomation.channel.ChannelService;
import de.ph87.homeautomation.channel.ChannelWriter;
import de.ph87.homeautomation.channel.IChannelOwner;
import de.ph87.homeautomation.web.WebSocketService;
import lombok.RequiredArgsConstructor;
@ -22,13 +22,13 @@ import static de.ph87.homeautomation.shared.Helpers.getCurrentTransactionName;
@Service
@Transactional
@RequiredArgsConstructor
public class PropertyWriteService {
public class PropertyWriter {
private static final String TITLE_PREFIX = "NEU ";
private final PropertyReader propertyReader;
private final ChannelService channelService;
private final ChannelWriter channelWriter;
private final PropertyMapper propertyMapper;
@ -40,7 +40,7 @@ public class PropertyWriteService {
public void updateAllProperties() {
propertyReader.findAllByReadChannelNotNull().forEach(property -> {
final Optional<IChannelOwner> ownerOptional = channelService.findByChannel(property.getReadChannel());
final Optional<IChannelOwner> ownerOptional = channelWriter.findByChannel(property.getReadChannel());
if (ownerOptional.isPresent()) {
ownerOptional.get().requestUpdate(property.getReadChannel());
} else {
@ -55,8 +55,6 @@ public class PropertyWriteService {
final List<Property> properties = propertyReader.findAllByReadChannel_Id(dto.getId());
if (!properties.isEmpty()) {
properties.forEach(property -> {
property.setValue(property.getReadChannel().getValue());
property.setTimestamp(property.getReadChannel().getTimestamp());
log.debug("Updated Property \"{}\" by Channel \"{}\"", property.getTitle(), property.getReadChannel().getName());
publish(property, true);
}
@ -65,7 +63,7 @@ public class PropertyWriteService {
}
public void writeToChannel(final Property property, final double value) {
channelService.write(property, value);
channelWriter.write(property, value);
}
public PropertyDto create() {
@ -79,7 +77,7 @@ public class PropertyWriteService {
int index = 0;
String title = null;
while (title == null || propertyRepository.existsByTitle(title)) {
title = PropertyWriteService.TITLE_PREFIX + ++index;
title = PropertyWriter.TITLE_PREFIX + ++index;
}
return title;
}

View File

@ -1,7 +1,7 @@
package de.ph87.homeautomation.schedule;
import de.ph87.homeautomation.bulk.BulkExecutor;
import de.ph87.homeautomation.property.PropertyWriteService;
import de.ph87.homeautomation.property.PropertyWriter;
import de.ph87.homeautomation.schedule.entry.ScheduleEntry;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -19,7 +19,7 @@ public class ScheduleExecutor {
private final ScheduleReader scheduleReader;
private final PropertyWriteService propertyWriter;
private final PropertyWriter propertyWriter;
private final BulkExecutor bulkExecutor;