Initial demo for Promo-Operation

This commit is contained in:
Gustice authored and Jakob Gegeniger committed 2026-09-08 23:23:37 +02:00
1 parent 55b7909717
commit eb1c84cf05
25 files changed
+24615 -2

No files matched your search

+222
View File
@@ -0,0 +1,222 @@
#include "swordMain.hpp"
#include "defines.hpp"
#include "mqttChannel.hpp"
using namespace pal;
using namespace std::literals::string_view_literals;
using namespace std::literals::chrono_literals;
using namespace std;
constexpr uint8_t VersionArr[4] = {'V', 0, 8, 0};
const string Version = "V 0.8.0";
// const string Version = fmt::format("{} {}.{}.{}", VersionArr[0], VersionArr[1], VersionArr[2], VersionArr[3]);
SwordConfig SwordCfg{};
unique_ptr<DeviceIoState> IoStat;
OpMode Mode = OpMode::Maintanance;
void processPromo(MqttChannel& mqtt, SeqLogger& log);
void processProduction(MqttChannel& mqtt, SeqLogger& log);
int main(int argc, char* argv[]) {
CLI::App app{"Sword Firmware"};
string modeArg = "test";
string assetsBasePath = "/home/user/assets/sword";
string brocker = "mqtts://nerdyssey.de:8883";
string topic = "staging/outdoor/king-arthur/sword/";
string user = "exodususer";
string password = "awesomeexodusoutdooradventures";
string logUrl = "log.nerdyssey.de";
string logApiKey = "uYpJC6WyZAbFK2MUgwNH";
app.add_option("startmode", modeArg, "Startup mode")->required();
app.add_option("basepath", assetsBasePath, "Base bath for assets")->required();
app.add_option("-b,--brocker", brocker, "MQTT Topic URL");
app.add_option("-t,--topic", topic, "MQTT Topic");
app.add_option("-p,--passwd", password, "MQTT Brocker password");
app.add_option("-u,--user", user, "MQTT Brocker user");
app.add_option("-l,--log", logUrl, "Logging Service");
app.add_option("-k,--key", logApiKey, "Logging API Key");
CLI11_PARSE(app, argc, argv);
SeqLogger log(logUrl, logApiKey, "Sword");
SwordCfg.setVar(assetsBasePath, brocker, topic, user, password);
fmt::println("{}", app.get_description());
if (modeArg == "promo") {
fmt::println("starting with promo");
Mode = OpMode::PromoMode;
} else if (modeArg == "game") {
fmt::println("starting with promo");
Mode = OpMode::GamingMode;
} else {
fmt::println("unknown {}", modeArg);
}
constexpr array<const char*, 4> modes = {"Undefined", "Maintanance", "PromoMode", "Production"};
log.sendBootUp(Version, modes[static_cast<int>(Mode)]);
auto itrHandler = [&]() {
TriggeredInput itr(26, "PItr");
while (true) {
cout << "Await next interrupt\n";
if (itr.await()) {
cout << "Interrupt Event\n";
}
}
};
thread interruptThread(itrHandler);
InputPort sbPort(SwordEntryPin, "PinSEntry");
InputPort sePort(SwordEndPin, "PInSEnd");
InputPort spPort(SwordPulledPin, "PInSPull");
InputPort sparePort(sparePin, "spare");
OutputPort mOut1(LinMotPin1, "M1:1");
OutputPort mOut2(LinMotPin2, "M1:2");
InputTransAware SwordEntry(sbPort);
InputTransAware SwordEnd(sePort);
InputTransAware SwordPulled(spPort);
LinMot SwordLatch(mOut1, mOut2);
IoStat = make_unique<DeviceIoState>(SwordEntry, SwordEnd, SwordPulled, SwordLatch);
MqttChannel mqtt(Version, SwordCfg, *IoStat, log);
auto resetCall = [&]() {
log.sendEvent("Reset", "");
};
mqtt.flushInput();
static auto conTask = Thread::createExplicit("MqttTask", MqttChannel::runMasterService, ref(mqtt), resetCall);
SwordLatch.moveOut();
fmt::println("Running App");
while (true) {
switch (Mode) {
case OpMode::Maintanance: {
fmt::println("Running Maintanance");
// txQueue.emplace<ResponseTxMsg>(msg->code, 0);
Thread::sleep(500ms);
IoStat->tick();
mqtt.sendStatusMessage(Mode);
// auto e = make_unique<ResponseTxMsg>(msg->code, 0);
// txQueue.enqueue(move(e));
} break;
case OpMode::PromoMode: {
fmt::println("Running PromoMode");
processPromo(mqtt, log);
} break;
case OpMode::GamingMode: {
fmt::println("Running GamingMode");
processProduction(mqtt, log);
} break;
default:
break;
}
}
interruptThread.join();
return EXIT_SUCCESS;
}
void processPromo(MqttChannel& mqtt, SeqLogger& log) {
auto tn = chrono::steady_clock::now();
auto& serCmds = mqtt.getSerCommands();
while (true) {
Thread::sleep(10ms);
IoStat->tick();
if (IoStat->SwordPulled.isPosEdge()) {
if (!IoStat->Mute) {
log.sendEvent("Pull", "Start Audio");
MediaPlayer::playWavFile(SwordCfg.getSoundPromo());
fmt::println("Waiting for {}", IoStat->PromoDelay);
Thread::sleep(IoStat->PromoDelay);
fmt::println("Waiting done");
}
}
if (chrono::steady_clock::now() > (tn + 1s)) {
tn = chrono::steady_clock::now();
mqtt.sendStatusMessage(Mode);
}
}
}
void processProduction(MqttChannel& mqtt, SeqLogger& log) {
auto& serCmds = mqtt.getSerCommands();
auto& gameCmds = mqtt.getGameCommands();
while (true) {
auto msg = mqtt.tryDeque();
if (!msg) {
continue;
}
auto code = gameCmds.at(msg->Payload);
switch (code) {
case GameModeCommands_e::GameStarted: {
fmt::println("Got GameStarted");
log.sendEvent("Req", "GameStarted");
}
case GameModeCommands_e::GameFinished: {
fmt::println("Got GameFinished");
log.sendEvent("Req", "GameFinished");
}
case GameModeCommands_e::GameNextTryLocked: {
fmt::println("Got NextTryLock");
log.sendEvent("Req", "StayLockded");
while (true) {
IoStat->SwordPulled.sample();
if (IoStat->SwordPulled.isPosEdge()) {
mqtt.sendStatusMessage(Mode);
// say: You are not the one
MediaPlayer::playWavFile(SwordCfg.getSoundDeny());
Thread::sleep(15s);
log.sendEvent("Req", "Pulled");
mqtt.sendEvent("pull");
}
}
} break;
case GameModeCommands_e::GameNextTryRelease: {
fmt::println("NextTryRelease");
log.sendEvent("Req", "UnlockSword");
IoStat->SwordLatch.moveIn();
while (true) {
IoStat->SwordEnd.sample();
if (IoStat->SwordEnd.isNegEdge()) {
mqtt.sendStatusMessage(Mode);
break;
}
}
while (true) {
IoStat->SwordEntry.sample();
if (IoStat->SwordEntry.isNegEdge()) {
mqtt.sendStatusMessage(Mode);
break;
}
}
mqtt.sendEvent("pulled-out");
log.sendEvent("Req", "Pulled Out");
// say: You ARE the one
MediaPlayer::playWavFile(SwordCfg.getSoundAllow());
Thread::sleep(15s);
mqtt.sendEvent("ceremonyDone");
while (true) {
IoStat->SwordEnd.sample();
if (IoStat->SwordEnd.isNegEdge()) {
mqtt.sendStatusMessage(Mode);
break;
}
}
while (true) {
IoStat->SwordEntry.sample();
if (IoStat->SwordEntry.isNegEdge()) {
mqtt.sendStatusMessage(Mode);
break;
}
}
log.sendEvent("Req", "Put Back");
mqtt.sendEvent("put-in");
} break;
}
}
}