001package jmri.jmrix.mqtt.logixng; 002 003import jmri.jmrit.logixng.actions.*; 004 005import java.beans.PropertyChangeEvent; 006import java.beans.PropertyChangeListener; 007import java.util.*; 008 009import jmri.*; 010import jmri.jmrit.logixng.*; 011import jmri.jmrit.logixng.util.LogixNG_SelectString; 012import jmri.jmrit.logixng.util.parser.ParserException; 013import jmri.jmrix.mqtt.MqttSystemConnectionMemo; 014import jmri.util.ThreadingUtil; 015 016/** 017 * This action publishes a message to MQTT. 018 * 019 * @author Daniel Bergqvist Copyright 2022 020 */ 021public class Publish extends AbstractDigitalAction 022 implements PropertyChangeListener { 023 024 private final LogixNG_SelectString _selectTopic = 025 new LogixNG_SelectString(this, this); 026 private final LogixNG_SelectString _selectMessage = 027 new LogixNG_SelectString(this, this); 028 029 private MqttSystemConnectionMemo _memo; 030 031 private Retain _retain; 032 033 034 public Publish(String sys, String user, MqttSystemConnectionMemo memo) 035 throws BadUserNameException, BadSystemNameException { 036 super(sys, user); 037 _memo = memo; 038 _retain = Retain.Default; 039 } 040 041 @Override 042 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException { 043 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 044 String sysName = systemNames.get(getSystemName()); 045 String userName = userNames.get(getSystemName()); 046 if (sysName == null) sysName = manager.getAutoSystemName(); 047 Publish copy = new Publish(sysName, userName, _memo); 048 copy.setComment(getComment()); 049 _selectTopic.copy(copy._selectTopic); 050 _selectMessage.copy(copy._selectMessage); 051 copy.setRetain(_retain); 052 return manager.registerAction(copy); 053 } 054 055 public void setMemo(MqttSystemConnectionMemo memo) { 056 assertListenersAreNotRegistered(log, "setMemo"); 057 _memo = memo; 058 } 059 060 public MqttSystemConnectionMemo getMemo() { 061 return _memo; 062 } 063 064 public LogixNG_SelectString getSelectTopic() { 065 return _selectTopic; 066 } 067 068 public LogixNG_SelectString getSelectMessage() { 069 return _selectMessage; 070 } 071 072 public void setRetain(Retain retain) { 073 assertListenersAreNotRegistered(log, "setRetain"); 074 _retain = retain; 075 } 076 077 public Retain getRetain() { 078 return _retain; 079 } 080 081 /** {@inheritDoc} */ 082 @Override 083 public Category getCategory() { 084 return Category.ITEM; 085 } 086 087 /** {@inheritDoc} */ 088 @Override 089 public void execute() throws JmriException { 090 091 String topic = _selectTopic.evaluateValue(getConditionalNG()); 092 String data = _selectMessage.evaluateValue(getConditionalNG()); 093 094 boolean retain = _retain.getRetainValue(_memo); 095 096 ThreadingUtil.runOnLayoutWithJmriException(() -> { 097 _memo.getMqttAdapter().publish(topic, data, retain); 098 }); 099 } 100 101 @Override 102 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 103 throw new UnsupportedOperationException("Not supported."); 104 } 105 106 @Override 107 public int getChildCount() { 108 return 0; 109 } 110 111 @Override 112 public String getShortDescription(Locale locale) { 113 return Bundle.getMessage(locale, "Publish_Short"); 114 } 115 116 @Override 117 public String getLongDescription(Locale locale) { 118 return Bundle.getMessage(locale, "Publish_Long", 119 _selectTopic.getDescription(locale), 120 _selectMessage.getDescription(locale), 121 _retain.toString()); 122 } 123 124 /** {@inheritDoc} */ 125 @Override 126 public void setup() { 127 // Do nothing 128 } 129 130 /** {@inheritDoc} */ 131 @Override 132 public void registerListenersForThisClass() { 133 _selectTopic.registerListeners(); 134 _selectMessage.registerListeners(); 135 } 136 137 /** {@inheritDoc} */ 138 @Override 139 public void unregisterListenersForThisClass() { 140 _selectTopic.unregisterListeners(); 141 _selectMessage.unregisterListeners(); 142 } 143 144 /** {@inheritDoc} */ 145 @Override 146 public void propertyChange(PropertyChangeEvent evt) { 147 getConditionalNG().execute(); 148 } 149 150 /** {@inheritDoc} */ 151 @Override 152 public void disposeMe() { 153 } 154 155 156 public enum Retain { 157 Default(Bundle.getMessage("Publish_Retain_Default")), 158 Yes(Bundle.getMessage("Publish_Retain_Yes")), 159 No(Bundle.getMessage("Publish_Retain_No")); 160 161 private final String _text; 162 163 private Retain(String text) { 164 this._text = text; 165 } 166 167 public boolean getRetainValue(MqttSystemConnectionMemo memo) { 168 switch (this) { 169 case Default: 170 return memo.getMqttAdapter().retained; 171 case Yes: 172 return true; 173 case No: 174 return false; 175 default: 176 throw new IllegalArgumentException("invalid retain"); 177 } 178 } 179 180 @Override 181 public String toString() { 182 return _text; 183 } 184 185 } 186 187 188 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Publish.class); 189 190}