2022-05-11 08:05:35 +02:00
package APIsigclient ;
2022-03-26 10:19:13 +01:00
#
# SPDX-License-Identifier: AGPL-3.0-or-later
# Copyright (c) Rainer Gümpelein, TeilRad GmbH
#
2022-05-11 08:05:35 +02:00
#Client for sig
2022-03-26 10:19:13 +01:00
#
2022-03-31 07:28:37 +02:00
#380116b5-0522-43da-ab66-477744a731a3
#
2022-05-27 17:11:35 +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 ;
2022-05-11 08:05:35 +02:00
$ ua - > agent ( "sharee sigclient" ) ;
2022-03-31 21:53:53 +02:00
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-05-04 08:02:59 +02:00
#will be called on bikes_available
2022-05-11 08:05:35 +02:00
sub sig_available {
2022-03-31 21:53:53 +02:00
my $ self = shift ;
my $ q = shift ;
my $ varenv = shift || { } ;
2022-05-11 08:05:35 +02:00
my $ ctadr = 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-08-11 11:42:24 +02:00
my $ lang = "de" ;
2022-03-26 10:19:13 +01:00
2022-03-31 21:53:53 +02:00
my $ authed = 0 ;
2022-06-30 16:35:02 +02:00
my $ ctpos = { c_id = > 0 } ;
my $ show_dialog = { } ;
if ( ref ( $ ctadr ) eq "HASH" && $ ctadr - > { c_id } && $ ctadr - > { c_id } > 0 ) {
$ authed = 1 ;
( $ ctpos , $ show_dialog ) = $ apif - > rental_to_feedback ( $ varenv , $ ctadr ) ;
}
2022-07-16 16:04:46 +02:00
my ( $ bike_group , $ bike_node , $ user_tour , $ tariff_content , $ adrtarif_hash ) = $ apif - > fetch_tariff ( $ varenv - > { dbname } , $ ctadr , $ q - > param ( 'authcookie' ) ) ;
2022-03-26 10:19:13 +01:00
2022-04-07 21:07:59 +02:00
my $ hotline_hash = {
table = > "contentuser" ,
fetch = > "one" ,
template_id = > 197 ,
c_id = > "1" ,
} ;
my $ hotline_data = $ dbt - > fetch_record ( $ dbh , $ hotline_hash ) ;
2022-05-04 17:50:14 +02:00
my $ td_template = $ dbt - > rental_description_template ( ) ;
2022-04-07 21:07:59 +02:00
2022-05-11 08:05:35 +02:00
open ( FILE , ">>$varenv->{logdir}/APIsigclient.log" ) ;
2022-06-24 14:38:22 +02:00
print FILE "\n0. *** $now_dt 'sig_available' ctadr: $ctadr->{c_id}\n" ;
2022-03-30 13:06:39 +02:00
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-04-04 14:57:43 +02:00
my $ response_out = { } ;
my $ return2copri = { } ;
2022-03-31 07:28:37 +02:00
my $ rest_json = "" ;
2022-05-11 08:05:35 +02:00
( my $ ret_json , my $ ret_status ) = $ self - > get_sig ( "$endpoint" , $ rest_json ) ;
2022-03-31 07:28:37 +02:00
eval {
$ response_in = decode_json ( $ ret_json ) ;
2022-05-04 08:02:59 +02:00
$ now_dt = strftime "%Y-%m-%d %H:%M:%S" , localtime ;
2022-05-04 14:18:58 +02:00
print FILE "<--- $now_dt station_and_bikes response_in with status_line: $ret_status:\n" ;
2022-03-31 21:53:53 +02:00
#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 } } ) {
2022-09-28 13:28:45 +02:00
print FILE "$now_dt response_in loop $dbt->{operator}->{$varenv->{dbname}}->{operatorApp}\n" . $ q - > param ( 'request' ) . "\n" . Dumper ( $ resp ) . "\n" ;
2022-03-31 21:53:53 +02:00
2022-05-04 08:02:59 +02:00
if ( ref ( $ resp - > { site } ) eq "HASH" && $ dbt - > { operator } - > { $ varenv - > { dbname } } - > { operatorApp } && $ q - > param ( 'request' ) eq "stations_available" ) {
2022-03-31 21:53:53 +02:00
#station (mainly using sigojson site object)
my $ station = "SX$resp->{site}->{id}" ;
2022-07-27 14:38:06 +02:00
print FILE "---> Station: $station| bike_group: @{$bike_group}[0])\n" ;
2022-06-09 15:31:31 +02:00
if ( $ station && looks_like_number ( $ resp - > { site } - > { id } ) && ref ( $ bike_group ) eq "ARRAY" && @ { $ bike_group } [ 0 ] ) {
2022-07-27 14:38:06 +02:00
print FILE "Station: $station\n\n" ;
2022-04-04 14:57:43 +02:00
$ response_out - > { $ station } - > { station } = "$station" ;
2023-03-17 13:23:04 +01:00
if ( $ resp - > { status } && $ resp - > { status } =~ /ACTIVE|PRIVATE/i && ! $ resp - > { reservation_state } ) {
$ response_out - > { $ station } - > { bike_count } + + ;
}
2022-04-04 14:57:43 +02:00
$ response_out - > { $ station } - > { authed } = "$authed" ;
$ response_out - > { $ station } - > { uri_operator } = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}" ;
2022-07-21 20:06:25 +02:00
#FIXME charset encoding
2022-07-27 14:38:06 +02:00
$ response_out - > { $ station } - > { description } = "" ;
2022-07-16 16:04:46 +02:00
#$response_out->{$station}->{description} = "$resp->{site}->{address}" || "";
2022-08-01 21:42:55 +02:00
$ response_out - > { $ station } - > { description } = Encode:: encode ( 'utf-8' , Encode:: decode ( 'iso-8859-1' , $ resp - > { site } - > { address } ) ) || "" ;
2022-07-12 19:59:44 +02:00
$ response_out - > { $ station } - > { station_group } = [ "SX300101" ] ; #Lastenrad alias type_id
2022-04-04 14:57:43 +02:00
$ response_out - > { $ station } - > { gps } - > { latitude } = "$resp->{site}->{lat}" || "" ;
$ response_out - > { $ station } - > { gps } - > { longitude } = "$resp->{site}->{lon}" || "" ;
$ response_out - > { $ station } - > { gps_radius } = "75" ;
2022-05-27 17:11:35 +02:00
#Other than Active status, should not be used to display information to a customer
2022-04-04 14:57:43 +02:00
$ response_out - > { $ station } - > { state } = "defect" ;
2022-08-02 16:36:41 +02:00
if ( uc ( $ resp - > { site } - > { status } ) =~ /ACTIVE|PRIVATE/i ) {
2022-04-04 14:57:43 +02:00
$ response_out - > { $ station } - > { state } = "available" ;
2022-08-02 18:00:45 +02:00
} elsif ( uc ( $ resp - > { site } - > { status } ) eq "MAINTENANCE" ) {
$ response_out - > { $ station } - > { state } = "maintenance" ;
2022-03-31 21:53:53 +02:00
}
2022-05-27 17:11:35 +02:00
2022-04-07 21:07:59 +02:00
$ response_out - > { $ station } - > { operator_data } = {
"operator_name" = > "" ,
"operator_hours" = > "" ,
"operator_phone" = > "" ,
"operator_email" = > "" ,
} ;
$ response_out - > { $ station } - > { operator_data } - > { operator_name } = Encode:: encode ( 'utf-8' , Encode:: decode ( 'iso-8859-1' , $ hotline_data - > { txt01 } ) ) if ( $ hotline_data - > { txt01 } ) ;
$ response_out - > { $ station } - > { operator_data } - > { operator_hours } = Encode:: encode ( 'utf-8' , Encode:: decode ( 'iso-8859-1' , $ hotline_data - > { txt84 } ) ) if ( $ hotline_data - > { txt84 } ) ;
$ response_out - > { $ station } - > { operator_data } - > { operator_phone } = $ hotline_data - > { txt07 } if ( $ hotline_data - > { txt07 } ) ;
$ response_out - > { $ station } - > { operator_data } - > { operator_email } = $ hotline_data - > { txt08 } if ( $ hotline_data - > { txt08 } ) ;
2022-03-31 07:28:37 +02:00
2022-04-05 12:29:58 +02:00
#just like caching
$ return2copri - > { $ station } - > { barcode } = $ 1 if ( $ response_out - > { $ station } - > { station } =~ /(\d+)/ ) ; #new on station context
$ return2copri - > { $ station } - > { int04 } = $ 1 if ( $ response_out - > { $ station } - > { station } =~ /(\d+)/ ) ;
2023-03-05 20:01:47 +01:00
$ return2copri - > { $ station } - > { txt12 } = "SX" ;
2022-04-05 12:29:58 +02:00
$ return2copri - > { $ station } - > { int06 } = $ 1 if ( $ response_out - > { $ station } - > { gps_radius } =~ /(\d+)/ ) ;
2022-08-16 06:44:58 +02:00
$ return2copri - > { $ station } - > { int05 } = 2 ; #capacity
$ return2copri - > { $ station } - > { int08 } = 2 ; #energy adapter
2022-04-05 12:29:58 +02:00
$ return2copri - > { $ station } - > { txt01 } = "$response_out->{$station}->{description}" ;
$ return2copri - > { $ station } - > { txt06 } = "$response_out->{$station}->{gps}->{latitude},$response_out->{$station}->{gps}->{longitude}" ;
2022-07-15 07:11:01 +02:00
$ return2copri - > { $ station } - > { txt24 } = "300102" ; #node.main_id
2022-08-06 10:47:06 +02:00
$ return2copri - > { $ station } - > { txt24 } = "300001" if ( $ response_out - > { $ station } - > { description } =~ /sigo GmbH/i ) ; #Contributor flot
2022-07-15 07:11:01 +02:00
$ return2copri - > { $ station } - > { txt25 } = "300101" ; #node_type_id
2022-08-10 07:30:50 +02:00
$ return2copri - > { $ station } - > { int42 } = "1" ; #A-A fahrten
$ return2copri - > { $ station } - > { int42 } = "0" if ( $ response_out - > { $ station } - > { description } =~ /Passau/i ) ; #A-B fahrten
2022-04-05 12:29:58 +02:00
while ( my ( $ key , $ value ) = each % { $ dbt - > { copri_conf } - > { station_state } } ) {
if ( $ response_out - > { $ station } - > { state } eq $ value ) {
$ return2copri - > { $ station } - > { int10 } = $ key ;
}
}
2022-07-27 14:38:06 +02:00
#print FILE "response_out:" . Dumper($response_out->{$station}) . "\n";
#print FILE "return2copri:" . Dumper($return2copri->{$station}) . "\n";
2022-08-06 10:47:06 +02:00
my $ user_station_available = 0 ;
foreach my $ main_id ( @ { $ bike_node } ) {
if ( $ main_id =~ /(\d+)/ ) {
my $ node_id = $ 1 ;
$ user_station_available = 1 if ( $ node_id == $ return2copri - > { $ station } - > { txt24 } ) ;
}
}
if ( ! $ user_station_available || uc ( $ resp - > { site } - > { status } ) !~ /ACTIVE|PRIVATE/i || ! $ resp - > { site } - > { lat } || ! $ resp - > { site } - > { lon } ) {
delete $ response_out - > { $ station } ;
}
2022-03-31 07:28:37 +02:00
}
2022-03-31 21:53:53 +02:00
} #end stations_available
2022-05-04 08:02:59 +02:00
if ( ref ( $ resp - > { site } ) eq "HASH" && $ dbt - > { operator } - > { $ varenv - > { dbname } } - > { operatorApp } && $ q - > param ( 'request' ) eq "bikes_available" ) {
2022-03-31 21:53:53 +02:00
#bike (mainly using sigojson state object)
2022-05-04 08:02:59 +02:00
#my $bike = "SX$resp->{mobile_bike_id}";
my $ bike = $ q - > escapeHTML ( $ resp - > { license_plate } ) || "" ;
my $ bike_id = $ bike ;
$ bike_id =~ s/S[1-9]X/SX/ ;
$ bike_id = $ 1 if ( $ bike_id =~ /(\d+)/ ) ;
2022-07-16 16:04:46 +02:00
print FILE "bike-data $bike_id | $resp->{site}->{id} | @{$bike_group}[0]\n" ;
2022-06-09 15:31:31 +02:00
if ( $ bike && looks_like_number ( $ bike_id ) && looks_like_number ( $ resp - > { site } - > { id } ) && ref ( $ bike_group ) eq "ARRAY" && @ { $ bike_group } [ 0 ] ) {
2022-07-27 14:38:06 +02:00
print FILE "Bike: $bike\n\n" ;
2022-06-30 16:35:02 +02:00
if ( $ ctpos - > { barcode } && $ ctpos - > { barcode } == $ bike_id ) {
$ response_out - > { $ bike } - > { user_miniquery } = $ show_dialog - > { user_miniquery } if ( $ show_dialog - > { user_miniquery } ) ;
2022-06-30 18:23:39 +02:00
$ response_out - > { $ bike } - > { co2saving } = "" ;
if ( $ show_dialog - > { co2saving } ) {
$ response_out - > { $ bike } - > { co2saving } = $ show_dialog - > { co2saving } ;
}
2022-06-30 16:35:02 +02:00
}
2022-04-04 14:57:43 +02:00
$ response_out - > { $ bike } - > { bike } = "$bike" ;
$ response_out - > { $ bike } - > { authed } = "$authed" ;
$ response_out - > { $ bike } - > { station } = "SX$resp->{site}->{id}" || "" ;
$ response_out - > { $ bike } - > { uri_operator } = "$dbt->{operator}->{$varenv->{dbname}}->{operatorApp}" ;
$ response_out - > { $ bike } - > { description } = "E-Lastenrad" ;
$ response_out - > { $ bike } - > { gps } - > { latitude } = "$resp->{state}->{lat}" || "" ;
$ response_out - > { $ bike } - > { gps } - > { longitude } = "$resp->{state}->{lon}" || "" ;
2022-06-10 06:47:18 +02:00
$ response_out - > { $ bike } - > { lock_state } = "locked" ;
2022-08-04 15:54:35 +02:00
$ response_out - > { $ bike } - > { state } = "defect" ;
if ( $ resp - > { status } && $ resp - > { status } =~ /ACTIVE|PRIVATE/i ) {
if ( uc ( $ resp - > { reservation_state } ) eq "RESERVED" ) {
2022-05-04 08:02:59 +02:00
$ response_out - > { $ bike } - > { state } = "requested" ;
2022-08-04 15:54:35 +02:00
} elsif ( uc ( $ resp - > { reservation_state } ) eq "ACTIVE-RENTAL" ) {
2022-06-10 06:47:18 +02:00
$ response_out - > { $ bike } - > { lock_state } = "unlocked" ;
2022-04-04 14:57:43 +02:00
$ response_out - > { $ bike } - > { state } = "occupied" ;
2022-08-04 15:54:35 +02:00
} elsif ( ! $ resp - > { reservation_state } ) {
2022-05-04 08:02:59 +02:00
$ response_out - > { $ bike } - > { state } = "available" ;
2022-08-04 15:54:35 +02:00
}
} elsif ( $ resp - > { status } && $ resp - > { status } eq "MAINTENANCE" ) {
2022-08-02 18:00:45 +02:00
$ response_out - > { $ bike } - > { state } = "maintenance" ;
}
$ response_out - > { $ bike } - > { bike_type } - > { engine } - > { manufacturer } = "sigo" ;
2022-07-21 20:06:25 +02:00
my $ max_bars = 5 ;
my $ current_bars = 0 ;
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { charge_max_bars } = "$max_bars" ;
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { charge_current_bars } = "$current_bars" ;
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { charge_current_percent } = "0" ;
2022-07-27 16:01:39 +02:00
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { backend_accessible } = "1" ; #got it from backend
2022-08-01 15:13:43 +02:00
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { hidden } = "0" ; #1=hide charge view
2022-07-21 20:06:25 +02:00
if ( looks_like_number ( $ resp - > { energy_level } ) ) {
$ current_bars = $ bw - > battery_bars ( $ max_bars , $ resp - > { energy_level } ) ;
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { charge_current_bars } = "$current_bars" ;
$ response_out - > { $ bike } - > { bike_type } - > { battery } - > { charge_current_percent } = "$resp->{energy_level}" ;
}
2022-04-04 14:57:43 +02:00
$ response_out - > { $ bike } - > { system } = "sigo" ;
2022-07-12 19:59:44 +02:00
$ response_out - > { $ bike } - > { bike_group } = [ "SX300101" ] ; #Lastenrad type_id
2022-04-04 14:57:43 +02:00
$ response_out - > { $ bike } - > { unlock_allowed } = "1" ;
2023-04-05 14:53:26 +02:00
$ response_out - > { $ bike } - > { aa_ride } = "1" ; #sig default to A-A
$ response_out - > { $ bike } - > { aa_ride } = "0" if ( $ resp - > { site } - > { address } && $ resp - > { site } - > { address } =~ /Passau/i ) ; #A-B
2022-05-04 17:50:14 +02:00
$ response_out - > { $ bike } - > { rental_description } = { } ;
2022-03-31 21:53:53 +02:00
if ( ref ( $ tariff_content ) eq "HASH" ) {
foreach my $ tid ( sort { $ tariff_content - > { $ a } - > { barcode } <=> $ tariff_content - > { $ b } - > { barcode } } keys ( %$ tariff_content ) ) {
2023-04-05 14:53:26 +02:00
2022-05-04 17:50:14 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { name } = "$tariff_content->{$tid}->{ct_name}" ;
$ response_out - > { $ bike } - > { rental_description } - > { id } = "$tariff_content->{$tid}->{barcode}" ;
2022-06-28 13:50:59 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { reserve_timerange } = "30" ;
2022-12-06 19:57:49 +01:00
$ response_out - > { $ bike } - > { rental_description } - > { rental_info } - > { 1 } = [ "Tracking" , "Ich stimme der Speicherung (Tracking) meiner Fahrstrecke zwecks wissenschaftlicher Auswertung und Berechnung der CO2-Einsparung zu!" ] ; # if($resp->{gps_tracker_id});
2023-04-05 14:53:26 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { rental_info } - > { 2 } = [ "AAFahrten" , "Dieses E-Lastenrad darf nur an der Station zurück gegeben werden an der es ausgeliehen wurde!" ] if ( $ resp - > { site } - > { address } && $ resp - > { site } - > { address } !~ /Passau/i ) ;
2022-04-21 21:15:01 +02:00
my $ i = 0 ;
2022-04-26 20:57:13 +02:00
foreach my $ td ( sort keys ( %$ td_template ) ) {
2022-04-21 21:15:01 +02:00
my $ time_unit = "" ;
2022-04-26 20:57:13 +02:00
if ( $ td_template - > { $ td } - > { int35 } && $ tariff_content - > { $ tid } - > { int35 } && $ tariff_content - > { $ tid } - > { int35 } > 0 ) {
2022-08-11 11:42:24 +02:00
$ tariff_content - > { $ tid } - > { int35 } =~ s/\./,/ if ( $ lang eq "de" ) ;
2022-04-21 21:15:01 +02:00
$ time_unit = $ dbt - > time_format ( $ tariff_content - > { $ tid } - > { time01 } ) ;
2022-05-04 17:50:14 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { tarif_elements } - > { $ td } = [ "$td_template->{$td}->{int35}" , "$tariff_content->{$tid}->{int35} € / $time_unit" ] ;
2022-04-26 20:57:13 +02:00
} elsif ( $ td_template - > { $ td } - > { int36 } && $ tariff_content - > { $ tid } - > { int36 } && $ tariff_content - > { $ tid } - > { int36 } > 0 ) {
2022-08-11 11:42:24 +02:00
$ tariff_content - > { $ tid } - > { int36 } =~ s/\./,/ if ( $ lang eq "de" ) ;
2022-04-26 20:57:13 +02:00
$ time_unit = $ dbt - > time_format ( $ tariff_content - > { $ tid } - > { time01 } ) ;
2022-05-04 17:50:14 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { tarif_elements } - > { $ td } = [ "$td_template->{$td}->{int36}" , "$tariff_content->{$tid}->{int36} € / $time_unit" ] ;
2022-04-26 20:57:13 +02:00
} elsif ( $ td_template - > { $ td } - > { int17 } && $ tariff_content - > { $ tid } - > { int17 } && $ tariff_content - > { $ tid } - > { int17 } > 0 ) {
2022-08-11 11:42:24 +02:00
$ tariff_content - > { $ tid } - > { int17 } =~ s/\./,/ if ( $ lang eq "de" ) ;
2022-05-04 17:50:14 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { tarif_elements } - > { $ td } = [ "$td_template->{$td}->{int17}" , "$tariff_content->{$tid}->{int17} € / Tag" ] ;
2022-04-26 20:57:13 +02:00
} elsif ( $ td_template - > { $ td } - > { time02 } && $ tariff_content - > { $ tid } - > { time02 } =~ /[1-9]/ ) {
2022-04-21 21:15:01 +02:00
$ time_unit = $ dbt - > time_format ( $ tariff_content - > { $ tid } - > { time02 } ) ;
2023-04-14 18:08:14 +02:00
$ response_out - > { $ bike } - > { rental_description } - > { tarif_elements } - > { $ td } = [ "$td_template->{$td}->{time02}" , "$time_unit / Tag" ] ;
2022-04-21 21:15:01 +02:00
}
2022-05-04 17:50:14 +02:00
} #end new rental_description
2022-04-21 21:15:01 +02:00
2022-03-31 21:53:53 +02:00
}
}
2022-04-05 12:29:58 +02:00
#just like caching
2022-08-06 10:47:06 +02:00
$ return2copri - > { $ bike } - > { main_id } = "300102" ;
$ return2copri - > { $ bike } - > { main_id } = "300001" if ( $ bike_id == 1001 || $ bike_id == 84 ) ; #Contributor bikes
2022-06-08 20:18:11 +02:00
$ return2copri - > { $ bike } - > { int11 } = 3 ; #system
$ return2copri - > { $ bike } - > { int25 } = 1 ; #tracking on
2022-05-04 08:02:59 +02:00
$ return2copri - > { $ bike } - > { barcode } = $ bike_id ;
2022-06-28 13:50:59 +02:00
$ return2copri - > { $ bike } - > { txt22 } = $ resp - > { id } ; #sig bikeId used by rental
2022-04-05 12:29:58 +02:00
$ return2copri - > { $ bike } - > { int04 } = $ 1 if ( $ response_out - > { $ bike } - > { station } =~ /(\d+)/ ) ;
$ return2copri - > { $ bike } - > { txt01 } = "$response_out->{$bike}->{description}" ;
2022-05-04 17:50:14 +02:00
$ return2copri - > { $ bike } - > { int25 } = "1" if ( $ resp - > { gps_tracker_id } ) ;
2022-04-05 12:29:58 +02:00
$ return2copri - > { $ bike } - > { txt06 } = "$response_out->{$bike}->{gps}->{latitude},$response_out->{$bike}->{gps}->{longitude}" ;
2022-07-21 20:06:25 +02:00
$ return2copri - > { $ bike } - > { int19 } = $ 1 if ( $ response_out - > { $ bike } - > { bike_type } - > { battery } - > { charge_current_percent } =~ /(\d+)/ ) ;
2022-04-05 12:29:58 +02:00
while ( my ( $ key , $ value ) = each % { $ dbt - > { copri_conf } - > { bike_state } } ) {
if ( $ response_out - > { $ bike } - > { state } eq $ value ) {
$ return2copri - > { $ bike } - > { int10 } = $ key ;
}
}
while ( my ( $ key , $ value ) = each % { $ dbt - > { copri_conf } - > { lock_state } } ) {
if ( $ response_out - > { $ bike } - > { lock_state } eq $ value ) {
$ return2copri - > { $ bike } - > { int20 } = $ key ;
}
}
2022-07-27 14:38:06 +02:00
delete $ response_out - > { $ bike } if ( uc ( $ resp - > { status } ) !~ /ACTIVE|PRIVATE/i || $ resp - > { reservation_state } ) ; #don't view not active bikes
2022-03-31 21:53:53 +02:00
}
} #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 ( $@ ) {
2022-05-04 14:18:58 +02:00
print FILE "<--- failure get_bikes raw response_in with status_line: $ret_status\n" . Dumper ( $ ret_json ) . "\n" ;
#warn $@;
print FILE "warn:" . $@ . "\n" ;
2022-03-31 07:28:37 +02:00
}
2022-05-11 08:05:35 +02:00
print FILE "sig_available response_out from response_in\n" . Dumper ( $ response_out ) . "\n" ;
2022-03-31 07:28:37 +02:00
close ( FILE ) ;
2022-03-26 10:19:13 +01:00
2022-04-04 14:57:43 +02:00
return ( $ response_out , $ return2copri ) ;
2022-05-11 08:05:35 +02:00
} #end sig_available
2022-04-07 21:07:59 +02:00
2022-06-22 18:29:46 +02:00
#bike smartlock unlocking
sub sig_unlock {
my $ self = shift ;
my $ varenv = shift || { } ;
my $ todo = shift || "" ;
my $ ctadr = shift || { } ;
my $ ct_bike = shift || { } ;
my $ ctpos = shift || { } ;
my $ sig_bikeId = $ ctpos - > { txt22 } || $ ct_bike - > { txt22 } ;
my $ dbh = "" ;
my $ owner = 169 ;
2022-06-23 14:22:35 +02:00
my $ sig_book = { } ;
my $ rows = 0 ;
2022-06-22 18:29:46 +02:00
open ( FILE , ">>$varenv->{logdir}/APIsigclient.log" ) ;
print FILE "\n3. *** $now_dt 'sig_unlock' \n" ;
2022-06-23 14:22:35 +02:00
my $ endpoint = "$dbt->{operator}->{$varenv->{dbname}}->{endpoint}/bikes/unlock/$sig_bikeId" ;
2022-06-22 18:29:46 +02:00
my $ response_out = { } ;
my $ return2copri = { } ;
2022-06-23 14:22:35 +02:00
my $ rest_json = "" ;
my $ ret_json = "failure: ret_json" ;
my $ ret_status = "failure: ret_status" ;
( $ ret_json , $ ret_status ) = $ self - > get_sig ( "$endpoint" , $ rest_json ) ;
2022-06-22 18:29:46 +02:00
eval {
2022-06-23 14:22:35 +02:00
$ sig_book = decode_json ( $ ret_json ) ;
2022-06-22 18:29:46 +02:00
$ now_dt = strftime "%Y-%m-%d %H:%M:%S" , localtime ;
2022-06-23 14:22:35 +02:00
print FILE "<--- $now_dt sig_unlock sig_book json with status_line: $ret_status:\n" . Dumper ( $ sig_book ) . "\n" ;
2022-06-22 18:29:46 +02:00
} ;
if ( $@ ) {
2022-06-23 14:22:35 +02:00
print FILE "<--- $now_dt failure sig_unlock raw ret_json with status_line: $ret_status\n" . Dumper ( $ ret_json ) . "\n" ;
2022-06-22 18:29:46 +02:00
#warn $@;
print FILE "warn:" . $@ . "\n" ;
}
2022-06-23 14:22:35 +02:00
#save always API return state for documentation
$ sig_book - > { return_state } = "$now_dt $todo: $ret_status" ;
if ( $ ctpos - > { c_id } ) {
my $ rows = 0 ;
my $ update_pos = {
table = > "contenttranspos" ,
mtime = > "now()" ,
owner = > "169" ,
txt25 = > "$ctpos->{txt25}\n$sig_book->{return_state}" ,
} ;
my $ update_content = {
table = > "content" ,
mtime = > "now()" ,
owner = > "169" ,
c_id = > $ ctpos - > { cc_id } ,
} ;
$ update_pos - > { int20 } = 2 if ( $ ret_json eq "Bike unlocked" ) ;
$ update_content - > { int20 } = 2 if ( $ ret_json eq "Bike unlocked" ) ;
$ rows = $ dbt - > update_record ( $ dbh , $ update_pos , $ ctpos ) ;
print FILE "<--- rows: $rows, update_pos: $ctpos->{c_id}, with:" . Dumper ( $ update_pos ) . "\n" ;
if ( $ ctpos - > { cc_id } && $ ret_json eq "Bike unlocked" ) {
$ rows = $ dbt - > update_record ( $ dbh , $ update_content , $ update_content ) ;
print FILE "<--- rows: $rows, update_content: $ctpos->{cc_id}, with:" . Dumper ( $ update_content ) . "\n" ;
}
}
2022-06-22 18:29:46 +02:00
print FILE "sig_unlock ret_json from response_in\n" . Dumper ( $ ret_json ) . "\n" ;
close ( FILE ) ;
2022-06-23 14:22:35 +02:00
return $ sig_book ;
2022-06-22 18:29:46 +02:00
}
2022-04-07 21:07:59 +02:00
#POST resverve, rental, ...
2022-06-21 15:30:22 +02:00
#will be called by sig_client
2022-05-04 08:02:59 +02:00
sub sig_booking {
2022-04-07 21:07:59 +02:00
my $ self = shift ;
my $ varenv = shift || { } ;
2022-06-02 10:34:03 +02:00
my $ todo = shift || "" ;
2022-05-11 08:05:35 +02:00
my $ ctadr = shift || { } ;
2022-04-07 21:07:59 +02:00
my $ ct_bike = shift || { } ;
2022-05-04 08:02:59 +02:00
my $ ctpos = shift || { } ;
2022-04-07 21:07:59 +02:00
my $ dbh = "" ;
my $ owner = 169 ;
2022-05-04 08:02:59 +02:00
my $ sig_book = { } ;
2022-04-07 21:07:59 +02:00
2022-05-11 08:05:35 +02:00
open ( FILE , ">>$varenv->{logdir}/APIsigclient.log" ) ;
2022-06-21 15:30:22 +02:00
print FILE "\n2. *** $now_dt 'sig_post $todo' \n" ;
2022-04-07 21:07:59 +02:00
my $ endpoint = "$dbt->{operator}->{$varenv->{dbname}}->{endpoint}/" ;
my % json = ( ) ;
2023-01-05 18:11:24 +01:00
$ ctadr - > { txt08 } =~ s/[a-z]-/-/ ; $ ctadr - > { txt08 } =~ s/[a-z]_/_/ ; $ ctadr - > { txt08 } =~ s/[0-9a-z]\@/\@/i ; $ ctadr - > { txt08 } =~ s/[0-9a-z]\@/\@/i ; $ ctadr - > { txt08 } =~ s/\@(\w{1,2})\w+\.(\w+)/\@$1email\.$2/i ;
2022-11-16 21:22:00 +01:00
$ ctadr - > { txt08 } =~ s/[a-z]\./\./ if ( $ ctadr - > { txt08 } =~ /\.\w+\@/ ) ;
2022-05-04 08:02:59 +02:00
#reservation start
2022-04-07 21:07:59 +02:00
if ( $ todo eq "reserve" ) {
$ endpoint . = "bikes/reserve" ;
% json = (
bikeId = > "$ct_bike->{txt22}" ,
2022-05-11 08:05:35 +02:00
email = > "$ctadr->{txt08}"
2022-04-07 21:07:59 +02:00
) ;
}
2022-05-11 08:05:35 +02:00
#reservation end, this sig request is still not defined. maybe end by rentalId
2022-05-27 17:11:35 +02:00
#int10 state will be set on booking_request
2022-05-04 08:02:59 +02:00
elsif ( $ todo eq "reserve_end" ) {
2022-06-10 06:47:18 +02:00
$ endpoint . = "bikes/reserve/end" ;
2022-05-04 08:02:59 +02:00
% json = (
2022-06-10 06:47:18 +02:00
rentalId = > "$ctpos->{txt11}" ,
2022-05-11 08:05:35 +02:00
email = > "$ctadr->{txt08}"
2022-05-04 08:02:59 +02:00
) ;
}
#rental start
2022-05-27 17:11:35 +02:00
#int10 state will be set on main booking_update
2022-04-12 11:21:19 +02:00
elsif ( $ todo eq "rental" ) {
2022-04-07 21:07:59 +02:00
$ endpoint . = "rental" ;
2022-06-10 06:47:18 +02:00
my $ sig_bikeId = $ ctpos - > { txt22 } || $ ct_bike - > { txt22 } ;
2022-05-04 08:02:59 +02:00
% json = (
2022-05-11 08:05:35 +02:00
bikeId = > "$sig_bikeId" ,
email = > "$ctadr->{txt08}"
2022-05-04 08:02:59 +02:00
) ;
}
#rental end
elsif ( $ todo eq "rental_end" ) {
$ endpoint . = "rental/end" ;
2022-04-07 21:07:59 +02:00
% json = (
2022-05-04 08:02:59 +02:00
rentalId = > "$ctpos->{txt11}" ,
2022-05-11 08:05:35 +02:00
email = > "$ctadr->{txt08}"
2022-04-07 21:07:59 +02:00
) ;
2022-05-04 08:02:59 +02:00
#keep in mind, it will return no json, just text: "Rental Ended"
2022-04-07 21:07:59 +02:00
}
2022-06-02 10:34:03 +02:00
#rentals running
#TODO, execute it before user_bikes_occupied
elsif ( $ todo eq "rentals_running" ) {
$ endpoint . = "rentals/running" ;
% json = (
email = > "$ctadr->{txt08}"
) ;
}
2022-04-12 11:21:19 +02:00
else {
print "Failure, request $todo not defined\n" ;
}
2022-04-07 21:07:59 +02:00
2022-04-12 11:21:19 +02:00
print FILE "---> DATA $endpoint:\n" . Dumper ( \ % json ) . "\n" ;
2022-04-07 21:07:59 +02:00
2022-04-12 11:21:19 +02:00
if ( ref ( \ % json ) eq "HASH" && $ json { email } ) {
my $ rest_json = encode_json ( \ % json ) ;
2022-05-11 08:05:35 +02:00
( my $ ret_json , my $ ret_status ) = $ self - > post_sig ( $ endpoint , $ rest_json ) ;
2022-05-04 08:02:59 +02:00
$ now_dt = strftime "%Y-%m-%d %H:%M:%S" , localtime ;
2022-04-07 21:07:59 +02:00
eval {
2022-05-04 08:02:59 +02:00
$ sig_book = decode_json ( $ ret_json ) ;
2022-05-11 08:05:35 +02:00
print FILE "<--- $now_dt sig_booking sig_post $todo response_in with status_line: $ret_status\n" . Dumper ( $ sig_book ) ;
2022-05-04 08:02:59 +02:00
#print $ret_json . "\n";
2022-04-07 21:07:59 +02:00
} ;
if ( $@ ) {
2022-05-11 08:05:35 +02:00
print FILE "<--- $now_dt failure sig_booking sig_post $todo raw response_in with status_line: $ret_status\n" . Dumper ( $ ret_json ) . "\n" ;
2022-04-07 21:07:59 +02:00
#warn $@;
print FILE "warn:" . $@ . "\n" ;
}
2022-06-02 10:34:03 +02:00
#save always API return state for documentation
$ sig_book - > { return_state } = "$now_dt $todo: $ret_status" ;
2022-04-12 11:21:19 +02:00
}
2022-04-07 21:07:59 +02:00
2022-05-04 14:18:58 +02:00
if ( ref ( $ sig_book ) ne "HASH" ) {
$ sig_book = {
2022-05-11 08:05:35 +02:00
bikeId = > "" ,
2022-05-04 14:18:58 +02:00
rentalId = > "" ,
} ;
2022-05-11 08:05:35 +02:00
print FILE "<--- $now_dt failure sig_booking sig_post $todo , reset sig_book hash to empty\n" ;
}
2022-06-21 21:30:47 +02:00
if ( $ ctpos - > { c_id } ) {
2022-05-27 17:11:35 +02:00
my $ rows = 0 ;
2022-05-11 08:05:35 +02:00
my $ update_pos = {
table = > "contenttranspos" ,
mtime = > "now()" ,
owner = > "169" ,
} ;
2022-06-10 20:49:26 +02:00
my $ update_content = {
table = > "content" ,
mtime = > "now()" ,
owner = > "169" ,
2022-06-21 21:30:47 +02:00
c_id = > $ ctpos - > { cc_id } ,
2022-06-10 20:49:26 +02:00
} ;
2022-05-27 17:11:35 +02:00
2022-06-10 20:49:26 +02:00
#rentalId will be only on success!
2022-06-10 06:47:18 +02:00
if ( $ sig_book - > { rentalId } ) {
$ update_pos - > { txt11 } = "$sig_book->{rentalId}" ;
}
2022-06-10 20:49:26 +02:00
if ( $ todo eq "reserve" || $ todo eq "rental" ) {
#mark it as unlocked if rentalId on rental
if ( $ todo eq "rental" && $ sig_book - > { rentalId } ) {
$ update_pos - > { int20 } = 2 ;
$ update_content - > { int20 } = 2 ;
}
#without rentalId, bike will be available and unlocked!
else {
2022-06-10 06:47:18 +02:00
$ update_pos - > { int10 } = 1 ;
$ update_pos - > { int20 } = 1 ;
2022-06-10 20:49:26 +02:00
$ update_content - > { int10 } = 1 ;
$ update_content - > { int20 } = 1 ;
}
2022-06-10 06:47:18 +02:00
}
2022-06-10 20:49:26 +02:00
#keep in mind, all other states will be done on REST, hopefully
2022-06-21 21:30:47 +02:00
$ update_pos - > { txt25 } = "$ctpos->{txt25}\n$sig_book->{return_state}" ; # if($sig_book->{return_state});
$ rows = $ dbt - > update_record ( $ dbh , $ update_pos , $ ctpos ) ;
print FILE "<--- rows: $rows, update_pos: $ctpos->{c_id}, with:" . Dumper ( $ update_pos ) . "\n" ;
2022-06-10 20:49:26 +02:00
2022-06-21 21:30:47 +02:00
if ( $ ctpos - > { cc_id } ) {
2022-06-10 20:49:26 +02:00
$ rows = $ dbt - > update_record ( $ dbh , $ update_content , $ update_content ) ;
2022-06-21 21:30:47 +02:00
print FILE "<--- rows: $rows, update_content: $ctpos->{cc_id}, with:" . Dumper ( $ update_content ) . "\n" ;
2022-06-10 20:49:26 +02:00
}
2022-05-04 14:18:58 +02:00
}
2022-04-07 21:07:59 +02:00
close ( FILE ) ;
2022-05-04 08:02:59 +02:00
return $ sig_book ;
2022-03-26 10:19:13 +01:00
}
2022-04-07 21:07:59 +02:00
2022-03-26 10:19:13 +01:00
#main GET
2022-05-11 08:05:35 +02:00
sub get_sig {
2022-04-07 21:07:59 +02:00
my $ self = shift ;
2022-03-26 10:19:13 +01:00
my $ endpoint = shift || "" ;
my $ rest_json = shift || "" ;
2022-05-11 08:05:35 +02:00
my $ sig_request = "$endpoint" ;
2022-03-26 10:19:13 +01:00
2022-05-11 08:05:35 +02:00
print FILE "===> GET sig >> " . $ sig_request . "\n" . $ rest_json . "\n" ;
2022-03-26 10:19:13 +01:00
2022-05-11 08:05:35 +02:00
my $ req = HTTP::Request - > new ( GET = > "$sig_request" ) ;
2022-03-26 10:19:13 +01:00
$ req - > content_type ( 'application/json' ) ;
$ req - > content ( $ rest_json ) ;
my $ res = $ ua - > request ( $ req ) ;
if ( $ res - > is_success ) {
#print $res->content;
2022-05-04 14:18:58 +02:00
#print $res->status_line, "\n";
return ( $ res - > content , $ res - > status_line ) ;
2022-03-26 10:19:13 +01:00
} else {
2022-05-04 14:18:58 +02:00
#print $res->status_line, "\n";
return ( "" , $ res - > status_line ) ;
2022-03-26 10:19:13 +01:00
}
}
2022-04-07 21:07:59 +02:00
#main POST
2022-05-11 08:05:35 +02:00
sub post_sig {
2022-04-07 21:07:59 +02:00
my $ self = shift ;
2022-03-26 10:19:13 +01:00
my $ endpoint = shift || "" ;
my $ rest_json = shift || "" ;
2022-05-11 08:05:35 +02:00
my $ sig_request = "$endpoint" ;
2022-03-26 10:19:13 +01:00
2022-05-11 08:05:35 +02:00
print FILE "===> POST sig >> " . $ sig_request . "\n" . $ rest_json . "\n" ;
2022-03-26 10:19:13 +01:00
2022-05-11 08:05:35 +02:00
my $ req = HTTP::Request - > new ( POST = > "$sig_request" ) ;
2022-03-26 10:19:13 +01:00
$ req - > content_type ( 'application/json' ) ;
$ req - > content ( $ rest_json ) ;
my $ res = $ ua - > request ( $ req ) ;
if ( $ res - > is_success ) {
#print $res->content;
2022-05-04 14:18:58 +02:00
#print $res->status_line, "\n";
return ( $ res - > content , $ res - > status_line ) ;
2022-03-26 10:19:13 +01:00
} else {
2022-05-04 14:18:58 +02:00
#print $res->status_line, "\n";
return ( "" , $ res - > status_line ) ;
2022-03-26 10:19:13 +01:00
}
}
1 ;