Android and Linux

Tuesday, January 4, 2011

Heyu home automation toggle for Tasker

(To my regular Android visitors, much of this has been posted here before, but I wanted to put it all together for any X10 users who stumble across it. Although it is related to specific home automation software, it might still be interesting to Tasker users too.)

If you're using X10 home automation devices at home, there are a few apps for controlling them on your Android phone, but if you don't mind using ssh and controlling your X10 from the command line, there are ways to make control your home for free. And, if you want to use an Android app called Tasker, it can be even more powerful that anything on the Market.

This will only concentrate on the simple stuff, how to get Tasker to control Heyu and how to make icons to imitate an X10 app. Tasker can perform so many other functions, like turning on your security system or opening your garage door when you reach certain GPS coordinates, that I don't want to touch on them here.

So, let's do the "simple" stuff. It may look crazily hard but it's not once you're familiar with Tasker/Heyu/X10. It took me 15 minutes to do all of this, another 45 to test workarounds to a Tasker bug, and like two hours of off-and-on writing to actually make the stinking post!

The first goal is to get Heyu running on your computer to control your X10 modules. I'll leave that to the reader because it was dead simple for me so my experience consists of "just install and run it". After that, we need to get ssh keys working and place the ssh key on the phone so you can log into the PC from the phone. There are many how-tos for setting up ssh keys so I won't get into that here either, but you may want to check this post for links that may help.

You should test your ssh logins with a terminal app on the phone. It's probably easiest to test the basic ssh command first:

ssh USER@IP -i /PATH/TO/SSH/KEY

Once you login (and exit) successfully with that, try something like this to bounce a command off your PC:

ssh USER@IP -i /PATH/TO/SSH/KEY "COMMAND"

That executes what I usually call a 'semi-login'. It uses the keys to log in, run the command and exit. Any output from the command on the PC will be shown in the terminal on your phone. Once that is working, let's make sure an x10 command works:

ssh USER@IP -i /PATH/TO/SSH/KEY "heyu on a1"

Now, you will probably want to put it in a script so you don't have to type it out all the time. I suggest changing the basic command to this first:

ssh USER@IP -i /PATH/TO/SSH/KEY "heyu $*"

That will log into your computer and run heyu with whatever arguments you give it on the command line. If the two arguments are "on a1" it will tell heyu to turn on a1. If they are "dim b2 10", it will tell heyu to dim b2 by level 10.

There are a couple of ways to use this as a script. If you're rooted, you can put the command in a file, add "#! /system/bin/sh" to the top and place the file in /system/bin. It can now be executed by typing the script name. I prefer doing this because it can be executed system-wide by any app.

If you're not rooted, you can put the command in a text file on the sdcard and run "sh /sdcard/filename"

I use the first method, and I'll call the script "ha" so, if you use the second method, anytime you see me executing "ha" just substitute "ha" with "sh /sdcard/filename"

Now that we have a command that works, let's put it to practical use. Using Tasker and it's free plugin named "Locale Execute Plugin", you can set up your commands to run from Tasker. All you have to do is create a new task, select "plugin", "execute" and type in your command.

Now, there are two approaches you can take, or a mixture of both if you wish. You can create widgets or shortcuts to Tasker tasks, so you can set up an "on" task and an "off" task for each X10 module, then put the shortcuts on the home screen. Or, as I prefer to do when using this approach, you can use Folder Organizer to group them all together in their own Heyu folder.

Another approach is to create on/off toggles for each module with icons to reflect the modules state. You first need a script on the PC to interpret the incoming command and dump a list of the on/off/dim state of all your modules to a file so Tasker can grab that file and update it's icons to reflect the state of the module.

Here's the script for the PC. Call it anything, but I'll name it "toggle" for this example. It performs two functions. First, it toggles the module you want to switch on/off. It checks, and if the module is on, it turns it off, and vice versa.

Secondly, it takes the overall state of the housemap from "heyu show h" and maps all the on/offs to a list of modules you want to keep track of. If you notice the last two lines, I am keeping track of j2 and b1. These would correspond to the Tasker icons that you want to update to reflect the on/off state of the modules. This info is stored in a file named "/etc/heyu/toggle.list"


(edited: Jan 9. Oops, I changed the custom "awkc" command to a
non-custom awk print command that will work for everyone)

#! /bin/sh
# don't knock the code! I prefer "compact" to "proper"

cd /etc/heyu
rm toggle.list
state=$(heyu onstate "$1")
if [[ $state == 1 ]]; then heyu off "$1"
elif [[ $state == 0 ]]; then heyu on "$1"
fi

