001/** 002 * MqttPowerManager.java 003 * 004 * PowerManager implementation for controlling layout power 005 * 006 * @author Dean Cording Copyright (C) 2023 007 * 008 */ 009package jmri.jmrix.mqtt; 010 011import jmri.JmriException; 012import jmri.managers.AbstractPowerManager; 013 014import javax.annotation.Nonnull; 015 016public class MqttPowerManager extends AbstractPowerManager<MqttSystemConnectionMemo> implements MqttEventListener { 017 018 private static final String onText = "ON"; 019 private static final String offText = "OFF"; 020 private final MqttAdapter mqttAdapter; 021 022 public MqttPowerManager(MqttSystemConnectionMemo memo) { 023 super(memo); 024 mqttAdapter = memo.getMqttAdapter(); 025 026 } 027 028 public void setSendTopic(@Nonnull String sendTopic) { 029 this.sendTopic = sendTopic; 030 } 031 public void setRcvTopic(@Nonnull String rcvTopic) { 032 this.mqttAdapter.unsubscribe(rcvTopic, this); 033 this.rcvTopic = rcvTopic; 034 this.mqttAdapter.subscribe(rcvTopic, this); 035 036 log.info("Subscribed to {}", rcvTopic); 037 038 } 039 040 @Nonnull 041 public String sendTopic = "track/power"; // for constructing topic; public for script access 042 @Nonnull 043 public String rcvTopic = "track/power"; // for constructing topic; public for script access 044 045 @Override 046 public boolean implementsIdle() { 047 return false; 048 } 049 050 @Override 051 public void setPower(int v) throws JmriException { 052 if (v == ON) { 053 // send TRACK_POWER_ON 054 sendMessage(onText); 055 } else if (v == OFF) { 056 // send TRACK_POWER_OFF 057 sendMessage(offText); 058 } else { 059 log.warn("Saw unknown power state : {}", v); 060 } 061 } 062 063 064 065 // to free resources when no longer used 066 @Override 067 public void dispose() throws JmriException { 068 this.mqttAdapter.unsubscribe(rcvTopic, this); 069 } 070 071 072 private void sendMessage(String c) { 073 jmri.util.ThreadingUtil.runOnLayoutEventually(() -> { 074 mqttAdapter.publish(this.sendTopic, c); 075 }); 076 log.debug("sent {}", c); 077 } 078 079 @Override 080 public void notifyMqttMessage(String receivedTopic, String message) { 081 if (!receivedTopic.endsWith(rcvTopic)) { 082 log.error("Got a message whose topic ({}) wasn't for me ({})", receivedTopic, rcvTopic); 083 return; 084 } 085 log.debug("notifyMqttMessage with {}", message); 086 087 // handle on/off 088 try { 089 switch (message) { 090 case onText: super.setPower(ON); break; 091 case offText: super.setPower(OFF); break; 092 default: log.error("Invalid message to power manager: {}", message); break; 093 } 094 } catch (JmriException e) { 095 log.error("JMRI Exception", e); 096 } 097 } 098 099 // Initialize logging information 100 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(MqttPowerManager.class); 101 102} 103 104 105