#!/bin/bash
######################################################################
# eXTENd X10 daemon configuration file
# Copyright (C) 2001 - 2003 Perette Barella
# GNU public license.  All other rights reserved.
#
# This file provides the X10 daemon configuration and the functions
# which are executed when the daemon receives a command.  The daemon
# is configured on startup by the x10iod.init script, which greps bits
# of this file out and sets up the daemon configuration appropriately
# (using x10cli set commands).
#
# Examples:
# A light:     			light L09 [twoway]
# An appliance:			appliance L09 [twoway]
# Function to execute:		function module_L09 { ... 
#
# Functions must be declared using the function command so that
# the x10iod.init script can be find them.  module_L09 () {... won't work.
# $Id: x10event,v 1.3 2004/10/18 01:19:28 perette Exp $
######################################################################

lights=""
lightgroups=""
appliances=""

housecode="$1"
devicecode="$2"
command="$3"

X10CLI=/usr/local/bin/x10cli
ACTION=~/bin/action
JUKEBOX=~/bin/jukebox
[ -x "$ACTION" ] || ACTION="$X10CLI"

PATH="/bin:/usr/bin:/usr/local/bin:$HOME/bin"

FADEOFF=true
FADEON=false

######################################################################
# These functions provide the configuration options
######################################################################

function light_group
{
	typeset group="$1"
	if eval "[ \"\$group_$group\" != 'true' ]"
	then
		eval "group_$group=true"
		lightgroups="$lightgroups $group"
	fi
}

function light
{
	lights="$lights $1"
	light_group "${1%%[0-9]*}"
}

function appliance 
{
	appliances="$appliances $1"
}

######################################################################
# Interface with jukebox
######################################################################
# JUKEBOX should implement:
# COMMAND	Equip	Ideal behavior.
# pause:	N/C	Pause the player, keeping current state.
# continue:	On	Start or continue playing music.
# stop:		Off.	Stop the player.  Restart from beginning of current
#			song or a new song on when restarted.
# quiet:	On	Turn on audio equipment, set volume to 0.
# skip:		N/C	Stop playing the current song.
# replay:	N/C	Rewind to the start of the current song.
# louder:	N/C	Increase volume a notch.
# quieter:	N/C	Decrease volume a notch.
# mute:		N/C	Set volume to a quiet level.
# unmute:	N/C	Set volume to default.
# check:	Off?	If volume is 0, or music is paused,
#			then turn off equipment.
# 
function music
{
	${JUKEBOX} "$@"
}

######################################################################
# Interface for turn command.
# Format: turn <device name> {on|off}
######################################################################
function turn
{
	${ACTION} turn "$@"
}

######################################################################
# Interface to test for device status.
# Format: is_on <device name>
######################################################################
function is_on
{
	${ACTION} test "$@" on
}

######################################################################
# Functions for processing commands to all lights
######################################################################
function all_stuff
{
	typeset item action="$1" groupaction="$1" stuff="$lights"

	case "$groupaction" in
		LightsOn)	action=On ;;
		LightsOff)	action=Off ;;
		AllOn)		action=On ;;
		AllOff)		action=Off ;;
		On)		groupaction=LightsOn ;;
		Off)		groupaction=LightsOff ;;
	esac
	[ "$groupaction" = "AllOff" -o "$groupaction" = "AllOn" ] &&
		stuff="$stuff $appliances"

	# First, try to switch devices quickly by housecode.
	# Not all devices respond to LightsOff, and sometimes
	# an appliance controller is used, so fall through to
	# repeat to individual devices later.
	# Note X10 does LightsOn, LightsOff, and AllOff -- no AllOn.
	if [ "$groupaction" = "LightsOn" -o "$action" = "AllOff" -o \
	     "$groupaction" = "LightsOff" ]
	then
		typeset house
		for house in $lightgroups
		do
			${X10CLI} turn $house $groupaction
		done
	fi
	if [ "$action" = "Dim" ]
	then
		for item in $stuff
		do
			if ! ${X10CLI} test "$item"  on
			then
				:
			elif ${X10CLI} test "$item" above 5
			then
				${X10CLI} turn "$item" "$1"
			else
				${X10CLI} turn "$item" off
			fi
		done
	elif [ "$action" = "Off" -o "$action" = "On" -o "$action" = "Bright" ]
	then
		for item in $stuff
		do
			${X10CLI} turn "$item" "$action"
		done
	fi
}




######################################################################
# Translate On/Off to fade instructions
######################################################################
function fade_action
{
	typeset action="$1" light
	shift
	for light in $@
	do
		case "$action" in
			Off)	$FADEOFF && ${X10CLI} fade "$light" off 0
				$FADEOFF || turn "$light" off ;;
			On)	$FADEON && ${X10CLI} fade "$light" on 0
				$FADEON || turn "$light" on ;;
			Dim)	turn "$light" dim 4 ;;
			Bright)	turn "$light" bright 4 ;;
		esac
	done
}


######################################################################
# Configuration data -- define lights and stuff here.
######################################################################

# light_group D
# light D01 is basement_dungeon southeast_basement.
# light D02 is basement_dungeon southwest_basement.
# light D03 is basement_dungeon northeast_basement.
# light D04 is basement_dungeon northwest_basement.
# light D05 is basement_dungeon stairwell_basement.


