001package jmri.jmrix.powerline.cp290;
002
003import jmri.Sensor;
004import jmri.jmrix.powerline.SerialReply;
005import jmri.jmrix.powerline.SerialSensorManager;
006import jmri.jmrix.powerline.SerialTrafficController;
007import jmri.jmrix.powerline.X10Sequence;
008import org.slf4j.Logger;
009import org.slf4j.LoggerFactory;
010
011/**
012 * Manage the system-specific Sensor implementation.
013 * <p>
014 * System names are "PSann", where a is the unit id, nn is the unit number
015 * without padding.
016 * <p>
017 * Sensors are not created automatically as there are frequently other X10 codes
018 * seen on the wire that you don't want in your panels.
019 * <p>
020 * Created from the cm11 version
021 *
022 * @author Bob Jacobsen Copyright (C) 2003, 2006, 2007, 2008
023 * @author Ken Cameron, (C) 2009, 2010 sensors from poll replies Converted to
024 * multiple connection
025 * @author kcameron Copyright (C) 2011
026 */
027public class SpecificSensorManager extends SerialSensorManager {
028
029    public SpecificSensorManager(SerialTrafficController tc) {
030        super(tc);
031    }
032
033    /**
034     * Process a reply to a poll of Sensors of one node
035     */
036    @Override
037    public synchronized void reply(SerialReply r) {
038        // process for updates
039        processForPollReq(r);
040    }
041
042    private void processForPollReq(SerialReply m) {
043        boolean goodSync = true;
044        boolean goodCheckSum = true;
045        int sum = 0;
046        String newHouseCode = null;
047        int newCmdCode = -1;
048        int newAddrCode = -1;
049        Sensor sensor = null;
050        if (m.getNumDataElements() == 12) {
051            for (int i = 0; i < 6; i++) {
052                if ((m.getElement(i) & 0xFF) != 0xFF) {
053                    goodSync = false;
054                }
055            }
056            for (int i = 7; i < 11; i++) {
057                sum = (sum + (m.getElement(i) & 0xFF)) & 0xFF;
058            }
059            if (sum != (m.getElement(11) & 0xFF)) {
060                goodCheckSum = false;
061            }
062            newCmdCode = m.getElement(7) & 0x0F;
063            newHouseCode = X10Sequence.houseCodeToText((m.getElement(7) >> 4) & 0x0F);
064            newAddrCode = (m.getElement(8) & 0x00FF) + ((m.getElement(9) & 0x00FF) << 8);
065            if (goodSync && goodCheckSum) {
066                int unitMask = 1 << 16;
067                int unitCnt = 0;
068                while (unitMask > 0) {
069                    unitMask = unitMask >> 1;
070                    unitCnt++;
071                    int hCode = newAddrCode & unitMask;
072                    if (hCode != 0) {
073                        String sysName = getSystemPrefix() + "S" + newHouseCode + unitCnt;
074                        sensor = provideSensor(sysName);
075
076                        if (newCmdCode == X10Sequence.FUNCTION_ON || newCmdCode == X10Sequence.FUNCTION_BRIGHT || newCmdCode == X10Sequence.FUNCTION_STATUS_ON) {
077                            try {
078                                sensor.setKnownState(Sensor.ACTIVE);
079                            } catch (jmri.JmriException e) {
080                                log.error("Exception setting {} sensor ACTIVE", sysName, e);
081                            }
082                        }
083                        if (newCmdCode == X10Sequence.FUNCTION_OFF || newCmdCode == X10Sequence.FUNCTION_DIM || newCmdCode == X10Sequence.FUNCTION_STATUS_OFF) {
084                            try {
085                                sensor.setKnownState(Sensor.INACTIVE);
086                            } catch (jmri.JmriException e) {
087                                log.error("Exception setting {} sensor INACTIVE", sysName, e);
088                            }
089                        }
090
091                    }
092                }
093            }
094        }
095    }
096
097    private final static Logger log = LoggerFactory.getLogger(SpecificSensorManager.class);
098}