From 012e5fb7720b99d4f0c555050659c4086b320328 Mon Sep 17 00:00:00 2001 From: catvayor Date: Sat, 12 Oct 2024 18:44:35 +0200 Subject: [PATCH] feat(agb02): api implementation --- machines/agb02/agb/agb.cpp | 71 ++++++++++++++++++++++++----- machines/agb02/secrets/default.nix | 4 ++ machines/agb02/secrets/secrets.nix | 1 + machines/agb02/secrets/token.age | Bin 0 -> 735 bytes 4 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 machines/agb02/secrets/token.age diff --git a/machines/agb02/agb/agb.cpp b/machines/agb02/agb/agb.cpp index 6b1bc3b..008cfba 100644 --- a/machines/agb02/agb/agb.cpp +++ b/machines/agb02/agb/agb.cpp @@ -1,12 +1,18 @@ #include +#include +#include #include #include +#include #include using namespace std::literals::chrono_literals; constexpr std::chrono::microseconds debounce = 40ms; constexpr std::chrono::microseconds poll_period = 5ms; +constexpr std::chrono::microseconds server_ratelimit = 50ms; + +constexpr const char* url = "https://agb.hackens.org/api/control-box"; constexpr std::pair joystick_movement(1.0, 1.0); @@ -40,8 +46,10 @@ inline void clamp_decoder(uint8_t& decoder, int move){ } int main(const int argc, char const* const* const argv) { - if(argc < 2) + if(argc < 3) { + std::cerr << "usage: agb gpiodevice tokenfile" << std::endl; return 1; + } /// init gpio chip /// @@ -69,8 +77,16 @@ int main(const int argc, char const* const* const argv) { /// init server communication /// cURLpp::initialize(); + std::string token; + { + std::ifstream tokenFile(argv[2]); + std::getline(tokenFile, token); + } + std::list header; + header.push_back("Content-Type: application/json"); + header.push_back("Authorization: Bearer " + token); - /// internal state /// + /// internal state and buffers /// gpiod::line::values joystick_read(4); std::pair spot_pos(0.0, 0.0); //TODO: init from server @@ -81,8 +97,9 @@ int main(const int argc, char const* const* const argv) { bool white_pressed = false; bool black_pressed = false; - - + bool has_changed = false; + std::chrono::time_point last_send = std::chrono::system_clock::now(); + std::string postData; for(;;){ std::this_thread::sleep_for(poll_period); @@ -97,32 +114,30 @@ int main(const int argc, char const* const* const argv) { if (bool(joystick_read[0]) || bool(joystick_read[1]) || bool(joystick_read[2]) || bool(joystick_read[3])) - ; //TODO: send to server + has_changed = true; /// Buttons /// bool pressed = bool(line_reader.get_value(black_button)); if(pressed ^ black_pressed) - ; //TODO: send to server + has_changed = true; black_pressed = pressed; pressed = bool(line_reader.get_value(white_button)); if(pressed ^ white_pressed) - ; //TODO: send to server + has_changed = true; white_pressed = pressed; /// decoder /// uint8_t new_realpos = read_decoder_realpos(line_reader); uint8_t seen_travel = std::abs(int(new_realpos) - int(decoder_realpos)); - //TODO: check CW and CCW - - // CW + // CCW if(seen_travel < 50 && new_realpos < decoder_realpos) clamp_decoder(decoder_pos, -seen_travel); if(seen_travel >= 50 && new_realpos > decoder_realpos) clamp_decoder(decoder_pos, seen_travel - 128); - // CCW + // CW if(seen_travel < 50 && new_realpos > decoder_realpos) clamp_decoder(decoder_pos, seen_travel); if(seen_travel >= 50 && new_realpos < decoder_realpos) @@ -130,6 +145,38 @@ int main(const int argc, char const* const* const argv) { decoder_realpos = new_realpos; if(seen_travel) - ; //TODO: send to server + has_changed = true; + + /// server notification + std::chrono::time_point now = std::chrono::system_clock::now(); + if(has_changed && (now - last_send > server_ratelimit)){ + curlpp::Easy request; + request.setOpt(curlpp::options::Url(url)); + request.setOpt(curlpp::options::HttpHeader(header)); + + postData.clear(); + std::format_to(std::back_inserter(postData), "{{" + "\"pan\": {}," + "\"tilt\": {}," + "\"focus\": {}," + "\"whiteButton\": {}," + "\"blackButton\": {}" + "}}", + spot_pos.first, + spot_pos.second, + int(decoder_pos), + white_pressed, + black_pressed + ); + request.setOpt(curlpp::options::PostFields(postData)); + request.setOpt(curlpp::options::PostFieldSize(postData.size())); + + //request.perform(); +// std::cout << std::chrono::system_clock::now() - now << std::endl; + std::cout << postData << std::endl; + + has_changed = false; + last_send = now; + } } } diff --git a/machines/agb02/secrets/default.nix b/machines/agb02/secrets/default.nix index 14efc4b..6abb220 100644 --- a/machines/agb02/secrets/default.nix +++ b/machines/agb02/secrets/default.nix @@ -8,4 +8,8 @@ file = ./wg.age; owner = "systemd-network"; }; + age.secrets."token" = { + file = ./token.age; + # owner = "systemd-network"; + }; } diff --git a/machines/agb02/secrets/secrets.nix b/machines/agb02/secrets/secrets.nix index c9744b6..3ec47cb 100644 --- a/machines/agb02/secrets/secrets.nix +++ b/machines/agb02/secrets/secrets.nix @@ -5,4 +5,5 @@ let (builtins.readFile (../../../pubkeys + "/${user}.keys"))); in { "wg.age".publicKeys = (readPubkeys "catvayor") ++ (readPubkeys "sinavir") ++ (readPubkeys "agb02"); + "token.age".publicKeys = (readPubkeys "catvayor") ++ (readPubkeys "sinavir") ++ (readPubkeys "agb02"); } diff --git a/machines/agb02/secrets/token.age b/machines/agb02/secrets/token.age new file mode 100644 index 0000000000000000000000000000000000000000..4365b469b36cf2ccde546c446edb1572e95f3607 GIT binary patch literal 735 zcmZ9_-AfYz008iyFPM@UVW0_nv81)#ZeO=S1-I|H@7>3?Ymj%h^Y(Rj^X@!%3k0E{ zm&_;;5h8=Wh>Q#@e9M&*CYDmxgOY+&4^j9Kg=oF|`v-m`%jg-N7S*zx7kGmpvVa0= z^yjpal+!a=lhq13v{q4MEv(jwRT$P& zu_BQ$=Zh1N$YMpKJHb>Ve3AuX9zW{~0%?Tugf(zLVd%IBM9 zEg32J@v6;!+87Fg8x3GK55ow1tt_`4w zAZHVJFqLIdR>1v5%;uy`SVF;Qj1s^^Bq5tU$vmXmHL66Ead(L3Q7?c800y-acq(YN z+fzsf2o_{KY~qlVo03heMz7avqb?v?kOf2BC8DJ z2veT8CQ}QYTz)ja-?dVQvVR)Y2c0XM3-9Vrx39h)eLiw+<4Auty#4sYkJJIBv%xUi zR`|9$bIaI7{#zd!Nj_X_ZB_2=yc&61a}6GUd8l)IaCNv(eri1bb8Bfn@_Tx+1gY{{dyw7+nAW literal 0 HcmV?d00001