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
37
38
39
40
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
73 }
74 } catch (Exception e) {
75 log.error("Error Init LCDDisplayImpl", e);
76 }
77 }
78
79 private void initPi4J() {
80 try {
81
82
83 gpio = OSManager.getInstance().getGpio();
84 if (null == gpio)
85 throw new IllegalArgumentException("GPIO Not Initialized");
86
87 lcdHandle = Lcd.lcdInit(LCD_ROWS,
88 LCD_COLUMNS,
89 LCD_BITS,
90 11,
91 10,
92 0,
93 1,
94 2,
95 3,
96 0,
97 0,
98 0,
99 0);
100
101
102
103 if (lcdHandle == -1) {
104 log.warn(" ==>> LCD INIT FAILED");
105 }
106
107
108
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
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
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
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
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
189 scroller.updateValues("[TIME]", mTime);
190 break;
191
192 }
193 }
194
195
196
197
198
199
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
280
281
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
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 }