Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

Monday, March 8, 2010

Adventures in X10 Home automation with iphone and JQTouch

This year my tax return was big. It let me afford to purchase some things that I've wanted to play with for a while now, not the least of which the cm19a X10 RF controller like this one here

http://www.thehomeautomationstore.com/cm19a.html

I think this device is probably anyone's best bet for this sort of thing as it does not interface directly with any sort of power outlet so you don't have to worry about some sort of freak occurrence happening and destroying your precious, precious computer.

This means though that you will also need to purchase the transceiver module

http://www.thehomeautomationstore.com/tm751.html

then of course you will want at least one or more lamp/appliance modules

X10 is sort of the old man at the table of home automation, so there's plenty of documentation on how it does what it does, not to mention hard ware and modules are pretty reasonable compared to the newer standards like Z-wave.

the beauty of this little device is it is supported in linux with control via the command line.

to achieve this we first get the most recent driver from here

http://lemaymd.com/drupal/node/3

extract the files to your home directory
(I'm using Ubuntu 9.10)

go ahead an plug in the device to an open USB port and confirm that the computer sees it

$ lsusb

...
Bus 005 Device 002: ID 0bc7:0002 X10 Wireless Technology, Inc. Firecracker Interface (ACPI-compliant)
...


To build the modules make sure you have the build-essential package installed

$ sudo apt-get install build-essential

then

$ cd x10-cm19a-0.1.1/

$ sudo make
$ sudo make install

if everything went well, it should compile with out any major complications or errors

if it didn't, or you feel like you need to recompile the module, be sure to run sudo make clean before trying again.


but now we are faced with some kernel confusion. Stock builds of Ubuntu will more then likely think the cm19a is some sort of ir receiver device or other kind of remote control. To set it straight we add these modules to the kernel module blacklist

$ sudo gedit /etc/modprobe.d/blacklist.conf

add these lines

blacklist lirc_atiusb
blacklist ati_remote

save and close
then remove the modules from the current state of the kernel

$ sudo rmmod lirc_atiusb
$ sudo rmmod ati_remote

then to add the cm19a module

$ sudo modprobe x10-cm19a

There may be some plugging and unplugging but you should see your new device show up in /dev

$ ls /dev/c*

/dev/cm19a0

if you don't see it here now, a reboot may solve the issue, or you can add some rules to udev to make sure it gets inserted with the right permissions and or other custom parameters. Check this post out for more on that

http://pr0gr4mm3r.com/linux/getting-your-x10-cm19a-module-working-in-linux/

if everything worked you should now be able to write commands directly to the device in this manner to turn off the X10 module with house code A unit code 5

$ echo -A5 > /dev/cm19a0

this does not give you any direct feedback though, so for debugging dmesg and syslog are your friend

open up a new terminal of your choice and run either

$ dmesg | tail

or

$ tail -f /var/log/syslog

(passing the -f flag to tail will let tail follow the file as new lines come in)

you should see something like


Mar 8 11:02:08 ubunbox kernel: [164153.964339] x10-cm19a: devf_write called with buffer length 4
Mar 8 11:02:08 ubunbox kernel: [164153.964346] x10-cm19a: got off command
Mar 8 11:02:08 ubunbox kernel: [164153.964348] x10-cm19a: house code A
Mar 8 11:02:08 ubunbox kernel: [164153.964351] x10-cm19a: unit = 1
Mar 8 11:02:08 ubunbox kernel: [164153.964354] x10-cm19a: Created HA command: off a 1
Mar 8 11:02:08 ubunbox kernel: [164153.964357] x10-cm19a: Transmitting 5 byte command:
Mar 8 11:02:08 ubunbox kernel: [164153.964360] x10-cm19a: buf[0] = 20
Mar 8 11:02:08 ubunbox kernel: [164153.964363] x10-cm19a: buf[1] = 60
Mar 8 11:02:08 ubunbox kernel: [164153.964365] x10-cm19a: buf[2] = 9F
Mar 8 11:02:08 ubunbox kernel: [164153.964368] x10-cm19a: buf[3] = 20
Mar 8 11:02:08 ubunbox kernel: [164153.964370] x10-cm19a: buf[4] = DF
Mar 8 11:02:08 ubunbox kernel: [164153.964376] x10-cm19a: wrote command
Mar 8 11:02:08 ubunbox kernel: [164153.964379] x10-cm19a: read back interrupt data
Mar 8 11:02:08 ubunbox kernel: [164153.964382] x10-cm19a: devf_write: back from x10_transmit_cmd
Mar 8 11:02:08 ubunbox kernel: [164153.966694] x10-cm19a: freeing buffer in callback (0xf685e020/0x3685e020)


So now that you have command line access to any X10 enabled appliance in your house, the next thing you want to do is set up some server side script to make access from mobile devices possible

this is a quick and dirty PHP file that takes arguments via http GET requests
By reading further you acknowledge that I am in no way responsible for any undesired effects!!!
but feel free to use it to whatever legal ends you see fit

Put this in some protected web directory in whatever php capable server you are running.

see .htaccess for more on using basic authincation to protect files and directories under apache

Some might also notice that I am using the command line backticks here. You can read up about this on the official PHP.org site to get more info on alternative methods for running cli commands and the potential security risks

<?
####
#Scott Cheezem
#03052010
###
#h - the house code
#u - the unit code
#s - the state 1 for on 0 for off
function check($ch){
#echo "checking $ch";
if (isset($_GET[$ch]) && strlen($ch) == 1){

return true;
}
}


if (check('h') && check('u') && check('s')){
$h=$_GET['h'];
$u=$_GET['u'];
$s=$_GET['s'];
if($s=="0"){
$s="-";
}else if($s=="1"){
$s="+";
}
$ts=`date`;
$command="echo ".$s.$h.$u." > /dev/cm19a0";
#echo $command;
`$command`;
$log=`echo "$ts $command" >> x10.log`;
}

?>

after that is done check to make sure everything is working as it should up to this point...

try going to

http://ip.address.of.your.computer/path/to/file/whateverYouCalledIt.php?h=A&u=1&s=1

and it should turn on house code A, unit code 1


and now the pay off!!!!

the next layer in this delicious cake of home automation is your interface.... Your iphone interface!!!

I have a working version of a webapp I call liveHouse. feel free to check it out here on your ipod touch/iphone/Safari (even windows safari works! YAY!)

http://user.theroyalwe.net/liveHouse









if you want to download the code to use on your own server go here

http://user.theroyalwe.net/liveHouse.zip


click the plus in safari and then add to home screen to install on your device











(note: in the case of webapps like this one, all the javascript CSS images and html are cached locally to your phone. when ever you run the app, it will check automatically for any updates to the code and download them. really,who needs the app sotre!?!)

this app was developed with jquery and the jqtouch extension.

more info on jqtouch here

http://code.google.com/p/jqtouch/

NOTE: this is just the first working draft. The control script url (the php file we made earlier) and optional login credentials are stored in a cookie in plain text. For anyone planning on using this from behind their home network, this should be fine. I would not recommend using this script from outside your local area network if security is an issue!!!


Cheers and Happy home-atuomating!!!

Monday, February 23, 2009

remote Tv

So about a year ago my now-roommate bequeathed me with a PCI-WinTv decoder/PVR/tv card. Always excited to try legacy hardware in my ubuntu box I popped it in, and got MythTv up and running. But much to my dismay MythTv ran like crap on my slightly older, surplussed hardware. Audio was not decoding at the correct sample rate, the display was lagged and pixilated, and MythTv was hogging all of my precious resources (is a mysql DB really necessary for watching TV?). At the time, recording Tv shows was lower on the priority totem than having clear crisp Tv on my Desktop.

TvTime was next and did what it does very well. Clear audio, crisp full screen Tv, no lag. But how quickly our satisfaction fades. One thing about the winTv cards is that the defacto hardware install calls for a patch cable to be run from the line out on the card to a line in on the motherBord/sound card in order to get analog sound. And this is Fine untill I move my computer, or the cat walks behind it or some other such thing that causes the cable to become unplugged. Plus it just seems so...extraneous.

Of course all this begged the question, why not use my favorite open source, seemingly trans-platform, streaming media player, VLC? why not indeed. First Run didn't produce much. In Linux world we get a V4L tab ( in windows its DirectShow ). pointing it at my video device (/dev/video0), only produced a screen full of static and no sound at all. Ultimately though, spurred on with much success streaming from webcams and the like, I knew I really wouldn't be happy until I could watch and stream TV with vlc. Last weekend, however, my patience and perseverance paid off and Now I am streaming TV from home to work as I write this very satisfied with my technological prowess.

and of course here is a road map to help other perspective tv streamers and sopCasters.


1. what driver do you need? where do you get it?

This part, mythTv took care of for me, but I know there are a variety of options here in terms of open source drivers. Mine ended up being Cx88xx (or some such thing) more information check on the v4l home page (http://www.linuxtv.org/)
Chances are, if you're using something like a Debian/ubuntu these are already included in your kernel so not much to worry about.

2. what's what in /dev

after I installed the card and mythTv did it's thing I noticed some new listings under the /dev directory. radio0, video0, vbi0, audio2. The trick is figuring out what's what. This step took me a while and turned out to be a huge pain in the ass as on the surface linux isn't very forthcoming about details (at least if you don't know how to ask). On top of that I also have two webcams plugged in to the machine in question. On reboot my kernel would sometimes switch around all the asignments of the name space (IE video0, a webcam might be come video1).

I don't reboot my machine that often, but when I do, I like it when my scripts dont get confused about what piece of hardware they should be talking to. Enter the magic of UDEV rules. Only really ever having used the ubuntu distro I can't speak to weather udev is common among other *nixes or not, but I'm glad that they are in Ubuntu. for those who don't know, they allow for a rule sheet with mappings to a consistent file system name space.

For example,
from (/etc/udev/rules.d/95-perso.rules)

KERNEL=="video[0-9]", SYSFS{name}=="cx88*video*", SYMLINK+="tv"

will tell the kernel at start up, after its done its initial hardware mapping to make an additional symlink to whatever device that comes up with "cx88" and "video" to /dev/tv. Of course thats only one way in an entire search syntax to have it map your devices for you (see the ubuntu forums and http://reactivated.net/writing_udev_rules.html for more on this).
so after a quick script to run through all the items in /dev and list only the ones that had something to do with the cx88 dirver...


for i in /dev/* ; do udevinfo -q path -n $i ; done 2>&1 | grep -v node | while read a ; do udevinfo -a -p "$a" | if grep -i some part of the driver name that you are searching for (like "cx88") ; then echo $a ; fi ; done

running that from a command line or script should list all the devices that use the search term in question.

3. VLC

with the freshly created /dev/tv and /dev/tvAudio we can now move on to working with VLC. Knowing that I would want to be able to remotely stop and start the stream with vlc I whipped up this little bash script called remotetv.

#!/bin/bash

if [[ $1 == '' ]] ; then
iam=$(ps ax | grep vlc | grep '/dev/tv');
iam="${iam# }";
iam="${iam%% *}";
if [[ $iam == '' ]] ; then
exit 0;
else
echo "$iam";
fi;
elif [[ $1 == 'start' ]] ; then


vlc -vvv -I dummy --ttl 12 v4l:/dev/tv:size=320x240:samplerate=48000:adev=/dev/tvAudio --sout '#transcode{vcodec=DIV3,vb=512,scale=1,acodec=mp3,ab=64,channels=1}:duplicate{dst=std{access=http,mux=ogg,dst=0.0.0.0:1235}}' 2>/dev/null 1>/dev/null &



elif [[ $1 == 'stop' ]] ; then
killMe=$(ps ax | grep vlc | grep '/dev/tv') ;
killMe="${killMe# }";
killMe="${killMe%% *}";
# echo "$killMe";
kill -9 "$killMe";
fi


put it in /usr/local/bin, chmod ug+x, and bam! start/stop vlc with remotetv stop or remotetv start. check the process-ID by simply calling remotetv and if its running it will tell you the PID
some things to note...

v4l:/dev/tv:size=320x240:samplerate=48000:adev=/dev/tvAudio

/dev/tv & /dev/tvAudio are the two devices that we made earlier with the UDEV rules.

:samplerate=48000

this one took me a loooooong time to figure out. my card's default sample rate is 48000. VLC calls v4l with a default sample rate of 42000 but this causes the audio to sound like its being squeezed through a tin horn. setting it corectly should take care of that.

for the rest of the parameters dealing with streaming (codecs, containers, bit-rates and stream destinations) and on the fly transcoding check out the videolan wiki (http://wiki.videolan.org)


once remotetv is running, you should be able to connect to the stream from multiple machines simultaneously with

vlc http://your.ip.address:1235


4. Changing Channels?

so there may be a way to pass the frequency to VLC directly, but from what I understand it will only take the frequency not the channel, so you need to have a mapping of frequency to channel. Fortunately we don't need VLC to change channels for us we can use the tools that came with ivtv (which were probably installed when we installed and ran tvtime or mythtv, if not a simple apt-get install ivtv should do it)

from the command line something like this will change to channel XX

me@ubunbox:~$ ivtv-tune -d /dev/tv -c XX

**a quick note: it is possible to change channels with the v4lctl command, something like v4lctl -c /dev/tv setchannel XX is supposed to work, but on my box with my card, it seems to cuase a bit of unpleasant panic**

and for some, that might be everything you need to enjoy some streaming tv and remotely change channels, but for me I wanted a more friendly interface, maybe even something I could use from my phone.

so after a little more coding I wrote up a page in php with so called smart phones in mind (but also works in the usual browsers, FF IE safari. not yet tested in chrome).

I've put the script and the php page I wrote up on source forge please feel free to check it out and check out the additional documentation I included (though really there is a lot in this post that isn't covered there).

check out
https://sourceforge.net/projects/remotetv/