package APIsigoclient; # # SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) Rainer Gümpelein, TeilRad GmbH # #Client for sigo # #380116b5-0522-43da-ab66-477744a731a3 # use lib qw(/var/www/copri-bike/shareeapp-sx/src); use warnings; use strict; use POSIX; use Exporter; our @ISA = qw (Exporter); #use POSIX; 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; use Mod::APIfunc; use Data::Dumper; my $q = new CGI; my $json = JSON->new->allow_nonref; my $cf = new Config; my $dbt = new DBtank; my $apif = new APIfunc; my $bw = new Basework; sub new { my $class = shift; my $self = {}; bless($self,$class); return $self; } 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; 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} ); sub sigo_available { my $self = shift; my $q = shift; my $varenv = shift || {}; my $auth = shift || {}; my $response_in = {}; my $dbh = ""; my $owner = 169; 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')); open(FILE,">>$varenv->{logdir}/APIsigo_client.log"); print FILE "\n*** $now_dt 'sigo client' \n"; #my $endpoint = "https://sigo.dev.sigo.green/api/v1/bikes"; my $endpoint = "$dbt->{operator}->{$varenv->{dbname}}->{endpoint}/bikes"; my $return = {}; my $rest_json = ""; my $ret_json = get_sigo("$endpoint",$rest_json); eval { $response_in = decode_json($ret_json); print FILE "<--- station_and_bikes response_in:\n"; #print FILE Dumper($response_in) . "\n"; if(ref($response_in) eq "HASH"){ 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} = {}; } }#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 AGB zugestimmt (Demo)." if($auth->{c_id} && ($auth->{c_id} == 1842 || $auth->{c_id} == 5781 || $auth->{c_id} == 22262)); } } } }#end bikes_available } } }; if ($@){ print FILE "<--- failure get_bikes raw response_in:\n" . Dumper($ret_json) . "\n"; warn $@; } close(FILE); return $return; } #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;