2022-03-26 10:19:13 +01:00
|
|
|
package APIsigoclient;
|
|
|
|
#
|
|
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
|
|
|
|
#
|
|
|
|
#Client for sigo
|
|
|
|
#
|
2022-03-31 07:28:37 +02:00
|
|
|
#380116b5-0522-43da-ab66-477744a731a3
|
|
|
|
#
|
2022-03-31 21:53:53 +02:00
|
|
|
use lib qw(/var/www/copri-bike/shareeapp-sx/src);
|
2022-03-26 10:19:13 +01:00
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
use POSIX;
|
|
|
|
use Exporter;
|
|
|
|
our @ISA = qw (Exporter);
|
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
#use POSIX;
|
2022-03-26 10:19:13 +01:00
|
|
|
use CGI;
|
|
|
|
use JSON;
|
|
|
|
use LWP::UserAgent;
|
|
|
|
use DateTime;
|
|
|
|
use Time::Piece;
|
|
|
|
use Scalar::Util qw(looks_like_number);
|
|
|
|
use Config::General;
|
|
|
|
|
|
|
|
use Lib::Config;
|
|
|
|
use Mod::DBtank;
|
|
|
|
use Mod::Basework;
|
2022-03-31 21:53:53 +02:00
|
|
|
use Mod::APIfunc;
|
2022-03-26 10:19:13 +01:00
|
|
|
use Data::Dumper;
|
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
my $q = new CGI;
|
|
|
|
my $json = JSON->new->allow_nonref;
|
2022-03-26 10:19:13 +01:00
|
|
|
my $cf = new Config;
|
|
|
|
my $dbt = new DBtank;
|
2022-03-31 21:53:53 +02:00
|
|
|
my $apif = new APIfunc;
|
2022-03-26 10:19:13 +01:00
|
|
|
my $bw = new Basework;
|
|
|
|
|
|
|
|
sub new {
|
|
|
|
my $class = shift;
|
|
|
|
my $self = {};
|
|
|
|
bless($self,$class);
|
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
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;
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
my $ua = LWP::UserAgent->new;
|
|
|
|
$ua->agent("sharee sigoclient");
|
|
|
|
my $size = $ua->max_size;
|
|
|
|
my $bytes = 100000;
|
|
|
|
$ua->max_size( $bytes );
|
|
|
|
$ua->default_header( 'x-api-key' => $apikeyconf{sigo}->{api_key} );
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
sub sigo_available {
|
|
|
|
my $self = shift;
|
|
|
|
my $q = shift;
|
|
|
|
my $varenv = shift || {};
|
|
|
|
my $auth = shift || {};
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
my $response_in = {};
|
|
|
|
my $dbh = "";
|
|
|
|
my $owner = 169;
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
my $authed = 0;
|
|
|
|
my $tariff_content = {};
|
|
|
|
$authed = 1 if(ref($auth) eq "HASH" && $auth->{c_id} && $auth->{c_id} > 0);
|
|
|
|
(my $bike_group,my $user_group,$tariff_content,my $user_tour) = $apif->fetch_tariff($varenv->{dbname},$auth,$q->param('authcookie'));
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
open(FILE,">>$varenv->{logdir}/APIsigo_client.log");
|
2022-03-30 13:06:39 +02:00
|
|
|
print FILE "\n*** $now_dt 'sigo client' \n";
|
|
|
|
|
2022-03-31 21:53:53 +02:00
|
|
|
#my $endpoint = "https://sigo.dev.sigo.green/api/v1/bikes";
|
|
|
|
my $endpoint = "$dbt->{operator}->{$varenv->{dbname}}->{endpoint}/bikes";
|
|
|
|
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 07:28:37 +02:00
|
|
|
my $return = {};
|
|
|
|
my $rest_json = "";
|
2022-03-31 21:53:53 +02:00
|
|
|
my $ret_json = get_sigo("$endpoint",$rest_json);
|
2022-03-31 07:28:37 +02:00
|
|
|
eval {
|
|
|
|
$response_in = decode_json($ret_json);
|
2022-03-31 21:53:53 +02:00
|
|
|
print FILE "<--- station_and_bikes response_in:\n";
|
|
|
|
#print FILE Dumper($response_in) . "\n";
|
|
|
|
|
2022-03-31 07:28:37 +02:00
|
|
|
if(ref($response_in) eq "HASH"){
|
2022-03-31 21:53:53 +02:00
|
|
|
foreach my $resp (@{ $response_in->{items} }) {
|
|
|
|
print FILE Dumper($resp) . "\n";
|
|
|
|
|
|
|
|
if($dbt->{operator}->{$varenv->{dbname}}->{operatorApp} && $q->param('request') eq "stations_available"){
|
|
|
|
|
|
|
|
#station (mainly using sigojson site object)
|
|
|
|
my $station = "SX$resp->{site}->{id}";
|
|
|
|
if($station && looks_like_number($resp->{site}->{id}) && $resp->{site}->{status} eq "ACTIVE" && $resp->{site}->{lat} && $resp->{site}->{lon}){
|
|
|
|
print FILE "Station: $station\n";
|
|
|
|
$return->{$station}->{station} = "$station";
|
|
|
|
$return->{$station}->{authed} = "$authed";
|
|
|
|
$return->{$station}->{uri_operator} = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}";
|
|
|
|
$return->{$station}->{description} = "$resp->{site}->{address}" || "";
|
|
|
|
$return->{$station}->{station_group} = ["SX300102"];#E-Lastenrad
|
|
|
|
$return->{$station}->{gps}->{latitude} = "$resp->{site}->{lat}" || "";
|
|
|
|
$return->{$station}->{gps}->{longitude} = "$resp->{site}->{lon}" || "";
|
|
|
|
$return->{$station}->{gps_radius} = "75";
|
|
|
|
$return->{$station}->{state} = "defect";
|
|
|
|
if($resp->{site}->{status} eq "ACTIVE"){#?
|
|
|
|
$return->{$station}->{state} = "available";
|
|
|
|
}elsif($resp->{site}->{status} eq "MAINTANANCE"){
|
|
|
|
$return->{$station}->{state} = "maintanance";
|
|
|
|
}elsif($resp->{site}->{status} eq "OFFLINE"){
|
|
|
|
$return->{$station}->{state} = "defect";
|
|
|
|
}
|
|
|
|
$return->{$station}->{operator_data} = {};
|
2022-03-31 07:28:37 +02:00
|
|
|
|
|
|
|
}
|
2022-03-31 21:53:53 +02:00
|
|
|
}#end stations_available
|
|
|
|
|
|
|
|
if($dbt->{operator}->{$varenv->{dbname}}->{operatorApp} && $q->param('request') eq "bikes_available"){
|
|
|
|
|
|
|
|
#bike (mainly using sigojson state object)
|
|
|
|
my $bike = "SX$resp->{mobile_bike_id}";
|
|
|
|
if($bike && looks_like_number($resp->{mobile_bike_id}) && $resp->{status} eq "ACTIVE"){
|
|
|
|
print FILE "Bike: $bike\n";
|
|
|
|
$return->{$bike}->{bike} = "$bike";
|
|
|
|
$return->{$bike}->{authed} = "$authed";
|
|
|
|
$return->{$bike}->{station} = "$resp->{site}->{id}" || "";
|
|
|
|
$return->{$bike}->{uri_operator} = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}";
|
|
|
|
$return->{$bike}->{description} = "E-Lastenrad";
|
|
|
|
$return->{$bike}->{gps}->{latitude} = "$resp->{state}->{lat}" || "";
|
|
|
|
$return->{$bike}->{gps}->{longitude} = "$resp->{state}->{lon}" || "";
|
|
|
|
$return->{$bike}->{bike_charge} = "$resp->{energy_level}" || "0";
|
|
|
|
$return->{$bike}->{state} = "defect";
|
|
|
|
if($resp->{status} eq "ACTIVE"){#?
|
|
|
|
$return->{$bike}->{state} = "available";
|
|
|
|
}elsif($resp->{status} eq "MAINTANANCE"){
|
|
|
|
$return->{$bike}->{state} = "maintanance";
|
|
|
|
}elsif($resp->{status} eq "OFFLINE"){
|
|
|
|
$return->{$bike}->{state} = "defect";
|
|
|
|
}elsif($resp->{status} eq "OPERATION"){#?
|
|
|
|
$return->{$bike}->{state} = "occupied";
|
|
|
|
}
|
|
|
|
|
|
|
|
#$return->{$bike}->{lock_state} = "undefined";#?
|
|
|
|
$return->{$bike}->{lock_state} = "unlocked";
|
|
|
|
if($resp->{state}->{locked}){
|
|
|
|
$return->{$bike}->{lock_state} = "locked";
|
|
|
|
}
|
|
|
|
$return->{$bike}->{system} = "sigo";
|
|
|
|
$return->{$bike}->{bike_group} = ["SX300102"];#E-Lastenrad
|
|
|
|
$return->{$bike}->{unlock_allowed} = "1";
|
|
|
|
$return->{$bike}->{tariff_description} = {};
|
|
|
|
if(ref($tariff_content) eq "HASH"){
|
|
|
|
foreach my $tid (sort { $tariff_content->{$a}->{barcode} <=> $tariff_content->{$b}->{barcode} } keys (%$tariff_content)){
|
|
|
|
$return->{$bike}->{tariff_description}->{name} = "$tariff_content->{$tid}->{ct_name}";
|
|
|
|
$return->{$bike}->{tariff_description}->{number} = "$tariff_content->{$tid}->{barcode}";
|
|
|
|
$return->{$bike}->{tariff_description}->{eur_per_hour} = "$tariff_content->{$tid}->{int02}" || "0";
|
|
|
|
$return->{$bike}->{tariff_description}->{max_eur_per_day} = "$tariff_content->{$tid}->{int17}" if($tariff_content->{$tid}->{int17});
|
|
|
|
$return->{$bike}->{tariff_description}->{free_hours} = "$tariff_content->{$tid}->{int16}" if($tariff_content->{$tid}->{int16});
|
|
|
|
$return->{$bike}->{tariff_description}->{abo_eur_per_month} = "$tariff_content->{$tid}->{int15}" if($tariff_content->{$tid}->{int15});
|
|
|
|
#TODO, have to be set on Tarif table
|
|
|
|
$return->{$bike}->{tariff_description}->{operator_agb} = "Mit der Mietrad Anmietung wird folgender Betreiber <a href='$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}/site/agb.html' target='_blank'>AGB</a> zugestimmt (Demo)." if($auth->{c_id} && ($auth->{c_id} == 1842 || $auth->{c_id} == 5781 || $auth->{c_id} == 22262));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}#end bikes_available
|
|
|
|
|
2022-03-31 07:28:37 +02:00
|
|
|
}
|
2022-03-26 10:19:13 +01:00
|
|
|
}
|
2022-03-31 07:28:37 +02:00
|
|
|
};
|
|
|
|
if ($@){
|
|
|
|
print FILE "<--- failure get_bikes raw response_in:\n" . Dumper($ret_json) . "\n";
|
|
|
|
warn $@;
|
|
|
|
}
|
|
|
|
|
|
|
|
close(FILE);
|
2022-03-26 10:19:13 +01:00
|
|
|
|
2022-03-31 07:28:37 +02:00
|
|
|
return $return;
|
2022-03-26 10:19:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#main GET
|
|
|
|
sub get_sigo {
|
|
|
|
my $endpoint = shift || "";
|
|
|
|
my $rest_json = shift || "";
|
|
|
|
my $sigo_request = "$endpoint";
|
|
|
|
|
|
|
|
print FILE "===> GET sigo >> " . $sigo_request . "\n" . $rest_json . "\n";
|
|
|
|
|
|
|
|
my $req = HTTP::Request->new(GET => "$sigo_request");
|
|
|
|
$req->content_type('application/json');
|
|
|
|
|
|
|
|
$req->content($rest_json);
|
|
|
|
|
|
|
|
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";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sub post_sigo {
|
|
|
|
my $endpoint = shift || "";
|
|
|
|
my $rest_json = shift || "";
|
|
|
|
my $sigo_request = "$endpoint";
|
|
|
|
|
|
|
|
print FILE "===> POST sigo >> " . $sigo_request . "\n" . $rest_json . "\n";
|
|
|
|
|
|
|
|
my $req = HTTP::Request->new(POST => "$sigo_request");
|
|
|
|
$req->content_type('application/json');
|
|
|
|
|
|
|
|
$req->content($rest_json);
|
|
|
|
|
|
|
|
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";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
1;
|