Алгоритм автоматического управления светом в санузле. Модель.

Oct 04, 2018 12:51

Пока ко мне едут датчики движения, релюшки и прочая электронная ерунда, решил смакетировать алгоритм управления светом в санузле. В качестве среды взял Лазаря. Для всяких мелких программулек - самое то. Это бесплатная и свободная кросс-платформенная реинкарнация Borland Delphi с Object Pascal и визуальной средой разработки. Правда я в свое время лет 10 на Delphi профессионально программировал и никаких трудностей с Лазарем у меня не возникло. В итоге настрогал программульку, которая эмулирует два датчика, содержит кнопки одновременного управления ими,  показывает включен или нет свет:



Исходники для Лазаруса под катами. Подсветку синтаксиса делал вот этим он-лайн инструментиком.
[main.pas]

unit main;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
ExtCtrls;

type
TDoorStatus = (dsOpen, dsOpenedOutside, dsOpenedInside, dsClosedInside, dsClosedOutside, dsClosed);

{ TForm1 }

TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
CheckBox3: TCheckBox;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Panel1: TPanel;
Timer1: TTimer;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Timer1Timer(Sender: TObject);

private
procedure SetSomebodyInside(AValue: boolean);
private
// last door status
FDoorPrevOpened: boolean;
// light on/off
FLightOn: boolean;
// somebody inside
FSomebodyInside: boolean;
// short auto-off timer
FAutoOffShort: TTime;
FAutoOffLong: TTime;

procedure LightOn();
procedure LightOff();

property SomebodyInside: boolean read FSomebodyInside write SetSomebodyInside;
public

end;

var
Form1: TForm1;

implementation

{$R *.lfm}
uses DateUtils;

{ TForm1 }

procedure TForm1.Timer1Timer(Sender: TObject);
var
aTime: TTime;
aDoorOpened, aMotion: boolean;
begin
// store time
aTime := Time();
Panel1.Caption:= TimeToStr(aTime) ;

// check sensor status
aDoorOpened := CheckBox1.Checked;
aMotion := CheckBox2.Checked;

// дверь открыта
if aDoorOpened then begin
// была открыта ранее, статус двери не поменялся
if FDoorPrevOpened then begin
// если фиксируем движение - значит кто-то вошел - включаем свет
if aMotion then LightOn()
// никого нет или затаился с открытой дверью - если свет горит, то проверяем таймер автовыключения и выключаем свет, если время кончилось
else
if FLightOn and (FAutoOffShort <> 0) and (MilliSecondsBetween(FAutoOffShort, aTime) > StrToInt(Edit1.Text)) then LightOff();
end
// была ранее закрыта, значит - открывают, включаем свет
else
LightOn();
// при открытой двери сбрасываем присутствие
SomebodyInside:= false;

end
else begin // дверь закрыта
// была открыта ранее, значит дверь закрыли
if FDoorPrevOpened then begin
// если фиксируем движение - значит кто-то закрыл дверь изнутри
SomebodyInside := aMotion;
// включаем свет и перезапускаем таймеры
if SomebodyInside then LightOn()
else // никого нет - выключаемся
LightOff();
end
// была ранее тоже закрыта
else begin
// движение перезапускает таймеры и включает свет, если кто-то есть
if aMotion then begin
if FSomebodyInside then LightOn();
// а если никого не завфиксировали при закрытии двери - значит это кошка, не реагируем
end
else
// иначе, если свет горел - то выключим по длинному таймеру
if FLightOn and (FAutoOffLong <> 0) and (MilliSecondsBetween(FAutoOffLong, aTime) > StrToInt(Edit2.text)) then LightOff();

end;
end;
// запомним статус двери
FDoorPrevOpened:=aDoorOpened;

end;

procedure TForm1.SetSomebodyInside(AValue: boolean);
begin
if FSomebodyInside=AValue then Exit;
FSomebodyInside:=AValue;

