more G-Labs products

Author Topic: How to schedule security?  (Read 1218 times)

May 03, 2015, 10:32:55 PM
Read 1218 times

Bemie

  • *
  • Information
  • Newbie
  • Posts: 13
Dear All,
As a non programmer, I have deepest respect for those who can create code. It is not as easy as it seems. As an old man I took it upon me to learn a bit, but I need some help please.

I have a question: How do I best schedule the built in security module?
All day I have cracked by old grey cells and came up with
1) the HG standard included App ' Scheduler', but adressing ID 90 does not help as I require the trigger to raise the level to 1. So I dropped this
2) So I figured in the code of the App '90 Security Alarm System' to add a line to allow alarming only within a certain time period. I found this part of the code op module App '90 Security Alarm System' (starting from line 45)

When.ModuleParameterChanged((module, parameter)=>
{
     if (Program.Parameter("HomeGenie.SecurityArmed").Value == "1" && (moment.datehour<6||moment.datehour>23))

The glowing text is my fantasy, but this does not compile for (I assume for you) obvious reasons.
I have two questions:
a) is this the logical way to schedule the security app? If not could you please take the time to explain me what to do.
b) how should I write the current time comparison as ' moment.Hour' is not accepted.

I thank you kindly in advance for your response(s).

Kind regards,
Bemie




May 05, 2015, 08:49:29 AM
Reply #1

mvdarend

  • *****
  • Information
  • Hero Member
  • Posts: 431
