001package jmri.jmrit.ussctc; 002 003import jmri.*; 004 005/** 006 * Drive a single Track Circuit section on a USS CTC panel. 007 * 008 * @author Bob Jacobsen Copyright (C) 2007, 2017 009 * TODO - add field state diagram 010 */ 011 012public class TrackCircuitSection implements Section<CodeGroupNoBits, CodeGroupOneBit> { 013 014 /** 015 * Anonymous object only for testing 016 */ 017 TrackCircuitSection() {} 018 019 /** 020 * Create and configure. 021 * 022 * Accepts user or system names. 023 * 024 * @param inputSensor Sensor for occupancy on layout 025 * @param panelOutput Turnout drives lamp on panel 026 * @param station Station to which this Section belongs 027 * @param bell Bell driver (can be null) 028 */ 029 public TrackCircuitSection(String inputSensor, String panelOutput, Station<CodeGroupNoBits, CodeGroupOneBit> station, Bell bell) { 030 NamedBeanHandleManager hm = InstanceManager.getDefault(NamedBeanHandleManager.class); 031 TurnoutManager tm = InstanceManager.getDefault(TurnoutManager.class); 032 SensorManager sm = InstanceManager.getDefault(SensorManager.class); 033 034 hInputSensor = hm.getNamedBeanHandle(inputSensor, sm.provideSensor(inputSensor)); 035 hPanelOutput = hm.getNamedBeanHandle(panelOutput, tm.provideTurnout(panelOutput)); 036 this.station = station; 037 this.bell = bell; 038 039 // align at start 040 indicationComplete(indicationStart()); 041 042 // attach listeners for future changes 043 sm.provideSensor(inputSensor).addPropertyChangeListener((java.beans.PropertyChangeEvent e) -> {layoutTurnoutChanged(e);}); 044 } 045 046 /** 047 * Create and configure. 048 * <p> 049 * Accepts user or system names. 050 * 051 * @param inputSensor Sensor for input from central CTC machine 052 * @param panelOutput Turnout name for maintainer call on layout 053 * @param station Station to which this Section belongs 054 */ 055 public TrackCircuitSection(String inputSensor, String panelOutput, Station<CodeGroupNoBits, CodeGroupOneBit> station) { 056 this(inputSensor, panelOutput, station, null); 057 } 058 059 NamedBeanHandle<Sensor> hInputSensor; 060 NamedBeanHandle<Turnout> hPanelOutput; 061 062 Bell bell; 063 064 Station<CodeGroupNoBits, CodeGroupOneBit> station; 065 @Override 066 public Station<CodeGroupNoBits, CodeGroupOneBit> getStation() { return station; } 067 @Override 068 public String getName() { return "TC for "+hInputSensor.getBean().getDisplayName(); } 069 070 /** 071 * Start of sending code operation. 072 * 073 * @return code line value to transmit 074 */ 075 @Override 076 public CodeGroupNoBits codeSendStart() { 077 return CodeGroupNoBits.None; 078 } 079 080 /** 081 * Process values received from the field unit. 082 */ 083 @Override 084 public void indicationComplete(CodeGroupOneBit value) { 085 if ( value == CodeGroupOneBit.Single1 && hPanelOutput.getBean().getCommandedState()!=Turnout.THROWN ) { 086 hPanelOutput.getBean().setCommandedState(Turnout.THROWN); 087 if (bell != null) bell.ring(); // ring on arrival 088 } else if (value == CodeGroupOneBit.Single0 && hPanelOutput.getBean().getCommandedState()!=Turnout.CLOSED ) { 089 hPanelOutput.getBean().setCommandedState(Turnout.CLOSED); 090 } 091 } 092 093 /** 094 * Notification that code has arrived in the field. Sets the turnout on the layout. 095 */ 096 @Override 097 public void codeValueDelivered(CodeGroupNoBits value) { 098 } 099 100 /** 101 * Provide state that's returned from field to machine via indication. 102 */ 103 @Override 104 public CodeGroupOneBit indicationStart() { 105 // Everything _except_ a clean INACTIVE shows active 106 if (hInputSensor.getBean().getState()!=Sensor.INACTIVE) return CodeGroupOneBit.Single1; 107 return CodeGroupOneBit.Single0; 108 } 109 110 void layoutTurnoutChanged(java.beans.PropertyChangeEvent e) { 111 if (e.getPropertyName().equals("KnownState") && !e.getNewValue().equals(e.getOldValue()) ) { 112 log.debug("Sensor changed from {} to {}, so requestIndicationStart", e.getOldValue(), e.getNewValue()); 113 // Always send an indication if there's a change in the turnout 114 station.requestIndicationStart(); 115 } 116 } 117 118 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(TrackCircuitSection.class); 119 120}