Jump to content

On/Off Switch


anixon
 Share

Recommended Posts

The following is some code which I have written that works on a 24 Hour clock which is used to switch a process on and off based on the start and finish times input by the user.

My question is not because the code does not work rather is there a simpler methodology to achieve the same result.

;//Start and Finish Timer '24 Hour Cycle'

;//Date Time Processing
#include <Date.au3>

;//Variables
Dim $Y, $M, $D
Global $Error = 0, $sSwitchOnOff = 0

;//Input in 24 Hr Time Format
Global $EsStart = String('0915')
Global $EsFinish = String('0918')

;//Check that Start Time [24 Hour Format] is Valid
If _DateIsValid(@YEAR & "/" & @MON & "/" & @MDAY & " " & StringLeft($EsStart, 2) & ":" & StringRight($EsStart, 2) & ":00") = 0 Or StringLen($EsStart) <> 4 Or $EsStart = '2400" Then $Error = 1
;//Check that the Finish Time [24 Hour Format] is Valid
If _DateIsValid(@YEAR & "/" & @MON & "/" & @MDAY & " " & StringLeft($EsFinish, 2) & ":" & StringRight($EsFinish, 2) & ":00") = 0 Or StringLen($EsFinish) <> 4 or $EsStop = '2400' Then $Error = 1

;//Exit on Invalid Date
If $Error = 1 Then Exit

;//Compile the Start Date String
$sStart = @YEAR & "/" & @MON & "/" & @MDAY & " " & StringLeft($EsStart, 2) & ":" & StringRight($EsStart, 2) & ":00"
;//Compile the Finish Date String
$sFinish = @YEAR & "/" & @MON & "/" & @MDAY & " " & StringLeft($EsFinish, 2) & ":" & StringRight($EsFinish, 2) & ":00"

;//24 Hour On/Off Switch
While 1
;//Switch the Process Flag "ON"
If Number($EsFinish) < Number($EsStart) And  _DateDiff('n', String($sStart), _NowCalc()) >= 0 And _DateDiff('n', String($sFinish), _NowCalc()) >= 0 Then $sSwitchOnOff = 1
If Number($EsFinish) > Number($EsStart) And  _DateDiff('n', String($sStart), _NowCalc()) >= 0 And _DateDiff('n', String($sFinish), _NowCalc()) < 0 Then $sSwitchOnOff = 1
;//Switch the Process Flag "OFF"
If Number($EsFinish) < Number($EsStart) And  _DateDiff('n', String($sFinish), _NowCalc()) >= 0 And _DateDiff('n', String($sStart), _NowCalc()) < 0 Then $sSwitchOnOff = 0
If Number($EsFinish) > Number($EsStart) And  _DateDiff('n', String($sFinish), _NowCalc()) >= 0 And _DateDiff('n', String($sStart), _NowCalc()) >= 0 Then $sSwitchOnOff = 0
If Number($EsFinish) = Number($EsStart) Then $sSwitchOnOff = 1
;//Slow down the Cycle
Sleep(5000)
;//Insert Code here that responds to the switch.
WEnd

Previous code example edited as it did not work... Ant..

Code Edited:

'2400' is a notional time for Midnight whereas the 24-hour time system from a processing point of view is from '0000' midnight to '2359' the last minute before midnight. In the case of the code if the Finish is the same

as the Start value then it is a 24-Hr processing cycle in which case the flag will always be set to 1 ie no stop or start. '2400' is also captured and processed as an invalid 240hr time value.

Ant..

Edited by anixon
Link to comment
Share on other sites

This is my stab at it.

;//Start and End Timer '24 Hour Cycle'

;//Date Time Processing
#include <Date.au3>

;//Variables
Global $sSwitch = 0, $sSwitchDateTime, $aTime[2]
Global $EsStart = '2359'
Global $EsEnd = '0001'
If $EsStart = $EsEnd Then Exit

$aTime[0] = StringLeft($EsStart, 2) & ":" & StringRight($EsStart, 2) & ":00"
$aTime[1] = StringLeft($EsEnd, 2) & ":" & StringRight($EsEnd, 2) & ":00"

$sSwitchDateTime = _NowCalcDate() & " " & $aTime[0] ; initialize toggle time to start time
While 1
    If _NowCalc() >= $sSwitchDateTime Then Toggle_Switch()
    Tooltip("Switch state: " & $sSwitch & "    Now: " & _NowCalc() & "    Next change: " & $sSwitchDateTime) ; for testing
    Sleep(5000)
WEnd

Func Toggle_Switch()
    Beep(800,100)
    $sSwitch = (Not $sSwitch) ; toggle switch
    $sSwitchDateTime = _NowCalcDate() & " " & $aTime[$sSwitch] ; set next toggle time
    If $sSwitch Then ; switch was turned on
