001package jmri.jmrix.powerline.dmx512; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005import jmri.jmrix.powerline.SerialTrafficController; 006 007/** 008 * Implementation of the Light class for DMX based subclasses. 009 * <p> 010 * DMX maps the value of 0.0 to 1.0 to values of 0 to 255. 011 * 012 * @author Dave Duchamp Copyright (C) 2004 013 * @author Bob Jacobsen Copyright (C) 2006, 2007, 2008, 2009, 2010 014 * @author Ken Cameron Copyright (C) 2009, 2010 Converted to multiple connection 015 * @author kcameron Copyright (C) 2023 016 */ 017public class SpecificDmxLight extends jmri.jmrix.powerline.SerialLight { 018 019 /** 020 * Create a Light object, with only system name. 021 * <p> 022 * 'systemName' was previously validated in SerialLightManager 023 * @param systemName system name 024 * @param tc traffic controller 025 */ 026 public SpecificDmxLight(String systemName, SerialTrafficController tc) { 027 super(systemName, tc); 028 this.tc = tc; 029 maxDimStep = tc.getNumberOfIntensitySteps(); 030 } 031 032 /** 033 * Create a Light object, with both system and user names. 034 * <p> 035 * 'systemName' was previously validated in SerialLightManager 036 * @param systemName system name 037 * @param tc traffic controller 038 * @param userName user name 039 */ 040 public SpecificDmxLight(String systemName, SerialTrafficController tc, String userName) { 041 super(systemName, tc, userName); 042 this.tc = tc; 043 maxDimStep = tc.getNumberOfIntensitySteps(); 044 } 045 046 SerialTrafficController tc = null; 047 protected int maxDimStep = 0; 048 049 /** 050 * Set the intensity for the DMX hardware to reach a specific 051 * intensity. Acts immediately, and changes no general state. 052 */ 053 @Override 054 protected void sendIntensity(double intensity) { 055 // correct for out of range value 056 if ((intensity < mMinIntensity) || (intensity > mMaxIntensity)) { 057 log.debug("correcting out of range intensity: {}", intensity); 058 if (intensity < mMinIntensity) { 059 intensity = mMinIntensity; 060 } 061 if (intensity > mMaxIntensity) { 062 intensity = mMaxIntensity; 063 } 064 } 065 // test current too, if the change is out of range... 066 if ((mCurrentIntensity < mMinIntensity) || (mCurrentIntensity > mMaxIntensity)) { 067 log.debug("correcting out of range current intensity: {}", mCurrentIntensity); 068 if (mCurrentIntensity < mMinIntensity) { 069 mCurrentIntensity = mMinIntensity; 070 } 071 if (mCurrentIntensity > mMaxIntensity) { 072 mCurrentIntensity = mMaxIntensity; 073 } 074 } 075 076 if (log.isDebugEnabled()) { 077 log.debug("sendIntensity({}) maxDimStep: {}", intensity, maxDimStep); 078 } 079 080 // find the new correct dim count 081 int newStep = (int) Math.round(intensity * maxDimStep); // maxDimStep is full on, 0 is full off, etc 082 083 // check for errors 084 if ((newStep < 0) || (newStep > maxDimStep)) { 085 log.error("newStep wrong: {} intensity: {} mCurrentIntensity {}", newStep, intensity, mCurrentIntensity); 086 return; 087 } 088 089 // update dmxArray 090 tc.sendDmxSequence(this.unitid, (byte) newStep); 091 } 092 093 /** 094 * Number of steps from dim to bright is maintained in specific 095 * SerialTrafficController implementation 096 */ 097 @Override 098 protected int getNumberOfSteps() { 099 return tc.getNumberOfIntensitySteps(); 100 } 101 102 /** 103 * Send a On/Off Command to the hardware 104 */ 105 @Override 106 protected void sendOnOffCommand(int newState) { 107 if (log.isDebugEnabled()) { 108 log.debug("sendOnOff({}) Current: {}", newState, mState); 109 } 110 111 // figure out command 112 byte newDim; 113 if (newState == ON) { 114 newDim = (byte) maxDimStep; 115 // set new intensity, skip stepping 116 mCurrentIntensity = 1; 117 mTransitionTargetIntensity = 1; 118 } else if (newState == OFF) { 119 newDim = 0; 120 // set new intensity, skip stepping 121 mCurrentIntensity = 0; 122 mTransitionTargetIntensity = 0; 123 } else { 124 log.warn("illegal state requested for Light: {}", getSystemName()); 125 return; 126 } 127 128 log.debug("set state {} unitid {} value {}", newState, unitid, newDim); 129 130 // send value to array 131 tc.sendDmxSequence(this.unitid, newDim); 132 133 if (log.isDebugEnabled()) { 134 log.debug("sendOnOff() unit {} state {} value {} ", this.unitid, newState, newDim); 135 } 136 } 137 138 private final static Logger log = LoggerFactory.getLogger(SpecificDmxLight.class); 139} 140 141