light_group L
# light L01 is matts_light in matthews_room aka attic_rear.
# light L02 is matts_light in matthews_room aka attic_front.
# light L03 is matts_light in Matthews_room aka attic_rear.
light L05 is bedroom_dungeon in blue_bedroom.
light L07 is living_side_lamp living_light_string in living_room
light L08 is living_side_lamp in living_room
light L09 is portable fire_lamp - living_fire_lamp - in living_room twoway.
light L10 is porch_exterior lamp on porch.
light L11 is porch_interior lamp on porch.

appliance P01 is the living_stereo - category house_stereo in living_room.
appliance P05 is the basement_stereo - category house_stereo .
appliance P14 is the sump_pump.

# This is some test crap.
appliance L10 does not exist.
appliance L13 is a twoway nonexistent device.
light L14 is a twoway nonexistent light.

######################################################################
# These are me functions -- they will be executed by the daemon
# when commands are received for their respective house/unit code.
# Parameters: $1 is house code, $2 is unit code, $3 is command.
######################################################################

# Housecode A #1-8 is the X10 controller in my bedroom.
function module_A02
{
	case "$3" in
		On)	music pause
			(sleep 1200; music continue) &
			;;
		Off)	music pause
			(sleep 600; music continue) &
			;;
		Bright)	music continue ;;
		Dim)	music pause ;;
		*)	return 1 ;;
	esac
}

function module_A03
{
	case "$3" in
		On)	music continue ;;
		Off)	music pause ;;
		Bright)	music louder ;;
		Dim)	music quieter ;;
		*)	return 1 ;;
	esac
}

function module_A04
{
	# If turning off stereo from my room, turn off equipment only
	# if the living room lamp is off.  If the lamp is on, Matt
	# or someone is watching TV, and might be using the stereo.
	# The basement stereo must remain on in this case, to prevent
	# extra hum from the living room stereo.
	case "$3" in
		On)	music continue ;;
		Off)	if is_on living_fire_lamp
			then
				music pause
			else
				music stop
			fi ;;
		Bright)	music unmute ;;
		Dim)	music mute ;;
		*)	return 1 ;;
	esac
	return 0
}

function module_A05
{
	case "$3" in
		On)	music replay ;;
		Off)	music skip ;;
		*)	return 1 ;;
	esac
	return 0
}

function module_A06
{
	case "$3" in
		On)	~/bin/bedroom_scene 60 body_rub ;;
		Off)	~/bin/scene_done ;;
	esac
	return $?
}


function module_A08
{
	all_stuff "$3"
	music stop
}



# Housecode B #1-8 is the X10 controller in the dungeon.
function module_B03
{
	module_A03 "$@"
	return $?
}


function module_B04
{
	case "$3" in
		On)	music continue ;;
		Off)	music stop ;;
		Bright)	music unmute ;;
		Dim)	music mute ;;
	esac
	return $?
}


function module_B05
{
	module_A05 "$@"
	return $?
}

function module_B06
{
	case "$3" in
		On)	turn porch on ;;
		Off)	if is_on porch_interior || is_on porch_exterior
			then
				turn porch off
			else
				turn porch on
				(sleep 300; turn porch off) &
			fi ;;
	esac
}

function module_B07
{
	case "$3" in
		On)	~/bin/bedroom_scene 60 ;;
		Off)	~/bin/scene_done ;;
	esac
	return $?
}

function module_B08
{
	if [ "$3" = "On" ]
	then
		all_stuff LightsOn
	elif [ "$3" = "Off" ]
	then
		turn living_room off
		turn porch off
	fi
}

# Housecode B #1-8 is the X10 remote control in the living room.
function module_F03
{
	module_A03 "$@"
	return $?
}

function module_F04
{
	case "$3" in
		On)	music continue
			# Braindead remotes do fucked up shit with
			# bright/dim, so use On = unmute
			music unmute ;;
		Off)	music stop ;;
		Bright)	music unmute ;;
		Dim)	music mute ;;
	esac
	return $?
}


function module_F05
{
	module_A05 "$@"
	return $?
}

function module_F06
{
	case "$3" in
		On)	turn porch on ;;
		Off)	if is_on porch_interior || is_on porch_exterior
			then
				turn porch off
			else
				turn porch on
				(sleep 300; turn porch off) &
			fi ;;
	esac
}

function module_F07
{
	case "$3" in
		On)	~/bin/bedroom_scene 60 ;;
		Off)	~/bin/scene_done ;;
	esac
	return $?
}

function module_F08
{
	if [ "$3" = "On" ]
	then
		if is_on living_side_lamp
		then
			fade living_fire_lamp 80% 0
		else
			turn living_side_lamp on
		fi
	else
		if ! is_on living_fire_lamp
		then
			turn living_light_string off
			music check
			(sleep 30; turn living_side_lamp off) &
		fi
		turn living_fire_lamp off
	fi
}

function module_F16
{
	all_stuff "$3"
}

######################################################################
# Cron jobs
######################################################################
function module_CRON1
{
	all_stuff Dim
}

if [ "$1" = "-q" ]
then
	echo "Light groups: $lightgroups"
	echo "Lights: $lights"
	echo "Appliances: $appliances"
fi

######################################################################
# Main
######################################################################
LOG=/home/x10/Logs/module.log
# exec >> $LOG 2>&1 && set -x
echo "`date`: $*" >> $LOG
if eval "module_$housecode$devicecode" "$@"
then
	echo "Success: Module $0 $*"
else
	echo "Failure: $0 $*"
fi >> $LOG 2>&1



