package de.ph87.homeautomation.knx.group; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import tuwien.auto.calimero.GroupAddress; import tuwien.auto.calimero.KNXException; import tuwien.auto.calimero.KNXFormatException; import tuwien.auto.calimero.dptxlator.DPTXlator; import tuwien.auto.calimero.dptxlator.DPTXlator8BitUnsigned; import tuwien.auto.calimero.dptxlator.DPTXlatorBoolean; import tuwien.auto.calimero.dptxlator.TranslatorTypes; import java.time.ZonedDateTime; import java.util.Objects; import java.util.Optional; @Slf4j @Service @Transactional(propagation = Propagation.REQUIRES_NEW) @RequiredArgsConstructor public class KnxGroupWriteService { private final KnxGroupRepository knxGroupRepository; public void updateIfExists(final int rawAddress, final byte[] data) { final Optional knxGroupOptional = knxGroupRepository.findByAddressRaw(rawAddress); if (knxGroupOptional.isEmpty()) { log.debug("No KnxGroup with address={}", new GroupAddress(rawAddress)); } knxGroupOptional.ifPresent(knxGroup -> { knxGroup.setValue(data); knxGroup.setValueTimestamp(ZonedDateTime.now()); knxGroup.setBooleanValue(null); knxGroup.setNumberValue(null); try { final DPTXlator translator = findTranslator(knxGroup); translator.setData(data); if (translator instanceof DPTXlatorBoolean) { knxGroup.setBooleanValue(((DPTXlatorBoolean) translator).getValueBoolean()); } // TODO implement all DPTXlator... } catch (NoTranslatorException e) { log.error(e.getMessage()); } log.debug("KnxGroup updated: {}", knxGroup); }); } public void markAllForRead() { knxGroupRepository.findAllByRead_AbleTrue().forEach(knxGroup -> knxGroup.getRead().setNextTimestamp(ZonedDateTime.now())); } public void create(final String name, final GroupAddress address, final String dpt, final boolean readable) { final KnxGroup trans = new KnxGroup(); trans.setAddress(address); trans.setDpt(dpt); trans.setName(name); trans.getRead().setAble(readable); knxGroupRepository.save(trans); } public boolean setSendValue(final GroupAddress groupAddress, final String value) throws KnxGroupFormatException { final Optional knxGroupOptional = knxGroupRepository.findByAddressRaw(groupAddress.getRawAddress()); if (knxGroupOptional.isEmpty()) { return false; } final KnxGroup knxGroup = knxGroupOptional.get(); try { final DPTXlator translator = findTranslator(knxGroup); if (translator instanceof DPTXlatorBoolean) { final boolean isTrue = Objects.equals(value, "true"); final boolean isFalse = Objects.equals(value, "false"); if (!isTrue && !isFalse) { throw new KnxGroupFormatException(knxGroup, value, "Must be \"true\" or \"false\"."); } ((DPTXlatorBoolean) translator).setValue(isTrue); } else if (translator instanceof DPTXlator8BitUnsigned) { ((DPTXlator8BitUnsigned) translator).setValue(Integer.parseInt(value)); } else { // TODO implement all DPTXlator... translator.setValue(value); } knxGroup.setSendValue(translator.getData()); knxGroup.getSend().setNextTimestamp(ZonedDateTime.now()); return true; } catch (NoTranslatorException | KNXFormatException e) { throw new KnxGroupFormatException(knxGroup, value, e.getMessage()); } } private DPTXlator findTranslator(final KnxGroup knxGroup) throws NoTranslatorException { if (knxGroup.getDpt() == null) { throw new NoTranslatorException("Missing DPT"); } final int mainNumber = Integer.parseInt(knxGroup.getDpt().split("\\.")[0]); try { return TranslatorTypes.createTranslator(mainNumber, knxGroup.getDpt()); } catch (KNXException e) { throw new NoTranslatorException(e); } } }