/** * Copyright (c) 2010-2016, openHAB.org and others. * <p> * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.fatekplc.items; import java.math.BigDecimal; import java.util.Calendar; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.openhab.core.items.Item; import org.openhab.core.library.types.DateTimeType; import org.openhab.core.types.State; import org.openhab.model.item.binding.BindingConfigParseException; import org.simplify4u.jfatek.registers.Reg; import org.simplify4u.jfatek.registers.RegValue; import org.simplify4u.jfatek.registers.UnknownRegNameException; /** * DateTime item implementation. * * @author Slawomir Jaranowski * @since 1.9.0 */ public class FatekDateTimeItem extends FatekPLCItem { class WordBits { protected Integer value; protected Reg reg; public WordBits(String regName) throws BindingConfigParseException { if (Character.isDigit(regName.charAt(0))) { value = Integer.parseInt(regName); } else { try { reg = Reg.parse(regName); } catch (UnknownRegNameException e) { throw new BindingConfigParseException(e.getMessage()); } if (reg.is32Bits() || reg.isDiscrete()) { throw new BindingConfigParseException("Please use 16 bit data register for DateTime item"); } } } public void fillRegs(Set<Reg> regs) { if (value == null) { regs.add(reg); } } public int getValue(Map<Reg, RegValue> response) { if (value != null) { return value; } return response.get(reg).intValueUnsigned(); } protected String toStringSuffix() { return ""; } @Override public String toString() { if (value != null) { return value.toString(); } return reg.toString() + toStringSuffix(); } } class WordBitsLB extends WordBits { public WordBitsLB(String regName) throws BindingConfigParseException { super(regName); } @Override public int getValue(Map<Reg, RegValue> response) { if (value != null) { return value; } return response.get(reg).intValueUnsigned() & 0x00ff; } @Override protected String toStringSuffix() { return "L"; } } class WordBitsHB extends WordBits { public WordBitsHB(String regName) throws BindingConfigParseException { super(regName); } @Override public int getValue(Map<Reg, RegValue> response) { if (value != null) { return value; } return (response.get(reg).intValueUnsigned() >> 8) & 0x00ff; } @Override protected String toStringSuffix() { return "H"; } } // registers for data private WordBits year; private WordBits month; private WordBits day; private WordBits hour; private WordBits minute; private WordBits second; private boolean relative; private Reg regSec; private BigDecimal factor; public FatekDateTimeItem(Item item, List<String> confItems) throws BindingConfigParseException { super(item, confItems); String sFactor = getParamsFromConf(confItems, "factor", null); if (sFactor != null) { factor = new BigDecimal(sFactor); } if (confItems.size() == 6) { year = getWordBits(confItems.get(0)); month = getWordBits(confItems.get(1)); day = getWordBits(confItems.get(2)); hour = getWordBits(confItems.get(3)); minute = getWordBits(confItems.get(4)); second = getWordBits(confItems.get(5)); } else if (confItems.size() == 1) { String regNamString = confItems.get(0); if (regNamString.endsWith("R")) { // relative time in second relative = true; regNamString = regNamString.substring(0, regNamString.length() - 1); } try { regSec = Reg.parse(regNamString); } catch (UnknownRegNameException e) { throw new BindingConfigParseException(e.getMessage()); } } } @Override public Collection<? extends Reg> getRegs() { Set<Reg> regs = new HashSet<>(); if (regSec == null) { year.fillRegs(regs); month.fillRegs(regs); day.fillRegs(regs); hour.fillRegs(regs); minute.fillRegs(regs); second.fillRegs(regs); } else { regs.add(regSec); } return regs; } @Override public State getState(Map<Reg, RegValue> response) { Calendar cal = Calendar.getInstance(); if (regSec == null) { // calculate some value int y = year.getValue(response); if (y < 50) { y += 2000; } else if (y < 100) { y += 1900; } int m = month.getValue(response) - 1; cal.clear(); cal.set(y, m, day.getValue(response), hour.getValue(response), minute.getValue(response), second.getValue(response)); } else { long value = response.get(regSec).longValue() * 1000; if (factor != null) { value = factor.multiply(BigDecimal.valueOf(value)).longValue(); } if (relative) { value = System.currentTimeMillis() - value; } cal.setTimeInMillis(value); cal.set(Calendar.MILLISECOND, 0); } return new DateTimeType(cal); } private WordBits getWordBits(String regName) throws BindingConfigParseException { if (regName.endsWith("L")) { return new WordBitsLB(regName.substring(0, regName.length() - 1)); } else if (regName.endsWith("H")) { return new WordBitsHB(regName.substring(0, regName.length() - 1)); } else { return new WordBits(regName); } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getSimpleName()).append("["); sb.append("slave=").append(getSlaveName()); sb.append(", name=").append(getItemName()); if (regSec == null) { sb.append(", Y=").append(year); sb.append(", m=").append(month); sb.append(", d=").append(day); sb.append(", H=").append(hour); sb.append(", M=").append(minute); sb.append(", S=").append(second); } else { sb.append(", regSec=").append(regSec); if (relative) { sb.append(" relative"); } } sb.append("]"); return sb.toString(); } }