442 lines
20 KiB
PHP
442 lines
20 KiB
PHP
<?php
|
||
|
||
//Скрипт для выполнения всевозможных проверок. Таких как прохождение контрольных точек. назначили ли на рейс автобус.
|
||
//Данный скрипт выполняется раз в минуту добавив расписание в CRON:
|
||
// sudo crontab -e -u www-data
|
||
// */1 * * * * wget -O /dev/null -q 'http://stations.istt.kz/engine/work.php'
|
||
|
||
|
||
//Создаём рейс по расписанию
|
||
|
||
@session_start();
|
||
|
||
require_once("./config.php");
|
||
|
||
$db=connectToDB();
|
||
//$db->exec('SET TIME ZONE 0;');
|
||
|
||
/*
|
||
$sql='
|
||
select
|
||
s.id,
|
||
s.repeat,
|
||
s.route_id,
|
||
((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time") as "time",
|
||
s."day",
|
||
s."month",
|
||
CASE WHEN s.direction THEN \'1\' ELSE \'0\' END as direction,
|
||
(select rc.company_id from main.routes_companies rc join main.companies c on c.id=rc.company_id where rc.del=false and c.company_type_id=2 and route_id=r.id and rc.type=true limit 1) as company_id,
|
||
coalesce(s.company_id,(select rc.company_id from main.routes_companies rc join main.companies c on c.id=rc.company_id where rc.del=false and c.company_type_id=1 and route_id=r.id order by rc.type desc limit 1)) as carrier_id,
|
||
s.date,
|
||
s.inform,
|
||
s.auto,
|
||
r.name as route_name
|
||
from
|
||
main.trips_schedules s
|
||
join main.routes r on r.id=s.route_id
|
||
where
|
||
s.del=false
|
||
and (s.date_start is null or s.date_start>now())
|
||
and (s.date_end is null or s.date_end<now())
|
||
and position(cast(EXTRACT(DOW FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")) as character varying) in s."day")>0
|
||
and position(case when EXTRACT(MONTH FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time"))=11 then \'a\' when EXTRACT(MONTH FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time"))=12 then \'b\' else cast(EXTRACT(DOW FROM ((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")) as character varying) end in s."month")>0
|
||
and s.date<((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")-s.inform
|
||
and now()>((now() AT TIME ZONE (EXTRACT(TIMEZONE FROM "time") * INTERVAL \'1 second\'))::date + s."time")-s.inform
|
||
order by s."time"
|
||
';
|
||
|
||
$res = NULL;
|
||
try
|
||
{
|
||
$res = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
|
||
if($res!=NULL && $res->rowCount()>0)
|
||
{
|
||
while ($row = $res->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
$dir='';
|
||
if($row['direction']=='1') $dir='в прямом направлении'; else $dir='в обратном направлении';
|
||
|
||
$msg='Для маршрута "'.$row['route_name'].'" '.$dir.' необходимо создать рейс, время отправления "'.$row['time'].'"!';
|
||
echo '<b>'.$msg."</b><br>";
|
||
echo 'Настройки для создания рейса:<br>';
|
||
$json='{"trip_type_id":1,"route_id":'.$row['route_id'].',"direction":'.$row['direction'].',"carrier_id":'.$row['carrier_id'].',"date":"'.$row['time'].'"}';
|
||
|
||
//echo $json;
|
||
echo '<br>';
|
||
|
||
if($row['auto']) //Если автоматическое создание рейса по расписанию.
|
||
{
|
||
|
||
}else //Создание рейса доверяем пользователю в автовокзале
|
||
{
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Creation_of_trips','".$msg."',".$row['company_id'].",'Create','".$json."');";
|
||
$db->query($sql);
|
||
echo $sql.'<br>';
|
||
}
|
||
|
||
echo '<br>';
|
||
//Создал либо проинформировал, обновляю расписание
|
||
$sql="update main.trips_schedules set date=(now() AT TIME ZONE (EXTRACT(TIMEZONE FROM \"time\") * INTERVAL '1 second'))::date + \"time\" where id=".$row['id'];
|
||
$db->query($sql);
|
||
echo $sql;
|
||
echo '<br>';
|
||
echo '<br>';
|
||
|
||
}
|
||
}else
|
||
{
|
||
echo 'Нет ни одного расписания!<br>';
|
||
}
|
||
*/
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Проверяем контрольные точки и если в контрольной точке нет ни одной коордионаты то считается что контрольная точка просрочена
|
||
|
||
//Выбираю те записи для которых нужна проверка выполнения расписания
|
||
//Для этого выбираю действующие рейсы (которые начались) и действующие контрольные точки которые закончались
|
||
//Исключаю из контрольных точек уже пройденные те. где time заполнено
|
||
/*
|
||
$sql='
|
||
select
|
||
t.id as trip_id,
|
||
t.object_id,
|
||
rc.id as checkpoint_id,
|
||
t.date_start+rc."time"-"interval" as start,
|
||
t.date_start+rc."time"+"interval" as stop
|
||
from
|
||
main.trips t
|
||
join main.routes_checkpoints rc on rc.route_id=t.route_id and rc.direction=t.direction
|
||
join main.routes r on r.id=rc.route_id
|
||
where
|
||
t.del=false
|
||
and rc.del=false
|
||
and r.del=false
|
||
and t.object_id is not null
|
||
and t.date_start<now()
|
||
and t.date_start+rc."time"+"interval" < now()
|
||
and rc.id not in (select route_checkpoint_id from main.trips_checkpoints where del=false and trip_id=t.id)
|
||
order by t.id;
|
||
';
|
||
|
||
$res = NULL;
|
||
try
|
||
{
|
||
$res = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
|
||
if($res!=NULL && $res->rowCount()>0)
|
||
{
|
||
while ($row = $res->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
//Проверяем каждую точку за заданный промежуток времени и если в геозоне нет такой точки то считаем что автобус опоздал либо ускорился
|
||
$sql="select id,date,lon,lat from main.terminals_locations where del=false and object_id=".$row["object_id"]." and date>'".$row["start"]."' and date<'".$row["stop"]."';";
|
||
|
||
echo $sql.'<br>';
|
||
|
||
$res2=null;
|
||
try
|
||
{
|
||
$res2 = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
|
||
}
|
||
|
||
if($res2!=NULL && $res2->rowCount()>0)
|
||
{
|
||
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
echo 'id='.$row2['id'].' date='.$row2['date'].' lat='.$row2['lon'].' lon='.$row2['lon'].'<br>';
|
||
}
|
||
}
|
||
echo '<br><br>';
|
||
|
||
}
|
||
}*/
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Проверка на то что назначили ли на рейс автобус за 10 минут до начала движения по рейсу, если нет то отправляем предупреждение
|
||
echo 'Проверка назначения автобуса на рейс за 10 минут до рейса если не назначем то генерим предупреждение<br>';
|
||
$sql='
|
||
select
|
||
t.id,
|
||
t.company_id,
|
||
t.company_carrier_id,
|
||
r.name as route_name,
|
||
t.date_start
|
||
from
|
||
main.trips t
|
||
join main.routes r on r.id=t.route_id
|
||
left join main.objects o on o.id=t.object_id and o.del=false
|
||
where
|
||
t.del=false
|
||
and o.id is null
|
||
and t.date_start<now()-\'10 minutes\'::interval
|
||
and t.date_start>now()-\'10 day\'::interval --Старые рейсы не сканируем
|
||
and (t.informed is null or t.informed=false)
|
||
|
||
';
|
||
$res = NULL;
|
||
try
|
||
{
|
||
$res = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
|
||
if($res!=NULL && $res->rowCount()>0)
|
||
{
|
||
while ($row = $res->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
$msg='Для рейса "'.$row['route_name'].'" с началом движения в "'.$row['date_start'].'" не был назначен автобус!';
|
||
$json='{}';
|
||
echo $msg.'<br>';
|
||
|
||
//Отправляю предупреждение перевозчику
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Attention','".$msg."',".$row['company_id'].",null,null);";
|
||
$db->query($sql);
|
||
|
||
//Отправляю предупреждение автобусному парку
|
||
if($row['company_carrier_id']!='')
|
||
{
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Attention','".$msg."',".$row['company_carrier_id'].",null,null);";
|
||
$db->query($sql);
|
||
}
|
||
|
||
//Отмечаю что по даному маршруту было отправлено предупреждение и больше его не стоит отправлять
|
||
$sql="update main.trips set informed=true where id=".$row['id'];
|
||
$db->query($sql);
|
||
}
|
||
}
|
||
echo 'OK<br>';
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Проверка прохождения контрольных точек и генерация сообщения о опоздании (делаю не в момент получения координат так как точки могут придти позже)
|
||
//Есть 2 варианта генерации сообщения 1: за заданный период нет координат 2: Координаты есть но ни одной в заданой области
|
||
echo 'Проверка прохождения контрольных точек и генерация сообщения об этом<br>';
|
||
$sql='
|
||
select
|
||
tc.id,
|
||
tc.route_checkpoint_id,
|
||
t.company_id,
|
||
t.company_carrier_id,
|
||
t.object_id,
|
||
t.date_start+rc."time"-rc."interval" as start,
|
||
t.date_start+rc."time"+rc."interval" as stop,
|
||
tc.informed,
|
||
o.name as object_name,
|
||
rc.name as checkpoint_name,
|
||
t.date_start,
|
||
r.name as route_name
|
||
from
|
||
main.trips_checkpoints tc
|
||
join main.trips t on tc.trip_id=t.id
|
||
join main.routes_checkpoints rc on rc.id=tc.route_checkpoint_id
|
||
left join main.objects o on o.id=t.object_id
|
||
left join main.routes r on r.id=t.route_id
|
||
where
|
||
tc.del=false
|
||
and t.del=false
|
||
and rc.del=false
|
||
and (tc.informed is null or tc.informed=false)
|
||
and tc."time" is null
|
||
and t.object_id is not null
|
||
and t.date_start+rc."time"+rc."interval"<now()
|
||
and t.date_start+rc."time"+rc."interval">now()-\'10 day\'::interval --Старые рейсы не сканируем
|
||
|
||
';
|
||
|
||
$res = NULL;
|
||
try
|
||
{
|
||
$res = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
|
||
if($res!=NULL && $res->rowCount()>0)
|
||
{
|
||
while ($row = $res->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
//Проверяю были ли точки в заданное время для автобуса
|
||
$sql='select sum(1) as cnt from main.terminals_locations where object_id='.$row['object_id'].' and date>\''.$row['start'].'\' and date<\''.$row['stop'].'\' and ST_Within(ST_SetSRID(ST_MakePoint(lon,lat),4326),(select geom from main.routes_checkpoints where id='.$row['route_checkpoint_id'].'))=true';
|
||
$res2 = NULL;
|
||
try
|
||
{
|
||
$res2 = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
if($res2!=NULL && $res2->rowCount()>0)
|
||
{
|
||
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
if($row2['cnt']===0)
|
||
{
|
||
$msg='Автобус "'.$row['object_name'].'" в заданное время c "'.$row['start'].'" по "'.$row['stop'].'" не был в контрольной точке "'.$row['checkpoint_name'].'" на маршруте "'.$row['route_name'].'" с началом движения в "'.$row['date_start'].'"!';
|
||
$json='{}';
|
||
echo $msg.'<br>';
|
||
|
||
//Отправляю предупреждение перевозчику
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_id'].",'Filtering','".$json."');";
|
||
$db->query($sql);
|
||
|
||
//Отправляю предупреждение автобусному парку
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_carrier_id'].",'Filtering','".$json."');";
|
||
$db->query($sql);
|
||
|
||
//Отмечаю что по даному маршруту было отправлено предупреждение и больше его не стоит отправлять
|
||
$sql="update main.trips_checkpoints set informed=true where id=".$row['id'];
|
||
$db->query($sql);
|
||
}else
|
||
{
|
||
$msg='Терминал автобуса "'.$row['object_name'].'" не передавал валидные координаты заданное время с "'.$row['start'].'" по "'.$row['stop'].'" для контрольной точки "'.$row['checkpoint_name'].'" на маршруте "'.$row['route_name'].'" с началом движения в "'.$row['date_start'].'"!';
|
||
$json='{}';
|
||
echo $msg.'<br>';
|
||
|
||
//Отправляю предупреждение перевозчику
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_id'].",'Filtering','".$json."');";
|
||
$db->query($sql);
|
||
|
||
//Отправляю предупреждение автобусному парку
|
||
$sql="insert into main.messages(subject,text,company_id,action_name,action_settings)values('Passage_of_control_points','".$msg."',".$row['company_carrier_id'].",'Filtering','".$json."');";
|
||
$db->query($sql);
|
||
|
||
//Отмечаю что по даному маршруту было отправлено предупреждение и больше его не стоит отправлять
|
||
$sql="update main.trips_checkpoints set informed=true where id=".$row['id'];
|
||
$db->query($sql);
|
||
}
|
||
}
|
||
}
|
||
echo '<br><br>';
|
||
}
|
||
}
|
||
echo 'OK<br>';
|
||
//----------------------------------------------------------------------------------------------------
|
||
//Выбираем точки в заданный промежуток времени если эта точка не находится на маршруте то проверяем её на зоны объезда и если она находится там то не реагируем
|
||
//а если точка в не зоны объезда то нужно проверить в предыдущей или следующей были выезды то не следует генерировать новое предуреждение.
|
||
//А предыдущий определяется по времени те если +- 5 минут небыло ни одного выезда то событие не генерим, это сделано потому что координаты с терминала приходят не последовательно по возможности с начала новые а потом старые.
|
||
//Коордионаты проходящие не по маршруту выписываем в отдельную таблицу
|
||
echo 'Проверка GPS координат на то что они в нужное время на маршруте с учётом объездов, если не на маршруте то генерим предупреждение<br>';
|
||
$sql="
|
||
select
|
||
t.id,
|
||
t.date_start + mint.min_time as date_start,
|
||
t.date_start + maxt.max_time as date_stop,
|
||
t.object_id,
|
||
t.route_id,
|
||
r.name
|
||
from
|
||
main.trips t
|
||
join main.routes r on r.id=t.route_id
|
||
join (
|
||
select
|
||
rc.route_id,
|
||
rc.\"time\"+rc.\"interval\" as min_time
|
||
from
|
||
main.routes_checkpoints rc
|
||
join (select route_id,min(\"time\") as \"time\" from main.routes_checkpoints where del=false and route_id=129 group by route_id) t on t.route_id=rc.route_id and t.\"time\"=rc.\"time\"
|
||
limit 1
|
||
) mint on mint.route_id=t.route_id
|
||
join
|
||
(
|
||
select
|
||
rc.route_id,
|
||
rc.\"time\"-rc.\"interval\" as max_time
|
||
from
|
||
main.routes_checkpoints rc
|
||
join (select route_id,max(\"time\") as \"time\" from main.routes_checkpoints where del=false and route_id=129 group by route_id) t on t.route_id=rc.route_id and t.\"time\"=rc.\"time\"
|
||
limit 1
|
||
) maxt on mint.route_id=t.route_id
|
||
where
|
||
t.del=false
|
||
and r.del=false
|
||
and t.object_id is not null
|
||
and t.date_start + maxt.max_time>now()-'10 day'::interval --Старые рейсы не сканируем
|
||
order by t.date_start
|
||
";
|
||
$res = NULL;
|
||
try
|
||
{
|
||
$res = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
|
||
if($res!=NULL && $res->rowCount()>0)
|
||
{
|
||
while ($row = $res->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
//Теперь проверяем координаты которые ещё небыли проверены
|
||
echo 'Проверяю для "'.$row['name']." c ".$row['date_start'].' по '.$row['date_stop'].'"<br>';
|
||
|
||
$sql='
|
||
select
|
||
sl.id,
|
||
ST_distance(r.geom::geography,ST_SetSRID(ST_MakePoint(sl.lon,sl.lat),4326)::geography)<width as on_route
|
||
from
|
||
main.terminals_locations sl,
|
||
main.routes r
|
||
where
|
||
sl.del=false
|
||
and r.del=false
|
||
and sl.on_trip is null
|
||
and r.id='.$row['object_id'].'
|
||
and sl.date>\''.$row['date_start'].'\'
|
||
and sl.date<\''.$row['date_stop'].'\'
|
||
';
|
||
$res2 = NULL;
|
||
try
|
||
{
|
||
$res2 = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
if($res2!=NULL && $res2->rowCount()>0)
|
||
{
|
||
while ($row2 = $res2->fetch(PDO::FETCH_ASSOC))
|
||
{
|
||
if($row2['on_route']==true)
|
||
{
|
||
//Помечаем точку что она на маршруте
|
||
$sql='update main.terminals_locations set on_trip=true where id='.$row2['id'];
|
||
$db->query($sql);
|
||
}else
|
||
{
|
||
//Для точек которые не на маршруте нужно пройти ещё одну проверку не находятся ли они в объездах
|
||
$sql='select sum(1) from main.terminals_locations sl,main.detours d where ST_Within(ST_SetSRID(ST_MakePoint(sl.lon,sl.lat),4326),d.geom)=true and sl.id='.$row2['id'];
|
||
$res3 = NULL;
|
||
try
|
||
{
|
||
$res3 = $db->query($sql);
|
||
}catch (Exception $e)
|
||
{
|
||
echo $e->getMessage();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
//++++++
|
||
}
|
||
}
|
||
echo 'OK<br>'; |