minAngleLight con 600 ;pulse low (Mystery servo) which flips the light off
maxAngleLight con 2600 'pulse low (Mystery servo) which flips the light on

minAngleHeater con 600 'pulse low (Hitec servo) to adjust the heater off
maxAngleHeater con 2400 'pulse high (Hitec servo) to adjust the heater on

servoRefreshPeriod con 20 ;20 milliseconds refresh rate on the servos

AlarmState VAR BYTE     ; stores the raw voltage value read from the speaker pin on the alarm  
TempByte VAR BYTE       ; used in the program for temporary storage of data
AlarmOn VAR BIT         ; true if alarm is on, else false
LightOn VAR BIT         ; true if light switch has been flipped on, else false
HeaterOn VAR BIT        ; true if heater has been turned on, else false
AlarmTimer VAR WORD     ; keeps track of amount of seconds elapsed since the alarm went off
AlarmThreshold VAR BYTE ; amount of time in minutes to wait between when the alarm goes off and when the speaker should be kicked on

SpeakerPin CON p4 ; pin connected to the relay which flips on or off the speaker using the relay
AlarmPin CON p6   ; pin connected to the other end of the relay and to the +v on the alarm speaker
LightPin CON p12  ; connected to the light servo
HeaterPin CON p7  ; connected to the heater servo

Initialize:

	AlarmState = 0
	AlarmTimer = 0
	AlarmOn = 1
	AlarmThreshold = 15; default time between when the alarm goes off and the speaker kicks on to 15 minutes
	LightOn = 0;
	HeaterOn = 0;
	Low SpeakerPin;
	Low LightPin
	Low HeaterPin;

main:

	GoSub ReadAlarmState; read in the current state of the alarm and set whether alarm is on/off
	
	if(AlarmOn) then
		GoSub ProcessAlarmOn
	else
		GoSub ProcessAlarmOff
	endif
	
	Pause 1000; pause for 1 second for timing purposes
	
goto main

;function turns the light and heater on as well as increments the 
;alarm timer, which tells how long the alarm has been on for in seconds
;if the gap between when the alarm was turn on and now is greater than the 
;specified alarm threshold, it kicks on the speaker, else keeps it turned off
ProcessAlarmOn

	GoSub TurnLightOn
	GoSub TurnHeaterOn

	AlarmTimer = AlarmTimer + 1 ; this is roughly in seconds due to the "Pause 1000" in main 

	;if elapsed time since alarm time has gone off has exceeded, turn the speaker on, else off
	if(AlarmTimer > (AlarmThreshold*60)) then
		GoSub TurnOnSpeaker
	else
		GoSub TurnOffSpeaker
	endif
	
return

;function turns the light, heater, and speaker off.
;it also resets the alarm timer, which keeps track of how
;long the alarm has been going off for
ProcessAlarmOff

	GoSub TurnLightOff
	GoSub TurnHeaterOff
	GoSub TurnOffSpeaker
	
	AlarmTimer = 0

return

;function flips the relay "on", which in turn turns on the speaker
TurnOnSpeaker
	High SpeakerPin
return

;function flips the relay "off", which in turn turns off the speaker
TurnOffSpeaker
	Low SpeakerPin
return

;function performs the necessary actions to flip on the light switch
TurnLightOn

	;if the light hasn't already been switched on, then pulse the servo to flip the switch on
	if(LightOn = 0) then
	
		for tempByte = 0 to 50 
			'pulse the pin to turn on light
			PulsOut LightPin, maxAngleLight;
			Pause servoRefreshPeriod;
		next

		;set the light to on
		LightOn = 1
	endif
	
return

;function performs the necessary actions to flip the light switch off
TurnLightOff

	;if the light is on then pulse the servo to switch it off
	if(LightOn = 1) then
	
		for tempByte = 0 to 50 
			'pulse the pin to turn on light
			PulsOut LightPin, minAngleLight
			Pause servoRefreshPeriod;
		next
		
		;set the light to off
		LightOn = 0
	endif

return


;function performs the necessary actions to turn the heater on
TurnHeaterOn

	;if the heater is currently off then pulse the survo to turn it on
	if(HeaterOn = 0) then

		for tempByte = 0 to 50 
			'pulse the pin to turn on heater
			PulsOut HeaterPin, maxAngleHeater
			Pause servoRefreshPeriod;
		next
		
		;set the heater as on
		HeaterOn = 1
	endif
	
return

;function performs the necessary action to turn the heater off
TurnHeaterOff

	;if the heater is on pulse the survo to turn it off
	if(HeaterOn = 1) then
	
		for tempByte = 0 to 50 
			'pulse the pin to turn off heater
			PulsOut HeaterPin, minAngleHeater
			Pause servoRefreshPeriod;
		next
	
		;set the heater as off
		HeaterOn = 0
	endif

return

;function reads the current state of the alarm (on/off) as well as sets the AlarmOn variable true or false appropriatley
ReadAlarmState
	ADIN AlarmPin, AlarmState; reads the voltage on the speaker +v wire

	;if reading some voltage on the speaker line, set the alarm on, else sample further
	if(AlarmState > 0) then
		AlarmOn = 1
	else
		;sample for 2 seconds to see if the alarm is on
		;this is necessary as when the alarm is on it beeps on and off about once a second
		;so need to sample for a couple seconds to just in case the above read on the off part of the beeping
		for tempByte = 0 to 20
			Pause 100
			
			ADIN AlarmPin, AlarmState; read the voltage on the speaker +v wire
			
			;if voltage read, the alarm must be on so set as such and exit the for loop, else set as off
			if(AlarmState > 0) then
				AlarmOn = 1			
				return;
			else
				AlarmOn = 0;
			endif
		next
	endif
return