This integration method is an advanced solution that requires the use of any 3rd party USB to 9-pin serial adapter, adding serial support into Python on Mac OS X, creating a small Python serial command-sending script, and creating both send and response triggers within Indigo to send TV commands and respond to the results of sending those commands. As an alternative, you could likely devise a less complex (and less functional) solution that uses an Insteon-to-IR device.
Serial-to-TV Connection
You'll first need to attach the TV's serial port to your Mac. The Panasonic TC-P65VT30 comes with a RS-232C adapter that must be plugged into it's proprietary dedicated 1/8" RS-232C plug. The adapter has a 1/8" stereo plug on one end and a female 9-pin serial port on the other end. You'll need to find or buy a USB-to-serial adapter. I use a rather generic PL2303 based USB-to-serial adapter. The biggest issue with that type of adapter is that the official PL2303 drivers for Mac OS X 10.6 don't actually work properly (at least they don't for me), so I had to find free alternative (beta) drivers. If you have a PL2303-based USB-to-serial adapter (commonly branded by companies like IOData, Samsung, Siemens, Nokia, RadioShack, and others), you can download the free SourceForge Mac OS X drivers (that work better for me) from here. Once you've connected everything (proprietary adapter into TV, serial cable into proprietary adapter, other end of serial cable into USB-to-serial adapter, USB-to-serial adapter into Mac running Indigo, USB adapter drivers installed), you can move on to the next phase of setup.
Install Pyserial for Python
Every Mac OS X installation (from at least 10.3 on, perhaps even earlier) includes the Python scripting language pre-installed. However, it doesn't include the required extension to access serial ports through Python, so you'll need to add that extension yourself. You can download the free "pyserial" extension from this page. Download the latest .tar.gz version of the pyserial extension (this is the version that's compatible with Mac OS X). Once downloaded, double-click on the resulting file to expand the tar.gz file. Use the Terminal application to execute the setup.py script.
- Code: Select all
cd ~/Downloads/pyserial-2.5
python serup.py install
Note that the above "pyserial-2.5" part of the first command assumes you've downloaded version 2.5 of the pyserial extension (the latest version as of this writing). If you've downloaded a newer version, use that version number. If you've placed your expanded pyserial extension download somewhere other than your Downloads folder, use the full path to that folder with the "cd" command above. Once you've executed the setup.py script, that should be all you need to do to install the extension.
Create the TV Command Sending Python Script
We now need to find out what name your system uses to refer to the USB-to-serial adapter. This could be difficult, especially if your adapter uses the same FTDI drivers used by Indigo to communicate with Insteon/X10 modules. In my case, since I used a PL2303-based USB-to-serial adapter, the name of the serial port was obvious. With the Terminal application still open, change to the "/dev" directory and list all the character devices.
- Code: Select all
cd /dev
ls -l cu*
You'll probably see something similar to what I do.
- Code: Select all
crw-rw-rw- 1 root wheel 10, 7 Jun 25 01:26 cu.Bluetooth-Modem
crw-rw-rw- 1 root wheel 10, 5 Jun 25 01:26 cu.Bluetooth-PDA-Sync
crw-rw-rw- 1 root wheel 10, 3 Jun 25 11:31 cu.PL2303-0000205D
crw-rw-rw- 1 root wheel 10, 1 Jun 25 11:31 cu.usbserial-A60089RB
In the above listing, the "usbserial-..." serial port is my USB PowerLinc Modem (2413U). The "PL2303-..." device is my USB-to-serial adapter. Write down or copy the full name of your USB-to-serial adapter in the listed output (for me that'd be "cu.PL2303-0000205D").
With the Terminal application still open, change working directories to an appropriate location for storing a background process script. I'm using Indigo Pro 4, so I put my script in the Indigo 4 background scripts folder
- Code: Select all
cd "/Library/Application Support/Perceptive Automation/Indigo 4/Scripts/Background Tasks"
Use the "vi" command-line utility to create the script that actually connects to the TV via serial connection, sends commands, and waits for responses to give back to Indigo. You can use another command-line text editor if you like (perhaps "nano") but all the instructions here will use vi.
- Code: Select all
vi tv-send-command.py
I used the file name "tv-send-command.py" but you can use any file name you prefer. It should, however, end with ".py" to designate it as a Python script. Insert the following Python script into the newly created file.
- Code: Select all
#!/usr/bin/python
import sys;
import time;
import serial;
theCommand = "\x02" + sys.argv[1] + "\x03"
ser = serial.Serial("/dev/cu.PL2303-0000205D", 9600, timeout=1)
if ser.readable() == True:
if ser.writable() == True:
ser.write(theCommand)
time.sleep(0.25)
n = ser.inWaiting()
x = ser.read(n)
x = x.strip("\x02")
x = x.strip("\x03")
print x
ser.close()
Note the serial port name in the above script. Be sure and change that "cu.PL2303..." name to the name of your USB-to-serial device. The above code takes whatever textual command you send the tv-send-command script, inserts the required special characters before and after that command, sends the full command to the TV, waits for the TV's response to that command, then removes the special characters the TV inserts before and after the response before returning the textual response as the output from the tv-send-command.
Now make the Python script executable by everyone. This is needed so Indigo can use it.
- Code: Select all
chmod a+x tv-send-command.py
You can now quit the Terminal application.
Create Indigo Variables and Triggers
Open the Indigo client. Create 2 new variables (Window menu, Variable List, click New, you can place the variables in any folder you deem appropriate, if you like). The first should be named "TVCommand" and the second should be named "TVCommandResponse".
Now, we're going to create 2 new triggers. The first will send whatever command is placed in the "TVCommand" variable to the TV and place the TV's response in the "TVCommandResponse" variable. The second will process the response placed in the "TVCommandResponse" variable to provide feedback within Indigo.
Create the first trigger with the following settings.
Name: Send TV Command
Trigger tab
Type: Variable Changed
Variable: TVCommand
"changes" radio button selected.
Condition tab
Upon trigger do action: "If script returns true" radio button selected, with the following code in the text entry area.
- Code: Select all
if value of variable "TVCommand" is not "" then
return true
else
return false
end if
Action tab
Type: Execute AppleScript
"Embedded:" radio button selected with the following code in the text entry area.
- Code: Select all
set theCommand to value of variable "TVCommand"
-- Send the command to the TV using the custom Python script that connects to the TV via serial connection.
set theResponse to do shell script "/Library/Application\\ Support/Perceptive\\ Automation/Indigo\\ 4/Scripts/Background\\ Tasks/tv-send-command.py " & theCommand
-- Assign the response value to an Indigo variable.
set value of variable "TVCommandResponse" to theResponse
-- Reset the TVCommand variable to blank.
set value of variable "TVCommand" to ""
Note that the above code assumes 1) you named the Python script the same way I did, 2) you put the tv-send-command.py file in the same location I did, and 3) you're using Indigo Pro 4. Adjust the "do shell script" command as necessary for your setup.
Create the second trigger with the following parameters.
Name: TV Command Response
Trigger tab
Type: Variable Changed
Variable: TVCommandResponse
"changes" radio button selected.
Condition tab
Upon trigger do action: "If script returns true" radio button selected, with the following code in the text entry area.
- Code: Select all
if value of variable "TVCommandResponse" is not "" then
return true
else
return false
end if
Action tab
Type: Execute AppleScript
"Embedded:" radio button selected with the following code in the text entry area.
- Code: Select all
-- Custom actions based on responses.
if value of variable "TVCommandResponse" starts with "ER" then
-- Invalid Command... Ignore it.
else if value of variable "TVCommandResponse" starts with "QPW" then
-- Power Query Response
if value of variable "TVCommandResponse" is "QPW:1" then
-- Power is On
else
-- Power is Off
end if
else if value of variable "TVCommandResponse" is "PON" then
-- Power is On
else if value of variable "TVCommandResponse" is "POF" then
-- Power is Off
else if value of variable "TVCommandResponse" starts with "AVL" then
-- Volume Change
else if value of variable "TVCommandResponse" starts with "QAV" then
-- Volume Query Response
else if value of variable "TVCommandResponse" is "AUU" then
-- Volume Up
else if value of variable "TVCommandResponse" is "AUD" then
-- Volume Down
else if value of variable "TVCommandResponse" starts with "QAM" then
-- Mute Query Response
else if value of variable "TVCommandResponse" starts with "AMT" then
-- Mute Toggle
else if value of variable "TVCommandResponse" starts with "IMS" then
-- Input Select Change
if value of variable "TVCommandResponse" is "IMS:TV" then
-- TV Input Selected
else if value of variable "TVCommandResponse" is "IMS:C1" then
-- Component Input Selected
else if value of variable "TVCommandResponse" is "IMS:V1" then
-- Composite Video Input Selected
else if value of variable "TVCommandResponse" is "IMS:H1" then
-- HDMI 1 Input Selected
else if value of variable "TVCommandResponse" is "IMS:H2" then
-- HDMI 2 Input Selected
else if value of variable "TVCommandResponse" is "IMS:H3" then
-- HDMI 3 Input Selected
else if value of variable "TVCommandResponse" is "IMS:H4" then
-- HDMI 4 Input Selected
else if value of variable "TVCommandResponse" is "IMS:PC" then
-- PC (VGA) Input Selected
else if value of variable "TVCommandResponse" is "IMS:SP" then
-- Photo Media Player Input Selected
else if value of variable "TVCommandResponse" is "IMS:SM" then
-- Video Media Player Input Selected
else if value of variable "TVCommandResponse" is "IMS:MC" then
-- Music Media Player Input Selected
else if value of variable "TVCommandResponse" is "IMS:VC" then
-- VIERA Connect (Internet) Input Selected
end if
else if value of variable "TVCommandResponse" starts with "QMI" then
-- Input Query Response (same input names as above)
if value of variable "TVCommandResponse" is "QMI:TV" then
-- TV Input Selected
else if value of variable "TVCommandResponse" is "QMI:C1" then
-- Component Input Selected
else if value of variable "TVCommandResponse" is "QMI:V1" then
-- Composite Video Input Selected
else if value of variable "TVCommandResponse" is "QMI:H1" then
-- HDMI 1 Input Selected
else if value of variable "TVCommandResponse" is "QMI:H2" then
-- HDMI 2 Input Selected
else if value of variable "TVCommandResponse" is "QMI:H3" then
-- HDMI 3 Input Selected
else if value of variable "TVCommandResponse" is "QMI:H4" then
-- HDMI 4 Input Selected
else if value of variable "TVCommandResponse" is "QMI:PC" then
-- PC (VGA) Input Selected
else if value of variable "TVCommandResponse" is "QMI:SP" then
-- Photo Media Player Input Selected
else if value of variable "TVCommandResponse" is "QMI:SM" then
-- Video Media Player Input Selected
else if value of variable "TVCommandResponse" is "QMI:MC" then
-- Music Media Player Input Selected
else if value of variable "TVCommandResponse" is "QMI:VC" then
-- VIERA Connect (Internet) Input Selected
end if
else if value of variable "TVCommandResponse" starts with "VPC" then
-- Picture Mode Change
if value of variable "TVCommandResponse" is "VPC:VVT" then
-- Vivid
else if value of variable "TVCommandResponse" is "VPC:STD" then
-- Standard
else if value of variable "TVCommandResponse" is "VPC:THX" then
-- THX
else if value of variable "TVCommandResponse" is "VPC:CNM" then
-- Cinema
else if value of variable "TVCommandResponse" is "VPC:GAM" then
-- Game
else if value of variable "TVCommandResponse" is "VPC:CST" then
-- Custom
end if
else if value of variable "TVCommandResponse" starts with "QPC" then
-- Picture Mode Query Response (same mode names as above).
if value of variable "TVCommandResponse" is "QPC:VVT" then
-- Vivid
else if value of variable "TVCommandResponse" is "QPC:STD" then
-- Standard
else if value of variable "TVCommandResponse" is "QPC:THX" then
-- THX
else if value of variable "TVCommandResponse" is "QPC:CNM" then
-- Cinema
else if value of variable "TVCommandResponse" is "QPC:GAM" then
-- Game
else if value of variable "TVCommandResponse" is "QPC:CST" then
-- Custom
end if
else if value of variable "TVCommandResponse" starts with "DAM" then
-- Aspect Mode Change
if value of variable "TVCommandResponse" is "DAS:ZOOM" then
-- Zoom
else if value of variable "TVCommandResponse" is "DAS:FULL" then
-- Full Screen
else if value of variable "TVCommandResponse" is "DAS:JUST" then
-- Justified (Stretch)
else if value of variable "TVCommandResponse" is "DAS:NORM" then
-- 4:3
else if value of variable "TVCommandResponse" is "DAS:HFIL" then
-- Fill (Stretch)
end if
else if value of variable "TVCommandResponse" starts with "QAS" then
-- Aspect Mode Request Response (same values as above).
if value of variable "TVCommandResponse" is "QAS:ZOOM" then
-- Zoom
else if value of variable "TVCommandResponse" is "QAS:FULL" then
-- Full Screen
else if value of variable "TVCommandResponse" is "QAS:JUST" then
-- Justified (Stretch)
else if value of variable "TVCommandResponse" is "QAS:NORM" then
-- 4:3
else if value of variable "TVCommandResponse" is "QAS:HFIL" then
-- Fill (Stretch)
end if
else if value of variable "TVCommandResponse" starts with "INF" then
-- Info (Resolution) Request Response.
set t to value of variable "TVCommandResponse"
set l to (count of characters in t)
set n to (characters 5 through l of t) as text
-- n is the current TV resolution.
else if value of variable "TVCommandResponse" starts with "QIF" then
-- Resolution Request Response (same as above)
set t to value of variable "TVCommandResponse"
set l to (count of characters in t)
set n to (characters 5 through l of t) as text
-- n is the current TV resolution.
end if
You can add your own AppleScript code to the areas above where I've left comments about what information was returned. For me, I assign values such as current input selection and picture mode into other Indigo variables for display on a control page viewable from my iPhone (or web browser, or other iOS device).
That should be it! For my setup, I use an iPod touch as an Indigo Touch client that views a control page I set up just for the TV. It shows the TV's current input, resolution, picture mode, and aspect mode and allows me to emulate a TV remote control with the iPod touch using an Indigo control page.