001package jmri.jmrix.loconet.pr3; 002 003import jmri.GlobalProgrammerManager; 004import jmri.InstanceManager; 005import jmri.PowerManager; 006import jmri.ThrottleManager; 007import jmri.jmrix.loconet.LnPowerManager; 008import jmri.jmrix.loconet.LnTrafficController; 009import jmri.jmrix.loconet.LocoNetMessage; 010import jmri.jmrix.loconet.LocoNetSystemConnectionMemo; 011import jmri.jmrix.loconet.SlotManager; 012import org.slf4j.Logger; 013import org.slf4j.LoggerFactory; 014 015/** 016 * Lightweight class to denote that a PR3 is active 017 * 018 * @author Bob Jacobsen Copyright (C) 2010 019 * @author B. Milhaupt Copyright (C) 2017 020 */ 021public class PR3SystemConnectionMemo extends LocoNetSystemConnectionMemo { 022 023 public PR3SystemConnectionMemo(LnTrafficController lt, 024 SlotManager sm) { 025 super(lt, sm); 026 } 027 028 public PR3SystemConnectionMemo() { 029 super(); 030 } 031 032 @SuppressWarnings("unchecked") 033 @Override 034 public <T> T get(Class<T> T) { 035 if (getDisabled()) { 036 return null; 037 } 038 if (mode == MS100MODE) { 039 return super.get(T); 040 } 041 if (T.equals(jmri.GlobalProgrammerManager.class)) { 042 return (T) getProgrammerManager(); 043 } 044 if (T.equals(jmri.AddressedProgrammerManager.class)) { 045 return (T) getProgrammerManager(); 046 } 047 048 if (T.equals(jmri.ThrottleManager.class)) { 049 return (T) getThrottleManager(); 050 } 051 if (T.equals(jmri.PowerManager.class)) { 052 return (T) getPowerManager(); 053 } 054 if(T.equals(jmri.ConsistManager.class)){ 055 return (T) getConsistManager(); 056 } 057 return null; 058 } 059 060 final static int PR3MODE = 0x00; 061 final static int MS100MODE = 0x01; 062 063 int mode = PR3MODE; 064 private Runnable restoreToLocoNetInterfaceModeTask; 065 066 /** 067 * Configure the subset of LocoNet managers valid for the PR3 in PR2 mode. 068 */ 069 public void configureManagersPR2() { 070 mode = PR3MODE; 071 log.info("Connection [{}] initialized as \"Stand Alone Programmer\", no access to attached devices. (see preferences)",getSystemPrefix()); 072 InstanceManager.store(getPowerManager(), jmri.PowerManager.class); 073 074 InstanceManager.setThrottleManager( 075 getThrottleManager()); 076 077 if (getProgrammerManager().isAddressedModePossible()) { 078 InstanceManager.store(getProgrammerManager(), jmri.AddressedProgrammerManager.class); 079 } 080 if (getProgrammerManager().isGlobalProgrammerAvailable()) { 081 InstanceManager.store(getProgrammerManager(), GlobalProgrammerManager.class); 082 } 083 // Establish a ShutDownTask so that the PR3 should be be returned to 084 // LocoNet Interface mode at shutdown 085 // Finally, create and register a shutdown task to ensure clean exit 086 if (restoreToLocoNetInterfaceModeTask == null) { 087 restoreToLocoNetInterfaceModeTask = () -> { 088 if (mode == PR3MODE) { 089 // try to change from "standalone programmer" to "LocoNet interface" mode 090 LnTrafficController tc; 091 tc = getLnTrafficController(); 092 if (tc != null) { 093 LocoNetMessage msg = new LocoNetMessage(6); 094 msg.setOpCode(0xD3); 095 msg.setElement(1, 0x10); 096 msg.setElement(2, 0); // set MS100, no power 097 msg.setElement(3, 0); 098 msg.setElement(4, 0); 099 tc.sendLocoNetMessage(msg); 100 log.info("Configuring PR3 for 'LocoNet Interface' mode"); // NOI18N 101 } 102 } 103 }; 104 InstanceManager.getDefault(jmri.ShutDownManager.class).register(restoreToLocoNetInterfaceModeTask); 105 } 106 107 register(); 108 } 109 110 @Override 111 public ThrottleManager getThrottleManager() { 112 if (super.getDisabled()) { 113 return null; 114 } 115 if (mode == MS100MODE) { 116 return super.getThrottleManager(); 117 } 118 return (ThrottleManager) classObjectMap.computeIfAbsent(ThrottleManager.class,(Class<?> c) -> new jmri.jmrix.loconet.LnPr2ThrottleManager(this)); 119 } 120 121 @Override 122 public boolean provides(Class<?> type) { 123 if (getDisabled()) { 124 return false; 125 } 126 if (mode == MS100MODE) { 127 return super.provides(type); 128 } 129 if (type.equals(jmri.GlobalProgrammerManager.class)) { 130 return getProgrammerManager().isGlobalProgrammerAvailable(); 131 } 132 if (type.equals(jmri.AddressedProgrammerManager.class)) { 133 return getProgrammerManager().isAddressedModePossible(); 134 } 135 136 if (type.equals(jmri.ThrottleManager.class)) { 137 return true; 138 } 139 if (type.equals(jmri.PowerManager.class)) { 140 return true; 141 } 142 if(type.equals(jmri.ConsistManager.class)){ 143 return(getConsistManager()!=null); 144 } 145 return false; 146 } 147 //private jmri.jmrix.loconet.pr2.LnPr2PowerManager powerManager; 148 149 /** 150 * Get the connection's LnPowerManager. 151 * 152 * @return the LocoNet power manager; may be null in some circumstances 153 */ 154 @Override 155 public LnPowerManager getPowerManager() { 156 if (getDisabled()) { 157 return null; 158 } 159 if (mode == MS100MODE) { 160 return super.getPowerManager(); 161 } 162 return (LnPowerManager) classObjectMap.computeIfAbsent(PowerManager.class,(Class<?> c) -> new jmri.jmrix.loconet.pr2.LnPr2PowerManager(this)); 163 } 164 165 /** 166 * Configure the LocoNet managers valid for the PR3 in MS100 mode, same as super, flag the interface type. 167 */ 168 public void configureManagersMS100() { 169 mode = MS100MODE; 170 log.info("Connection [{}] initialized as LocoNet interface, allows access to attached devices. (see preferences)",getSystemPrefix()); 171 super.configureManagers(); 172 } 173 174 @Override 175 public void dispose() { 176 InstanceManager.deregister(this, PR3SystemConnectionMemo.class); 177 if(tm!=null){ 178 tm.dispose(); 179 } 180 super.dispose(); 181 } 182 183 private final static Logger log = LoggerFactory.getLogger(PR3SystemConnectionMemo.class); 184 185}