001package jmri.jmrit.logixng.actions; 002 003import java.beans.PropertyChangeEvent; 004import java.beans.PropertyChangeListener; 005import java.util.*; 006 007import jmri.*; 008import jmri.jmrit.logixng.*; 009import jmri.jmrit.logixng.util.LogixNG_SelectNamedBean; 010 011/** 012 * Runs an engine. 013 * This action reads an analog expression with the loco address and sets its 014 * speed according to an alaog expression and the direction according to a 015 * digital expression. 016 * 017 * @author Daniel Bergqvist Copyright 2019 018 */ 019public class ActionLightIntensity extends AbstractDigitalAction 020 implements FemaleSocketListener, PropertyChangeListener { 021 022 public static final int INTENSITY_SOCKET = 0; 023 024 private final LogixNG_SelectNamedBean<VariableLight> _selectNamedBean = 025 new LogixNG_SelectNamedBean<>( 026 this, VariableLight.class, InstanceManager.getDefault(VariableLightManager.class), this); 027 028 private String _intensitySocketSystemName; 029 private final FemaleAnalogExpressionSocket _intensitySocket; 030 031 032 public ActionLightIntensity(String sys, String user) { 033 super(sys, user); 034 _intensitySocket = InstanceManager.getDefault(AnalogExpressionManager.class) 035 .createFemaleSocket(this, this, Bundle.getMessage("ActionLightIntensity_SocketName")); 036 } 037 038 @Override 039 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws JmriException { 040 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 041 String sysName = systemNames.get(getSystemName()); 042 String userName = userNames.get(getSystemName()); 043 if (sysName == null) sysName = manager.getAutoSystemName(); 044 ActionLightIntensity copy = new ActionLightIntensity(sysName, userName); 045 copy.setComment(getComment()); 046 _selectNamedBean.copy(copy._selectNamedBean); 047 return manager.registerAction(copy).deepCopyChildren(this, systemNames, userNames); 048 } 049 050 public LogixNG_SelectNamedBean<VariableLight> getSelectNamedBean() { 051 return _selectNamedBean; 052 } 053 054 /** {@inheritDoc} */ 055 @Override 056 public Category getCategory() { 057 return Category.ITEM; 058 } 059 060 /** {@inheritDoc} */ 061 @Override 062 public void execute() throws JmriException { 063 VariableLight light = _selectNamedBean.evaluateNamedBean(getConditionalNG()); 064 065 if (light == null) { 066// log.warn("light is null"); 067 return; 068 } 069 070 double intensity = 0.0; 071 072 if (_intensitySocket.isConnected()) { 073 intensity = 074 ((MaleAnalogExpressionSocket)_intensitySocket.getConnectedSocket()) 075 .evaluate(); 076 } 077 078 if (intensity < 0.0) intensity = 0.0; 079 if (intensity > 100.0) intensity = 100.0; 080 081 light.setTargetIntensity(intensity/100.0); 082 } 083 084 @Override 085 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 086 switch (index) { 087 case INTENSITY_SOCKET: 088 return _intensitySocket; 089 090 default: 091 throw new IllegalArgumentException( 092 String.format("index has invalid value: %d", index)); 093 } 094 } 095 096 @Override 097 public int getChildCount() { 098 return 1; 099 } 100 101 @Override 102 public void connected(FemaleSocket socket) { 103 if (socket == _intensitySocket) { 104 _intensitySocketSystemName = socket.getConnectedSocket().getSystemName(); 105 } else { 106 throw new IllegalArgumentException("unkown socket"); 107 } 108 } 109 110 @Override 111 public void disconnected(FemaleSocket socket) { 112 if (socket == _intensitySocket) { 113 _intensitySocketSystemName = null; 114 } else { 115 throw new IllegalArgumentException("unkown socket"); 116 } 117 } 118 119 @Override 120 public String getShortDescription(Locale locale) { 121 return Bundle.getMessage(locale, "ActionLightIntensity_Short"); 122 } 123 124 @Override 125 public String getLongDescription(Locale locale) { 126 String namedBean = _selectNamedBean.getDescription(locale); 127 128 return Bundle.getMessage(locale, "ActionLightIntensity_Long", namedBean); 129 } 130 131 public FemaleAnalogExpressionSocket getIntensitySocket() { 132 return _intensitySocket; 133 } 134 135 public String getIntensitySocketSystemName() { 136 return _intensitySocketSystemName; 137 } 138 139 public void setIntensitySystemName(String systemName) { 140 _intensitySocketSystemName = systemName; 141 } 142 143 /** {@inheritDoc} */ 144 @Override 145 public void setup() { 146 try { 147 if ( !_intensitySocket.isConnected() 148 || !_intensitySocket.getConnectedSocket().getSystemName() 149 .equals(_intensitySocketSystemName)) { 150 151 String socketSystemName = _intensitySocketSystemName; 152 _intensitySocket.disconnect(); 153 if (socketSystemName != null) { 154 MaleSocket maleSocket = 155 InstanceManager.getDefault(AnalogExpressionManager.class) 156 .getBySystemName(socketSystemName); 157 _intensitySocket.disconnect(); 158 if (maleSocket != null) { 159 _intensitySocket.connect(maleSocket); 160 maleSocket.setup(); 161 } else { 162 log.error("cannot load analog expression {}", socketSystemName); 163 } 164 } 165 } else { 166 _intensitySocket.getConnectedSocket().setup(); 167 } 168 } catch (SocketAlreadyConnectedException ex) { 169 // This shouldn't happen and is a runtime error if it does. 170 throw new RuntimeException("socket is already connected"); 171 } 172 } 173 174 /** {@inheritDoc} */ 175 @Override 176 public void registerListenersForThisClass() { 177 _selectNamedBean.registerListeners(); 178 _listenersAreRegistered = true; 179 } 180 181 /** {@inheritDoc} */ 182 @Override 183 public void unregisterListenersForThisClass() { 184 _selectNamedBean.unregisterListeners(); 185 _listenersAreRegistered = false; 186 } 187 188 /** {@inheritDoc} */ 189 @Override 190 public void disposeMe() { 191 } 192 193 /** {@inheritDoc} */ 194 @Override 195 public void propertyChange(PropertyChangeEvent evt) { 196 getConditionalNG().execute(); 197 } 198 199 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionLightIntensity.class); 200 201}