;       Start_Process()
        If $aTime[0] > $aTime[1] Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; if run spans midnight, set end to next day
    Else ; switch was turned off
;       End_Process()
        If $aTime[1] > $aTime[0] Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; if doesn't span midnight, set start to next day
    EndIf
EndFunc
Link to comment
Share on other sites

This is my stab at it.

;//Start and End Timer '24 Hour Cycle'

;//Date Time Processing
#include <Date.au3>

;//Variables
Global $sSwitch = 0, $sSwitchDateTime, $aTime[2]
Global $EsStart = '2359'
Global $EsEnd = '0001'
If $EsStart = $EsEnd Then Exit

$aTime[0] = StringLeft($EsStart, 2) & ":" & StringRight($EsStart, 2) & ":00"
$aTime[1] = StringLeft($EsEnd, 2) & ":" & StringRight($EsEnd, 2) & ":00"

$sSwitchDateTime = _NowCalcDate() & " " & $aTime[0] ; initialize toggle time to start time
While 1
    If _NowCalc() >= $sSwitchDateTime Then Toggle_Switch()
    Tooltip("Switch state: " & $sSwitch & "    Now: " & _NowCalc() & "    Next change: " & $sSwitchDateTime) ; for testing
    Sleep(5000)
WEnd

Func Toggle_Switch()
    Beep(800,100)
    $sSwitch = (Not $sSwitch) ; toggle switch
    $sSwitchDateTime = _NowCalcDate() & " " & $aTime[$sSwitch] ; set next toggle time
    If $sSwitch Then ; switch was turned on
;        Start_Process()
        If $aTime[0] > $aTime[1] Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; if run spans midnight, set end to next day
    Else ; switch was turned off
;        End_Process()
        If $aTime[1] > $aTime[0] Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; if doesn't span midnight, set start to next day
    EndIf
EndFunc

There is always a way to perform a process there was my code and then there was your elegant efficient and I guess much better code I am humbled and thank you for the lesson which was very much appreciated

Gosh so much to learn so little time.. Ant..

Link to comment
Share on other sites

I... thank... you

You're very welcome. I had nothing better to do last night (unfortunately).

Glancing at it a second time, I see it's not perfect, and has 2 glitches regarding initialization:

1. When the script is first launched, it could turn your process on for the first 5 seconds, even though the specified time range indicates that the run should be over for the day. After 5 seconds, it turns off as it should and would then run correctly forever after.

2. It would fail to start your process when the script is first launched within a specified time range that overlaps midnight, and would instead set itself to kick off the next day, after which it would behave nicely in perpetuity.

A couple one-time tests to adjust the initial dates up or down a day, inserted just before entering the main loop, seem to make it behave without any peculiarities:

;//Start and End Timer '24 Hour Cycle'

;//Date Time Processing
#include <Date.au3>

;//Variables
Global $sSwitch = False, $sSwitchDateTime, $aTime[2]
$EsStart = '1540'
$EsEnd = '0242'
If $EsStart = $EsEnd Then Exit

$aTime[0] = StringLeft($EsStart, 2) & ":" & StringRight($EsStart, 2) & ":00"
$aTime[1] = StringLeft($EsEnd, 2) & ":" & StringRight($EsEnd, 2) & ":00"

$sSwitchDateTime = _NowCalcDate() & " " & $aTime[0] ; set initial toggle time to start time
If $aTime[1] > $aTime[0] Then ; run does not span midnight
    If _NowCalc() > (_NowCalcDate() & " " & $aTime[1]) Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; set start to next day
Else ; run spans midnight
    If _NowCalc() < (_NowCalcDate() & " " & $aTime[1]) Then $sSwitchDateTime = _DateAdd("D", -1, $sSwitchDateTime) ; set start to prior day
EndIf

While 1
    If _NowCalc() >= $sSwitchDateTime Then Toggle_Switch()
    Tooltip("Switch state: " & $sSwitch & "    Now: " & _NowCalc() & "    Next change: " & $sSwitchDateTime) ; for testing
    Sleep(5000)
WEnd

Func Toggle_Switch()
    Beep(800,100); just for fun
    $sSwitch = (Not $sSwitch) ; toggle switch
    $sSwitchDateTime = _NowCalcDate() & " " & $aTime[$sSwitch] ; set next toggle time
    If $sSwitch Then ; switch was turned on
;       Start_Process()
        If $aTime[0] > $aTime[1] Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; if run spans midnight, set end to next day
    Else ; switch was turned off
;       End_Process()
        If $aTime[1] > $aTime[0] Then $sSwitchDateTime = _DateAdd("D", 1, $sSwitchDateTime) ; if doesn't span midnight, set start to next day
    EndIf
EndFunc

edit: added some parens to the new compares (properly, on the second try)

Edited by Spiff59
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...