stat ()
{
house=$(expr substr "$1" 1 1)
unit=$(expr substr "$1" 2 1)
t=$(heyu show h | grep House | awk '{ print $3,$2 }' | tr -d '()')
onoff=$(expr substr $(echo "$t" | grep -i "$house" | awk '{ print $1 }') "$unit" 1)

if [[ $onoff == \* ]]; then echo ${house}${unit} on >> toggle.list
elif [[ $onoff == x ]]; then echo ${house}${unit} dim >> toggle.list
else echo ${house}${unit} off >> toggle.list; fi
}


# List all modules you want to track here in the form of: "stat Hu"
# j2 and b1 are examples

stat j2
stat b1

# end

Now, we need a script on the phone to interact with the script on the computer. Let's call it "atoggle." This will connect to the PC and toggle the module, then copy the toggle.list file to the phone over scp.
#! /system/bin/sh
ssh USER@IP -i /PATH/TO/SSH/KEY "toggle $1"
scp -i /PATH/TO/SSH/KEY COMPUSER@IP:/etc/heyu/toggle.list /sdcard/Tasker/
Using j2 and b1 as examples, with Tasker, you want to create two new tasks to use the execute plugin to execute to following two commands:

atoggle j2
atoggle b1

Back on the home screen, create new widgets for both those tasks and name them by their house/unit code. I suggest picking icons that will not indicate whether the modules are on or off because the icons will be changed to reflect the state later. Here is an example of the icons I picked.



Now, let's set up a Tasker task to update the icons. This started out as an elegant task that tested well but upon real execution the task outran the scp command and ran before the file was transferred. Tasker is really poor at reading files so the first five lines are there just to pause the task until the file transfer is complete. It's completely illogical, but it works and is necessary and, trust me, you will go crazy trying to find an alternative! Just a quick explanation of what's going on in the first five lines: set the variable to tell it which line to read, overwrite the original file with "WAIT", copy it to a separate file because it messes up later reads if you start reading the original, read it and start over if the file still contains "WAIT."

1- Variable Set %ONE to 1
2- Write File Tasker/toggle.list. Text: WAIT
3- Copy File Tasker/toggle.list to Tasker/toggle.list2
4- Read Line. File: Tasker/toggle.list2 Line: %ONE to Var %WAIT
5- Go To Action 3 if %WAIT matches WAIT

6- Read Line. File: Tasker/toggle.list to Var %VAR
7- Variable Split. %Var
8- Set Widget Icon. Name: %VAR1 if %VAR2 matches on (pick an "on" icon)
9- Set Widget Icon. Name: %VAR1 if %VAR2 matches off (pick an "off" icon)
10- Set Widget Icon. Name: %VAR1 if %VAR2 matches dim (pick a "dim" icon)
11- GoTo Action: Number 1. If %VAR doesn't match EOF

Those last 6 lines are the real meat of the task and are rather elegant if you understand Tasker. Edit: I forgot to mention, you need to name that task and add it to the "atoggle j2" and "atoggle b1" tasks. So step 1 for each module would be execute the atoggle command and step two would be to perform the task I just mentioned to read the file.

Ok, let's walk through everything we've learned. You have two icons, j2 and b1 which are set to "neutral." In reality, both modules are on. When you click the j2 icon, Tasker executes "atoggle j2." This uses ssh to connect to your computer and run "toggle j2".

The toggle script checks if j2 is on or off and sets it to the opposite, then gets the state of all 256 modules and filters out the ones you are interested in (the ones placed near the bottom of the toggle script on the PC), then puts their state in toggle.list. Tasker uses scp to transfer toggle.list to the phone then reads all the lines, checking the module and changing it's icon to reflect it's state.

If j2 and b1 were both on and I toggled j2, the end result is this:



j2 has been toggled off and both icons have been updated to reflect their state.

If you followed all that, you hopefully understand how it all worked. But you may wonder why I update all modules if you're only toggling one? Well, although tapping the icons only blindly toggles the module, looking at it will tell you if it's on or off. I update all icons because some modules may have been turned on/off through other means. It's always possible that the icon you tap is in the wrong state, but by updating all icons every time any icon is clicked, it lessens the chances that an icon will be "out of date."

You may want to create a task just to update the status of all modules. You can create your own, or you can just run "atoggle" on a dummy module that you don't use. Just leave it out of the end of the "toggle" script on the PC so Tasker won't track it's status.

If you want to add modules that may be in a dimmed state, the script does report them so you only need to select an icon for "dim." In this image, j2 is in a dimmed state.



If you use dimming but only want to report off/on states, just select the same icon for dim as you use for "on."

If you want to create an icon that dims a module instead of simply turning it on and off, you can use the information in this post and my previous post to set up a new task for dimming.

Phwew, I hope this is useful for someone!

Monday, January 3, 2011

Tasker variable select function

