I thought it might benefit some people to see the plugin code to accomplish some cool things with this setup.
Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Phidgets;
using Phidgets.Events;
namespace BuickPhidget
{
[
GuidAttribute("69CECAE8-7125-4cf4-8726-AF40503CC406"),
ProgId("StreetDeck.BuickPhidget"),
ComVisible(true)
]
public class Class1 : StreetDeck.IDualStreetDeckAddin
{
const int headUnitId = 22284;
const int relayId = 29584;
const int numheadUnitOptions = 16;
const int refreshRate = 1000; // Clock time to check for updates. Time in mils
enum buttonPanelValues:int
{
Home = 0,
MP3 = 1,
GPS = 2,
XM = 3,
Engine = 4,
DVD = 5,
AMFM = 6,
Phone = 7
}
enum musicMode : int
{
nowPlaying = 0,
queue = 1,
albums = 2,
artist = 3,
musicHome = 4,
playlist = 5
}
musicMode currentMusicMode = musicMode.nowPlaying;
int numMusicModeOptions = 6;
StreetDeck.StreetDeckApp app;
StreetDeck.ScriptOverlay overlay;
Timer Clock;
string lastModule = "";
string lastArtist = "";
string lastSong = "";
InterfaceKit ifkit1, headUnit;
InterfaceKit ifkit2, buttonPanel;
InterfaceKit ifkit3, relay;
Phidgets.Encoder enc;
TextLCD lcd;
int lastEncodedValue = 0;
int lcdMode = 0;
int insideTemperature = 0;
int fuelLevel = 0;
int dashboardDim = 0;
string currentHeadUnitMode = "";
//This OnConnection event is where we create all of the modules and overlay streetdeck needs
//This example creates one module and one overlay
void StreetDeck.IDualStreetDeckAddin.OnConnection(object o, StreetDeck.enumAddinConnectMode e)
{
//Save a pointer to the StreetDeck App object for future reference
app = (StreetDeck.StreetDeckApp)o;
//Create an overlay that will contain the other controls. Overlays are global and will be shown
//above every other module
overlay = app.CreateOverlay("OverlayTest");
Clock = new Timer();
Clock.Interval = refreshRate;
Clock.Start();
Clock.Tick += new EventHandler(Timer_Tick);
// Get our first InterfaceKit going
ifkit1 = new InterfaceKit();
ifkit1.Attach += new AttachEventHandler(ifkit_Attach);
ifkit1.Detach += new DetachEventHandler(ifkit_Detach);
ifkit1.open();
// Get our second InterfaceKit going
ifkit2 = new InterfaceKit();
ifkit2.Attach += new AttachEventHandler(ifkit_Attach);
ifkit2.Detach += new DetachEventHandler(ifkit_Detach);
ifkit2.open();
// Get our third InterfaceKit going
ifkit3 = new InterfaceKit();
ifkit3.Attach += new AttachEventHandler(ifkit_Attach);
ifkit3.Detach += new DetachEventHandler(ifkit_Detach);
ifkit3.open();
// Load the encoder
enc = new Phidgets.Encoder();
enc.Attach += new AttachEventHandler(enc_Attach);
enc.Detach += new DetachEventHandler(enc_Detach);
enc.InputChange += new InputChangeEventHandler(enc_InputChange);
enc.PositionChange += new EncoderPositionChangeEventHandler(enc_PositionChange);
enc.open();
// Load the LCD
lcd = new TextLCD();
lcd.Attach += new AttachEventHandler(lcd_Attach);
lcd.Detach += new DetachEventHandler(lcd_Detach);
lcd.open();
}
void StreetDeck.IDualStreetDeckAddin.OnDisconnect()
{
//Unregister the events
ifkit1.close();
ifkit2.close();
//module.OnExec -= new StreetDeck.IModuleEvents_OnExecEventHandler(module_OnExec);
}
public void Timer_Tick(object sender, EventArgs eArgs)
{
try
{
if (sender == Clock && lcd.Attached)
{
// See if the module has changed
string currentModule = app.GetCurrentModuleName();
if (currentModule != lastModule)
{
lastModule = currentModule;
//lcd.rows[0].DisplayString = currentModule;
// The module has changed... We need to change the
// status lights on the button pannel.
string shorModuleName = currentModule.Substring(0,3);
if (shorModuleName == "CMu")
moduleChange(buttonPanelValues.MP3);
else
if (shorModuleName == "CNa")
moduleChange(buttonPanelValues.GPS);
else
if (shorModuleName == "CXM")
moduleChange(buttonPanelValues.XM);
else
if (shorModuleName == "CVe")
moduleChange(buttonPanelValues.Engine);
else
if (shorModuleName == "CDV")
moduleChange(buttonPanelValues.DVD);
else
if (shorModuleName == "CRa")
moduleChange(buttonPanelValues.AMFM);
else
if (shorModuleName == "CBl")
moduleChange(buttonPanelValues.Phone);
}
updateDisplay();
}
} catch {} // If the phidget is not attached we don't want errors
}
void updateDisplay()
{
switch (lcdMode)
{
case 0: // Music
currentHeadUnitMode ="Now Playing";
string currentArtist = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaArtist);
if (currentArtist != lastArtist)
{
lastArtist = currentArtist;
lcd.rows[0].DisplayString = currentArtist;
}
string currentSong = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaTitle);
if (currentSong != lastSong)
{
lastSong = currentSong;
lcd.rows[1].DisplayString = currentSong;
}
break;
case 1: // Time Left
currentHeadUnitMode = "Media Time Left";
lcd.rows[0].DisplayString = "Media Time Left";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaTimeLeft);
break;
case 2: // media Type
currentHeadUnitMode ="Media Type";
lcd.rows[0].DisplayString = "Media Type";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaType);
break;
case 3: // Distance
currentHeadUnitMode = "Distance to Destination";
lcd.rows[0].DisplayString = "Distance to Destination";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTNAVDistanceToDest);
break;
case 4: // direction
currentHeadUnitMode = "Heading";
lcd.rows[0].DisplayString = "Heading";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTNAVHeading);
break;
case 5: // Navigation Turn
currentHeadUnitMode = "Next Turn";
lcd.rows[0].DisplayString = "Next Turn";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTNAVNextStreet);
break;
case 6: // Speed
currentHeadUnitMode = "Speed";
lcd.rows[0].DisplayString = "Speed";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTNAVSpeed);
break;
case 7: // Temperatrue
lcd.rows[0].DisplayString = "Temperature";
currentHeadUnitMode = "Temperature";
lcd.rows[1].DisplayString = Convert.ToString(insideTemperature)+"F";
//app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTHWStatusTemperature);
break;
case 8: // City State Location
lcd.rows[0].DisplayString = "Location";
currentHeadUnitMode = "Location";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTNAVCityStateZip);
break;
case 9: // Current Module
currentHeadUnitMode = "Module";
lcd.rows[0].DisplayString = "Module";
lcd.rows[1].DisplayString = app.GetCurrentModuleName();
break;
case 10: // Time Left
currentHeadUnitMode = "Media Duration";
lcd.rows[0].DisplayString = "Media Duration";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaDuration);
break;
case 11: // Time
currentHeadUnitMode = "Current Heading";
lcd.rows[0].DisplayString = "Heading";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTTime);
break;
case 12: // Time
currentHeadUnitMode = "Time to Destination";
lcd.rows[0].DisplayString = "Time to Destination";
lcd.rows[1].DisplayString = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTNAVTimeToDest);
break;
case 13: // Logo
currentHeadUnitMode = "Nineteen fifty-five Buick special";
lcd.rows[0].DisplayString = " 1955";
lcd.rows[1].DisplayString = " BUICK SPECIAL";
break;
case 14: // Fuel
currentHeadUnitMode = "Fuel Level";
lcd.rows[0].DisplayString = "Fuel";
lcd.rows[1].DisplayString = Convert.ToString(fuelLevel); // Read from Voltage sensor.
break;
default:
lcdMode = 0;
break;
}
}
void buttonPanel_InputChange(object sender, InputChangeEventArgs e)
{
if (e.Value) // We don't want to run this on up and down push of hte button
{
switch ((buttonPanelValues)e.Index)
{
case buttonPanelValues.Home:
//inputCheckBox0.Checked = e.Value
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionHome);
lcd.rows[0].DisplayString = "Home";
break;
case buttonPanelValues.MP3:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionMusic);
lcd.rows[0].DisplayString = "MP3";
currentMusicMode = (musicMode)((int)((int)currentMusicMode + 1) % numMusicModeOptions);
switch (currentMusicMode)
{
case musicMode.nowPlaying:
overlay.Exec("CMusicNowPlayingModule");
break;
case musicMode.queue:
overlay.Exec("CMusicNowPlayingModule");
break;
case musicMode.albums:
overlay.Exec("CMusicAlbumStringColModule");
break;
case musicMode.artist:
overlay.Exec("CMusicArtistStringColModule");
break;
case musicMode.musicHome:
overlay.Exec("CMusicModule");
break;
case musicMode.playlist:
overlay.Exec("CMusicPlaylistModule");
break;
default:
break;
}
break;
case buttonPanelValues.GPS:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionNavigation);
lcd.rows[0].DisplayString = "GPS";
break;
case buttonPanelValues.XM:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionXMRadio);
lcd.rows[0].DisplayString = "XM";
break;
case buttonPanelValues.Engine:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionVehicle);
overlay.Exec("CVehicleGraphOBDIIModule");
lcd.rows[0].DisplayString = "Engine";
buttonPanel.outputs[(int)buttonPanelValues.Engine] = true;
break;
case buttonPanelValues.DVD:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionDVD);
lcd.rows[0].DisplayString = "DVD";
break;
case buttonPanelValues.AMFM:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionRadio);
lcd.rows[0].DisplayString = "AM/FM";
break;
case buttonPanelValues.Phone:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionBluetoothModule);
lcd.rows[0].DisplayString = "Phone";
break;
default:
break;
}
moduleChange((buttonPanelValues)e.Index);
}
}
void moduleChange(buttonPanelValues v)
{
// first turn everything off
for (int i = 0; i < 8; i++)
buttonPanel.outputs[i] = false;
// Now, turn on the specific value
buttonPanel.outputs[(int)v] = true;
// Then, light up the music/satalite/DVD button if they are playing
string mediaType = app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaType);
if (mediaType == "Music")
buttonPanel.outputs[(int)buttonPanelValues.MP3] = true;
if (mediaType == "Satelite")
buttonPanel.outputs[(int)buttonPanelValues.XM] = true;
if (mediaType == "DVD")
buttonPanel.outputs[(int)buttonPanelValues.DVD] = true;
lastModule = app.GetCurrentModuleName(); // so we won't detect amodule change.
// make sure the radio anteana is up if we are in radio mode
if (v == buttonPanelValues.AMFM)
relay.outputs[0] = true;
else
relay.outputs[0] = false;
}
// There are currently no sensors on this interface kit.
void buttonPanel_SensorChange(object sender, SensorChangeEventArgs e)
{
}
void headUnit_InputChange(object sender, InputChangeEventArgs e)
{
if (e.Value) // We don't want to run this on up and down push of the button
{
switch (e.Index)
{
case 0:
//Togle display mode
lcdMode = (lcdMode + 1) % numheadUnitOptions;
// lcd.rows[0].DisplayString = "LcdMode " + Convert.ToString(lcdMode);
lastArtist = ""; // force redisplay of current artist
lastSong = "";
updateDisplay();
app.SpeechController.Speak(currentHeadUnitMode);
break;
case 1:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionTogglePause);
app.SpeechController.Speak(app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaState));
break;
case 3:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionNext);
app.SpeechController.Speak("Next");
break;
case 2:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionPrevious);
app.SpeechController.Speak("Previous");
break;
case 4:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionFF);
app.SpeechController.Speak(app.GetDynamicStringValue(StreetDeck.enumDynamicLabelType.eDLTMediaState));
break;
default:
break;
}
}
}
void headUnit_SensorChange(object sender, SensorChangeEventArgs e)
{
switch (e.Index)
{
case 0:
//Volume Knob
uint vol = (uint)(1000 - e.Value) / 10;
app.SetVolume(StreetDeck.enumVolumeTypes.eVTMaster, vol);
break;
case 1:
// Inner Tone knob
if (e.Value < 500)
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionSetNightMode);
else
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionSetDayMode);
break;
case 2: // Temperature
insideTemperature = (9 / 5) * ((e.Value - 200) / 4) + 32;
break;
case 3:
//Fuel Sensor
fuelLevel = (e.Value - 553) / (739-553) * 100; //739 ;
//app.SetVolume(StreetDeck.enumVolumeTypes.eVTMaster, vol);
break;
case 7:
// Dashboard light dimmer
dashboardDim = (e.Value - 553) / (739 - 553) * 100;
break;
default:
break;
}
}
void ifkit_Detach(object sender, DetachEventArgs e)
{
}
private void ifkit_Attach(object sender, AttachEventArgs e)
{
InterfaceKit phid = (InterfaceKit)sender;
switch (phid.SerialNumber)
{
case headUnitId: // Head Unit
phid.SensorChange += new SensorChangeEventHandler(headUnit_SensorChange);
phid.InputChange += new InputChangeEventHandler(headUnit_InputChange);
headUnit = phid;
break;
case relayId: // The relay
relay = phid;
break;
default: // The button pannel
phid.SensorChange += new SensorChangeEventHandler(buttonPanel_SensorChange);
phid.InputChange += new InputChangeEventHandler(buttonPanel_InputChange);
buttonPanel = phid;
// Turn everything on to show that we are working
for (int i = 0; i < 8; i++)
buttonPanel.outputs[i] = true;
break;
}
}
// If you rotate the encoder, then do function up or down.
void enc_PositionChange(object sender, EncoderPositionChangeEventArgs e)
{
switch (e.Index)
{
case 0:
if (enc.encoders[0] > lastEncodedValue)
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionUp);
else
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionDown);
lastEncodedValue = enc.encoders[0];
break;
default:
break;
}
}
// If you press the encoder in, then emit "OK".
void enc_InputChange(object sender, InputChangeEventArgs e)
{
switch (e.Index)
{
case 0:
app.SendFunction(StreetDeck.enumSDFunctions.eFunctionOk);
break;
default:
break;
}
}
void enc_Detach(object sender, DetachEventArgs e)
{
}
void enc_Attach(object sender, AttachEventArgs e)
{
Phidgets.Encoder phid = (Phidgets.Encoder)sender;
}
void lcd_Detach(object sender, DetachEventArgs e)
{
}
void lcd_Attach(object sender, AttachEventArgs e)
{
Phidgets.TextLCD phid = (Phidgets.TextLCD)sender;
lcd.rows[0].DisplayString = " 1955";
lcd.rows[1].DisplayString = " BUICK";
}
}
}
As always with software, this is version 0.1. I still have to add support for my HQCT-eA. That should be fun!
Bookmarks