001package jmri.managers; 002 003import jmri.JmriException; 004import jmri.PowerManager; 005 006import java.beans.PropertyChangeEvent; 007import java.beans.PropertyChangeListener; 008import java.time.Instant; 009import jmri.beans.PropertyChangeSupport; 010import jmri.SystemConnectionMemo; 011 012/** 013 * Base PowerManager implementation for controlling layout power. 014 * <p> 015 * These are registered when they are added to the InstanceManager 016 * 017 * @author Bob Jacobsen Copyright (C) 2001, 2003, 2010 018 * @author Randall Wood Copyright 2020 019 * @param <M> the type of SystemConnectionMemo supported by this PowerManager 020 */ 021abstract public class AbstractPowerManager<M extends SystemConnectionMemo> extends PropertyChangeSupport implements PowerManager { 022 023 protected final M memo; 024 /** 025 * Note that all changes must fire a property change with the old and new values 026 */ 027 protected int power = UNKNOWN; 028 private Instant lastOn; 029 030 public AbstractPowerManager(M memo) { 031 this.memo = memo; 032 TimeKeeper tk = new TimeKeeper(); 033 AbstractPowerManager.this.addPropertyChangeListener(tk); 034 } 035 036 /** 037 * {@inheritDoc} 038 */ 039 @Override 040 public int getPower() { 041 return power; 042 } 043 044 /** 045 * {@inheritDoc} 046 */ 047 @Override 048 public void setPower(int state) throws JmriException { 049 int old = power; 050 power = state; 051 firePowerPropertyChange(old, power); 052 } 053 054 /** {@inheritDoc} */ 055 @Override 056 public final String getUserName() { 057 return memo.getUserName(); 058 } 059 060 // a class for listening for power state changes 061 public class TimeKeeper implements PropertyChangeListener { 062 @Override 063 public void propertyChange(PropertyChangeEvent e) { 064 if (POWER.equals(e.getPropertyName())) { 065 int newPowerState = getPower(); 066 if (newPowerState != power) { 067 power = newPowerState; 068 if (newPowerState == ON) { 069 lastOn = Instant.now(); 070 } 071 } 072 } 073 } 074 } 075 076 /** 077 * Returns the amount of time since the layout was last powered up, 078 * in milliseconds. If the layout has not been powered up as far as 079 * JMRI knows it returns a very long time indeed. 080 * 081 * @return long int 082 */ 083 public long timeSinceLastPowerOn() { 084 if (lastOn == null) { 085 return Long.MAX_VALUE; 086 } 087 return Instant.now().toEpochMilli() - lastOn.toEpochMilli(); 088 } 089 090 /** 091 * Fires a {@link java.beans.PropertyChangeEvent} for the power state using 092 * property name "power". 093 * 094 * @param old the old power state 095 * @param current the new power state 096 */ 097 protected final void firePowerPropertyChange(int old, int current) { 098 firePropertyChange(POWER, old, current); 099 } 100}