001package jmri.jmrix.roco.z21; 002 003import jmri.*; 004import jmri.implementation.DefaultMeter; 005import jmri.implementation.MeterUpdateTask; 006 007/** 008 * Provide access to voltage and current readings from the Roco Z21 009 * 010 * @author Mark Underwood Copyright (C) 2015 011 * @author Paul Bender Copyright (C) 2017 012 * @author Daniel Bergqvist Copyright (C) 2020 013 */ 014public class Z21PredefinedMeters { 015 016 private Z21TrafficController tc; 017 private Z21SystemConnectionMemo _memo; 018 private final MeterUpdateTask updateTask; 019 private final Meter currentMeter; 020 private final Meter voltageMeter; 021 private boolean enabled = false; // disable by default; prevent polling when not being used. 022 023 public Z21PredefinedMeters(Z21SystemConnectionMemo memo) { 024 025 _memo = memo; 026 tc = _memo.getTrafficController(); 027 028 updateTask = new UpdateTask(-1); 029 030 currentMeter = new DefaultMeter.DefaultCurrentMeter( 031 memo.getSystemPrefix() + "V" + "CommandStationCurrent", 032 Meter.Unit.Milli, 0, 10000.0, 100, updateTask); 033 034 voltageMeter = new DefaultMeter.DefaultVoltageMeter( 035 memo.getSystemPrefix() + "V" + "CommandStationVoltage", 036 Meter.Unit.Milli, 0, 50000.0, 500, updateTask); 037 038 InstanceManager.getDefault(MeterManager.class).register(currentMeter); 039 InstanceManager.getDefault(MeterManager.class).register(voltageMeter); 040 041 log.debug("Z21MultiMeter constructor called"); 042 043 } 044 045 public void setZ21TrafficController(Z21TrafficController controller) { 046 tc = controller; 047 } 048 049 public void dispose() { 050 updateTask.disable(currentMeter); 051 updateTask.disable(voltageMeter); 052 InstanceManager.getDefault(MeterManager.class).deregister(currentMeter); 053 InstanceManager.getDefault(MeterManager.class).deregister(voltageMeter); 054 updateTask.dispose(currentMeter); 055 updateTask.dispose(voltageMeter); 056 } 057 058 059 private class UpdateTask extends MeterUpdateTask implements Z21Listener { 060 061 public UpdateTask(int interval) { 062 super(interval); 063 tc.addz21Listener(this); 064 } 065 066 @Override 067 public void enable(){ 068 enabled = true; 069 RocoZ21CommandStation cs = _memo.getRocoZ21CommandStation(); 070 cs.setSystemStatusMessagesFlag(true); 071 tc.sendz21Message(Z21Message.getLanSetBroadcastFlagsRequestMessage(cs.getZ21BroadcastFlags()),this); 072 super.enable(); 073 } 074 075 @Override 076 public void disable(){ 077 if (!enabled) return; 078 super.disable(); 079 enabled = false; 080 RocoZ21CommandStation cs = _memo.getRocoZ21CommandStation(); 081 cs.setSystemStatusMessagesFlag(false); 082 tc.sendz21Message(Z21Message.getLanSetBroadcastFlagsRequestMessage(cs.getZ21BroadcastFlags()),this); 083 } 084 085 @Override 086 public void message(Z21Message m) { 087 } 088 089 @Override 090 public void reply(Z21Reply r) { 091 log.debug("Z21MultiMeter received reply: {}", r.toString()); 092 if (r.isSystemDataChangedReply()) { 093 try { 094 setCurrent(r.getSystemDataMainCurrent() * 1.0f); 095 setVoltage(r.getSystemDataVCCVoltage() * 1.0f); 096 } catch (JmriException e) { 097 log.error("exception thrown by setCurrent or setVoltage", e); 098 } 099 } 100 } 101 102 private void setCurrent(double value) throws JmriException { 103 currentMeter.setCommandedAnalogValue(value); 104 } 105 106 private void setVoltage(double value) throws JmriException { 107 voltageMeter.setCommandedAnalogValue(value); 108 } 109 110 @Override 111 public void requestUpdateFromLayout() { 112 if( enabled ) { 113 tc.sendz21Message(Z21Message.getLanSystemStateDataChangedRequestMessage(), this); 114 } 115 } 116 } 117 118 private final static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Z21PredefinedMeters.class); 119 120}