diff --git a/arduino/arduino.ino b/arduino/arduino.ino index 5843903..e080271 100644 --- a/arduino/arduino.ino +++ b/arduino/arduino.ino @@ -15,6 +15,7 @@ enum state { enum state current_state; char input_code[INPUT_SIZE + 1]; +int user_id; MKRIoTCarrier carrier; WiFiSSLClient wifi_client; @@ -24,7 +25,9 @@ MqttClient mqtt_client(wifi_client); int motor_count = 0; int motor_count_max = 64; +uint32_t red_led_color = carrier.leds.Color(255, 0, 0); uint32_t green_led_color = carrier.leds.Color(0, 255, 0); +uint32_t blue_led_color = carrier.leds.Color(0, 0, 255); bool is_input_empty() { @@ -61,7 +64,10 @@ void change_state(enum state new_state) void draw_state() { + // Reset carrier.display.fillScreen(0x000); + carrier.leds.fill(0, 0, 5); + carrier.leds.setBrightness(5); switch (current_state) { case STATE_CONNECTING: @@ -75,8 +81,6 @@ void draw_state() carrier.display.setTextSize(2); carrier.display.print("Press Green Button"); carrier.leds.fill(green_led_color, 2, 1); - carrier.leds.setBrightness(5); - carrier.leds.show(); break; case STATE_INPUT_PASSCODE: @@ -97,14 +101,22 @@ void draw_state() carrier.display.print(' '); } } + + carrier.leds.fill(blue_led_color, 0, 2); + carrier.leds.fill(red_led_color, 2, 1); + carrier.leds.fill(blue_led_color, 3, 2); break; case STATE_LOGGED_IN: carrier.display.setCursor(40, 100); carrier.display.setTextSize(3); carrier.display.print("Logged in"); + carrier.leds.fill(green_led_color, 2, 1); + carrier.leds.fill(red_led_color, 4, 1); break; } + + carrier.leds.show(); } void setup() @@ -183,11 +195,10 @@ void loop() Serial.println("Dispensing..."); // Start rotating motor - motor_count = motor_count_max; + motor_count += motor_count_max; } else if (topic == "login") { Serial.println("Logged in"); - int user_id; if (sscanf(message, "%d", &user_id) > 0) { change_state(STATE_LOGGED_IN); } else { @@ -198,6 +209,9 @@ void loop() free(message); } + touchButtons buttons[] = { TOUCH0, TOUCH1, TOUCH3, TOUCH4 }; + char input_characters[] = "1234"; + switch (current_state) { case STATE_LOGGED_OUT: if (carrier.Buttons.onTouchDown(TOUCH2)) { @@ -205,8 +219,19 @@ void loop() } break; case STATE_INPUT_PASSCODE: - touchButtons buttons[] = { TOUCH0, TOUCH1, TOUCH3, TOUCH4 }; - char input_characters[] = "1234"; + if (carrier.Buttons.onTouchDown(TOUCH2)) { + if (is_input_empty()) { + change_state(STATE_LOGGED_OUT); + } else { + for (int i = INPUT_SIZE - 1; i >= 0; i--) { + if (input_code[i]) { + input_code[i] = '\0'; + draw_state(); + break; + } + } + } + } for (int i = 0; i < sizeof(buttons) / sizeof(buttons[0]); i++) { if (carrier.Buttons.onTouchDown(buttons[i])) { @@ -229,6 +254,24 @@ void loop() } } + break; + case STATE_LOGGED_IN: + if (carrier.Buttons.onTouchDown(TOUCH2)) { + char *user_id_str = (char *)malloc(4); + snprintf(user_id_str, 4, "%d", user_id); + + mqtt_client.beginMessage("dispense_request"); + mqtt_client.print(user_id_str); + mqtt_client.endMessage(); + + free(user_id_str); + } + + if (carrier.Buttons.onTouchDown(TOUCH4)) { + change_state(STATE_LOGGED_OUT); + } break; } + + delay(2); } diff --git a/backend/Program.cs b/backend/Program.cs index 5cb1c55..fefa16c 100644 --- a/backend/Program.cs +++ b/backend/Program.cs @@ -1,6 +1,7 @@ using MQTTnet; using MQTTnet.Client; using backend.Application; +using backend.Models; var builder = WebApplication.CreateBuilder(args); @@ -50,7 +51,11 @@ var options = new MqttClientOptionsBuilder() await mqttClient.ConnectAsync(options, CancellationToken.None); await mqttClient.SubscribeAsync( - new MqttFactory().CreateSubscribeOptionsBuilder().WithTopicFilter(f => f.WithTopic("login_request")).Build(), + new MqttFactory() + .CreateSubscribeOptionsBuilder() + .WithTopicFilter(f => f.WithTopic("login_request")) + .WithTopicFilter(f => f.WithTopic("dispense_request")) + .Build(), CancellationToken.None ); @@ -58,13 +63,15 @@ ApplicationState.DbContext = new DispenserContext(); mqttClient.ApplicationMessageReceivedAsync += delegate(MqttApplicationMessageReceivedEventArgs args) { var payload = System.Text.Encoding.Default.GetString(args.ApplicationMessage.PayloadSegment); + User? user; + MqttApplicationMessageBuilder message; switch (args.ApplicationMessage.Topic) { case "login_request": - var user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.TouchCode == payload); + user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.TouchCode == payload); - var message = new MqttApplicationMessageBuilder() - .WithTopic("login"); + message = new MqttApplicationMessageBuilder() + .WithTopic("login"); if (user == null) { message.WithPayload("error"); @@ -74,6 +81,20 @@ mqttClient.ApplicationMessageReceivedAsync += delegate(MqttApplicationMessageRec mqttClient.PublishAsync(message.Build()); + break; + case "dispense_request": + user = ApplicationState.DbContext!.Users.FirstOrDefault(user => user.Id == int.Parse(payload)); + if (user == null || (!user.IsParent && user.Dispenses <= 0)) { + // TODO error + break; + } + + message = new MqttApplicationMessageBuilder() + .WithTopic("dispense") + .WithPayload("dispense"); + + mqttClient.PublishAsync(message.Build()); + break; }