2021-12-30 12:05:56 +01:00
|
|
|
#!/usr/bin/perl
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
|
|
|
|
#
|
|
|
|
#get lock event for last 20 minutes
|
|
|
|
#cronjob interval 15 minutes
|
|
|
|
#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events"
|
|
|
|
#
|
|
|
|
#Ilockit GPS cloud
|
|
|
|
#
|
|
|
|
#4. Get a list of positions
|
|
|
|
#fetch_ >> https://tracking.ilockit.bike/api/positions?from=2021-05-31T07:44:10Z&to=2021-06-06T07:44:10Z&deviceId=4272
|
|
|
|
|
|
|
|
#5. Get a list of Events
|
|
|
|
#fetch_ >> https://tracking.ilockit.bike/api/reports/events?from=2021-05-31T07:44:10Z&to=2021-06-06T07:44:10Z&deviceId=4272
|
|
|
|
|
|
|
|
use vars qw($syshost);
|
|
|
|
|
|
|
|
BEGIN {
|
|
|
|
$syshost = $ARGV[0] || die;
|
|
|
|
}
|
|
|
|
|
2022-01-09 18:31:20 +01:00
|
|
|
use lib "/var/www/copri-bike/$syshost/src";
|
2021-12-30 12:05:56 +01:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
use POSIX;
|
|
|
|
use CGI;
|
|
|
|
use Lib::Config;
|
|
|
|
use JSON;
|
|
|
|
use LWP::UserAgent;
|
|
|
|
use DateTime;
|
|
|
|
use Time::Piece;
|
|
|
|
|
|
|
|
my $cf = new Config;
|
|
|
|
use Mod::DBtank;
|
|
|
|
use Data::Dumper;
|
|
|
|
|
|
|
|
my $q = new CGI;
|
|
|
|
my $dbt = new DBtank;
|
|
|
|
my %varenv = $cf->envonline($syshost);
|
|
|
|
|
|
|
|
my $lang = "de";
|
|
|
|
my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime;
|
|
|
|
|
|
|
|
my $api_file = "/var/www/copri4/shareeconf/apikeys.cfg";
|
|
|
|
my $aconf = Config::General->new($api_file);
|
|
|
|
my %apikeyconf = $aconf->getall;
|
|
|
|
#print "---> " . $apikeyconf{Ilockitcloud}->{username} . "\n";
|
|
|
|
|
|
|
|
my $ua = LWP::UserAgent->new;
|
|
|
|
$ua->agent("sharee APIclient");
|
|
|
|
$ua->credentials( 'tracking.ilockit.bike:443', 'api', "$apikeyconf{Ilockitcloud}->{username}", "$apikeyconf{Ilockitcloud}->{passwd}");
|
|
|
|
|
|
|
|
my $json = JSON->new->allow_nonref;
|
|
|
|
my $response_in = {};
|
|
|
|
my $dbh = "";
|
|
|
|
my $owner = 183;
|
|
|
|
|
|
|
|
my $todo = $ARGV[1];
|
|
|
|
my $deviceId = $ARGV[2] || "";
|
|
|
|
|
|
|
|
open(FILE,">>$varenv{logdir}/Ilockit_cloud.log");
|
|
|
|
print FILE "\n\n*** $now_dt\n";
|
|
|
|
|
|
|
|
#my $endpoint = "https://tracking.ilockit.bike/api/commands";
|
|
|
|
#utc to localtime
|
|
|
|
sub localizedtime {
|
|
|
|
my $date = shift;
|
|
|
|
|
|
|
|
$date =~ s/\..*$//;
|
|
|
|
my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S");
|
|
|
|
print FILE "localizedtime GMT alias Zulu: " . $time->datetime . "\n";#GMT alias Zulu
|
|
|
|
$time = localtime($time->epoch);#epoch
|
|
|
|
print FILE "localizedtime localized date time: " . $time->datetime . "\n";#localized date time
|
|
|
|
|
|
|
|
return $time->datetime;
|
|
|
|
}
|
|
|
|
#print localizedtime("2021-06-11T11:58:09.000+0000") . " example\n";
|
|
|
|
|
|
|
|
#localtime to utc
|
|
|
|
#my $now = strftime "%Y-%m-%dT%H:%M:%S", localtime;
|
|
|
|
#utctime($now);
|
|
|
|
sub utctime {
|
|
|
|
my $date = shift;
|
|
|
|
my $latency = shift || 0;
|
|
|
|
|
|
|
|
$date =~ s/\..*$//;
|
|
|
|
$date =~ s/\+\d+$//;
|
|
|
|
print FILE "requested datetime: " . $date . "\n";
|
|
|
|
|
|
|
|
my $time = Time::Piece->strptime($date, "%Y-%m-%dT%H:%M:%S");
|
|
|
|
print FILE "localtime: " . $time->datetime . "\n";#localtime
|
|
|
|
my $utc_epoch = $time->epoch;
|
|
|
|
#
|
|
|
|
#only -1 hour, because of deviceTime and serverTime differs
|
|
|
|
#'deviceTime' => '2021-10-14T08:19:35.000+0000',
|
|
|
|
#'serverTime' => '2021-10-14T07:19:37.000+0000',
|
2022-04-20 12:07:48 +02:00
|
|
|
|
|
|
|
$utc_epoch -= 2*60*60;# -2 std (Sommerzeit)
|
|
|
|
#$utc_epoch -= 1*60*60;# -1 std (Winterzeit)
|
|
|
|
|
2021-12-30 12:05:56 +01:00
|
|
|
$utc_epoch += $latency;
|
|
|
|
$time = gmtime($utc_epoch);#epoch
|
|
|
|
print FILE "utctime: " . $time->datetime . "\n";#utc zulu date time
|
|
|
|
#
|
|
|
|
return $time->datetime;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#get all device localy
|
|
|
|
sub get_devicesONcontent_all {
|
|
|
|
my $deviceId = shift;
|
|
|
|
my $pref = {
|
|
|
|
table => "content",
|
|
|
|
fetch => "all",
|
|
|
|
keyfield => "int13",
|
|
|
|
template_id => "205",
|
|
|
|
int13 => ">::0",
|
|
|
|
};
|
|
|
|
my $record = $dbt->fetch_record($dbh,$pref);
|
|
|
|
return $record;
|
|
|
|
}
|
|
|
|
|
|
|
|
#get one device localy in contenttranspos to check if bike is locked
|
|
|
|
sub get_devicesONcontenttranspos {
|
|
|
|
my $deviceId = shift;
|
|
|
|
my $pref = {
|
|
|
|
table => "contenttranspos",
|
|
|
|
fetch => "one",
|
|
|
|
int13 => "$deviceId",
|
|
|
|
#int20 => "1",#locked
|
|
|
|
};
|
|
|
|
my $record = $dbt->fetch_tablerecord($dbh,$pref);
|
|
|
|
return $record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#get one device localy
|
|
|
|
sub get_devicesONcontent {
|
|
|
|
my $deviceId = shift;
|
|
|
|
my $pref = {
|
|
|
|
table => "content",
|
|
|
|
fetch => "one",
|
|
|
|
template_id => "205",
|
|
|
|
int13 => "$deviceId",
|
|
|
|
};
|
|
|
|
my $record = $dbt->fetch_record($dbh,$pref);
|
|
|
|
return $record;
|
|
|
|
}
|
|
|
|
|
|
|
|
#get and check if theft exist in contenttranspos not older than 1 day
|
|
|
|
sub get_devicesONcontenttheftpos {
|
|
|
|
my $key = shift;
|
|
|
|
my $id = shift;
|
|
|
|
my $pref = {
|
|
|
|
table => "contenttheftpos",
|
|
|
|
fetch => "one",
|
|
|
|
#mtime => ">::(now() - interval '1 day')",
|
|
|
|
$key => "$id",
|
|
|
|
};
|
|
|
|
my $record = $dbt->fetch_tablerecord($dbh,$pref);
|
|
|
|
return $record;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#per cronjob once a day to get and update content with cloud device id
|
|
|
|
#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_devices"
|
|
|
|
&get_devices if($todo eq "get_devices");
|
|
|
|
sub get_devices {
|
|
|
|
my $endpoint = "https://tracking.ilockit.bike/api/devices";
|
|
|
|
my $rest = "";
|
|
|
|
|
|
|
|
my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
|
|
|
|
$response_in = decode_json($ret_json);
|
|
|
|
|
|
|
|
print FILE "ilockit get_devices response_in:" . Dumper($response_in);
|
|
|
|
#foreach my $result (@{ $response_in }) {
|
|
|
|
# if($result->{id}){
|
|
|
|
# print $result->{id} . "\n";
|
|
|
|
# print $result->{name} . "\n";
|
|
|
|
# }
|
|
|
|
#}
|
|
|
|
|
|
|
|
my $pref = {
|
|
|
|
table => "content",
|
|
|
|
fetch => "all",
|
|
|
|
keyfield => "barcode",
|
|
|
|
template_id => "205",
|
|
|
|
#int10 => "1",#1 = "available"
|
|
|
|
};
|
|
|
|
my $record = $dbt->fetch_record($dbh,$pref);
|
|
|
|
my $rows = 0;
|
|
|
|
if(1==1 && ref($response_in) eq "ARRAY"){
|
|
|
|
foreach my $id (sort { $record->{$a}->{barcode} <=> $record->{$b}->{barcode} } keys (%$record)){
|
|
|
|
foreach my $resp (@{ $response_in }) {
|
|
|
|
#print "if($resp->{name} eq $record->{$id}->{txt18} && ($resp->{id} && $resp->{id} ne $record->{$id}->{int13}))\n";
|
|
|
|
if($resp->{name} eq $record->{$id}->{txt18} && ($resp->{id} && $resp->{id} ne $record->{$id}->{int13})){
|
|
|
|
my $update = {
|
|
|
|
table => "content",
|
|
|
|
mtime => "now()",
|
|
|
|
owner => "$owner",
|
|
|
|
int13 => "$resp->{id}",
|
|
|
|
};
|
|
|
|
$rows = $dbt->update_record($dbh,$update,$record->{$id});
|
|
|
|
print FILE "update_record content.int13=$resp->{id}" . $rows . "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}#end if($todo eq "get_devices"){
|
|
|
|
|
|
|
|
|
|
|
|
#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_events 6572 20"
|
|
|
|
&get_events if($todo eq "get_events");
|
|
|
|
sub get_events {
|
|
|
|
|
|
|
|
#1. select all devices on content
|
2022-01-15 11:17:07 +01:00
|
|
|
print FILE "ilockit get_events get_devicesONcontent_all\n";
|
2021-12-30 12:05:56 +01:00
|
|
|
my $record_cc = get_devicesONcontent_all();
|
|
|
|
my $today = DateTime->now( time_zone => "Europe/Berlin" );
|
|
|
|
$today .= "Z";
|
|
|
|
my $from_datetime = DateTime->now( time_zone => "Europe/Berlin" );
|
|
|
|
$from_datetime->subtract( days => 1 );
|
|
|
|
$from_datetime .= "Z";
|
|
|
|
|
|
|
|
my $endpoint = "https://tracking.ilockit.bike/api/reports/events";
|
|
|
|
#my $rest = "from=2021-05-31T07:44:10Z\&to=2021-06-06T07:44:10Z\&deviceId=4272";
|
|
|
|
#my $rest = "from=2021-06-11T07:44:10Z\&to=2021-06-11T12:44:10Z\&deviceId=$deviceId";
|
|
|
|
#
|
|
|
|
#2. loope cloud
|
|
|
|
foreach my $id (sort { $record_cc->{$a}->{barcode} <=> $record_cc->{$b}->{barcode} } keys (%$record_cc)){
|
|
|
|
|
|
|
|
my $rest = "from=$from_datetime\&to=$today\&deviceId=$record_cc->{$id}->{int13}";
|
|
|
|
|
|
|
|
my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
|
|
|
|
$response_in = decode_json($ret_json);
|
|
|
|
print FILE "ilockit get_events response_in:" . Dumper($response_in);
|
|
|
|
|
|
|
|
|
|
|
|
foreach my $resp (@{ $response_in }) {
|
|
|
|
#if($record_cc->{$id}->{int13} eq $resp->{deviceId} && $resp->{type} eq "deviceOnline"){
|
|
|
|
if($record_cc->{$id}->{int13} && $record_cc->{$id}->{int13} eq $resp->{deviceId} && ref($resp->{attributes}) eq "HASH" && $resp->{attributes}->{statusCode} && $resp->{attributes}->{statusCode} eq "alarm"){
|
|
|
|
my $theft_record = get_devicesONcontenttheftpos("int01",$resp->{id});
|
|
|
|
print FILE "id: $resp->{id}\n";
|
|
|
|
print FILE "deviceId: $resp->{deviceId}\n";
|
|
|
|
print FILE "type: $resp->{type}\n";
|
|
|
|
print FILE "statusCode: $resp->{attributes}->{statusCode}\n";
|
|
|
|
print FILE "serverTime: $resp->{serverTime}\n\n";
|
|
|
|
if(!$theft_record->{c_id}){
|
|
|
|
my $serverTime = localizedtime($resp->{serverTime});
|
|
|
|
my $insert = {
|
|
|
|
table => "contenttheftpos",
|
|
|
|
cc_id => "$record_cc->{$id}->{c_id}",
|
|
|
|
barcode => "$record_cc->{$id}->{barcode}",
|
|
|
|
int04 => "$record_cc->{$id}->{int04}",#end station
|
|
|
|
txt06 => "$record_cc->{$id}->{txt06}",#end gps
|
|
|
|
txt18 => "$record_cc->{$id}->{txt18}",
|
|
|
|
owner => $owner,
|
|
|
|
mtime => "now()",
|
|
|
|
int10 => "7",#theft alarm
|
|
|
|
int01 => "$resp->{id}",#keeps id for event_type
|
|
|
|
int13 => "$resp->{deviceId}",
|
|
|
|
start_time => "$serverTime",
|
|
|
|
end_time => "$serverTime",
|
|
|
|
};
|
|
|
|
|
|
|
|
my $c_id = $dbt->insert_contentoid($dbh,$insert);
|
|
|
|
print FILE "insert sub get_events:" . Dumper($insert);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}#end if($todo eq "get_events"){
|
|
|
|
|
|
|
|
|
|
|
|
#sudo su www-data -c "./src/scripts/Ilockit_cloud.pl shareedms-fr01 get_positions 6572"
|
|
|
|
#2021-10-27, cron disabled, unspecific and not only alarm
|
|
|
|
&get_positions if($todo eq "get_positions");
|
|
|
|
sub get_positions {
|
|
|
|
#1. select all devices on content
|
|
|
|
my $record_cc = get_devicesONcontent_all();
|
|
|
|
my $today = DateTime->now( time_zone => "Europe/Berlin" );
|
|
|
|
$today .= "Z";
|
|
|
|
my $from_datetime = DateTime->now( time_zone => "Europe/Berlin" );
|
|
|
|
$from_datetime->subtract( days => 1 );
|
|
|
|
$from_datetime .= "Z";
|
|
|
|
|
|
|
|
|
|
|
|
my $endpoint = "https://tracking.ilockit.bike/api/positions";
|
|
|
|
#my $rest = "from=2021-06-11T07:44:10Z\&to=2021-06-11T12:44:10Z\&deviceId=$deviceId" if($deviceId);
|
|
|
|
#my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
|
|
|
|
#$response_in = decode_json($ret_json);
|
|
|
|
#print Dumper($response_in);
|
|
|
|
|
|
|
|
#2. loope cloud
|
|
|
|
foreach my $id (sort { $record_cc->{$a}->{barcode} <=> $record_cc->{$b}->{barcode} } keys (%$record_cc)){
|
|
|
|
|
|
|
|
my $ctpos = get_devicesONcontenttranspos("$record_cc->{$id}->{int13}");
|
|
|
|
if($ctpos->{int20} == 1){#if locked then get position in range of end_time to now
|
|
|
|
print FILE "record_pos.int13: $ctpos->{int13} --> lock_state:$ctpos->{int20}| end_time:$ctpos->{end_time}\n";
|
|
|
|
|
|
|
|
#get only positions until smartlock end_time is locked
|
|
|
|
if($ctpos->{int13} && $ctpos->{end_time} =~ /(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/){
|
|
|
|
$ctpos->{end_time} =~ s/\..*$//;
|
|
|
|
my $end_time = $ctpos->{end_time};
|
|
|
|
$end_time =~ s/\s/T/;
|
|
|
|
$from_datetime = utctime($end_time,"0");
|
|
|
|
$from_datetime .= "Z";
|
|
|
|
|
|
|
|
#keep in mind, api-from maybe deviceTime (end_time-1) and position timestamp is serverTime+2
|
|
|
|
my $rest = "from=$from_datetime\&to=$today\&deviceId=$record_cc->{$id}->{int13}";
|
|
|
|
my $ret_json = fetch_ilockit_cloud("","$endpoint",$rest);
|
|
|
|
$response_in = decode_json($ret_json);
|
|
|
|
print FILE "ilockit get_positions response_in:" . Dumper($response_in);
|
|
|
|
|
|
|
|
foreach my $resp (@{ $response_in }) {
|
|
|
|
if($record_cc->{$id}->{int13} eq $resp->{deviceId}){
|
|
|
|
my $theft_record = get_devicesONcontenttheftpos("int02",$resp->{id});
|
|
|
|
print FILE "id: $resp->{id}\n";
|
|
|
|
print FILE "deviceId: $resp->{deviceId}\n";
|
|
|
|
print FILE "serverTime: $resp->{serverTime}\n\n";
|
|
|
|
if(!$theft_record->{c_id}){
|
|
|
|
my $serverTime = localizedtime($resp->{serverTime});
|
|
|
|
my $insert = {
|
|
|
|
table => "contenttheftpos",
|
|
|
|
cc_id => "$record_cc->{$id}->{c_id}",
|
|
|
|
barcode => "$record_cc->{$id}->{barcode}",
|
|
|
|
txt06 => "$resp->{latitude}, $resp->{longitude}",
|
|
|
|
owner => $owner,
|
|
|
|
mtime => "now()",
|
|
|
|
int10 => "8",#gps position
|
|
|
|
int02 => "$resp->{id}",#keeps id for event_type
|
|
|
|
int07 => "$resp->{speed}",
|
|
|
|
int08 => "$resp->{attributes}->{distance}",
|
|
|
|
int09 => "$resp->{attributes}->{totalDistance}",
|
|
|
|
int13 => "$resp->{deviceId}",
|
|
|
|
start_time => "$serverTime",
|
|
|
|
end_time => "$serverTime",
|
|
|
|
};
|
|
|
|
|
|
|
|
my $c_id = $dbt->insert_contentoid($dbh,$insert);
|
|
|
|
print FILE "insert sub get_positions:" . Dumper($insert);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}#end if($todo eq "get_positions"){
|
|
|
|
|
|
|
|
|
|
|
|
#ilockit http request
|
|
|
|
sub fetch_ilockit_cloud {
|
|
|
|
my $self = shift;
|
|
|
|
my $ilockitserver = shift || "";
|
|
|
|
my $rest = shift || "";
|
|
|
|
my $ilockit_request = "$ilockitserver?$rest";
|
|
|
|
|
|
|
|
print FILE "fetch_ >> " . $ilockit_request . "\n";
|
|
|
|
|
|
|
|
my $req = HTTP::Request->new(GET => "$ilockit_request");
|
|
|
|
#$req->content_type('application/x-www-form-urlencoded');
|
|
|
|
$req->content_type('application/json');
|
|
|
|
$req->content($rest);
|
|
|
|
|
|
|
|
my $res = $ua->request($req);
|
|
|
|
if ($res->is_success) {
|
|
|
|
#print $res->content;
|
|
|
|
return $res->content;
|
|
|
|
print $res->status_line, "\n";
|
|
|
|
}else {
|
|
|
|
print $res->status_line, "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
close(FILE);
|
|
|
|
|