(DateTime.Now.Hour<6||DateTime.Now.Hour>23) should compile. (I haven't tested this though)

Small tip: If you're changing an existing Program you can best export the original and then import it as a new program, I usually rename it to '[Original Module Name] Custom'

May 05, 2015, 03:58:31 PM
Reply #2

Bemie

  • *
  • Information
  • Newbie
  • Posts: 13
Dear mvdarend,
Thank you very  much for your solution. It did work and now have a scheduled security system. Thanks to you.

I hereby share my code for all who wish to do the same (existing security code with some minor changes of my own).
In the menu (trigger) I have created two additional options 'Hour Time when alarm should be armed' and 'Hour Time when alarm should be disarmed'.
The solution allows for human intervention at any time.

Program
Code: [Select]
//
// init program parameters
//
Program.RaiseEvent("HomeGenie.SecurityArmed", "0", "Security System");
Program.Parameter("HomeGenie.SecurityTriggered").Value = "0";
Program.Parameter("Status.Level").Value = "0";
var AlarmHourOn=(Program.InputField("Trigger.TimeAlarmOn").DecimalValue);
var AlarmHourOff=(Program.InputField("Trigger.TimeAlarmOff").DecimalValue);
var TimedAlarm=true;
//
Func<bool> _armdisarm = new Func<bool>(()=>{
  Program.RunAsyncTask(()=>
{
        if (Program.Parameter("Status.Level").Value == "0")
        {
          // disarming
          Program.Parameter("HomeGenie.SecurityTriggered").Value = "0";
        }
      else
        {
          // arming
        Pause( Program.InputField("System.ArmDelay").DecimalValue );
        }
        Program.RaiseEvent("HomeGenie.SecurityArmed", Program.Parameter("Status.Level").Value, "Security System"); 
      // run armed/disarmed program
      if (Program.Parameter("Status.Level").Value != "0")
        {
          var armedProgram = Program.InputField("Trigger.ArmedProgram").Value;
          if (armedProgram != "")
            {
              Program.Run(armedProgram);
            }
        }
      else
        {
          var disarmedProgram = Program.InputField("Trigger.DisarmedProgram").Value;
          if (disarmedProgram != "")
            {
              Program.Run(disarmedProgram);
            }
        }
    });
  return true;
});

//
// module events handling
//
When.ModuleParameterChanged((module, parameter)=>
{
///vanaf hier
TimedAlarm=true;
if ((AlarmHourOff-AlarmHourOn)>=0)
{
if ((DateTime.Now.Hour<AlarmHourOn)||(DateTime.Now.Hour>=AlarmHourOff))
  {
    TimedAlarm=false;
}
}
  else
    {
      if ((DateTime.Now.Hour>=AlarmHourOff)||(DateTime.Now.Hour<AlarmHourOn))
  {
    TimedAlarm=false;
}
    }
///tot hier
 
  if (Program.Parameter("HomeGenie.SecurityArmed").Value == "1")
    {

      if (module.HasFeature("HomeGenie.SecuritySensor")
            && Program.Parameter("HomeGenie.SecurityTriggered").Value != "1"
            && (   parameter.Name == "Status.Level"
              || parameter.Name == "Sensor.Generic"
                || parameter.Name == "Sensor.Tamper"
                || parameter.Name == "Sensor.MotionDetect"
|| parameter.Name == "Sensor.DoorWindow"
                || parameter.Name == "Sensor.Flood"
                || parameter.Name == "Sensor.Smoke"
                || parameter.Name == "Sensor.Heat"
                || parameter.Name == "Sensor.CarbonMonoxide"
                || parameter.Name == "Sensor.CarbonDioxide" )
            && parameter.DecimalValue > 0 && TimedAlarm)
        {
            Program.RaiseEvent("HomeGenie.SecurityTriggered", "1", "Security System");
Program.Parameter("HomeGenie.SecurityTriggerSource").Value =
              module.Instance.Name + " " + parameter.Name + " (" +
              module.Instance.Domain + "." +
              module.Instance.Address + ")";

            var triggeredProgram = Program.InputField("Trigger.TriggeredProgram").Value;
          if (triggeredProgram != "")
            {
              Program.Run(triggeredProgram);
            }
         
  return false;
        }
    }
  return true;
});
//
// web service calls handling
//
When.WebServiceCallReceived(Program.Module.Domain + "/" + Program.Module.Address, (args) => //"HomeGenie.SecuritySystem", ( args ) =>
{
    string[] reqs = ((string)args).Split('/');
    var res = "";
   
    try
    {
      string command = reqs[2];
      string pid = reqs[1];
      if (pid == Program.Module.Address)
      {

        switch(command)
        {
          case "Control.On":
Program.RaiseEvent("Status.Level", "1", "Security System");
          _armdisarm();
            res = "{ 'ResponseValue' : 'ARMED' }";
            break;
          case "Control.Off":
Program.RaiseEvent("Status.Level", "0", "Security System");
          _armdisarm();
            res = "{ 'ResponseValue' : 'DISARMED' }";
            break;
        }

      }
    }
    catch (Exception ex)
    {
      res = "{ 'ResponseValue' : 'ERROR: " + ex.Message + " " + ex.StackTrace + "' }";
    }
    // unable to process request
    return res;

});
//
// main program loop
//
var sirenModules = Modules.WithFeature("HomeGenie.SecurityAlarm").OfDeviceType("Siren");
var alarmModules = Modules.WithFeature("HomeGenie.SecurityAlarm").OfDeviceType("Dimmer,Switch,Light");
while (Program.IsEnabled)
{

  if (Program.Parameter("HomeGenie.SecurityTriggered").Value == "1")
    {
        sirenModules.On();
      //
      var alarmstart = DateTime.Now;
      //
      // send email
      //
      var subject = "HomeGenie Security System Alarmed";
      var messagetext = "Security System Alarm triggered by " + Program.Parameter("HomeGenie.SecurityTriggerSource").Value;
      var recipients = Program.InputField("Email.Recipients").Value;
      if (recipients != "")
        {
          Program.RunAsyncTask(()=>{
      Net.SendMessage(recipients, subject, messagetext);
            });
        }
        //
      var sirenstopped = false;
        while (Program.Parameter("HomeGenie.SecurityTriggered").Value == "1")
        {
            // flashing SecurityAlarm lights
            alarmModules.Toggle();
            Pause(1);
            alarmModules.Toggle();
            Pause(1);
          //
          var elapsed = new TimeSpan(DateTime.Now.Ticks - alarmstart.Ticks);
          if (!sirenstopped && Program.InputField("System.SirenMaxTime").DecimalValue > 0 && elapsed.TotalSeconds > Program.InputField("System.SirenMaxTime").DecimalValue)
            {
sirenModules.Off();
              sirenstopped = true;
            }
        }
  //Pause(1);
        alarmModules.Off();
        sirenModules.Off();
    }
  Pause(1);
}


Trigger
Code: [Select]
Program.Setup( () => {
 
  Program.AddControlWidget("homegenie/generic/securitysystem");
 
Program.AddFeature("Sensor,DoorWindow", "HomeGenie.SecuritySensor", "Use as Security Sensor");
Program.AddFeature("Siren,Light,Dimmer,Switch", "HomeGenie.SecurityAlarm", "Use as Security Alarm");
  //
    Program.AddInputField("System.ArmDelay", "10", "1. Arm Delay (seconds)");
    Program.AddInputField("System.SirenMaxTime", "30", "2. Sirens Max Time (seconds, 0=infinite)");
 
    Program.AddInputField("Email.Recipients", "", "3. Comma separated list of recipients e-mails for alarm notifications"); 
 
    Program.AddInputField("Trigger.ArmedProgram", "", "4. Program to run when armed"); 
    Program.AddInputField("Trigger.DisarmedProgram", "", "5. Program to run when disarmed"); 
    Program.AddInputField("Trigger.TriggeredProgram", "", "6. Program to run when triggered");
  Program.AddInputField("Trigger.TimeAlarmOn", "20", "7. Hour time to arm alarm");
Program.AddInputField("Trigger.TimeAlarmOff", "23", "8. Hour time to disarm alarm");
 
});
// this program will be running in background
return true;

As stated before, I am not real good in programming, so it could probably be done much cleaner. But I am already happy with the fact that is works.
« Last Edit: June 15, 2015, 08:16:17 PM by Bemie »