I had a task where I wanted to be able to enter a custom number into a variable. Tasker has a "variable Query" action that pops up a box and allows you to type in the variable, but I didn't like it because you have to tap on the box to bring up the keyboard, type out the entry, then save it. But a workaround is simple, as long as you know certain values the variable could be.

Task: VarMenu1
1 Variable Set %VAR to EOF (you could use 'variable clear' but I prefer using EOF since errors will sometimes manifest as EOF)
2 Perform Task VarMenu2
3 Wait Until %VAR doesn't match EOF

Task: VarMenu2
Task Type: Menu
1 Set Variable %VAR to 0
2 Set Variable %VAR to 1
3 Set Variable %VAR to 2
4 Set Variable %VAR to 3
...etc (change numbers to suit your needs)

Used alone, VarMenu1 acts like a function or library, a piece of code that you can leave by itself and call any time you need to perform a certain task, in this case custom setting a variable. Any time you're writing a task that requires you to input a custom value for a variable, just put "Perform Task: VarMenu1" and your task will pause to allow you to select a value from a list.

You can also use variables for task names when using the "Perform Task" action. This would be useful if you want to prepare more than one menu of variables. Instead of 0,1,2,3, maybe you also want to have a menu for 0,5,10,20. Just make a new menu task containing those numbers, let's call it VarMenu3, change the "Perform Task" in VarMenu1 to a variable and set the variable before that step.

1 Variable Set %VAR to EOF
2 Variable Set %VARMENU to VarMenu3
3 Perform Task %VARMENU
4 Wait Until %VAR doesn't match EOF

Voila, flexibility!

Tuesday, December 28, 2010

X10 coolness

I've been slowly getting into X10 home automation lately. It works like this, you get an X10 control module that plugs into the wall near the computer and a cable comes from it and plugs into your computer. Then you get software to control the control module. The control module controls whatever other modules you want to use throughout the house.

The most basic module is the lamp module, which is a small box that plugs into a wall outlet, then your lamp plugs into the module. From the computer, you tell that module to turn on or off.

What happens is that the control module sends a special signal through the wires in your house. The signal is picked up by all the X10 modules you have. The modules themselves have dials where you can select identification letters and numbers on them. You take a module and select, let's say, B4, so that module is now identified as B4. When you send the signal "B4 on," it turns itself on, which turns the lamp on.

There are numerous different modules to do different things. There are wall switches, modules for plug-in electronics like the lamp module and a similar appliance module, security modules, camera modules, dimmers, timers, weather sensors. Anything you can think of, the possibilities are endless.

You can also use them with remote controls and there are a few apps in the Android Market to run them from your phone, but I like setting them up to control from my phone over ssh. There is a Linux program called Heyu for use with the CM11A control module. Heyu can perform nearly two hundred different commands and uses simple command line syntax like heyu on B4. This makes it extremely simple to script, which in turn makes it extremely simple to control through the phone using the basic ssh command I've posted many times:

ssh USER@IP -i /PATH/TO/SSH/KEY 'heyu on B4'

This can be set up as a script to be ran from a terminal, through a GScript shortcut, or with Tasker. Of course, Tasker and X10 make an extremely useful pair.

I really haven't set much up yet except to manually turn a couple of lights on. I plan on getting a module to control the garage door next. This is done by using a "universal module" that acts like a single state button instead of an on/off switch. When the module is activated, it just does it's thing once and there is no way to reverse it. Every time it is activated, it is the same as pushing the garage door opening button so there is no way to know if it is up or down.

I plan to set it up with Tasker to activate it when I am close to home so the door will be open by the time I pull into the driveway. I'm not sure how reliable that will be, so I'll probably add a statusbar reminder that the door is open in case it is activated accidentally.

I've also considered getting a camera for the front door and a doorbell sensor. When someone rings the doorbell, the computer could tell the camera to take a photo then send it to me via MMS. If it looks like someone trying to sell something, I can ignore them. If it's a family member with a birthday present and I'm at work, I can open the garage door so they can come in.

I have no plans to do this, but this would be a cool setup...

Send a notification to the phone when the door is open

Have Tasker silence/ignore the notification if I'm at home and end the task.

If I'm not at home have Tasker say "Sir, I've detected that your garage door is open but you don't appear to be near your house. Would you like me to close it?"

Pop up the voice command window.

Using yes/no, open/closed, up/down as the keyword, I could answer in a natural voice and say "yes please close it for me" or "sure, close that sucker, I must have forgotten" or "nah, leave it up" or "it's ok, I want it open"

It could then say "Ok, closing it now," run the command to close the door and once the sensor detects that the door is closed say "It's closed, sir"

Like I said, I'm not going to do that, but it illustrates how well Tasker and X10 gear could work together to both perform really cool actions like opening doors for you and also make your phone behave somewhat like an intelligent assistant.

