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 updateOrCreate(final int rawAddress, final byte[] data) { final KnxGroup knxGroup = getOrCreate(rawAddress); 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); } private KnxGroup getOrCreate(final int rawAddress) { return knxGroupRepository.findByAddressRaw(rawAddress).orElseGet(() -> { final KnxGroup trans = new KnxGroup(); trans.setAddress(rawAddress); final KnxGroup saved = knxGroupRepository.save(trans); log.info("KnxGroup created: {}", saved); return saved; }); } public void markAllForRead() { knxGroupRepository.findAllByRead_AbleTrue().forEach(knxGroup -> knxGroup.getRead().setNextTimestamp(ZonedDateTime.now())); } public void create(final String name, final int main, final int middle, final int sub, final String dpt, final boolean readable) { create(name, new GroupAddress(main, middle, sub), dpt, readable); } 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); } } }