CheckBox3.Checked:=FSomebodyInside;

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
// sensor status
FDoorPrevOpened:= CheckBox1.Checked;
SomebodyInside:= false;
// light on/off
LightOff();
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
CheckBox1.Checked:=true;
CheckBox2.Checked:=false;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
CheckBox1.Checked:=true;
CheckBox2.Checked:=true;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
CheckBox1.Checked:=false;
CheckBox2.Checked:=true;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
CheckBox1.Checked:=false;
CheckBox2.Checked:=false;
end;

procedure TForm1.LightOn();
begin
// перезапускаем таймеры
FAutoOffShort:= Time();
FAutoOffLong:= Time();
if not FLightOn then begin
FLightOn:=true;
// включаем свет
Panel1.Color := clYellow;
end;
end;

procedure TForm1.LightOff();
begin
// сбрасываем таймеры
FAutoOffShort:= 0;
FAutoOffLong:= 0;
if FLightOn then begin
FLightOn:=false;
// выключаем свет
Panel1.Color := clBlack;
end;
end;

end.


[main.lfm]

object Form1: TForm1
Left = 405
Height = 340
Top = 179
Width = 525
Caption = 'Form1'
ClientHeight = 340
ClientWidth = 525
DesignTimePPI = 120
OnCreate = FormCreate
LCLVersion = '1.8.4.0'
object CheckBox1: TCheckBox
Left = 57
Height = 24
Top = 29
Width = 127
Caption = 'Дверь открыта'
TabOrder = 0
end
object CheckBox2: TCheckBox
Left = 57
Height = 24
Top = 64
Width = 96
Caption = 'Движение'
TabOrder = 1
end
object Panel1: TPanel
Left = 224
Height = 66
Top = 54
Width = 256
BevelOuter = bvNone
BevelWidth = 2
BorderStyle = bsSingle
Color = clBlack
Font.Color = clTeal
ParentColor = False
ParentFont = False
TabOrder = 2
end
object Button1: TButton
Left = 56
Height = 25
Top = 128
Width = 139
Caption = 'Открыть снаружи'
OnClick = Button1Click
TabOrder = 3
end
object Button2: TButton
Left = 56
Height = 25
Top = 168
Width = 139
Caption = 'Открыть изнутри'
OnClick = Button2Click
TabOrder = 4
end
object Button3: TButton
Left = 56
Height = 25
Top = 208
Width = 139
Caption = 'Закрыть изнутри'
OnClick = Button3Click
TabOrder = 5
end
object Button4: TButton
Left = 56
Height = 25
Top = 248
Width = 139
Caption = 'Закрыть снаружи'
OnClick = Button4Click
TabOrder = 6
end
object CheckBox3: TCheckBox
Left = 352
Height = 24
Top = 129
Width = 121
Alignment = taLeftJustify
Caption = 'Кто-то внутри'
Enabled = False
TabOrder = 7
end
object Button5: TButton
Left = 56
Height = 25
Top = 290
Width = 137
Caption = 'Reset'
OnClick = FormCreate
TabOrder = 8
end
object Edit1: TEdit
Left = 384
Height = 28
Top = 165
Width = 100
TabOrder = 9
Text = '3000'
end
object Label1: TLabel
Left = 337
Height = 20
Top = 23
Width = 34
Caption = 'Свет:'
ParentColor = False
end
object Label2: TLabel
Left = 224
Height = 20
Top = 168
Width = 147
Caption = 'Короткий таймер, мс'
ParentColor = False
end
object Edit2: TEdit
Left = 384
Height = 28
Top = 208
Width = 100
TabOrder = 10
Text = '7000'
end
object Label3: TLabel
Left = 224
Height = 20
Top = 211
Width = 145
Caption = 'Длинный таймер, мс'
ParentColor = False
end
object Timer1: TTimer
Interval = 100
OnTimer = Timer1Timer
left = 344
top = 8
end
end

алгоритм, управление светом, макет

Previous post Next post
Up