Wednesday, December 22, 2010

Happy Holidays!

I haven't been around much lately but I wanted to drop in and wish everyone Happy Holidays. I also wanted to let everyone know that the current economic climate has not affected my Christmas budget and all of the readers of this little blog can expect to receive the same thing I got you last year!

Sunday, November 7, 2010

ssh error and fix

I've helped several people with this so I might as well post it here for others to stumble across. ssh can sometimes give this error:

stderr: ssh: Warning: failed creating //.ssh:
Read-only file system
stderr: Host '[my PC's ip address]' is not in the trusted hosts file

For some reason, ssh is trying to create it's hosts file in /.ssh, which is read-only, giving the error. For me, it happened when trying to use it in a script executed through GScript, but I believe it happens in other circumstances as well.

The solution that has worked for me and a few others is to replace the stock ssh binary in /system/xbin with a link to the ssh binary from Better Terminal Emulator Pro. Unfortunately, BTEP costs money but if you're using ssh or anything else from a terminal, I highly recommend buying it.

After you install Better Terminal Emulator Pro, back up the stock binary by typing this in a terminal:

mv /system/xbin/ssh /system/xbin/ssh.bak

Then put a link in /system/xbin to the BTEP ssh binary:

ln -s /data/data/com.magicandroidapps.bettertermpro/bin/ssh /system/xbin

This has been necessary every time I install an update because they always contain the stock ssh binary. Luckily, this fix has worked every time.

Thursday, November 4, 2010

Finally, a use for twitter

I've never had much use for Twitter but I've recently found myself using my phone to log into my computer to check various things throughout the day. While I have those things set up with GScript shortcuts for quick checking, there's no reason I need to manually be logging in to check them.

You used to be able to post to twitter with curl, but not since they switched to OAuth. Now the simplest way is with TTYtter, the command line Perl Twitter posting script.

Once you run TTYtter and set up your login info, you can post to Twitter using ttytter -status="blah blah blah", but I usually like setting up things to use either pipes or argument type input, plus I'll never remember the name ttytter, so I use this little script named "twit"
#! /bin/sh
if test -z "$1"

then
in=$(cat /dev/stdin)
ttytter -status="$in"

else
ttytter -status="$@"

fi
which can be used in two ways:

command | twit

or

twit blah blah blah

I set up a private twitter account and use TTYter to push various information to it. Some information comes from and hourly cron and for others that run at unexpected times, I just added "| twit" to them.

I use LauncherPro on the phone and it comes with a twitter widget. Set to update every 30 minutes, I just look at the widget to get an update on pretty much anything I may be interested in.

Monday, November 1, 2010

Simple "to do list" voice script for Tasker/voice

I had to do something at work today which required me to examine several things to see if they needed done, do something to them, and mark them off my mental list of things that needed done.

This is something that nearly everyone does on a daily basis but there were just too many items on my todo list to remember them all so I took 10 minutes and whipped up this little script which I named "list".

#! /system/bin/sh
grep -E -i -q "add|delete" /sdcard/.voice || exec echo sorry
grep -E -i -q "^add|^delete" /sdcard/.voice && sed -i 's/^/list /' /sdcard/.voice

COMMAND=$(awk '{ print $2}' /sdcard/.voice)
ARG=$(cut -f3- -d ' ' < /sdcard/.voice)

if [ $COMMAND == "add" ]; then
echo $ARG >> /sdcard/list
echo "Added: $ARG"

elif [ $COMMAND == "delete" ]; then
sed -i "/$ARG/d" /sdcard/list
echo "Deleted: $ARG"

fi
This simply adds or deletes things from a list based on whether it finds "add blah blah blah" or "delete blah blah blah" in the file at /sdcard/.voice.

I created a new task in Tasker with the following actions:

1- Variable set %LIST to EOF
2- Locale Execute Plugin: @ list
3- Wait 500ms
4- Read Paragraph /sdcard/list to var %LIST
5- Flash %LIST

I set this to trigger on the keyword "list**" with the Tasker voice command I've been talking about in the last few posts. The end result is this:

I say "list add go to work"

It flashes:
go to work

I say "list add pay bills"

It flashes:
go to work
pay bills

I say "list delete work"

It flashes:
pay bills

I say "list add go on vacation"
It flashes:
pay bills
go on vacation

I say "list delete bills"
It flashes:
go on vacation

I say "list add sleep late"
It flashes:
go on vacation
sleep late

I added a line in the script to make this loopable. The line I added will add "list" to the beginning if it's not there already and execute normally. If called by the normal voice task, you still have to say "list add/delete blah blah blah" because "list" is the trigger word, but when called in a loop, you can just say "add/delete blah blah blah" and the script will recognize it. This makes it possible to keep using the list while performing your duties.

Followers