View Javadoc

1   package org.rpi.plugin.lcddisplay;
2   
3   import java.io.File;
4   import java.util.ArrayList;
5   import java.util.Observable;
6   import java.util.Observer;
7   
8   import javax.xml.parsers.DocumentBuilder;
9   import javax.xml.parsers.DocumentBuilderFactory;
10  import javax.xml.xpath.XPath;
11  import javax.xml.xpath.XPathFactory;
12  
13  import net.xeoh.plugins.base.annotations.PluginImplementation;
14  import net.xeoh.plugins.base.annotations.events.Shutdown;
15  
16  import org.apache.log4j.Logger;
17  import org.rpi.os.OSManager;
18  import org.rpi.player.PlayManager;
19  import org.rpi.player.events.*;
20  import org.rpi.player.observers.ObservableVolume;
21  import org.rpi.playlist.CustomTrack;
22  import org.w3c.dom.Document;
23  import org.w3c.dom.Element;
24  import org.w3c.dom.Node;
25  import org.w3c.dom.NodeList;
26  
27  import com.pi4j.io.gpio.GpioController;
28  import com.pi4j.wiringpi.Lcd;
29  
30  @PluginImplementation
31  public class LCDDisplayImpl implements LCDDislayInterface, Observer {
32  
33  	private static Logger log = Logger.getLogger(LCDDisplayImpl.class);
34  	private GpioController gpio = null;
35  
36  	// provision gpio pin #02 as an input pin with its internal pull down
37  	// resistor enabled
38  
39  	// private GpioPinDigitalInput myButton = null;
40  	// private GpioPinDigitalOutput myMuteLed = null;
41  
42  	public int LCD_ROWS = 2;
43  	public ArrayList<RowDefinition> row_definition = new ArrayList<RowDefinition>();
44  	public ArrayList<RowDefinition> standby_definition = new ArrayList<RowDefinition>();
45  	public int LCD_COLUMNS = 20;
46  	public final static int LCD_BITS = 4;
47  	private int lcdHandle = -1;
48  	private long mVolume = 100;
49  	private String mTime = "0:00";
50  	private boolean isMute = false;
51  	private LCDScroller scroller = null;
52  
53  	public LCDDisplayImpl() {
54  		log.debug("Init LCDDisplayImpl");
55  		try {
56  			getConfig();
57  			PlayManager.getInstance().observInfoEvents(this);
58  			PlayManager.getInstance().observVolumeEvents(this);
59  			PlayManager.getInstance().observTimeEvents(this);
60  			PlayManager.getInstance().observeProductEvents(this);
61  			try {
62  				initPi4J();
63  			} catch (Exception e) {
64  				log.error("Error Init Pi4J: " + e);
65  			}
66  			scroller = new LCDScroller(LCD_ROWS, LCD_COLUMNS, row_definition,standby_definition);
67  			scroller.setStandBy(PlayManager.getInstance().isStandby());
68  			scroller.setReset();
69  			if (lcdHandle != -1) {
70  				scroller.setLCDHandle(lcdHandle);
71  				scroller.start();
72  				// welcomeMessage();
73  			}
74  		} catch (Exception e) {
75  			log.error("Error Init LCDDisplayImpl", e);
76  		}
77  	}
78  
79  	private void initPi4J() {
80  		try {
81  
82  			// gpio = GpioFactory.getInstance();
83  			gpio = OSManager.getInstance().getGpio();
84  			if (null == gpio)
85  				throw new IllegalArgumentException("GPIO Not Initialized");
86  
87  			lcdHandle = Lcd.lcdInit(LCD_ROWS, // number of row supported by LCD
88  					LCD_COLUMNS, // number of columns supported by LCD
89  					LCD_BITS, // number of bits used to communicate to LCD
90  					11, // LCD RS pin
91  					10, // LCD strobe pin
92  					0, // LCD data bit 1
93  					1, // LCD data bit 2
94  					2, // LCD data bit 3
95  					3, // LCD data bit 4
96  					0, // LCD data bit 5 (set to 0 if using 4 bit communication)
97  					0, // LCD data bit 6 (set to 0 if using 4 bit communication)
98  					0, // LCD data bit 7 (set to 0 if using 4 bit communication)
99  					0); // LCD data bit 8 (set to 0 if using 4 bit
100 						// communication)
101 
102 			// verify initialization
103 			if (lcdHandle == -1) {
104 				log.warn(" ==>> LCD INIT FAILED");
105 			}
106 
107 			// clear LCD
108 			// LCDClear();
109 			log.info("Finished Configuring LCD");
110 		} catch (Exception e) {
111 			log.error("Error Initializing Pi4J" + e);
112 		}
113 
114 	}
115 
116 	@Override
117 	public void update(Observable o, Object e) {
118 		// log.debug("Event: " + e.toString());
119 		EventBase base = (EventBase) e;
120 		switch (base.getType()) {
121 		case EVENTTRACKCHANGED:
122 			EventTrackChanged etc = (EventTrackChanged) e;
123 			CustomTrack track = etc.getTrack();
124 			if (track != null) {
125 				String s = track.getFullDetails();
126 				log.debug("TrackChanged: " + s);
127 				// UpdateScroller(s, 0);
128 				scroller.updateValues("[FULL_DETAILS]", s);
129 				scroller.updateValues("[ARTIST]", track.getArtist());
130 				scroller.updateValues("[TITLE]", track.getTitle());
131 				scroller.updateValues("[ALBUM]", track.getAlbum());
132                 scroller.updateValues("[PERFORMER]", track.getPerformer());
133 				scroller.updateValues("[COMPOSER]", track.getComposer());
134 				scroller.updateValues("[CONDUCTOR]", track.getConductor());
135 				scroller.updateValues("[DATE]", track.getDate());
136 				scroller.updateValues("[STANDBY]", "");
137 			} else {
138 				log.debug("Track was NULL");
139 			}
140 
141 			break;
142 		case EVENTUPDATETRACKMETATEXT:
143 			EventUpdateTrackMetaText et = (EventUpdateTrackMetaText) e;
144 			log.debug("Track Changed: " + et.getTitle() + " : " + et.getArtist());
145 			if (scroller != null) {
146 				// UpdateScroller(et.getTitle() + " - " + et.getArtist(), 0);
147 				scroller.updateValues("[TITLE]", et.getTitle());
148 				scroller.updateValues("[ARTIST]", et.getArtist());
149 			}
150 			break;
151 		case EVENTVOLUMECHANGED:
152 			EventVolumeChanged ev = (EventVolumeChanged) e;
153 			mVolume = ev.getVolume();
154 			// updateVolume();
155 			scroller.updateValues("[VOLUME]", "" + mVolume);
156 			break;
157 		case EVENTMUTECHANGED:
158 			if (o instanceof ObservableVolume) {
159 				EventMuteChanged em = (EventMuteChanged) e;
160 				log.debug("MuteStateChanged: " + em.isMute());
161 				isMute = em.isMute();
162 				if (em.isMute()) {
163 					scroller.updateValues("[VOLUME]", "Mute");
164 				} else {
165 					scroller.updateValues("[VOLUME]", "" + mVolume);
166 				}
167 			}
168 			break;
169 		case EVENTSTANDBYCHANGED:
170 			EventStandbyChanged es = (EventStandbyChanged) e;
171 			scroller.setReset();
172 			String sStandby = "false";
173 			if (es.isStandby()) {
174 				scroller.setStandBy(true);
175 				sStandby = "true";
176 			} else {
177 				scroller.setStandBy(false);
178 				try {
179 				} catch (Exception ex) {
180 
181 				}
182 			}
183 			scroller.updateValues("[STANDBY", sStandby);
184 			break;
185 		case EVENTTIMEUPDATED:
186 			EventTimeUpdate etime = (EventTimeUpdate) e;
187 			mTime = ConvertTime(etime.getTime());
188 			// updateVolume();
189 			scroller.updateValues("[TIME]", mTime);
190 			break;
191 
192 		}
193 	}
194 
195 	/***
196 	 * Convert seconds to Hours:Seconds
197 	 * 
198 	 * @param lTime
199 	 * @return
200 	 */
201 	private String ConvertTime(long lTime) {
202 		if (lTime == 0)
203 			return "0:00";
204 		try {
205 			if (lTime <= Integer.MAX_VALUE) {
206 				int minutes = (int) lTime / 60;
207 				int seconds = (int) lTime % 60;
208 				String sSeconds = "";
209 				if (seconds < 10) {
210 					sSeconds = "0" + seconds;
211 				} else {
212 					sSeconds = "" + seconds;
213 				}
214 				return "" + minutes + ":" + sSeconds;
215 			}
216 		} catch (Exception e) {
217 
218 		}
219 		return "" + lTime;
220 	}
221 
222 	private void getConfig() {
223 		try {
224 			String class_name = this.getClass().getName();
225 			log.debug("Find Class, ClassName: " + class_name);
226 			String path = OSManager.getInstance().getFilePath(this.getClass(), false);
227 			log.debug("Getting LCD.xml from Directory: " + path);
228 			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
229 			DocumentBuilder builder = factory.newDocumentBuilder();
230 			Document doc = builder.parse(new File(path + "LCD.xml"));
231 
232 			try {
233 				String ex_columns = "/LCD/@columns";
234 				XPath xPath = XPathFactory.newInstance().newXPath();
235 				String sColumns = xPath.compile(ex_columns).evaluate(doc);
236 				log.debug("Number of Columns: " + sColumns);
237 				LCD_COLUMNS = Integer.parseInt(sColumns);
238 			} catch (Exception e) {
239 				log.debug("Error getting Number of Columns:", e);
240 			}
241 			NodeList listOfRows = doc.getElementsByTagName("lcdrow");
242 			log.debug("Number of Rows: " + listOfRows.getLength());
243 			LCD_ROWS = listOfRows.getLength();
244 			for (int s = 0; s < listOfRows.getLength(); s++) {
245 				Node row = listOfRows.item(s);
246 				if (row.getNodeType() == Node.ELEMENT_NODE) {
247 					Element element = (Element) row;
248 					String text = getElement(element, "text");
249 					log.debug(text);
250 					RowDefinition rd = new RowDefinition();
251 					rd.setText(text);
252 					row_definition.add(rd);
253 				}
254 			}
255 
256 			NodeList listOfStandby = doc.getElementsByTagName("lcdstandby");
257 			log.debug("Number of Standby Rows: " + listOfStandby.getLength());
258 			if (LCD_ROWS < listOfStandby.getLength())
259 				LCD_ROWS = listOfStandby.getLength();
260 			for (int s = 0; s < listOfStandby.getLength(); s++) {
261 				Node row = listOfStandby.item(s);
262 				if (row.getNodeType() == Node.ELEMENT_NODE) {
263 					Element element = (Element) row;
264 					String text = getElement(element, "text");
265 					log.debug(text);
266 					RowDefinition rd = new RowDefinition();
267 					rd.setText(text);
268 					standby_definition.add(rd);
269 				}
270 			}
271 
272 		} catch (Exception e) {
273 			log.error("Error Getting LCD.xml", e);
274 		}
275 	}
276 
277 	/***
278 	 * 
279 	 * @param element
280 	 * @param name
281 	 * @return
282 	 */
283 	private String getElement(Element element, String name) {
284 		String res = "";
285 		NodeList nid = element.getElementsByTagName(name);
286 		if (nid != null) {
287 			Element fid = (Element) nid.item(0);
288 			if (fid != null) {
289 				res = fid.getTextContent();
290 				// log.debug("ElementName: " + name + " Value: " + res);
291 				return res;
292 
293 			}
294 		}
295 		return res;
296 	}
297 
298 	@Shutdown
299 	public void bye() {
300 		log.debug("ShutDown Called");
301 		if (scroller != null) {
302 			scroller = null;
303 		}
304 
305 		if (lcdHandle != -1) {
306 			int i = 0;
307 			for (int iRow = 0; iRow <= LCD_ROWS; iRow++) {
308 				Lcd.lcdPuts(i, "");
309 			}
310 			Lcd.lcdClear(lcdHandle);
311 		}
312 	}
313 
314 }