package Mod::APIvelo; # # SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) Rainer Gümpelein, TeilRad GmbH # #Server for velofaktur # #curl -d '{"Typ":"Statusmeldung","Station":8,"Slot":1,"Fahrzeug":{"Buchbar":false,"Id":"200008","LadezustandBatterie":"75"}}' -H "Content-Type: application/json" -X POST https://shareeapp-fr01.copri4.de/APIvelo # #ATTENTION ##In DB context $q->escapeHTML must always done by API # #use lib qw(/var/www/copri4/shareeapp-fr01/src); use warnings; use strict; use POSIX; use Exporter; our @ISA = qw (Exporter); #use POSIX; use CGI; use Apache2::Const -compile => qw(OK ); use JSON; use Scalar::Util qw(looks_like_number); use Config::General; use Lib::Config; use Mod::DBtank; use Mod::Basework; use Mod::APIfunc; use Mod::APIjsonclient; use Data::Dumper; sub handler { my ($r) = @_; my $q = new CGI; my $json = JSON->new->allow_nonref; my $cf = new Config; my $dbt = new DBtank; my $bw = new Basework; my %varenv = $cf->envonline(); my $now_dt = strftime "%Y-%m-%d %H:%M:%S", localtime; my $lang="de"; my $owner=182;#velofactur API my $debug=1; my $user_agent = $q->user_agent(); my $dbh = ""; $bw->log("APIvelo POST:\n--> user-agent: '$user_agent' to syshost: $varenv{syshost}\n",$q,""); print $q->header(-type => "application/json", -charset => "utf-8", -'Access-Control-Allow-Origin' => "*"); open(FILE,">>$varenv{logdir}/APIvelo.log") if($debug); print FILE "\n*** $now_dt user-agent: '$user_agent' to syshost: $varenv{syshost}\n" if($debug); print FILE "<=== veloDUMP\n " . Dumper($q) . "\n" if($debug); print FILE "<=== DUMP postdata:\n " . Dumper($q->param('POSTDATA')) . "\n" if($debug); my $jrout = "seems to be not valid"; eval { my $response_in = decode_json( $q->param('POSTDATA')); #- int19=bike charge #- int27=velofactur bike ID #- int28=station_lock_state (station lock velofactur) #- int29=velofactur Buchbar (true|false) #- int30=velofactur station ID #- int31=velofactur slot ID #- txt25=velofactur last station message (error or success) my $jrout = $json->pretty->encode({ fakturjson => $response_in }); print FILE "<=== JSON POST from velofactur:\n$jrout\n" if($debug); my $record_cc = { c_id => 0 }; if($response_in->{Typ} eq "Statusmeldung" && $response_in->{Fahrzeug}->{Id} =~ /(\d+)/){ my $velo_id = $1; print FILE "condition: : $response_in->{Typ} && $response_in->{Fahrzeug}->{Id}\n" if($debug); my $pref_cc = { table => "content", fetch => "one", template_id => "205", int27 => $velo_id, }; #loop operators to get velofactur bike Id while (my ($mandant_conf, $value) = each %{ $dbt->{operator} }) { if($value->{database}->{dbname} && $value->{hwtype} eq "velofactur"){ my $rows = 0; my $sharee_operator = $value->{database}->{dbname}; my $dbh_operator = $dbt->dbconnect_extern($sharee_operator); $record_cc = $dbt->fetch_record($dbh_operator,$pref_cc); if($record_cc->{c_id}){ my $update_cc = { table => "content", mtime => "now()", owner => "$owner", }; #$update_cc->{int28} = 0;#where is the key=value for station_lock_state? Buchbar? $update_cc->{int19} = $response_in->{Fahrzeug}->{LadezustandBatterie} if(looks_like_number($response_in->{Fahrzeug}->{LadezustandBatterie})); $update_cc->{int27} = $1 if($response_in->{Fahrzeug}->{Id} && $response_in->{Fahrzeug}->{Id} =~ /(\d+)/); $update_cc->{int30} = $1 if($response_in->{Station} && $response_in->{Station} =~ /(\d+)/); $update_cc->{int31} = $1 if($response_in->{Slot} && $response_in->{Slot} =~ /(\d+)/); $update_cc->{txt25} = $response_in->{Status} if($response_in->{Status}); #velofactur false|true boeelan #set bike_state to maintanance #only if saved! velofactur Buchbar_state = true and bike_state = available $update_cc->{int10} = 4 if($update_cc->{int29} == 1 && $update_cc->{int10} == 1); $update_cc->{int29} = 0; if($response_in->{Fahrzeug}->{Buchbar}){ #set bike_state to available #only if saved! velofactur Buchbar_state = false and bike_state = maintanance $update_cc->{int10} = 1 if($update_cc->{int29} == 0 && $update_cc->{int10} == 4); $update_cc->{int29} = 1; } $rows = $dbt->update_record($dbh_operator,$update_cc,$record_cc); $bw->log("velofactur updates dbname: $sharee_operator, c_id=$record_cc->{c_id} by fakturjson $response_in->{Typ} | rows:$rows",$update_cc,""); print FILE "---> velofactur updates dbname: $sharee_operator, c_id=$record_cc->{c_id} by fakturjson $response_in->{Typ} | rows:$rows\n" . Dumper($update_cc) . "\n" if($debug); } } } ############ #stdout printed JSON to velofactur endpoint my %jsonout; $jsonout{Typ} = "sharee Befehlsmeldung"; $jsonout{Status} = "DONE"; foreach my $resp (keys (%{ $response_in })) { #print $resp . ":" . $response_in->{$resp} . "\n"; $jsonout{$resp} = $response_in->{$resp} if($resp eq "Id"); } my $rest_json = $json->pretty->encode(\%jsonout); print $rest_json; ############ }else{ print FILE "condition anywhere an for selftests\n" if($debug); print $jrout; } }; if ($@){ print FILE "failure! can not decode POST json, POSTDATA:\n" . Dumper($q->param('POSTDATA')) . "\n" if($debug); warn $@; } close(FILE) if($debug); return Apache2::Const::OK; } 1;