From 2911cd4bad54b2560e52849d615337a0b306998d Mon Sep 17 00:00:00 2001 From: Andreas Berthoud Date: Tue, 27 Jul 2021 21:15:49 +0200 Subject: [PATCH] pump_ctrl: Implement pump controlling --- backend/monsun_backend/commands.py | 73 +++++++++++++++++++ nucleo-wb55-ble/Core/Inc/pump_control.h | 23 ++++++ nucleo-wb55-ble/Core/Inc/pump_control.hpp | 21 ++++++ nucleo-wb55-ble/Core/Src/main.c | 3 +- nucleo-wb55-ble/Core/Src/pump_control.cpp | 65 +++++++++++++++++ nucleo-wb55-ble/commands/PumpCommand.cpp | 59 +++++++++++++++ nucleo-wb55-ble/commands/PumpCommand.hpp | 48 ++++++++++++ nucleo-wb55-ble/commands/dispatch.cpp | 4 + .../shared_commands/commands.hpp | 2 + 9 files changed, 297 insertions(+), 1 deletion(-) create mode 100644 nucleo-wb55-ble/Core/Inc/pump_control.h create mode 100644 nucleo-wb55-ble/Core/Inc/pump_control.hpp create mode 100644 nucleo-wb55-ble/Core/Src/pump_control.cpp create mode 100644 nucleo-wb55-ble/commands/PumpCommand.cpp create mode 100644 nucleo-wb55-ble/commands/PumpCommand.hpp diff --git a/backend/monsun_backend/commands.py b/backend/monsun_backend/commands.py index 146a2d2..0aa0c23 100644 --- a/backend/monsun_backend/commands.py +++ b/backend/monsun_backend/commands.py @@ -27,6 +27,9 @@ class CommandId(Enum): command_gp_request = 0x6 command_gp_response = 0x7 + command_pump_request = 0x8 + command_pump_response = 0x9 + class CommandTarget(Enum): client = 0 @@ -376,3 +379,73 @@ register_response( cls=GPResponse, command_id=CommandId.command_gp_response, ) + + +class PumpResponse(Response): + was_successful = True + + def unpack_payload( + self, + data: bytes, + ): + self.was_successful = bool(data[0]) + self.is_on = bool(data[1]) + + +class PumpRequest(Request): + def __init__(self, do: str, timeout: Union[int, str] = 60, *args, **kwargs) -> None: + super().__init__(*args, **kwargs) + try: + self.do = { + "turn_off": 0, + "turn_on": 1, + "is_on": 2, + }[do] + except KeyError: + self.do = int(do) + + self.pump_timeout = int(timeout) + + @property + def identifier(self) -> CommandId: + return CommandId.command_pump_request + + @property + def timeout(self) -> float: + return 1 + + def process_response(self, response: Response): + if not isinstance(response, PumpResponse): + raise TypeError(f"{response} is not a {PumpResponse}") + + if response.was_successful: + self._logger.debug("Pump command was successful") + else: + self._logger.debug("Pump command was not successful") + + if response.is_on: + self._logger.debug("Pump is on") + else: + self._logger.debug("Pump is off") + + def execute(self, serial: Serial): + payload = pack( + ">BH", + self.do, + self.pump_timeout, + ) + self.send_command( + payload=payload, + serial=serial, + ) + + +register_request( + cls=PumpRequest, + command_id=CommandId.command_pump_request, + alias="pump", +) +register_response( + cls=PumpResponse, + command_id=CommandId.command_pump_response, +) diff --git a/nucleo-wb55-ble/Core/Inc/pump_control.h b/nucleo-wb55-ble/Core/Inc/pump_control.h new file mode 100644 index 0000000..001977c --- /dev/null +++ b/nucleo-wb55-ble/Core/Inc/pump_control.h @@ -0,0 +1,23 @@ +/* + * pump_control.h + * + * Created on: Jul 27, 2021 + * Author: Andreas Berthoud + */ + +#ifndef INC_PUMP_CONTROL_H_ +#define INC_PUMP_CONTROL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + uint8_t pump_init(); + +#ifdef __cplusplus +} +#endif + +#endif /* INC_PUMP_CONTROL_H_ */ diff --git a/nucleo-wb55-ble/Core/Inc/pump_control.hpp b/nucleo-wb55-ble/Core/Inc/pump_control.hpp new file mode 100644 index 0000000..8e90b0e --- /dev/null +++ b/nucleo-wb55-ble/Core/Inc/pump_control.hpp @@ -0,0 +1,21 @@ +/* + * pump_control.hpp + * + * Created on: Jul 27, 2021 + * Author: Andreas Berthoud + */ + +#ifndef INC_PUMP_CONTROL_H_ +#define INC_PUMP_CONTROL_H_ + +#include + +namespace pump { + + void turn_on(uint16_t timeout); + uint8_t is_on(); + void turn_off(); + +} + +#endif /* INC_PUMP_CONTROL_H_ */ diff --git a/nucleo-wb55-ble/Core/Src/main.c b/nucleo-wb55-ble/Core/Src/main.c index 39280c2..b1030f1 100644 --- a/nucleo-wb55-ble/Core/Src/main.c +++ b/nucleo-wb55-ble/Core/Src/main.c @@ -29,6 +29,7 @@ #include "dbg_trace.h" #include "hw_conf.h" #include "otp.h" +#include "pump_control.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -104,7 +105,7 @@ int main(void) MX_RTC_Init(); MX_USB_Device_Init(); /* USER CODE BEGIN 2 */ - + pump_init(); /* USER CODE END 2 */ /* Init code for STM32_WPAN */ diff --git a/nucleo-wb55-ble/Core/Src/pump_control.cpp b/nucleo-wb55-ble/Core/Src/pump_control.cpp new file mode 100644 index 0000000..029584e --- /dev/null +++ b/nucleo-wb55-ble/Core/Src/pump_control.cpp @@ -0,0 +1,65 @@ +/* + * pump_control.cpp + * + * Created on: Jul 27, 2021 + * Author: Andreas Berthoud + */ + +#include "pump_control.h" +#include "pump_control.hpp" +#include "main.h" +#include "stm32wbxx_hal.h" +#include "hw_if.h" +#include "LogCommand.hpp" + + +namespace pump { + + typedef struct { + bool is_on; + uint8_t timer_id; + } pump_state_t; + + pump_state_t pump_state { + .is_on=false + }; + + void turn_on(uint16_t timeout) { + + uint32_t ticks = (timeout*1000*1000/CFG_TS_TICK_VAL); + if (ticks > 0xFFFF0000) { + log_error("pump::turn_on", "max timout exceeded", 0); + return; + } + + HW_TS_Start(pump_state.timer_id, ticks); + HAL_GPIO_WritePin(RELAY_12V_OUT1_GPIO_Port, RELAY_12V_OUT1_Pin, GPIO_PIN_SET); + pump_state.is_on = true; + log_debug("pump", "turned on", 0); + } + + uint8_t is_on() { + return (uint8_t)pump_state.is_on; + } + + void turn_off() { + pump_state.is_on = false; + HAL_GPIO_WritePin(RELAY_12V_OUT1_GPIO_Port, RELAY_12V_OUT1_Pin, GPIO_PIN_RESET); + HW_TS_Stop(pump_state.timer_id); + log_debug("pump", "turned off", 0); + } + + uint8_t init() { + HW_TS_ReturnStatus_t return_status = HW_TS_Create(CFG_TIM_PROC_ID_ISR, &(pump_state.timer_id), hw_ts_SingleShot, turn_off); + if (return_status == hw_ts_Failed) { + log_error("pump::init", "Creating hardware timer failed", 0); + return 1; + } + return 0; + } + +} + +uint8_t pump_init() { + return pump::init(); +} diff --git a/nucleo-wb55-ble/commands/PumpCommand.cpp b/nucleo-wb55-ble/commands/PumpCommand.cpp new file mode 100644 index 0000000..0bb6464 --- /dev/null +++ b/nucleo-wb55-ble/commands/PumpCommand.cpp @@ -0,0 +1,59 @@ +/* + * PumpCommand.cpp + * + * Created on: Jul 27, 2021 + * Author: Andreas Berthoud + */ + +#include "PumpCommand.hpp" +#include "pump_control.hpp" +#include "main.h" + + +PumpResponse::PumpResponse(com_channel_type_t com_channel_type, uint16_t response_identifier, bool was_successful, bool is_on) + : Response(com_channel_type, response_identifier) { + uint8_t * next_free_payload = this->payload_ptr + this->get_payload_size(); + next_free_payload[0] = (uint8_t)was_successful; + next_free_payload[1] = (uint8_t)is_on; + this->add_to_payload_size(2); +} + +PumpRequest::PumpRequest(com_channel_type_t com_channel_type, uint8_t * payload_ptr, uint16_t size) + : Request(com_channel_type, payload_ptr, size) { + uint16_t expected_length = this->buffer_offset + 3; + if (expected_length != size) { + this->has_error = true; + return; + } + + uint8_t * data_ptr = payload_ptr + this->buffer_offset; + this->pump_command = static_cast(data_ptr[0]); + this->timeout = data_ptr[1] << 8 | data_ptr[2]; +} + +PumpResponse * PumpRequest::execute_request(com_channel_type_t com_channel_type, uint16_t response_identifier) { + bool was_successful = true; + + + if (this->pump_command >= pump_command_max) { + was_successful = false; + } else { + switch (this->pump_command) + { + case pump_command_turn_off: + pump::turn_on(this->timeout); + break; + case pump_command_turn_on: + pump::turn_off(); + break; + case pump_command_get_state: + break; + default: + was_successful = false; + break; + } + } + bool is_on = pump::is_on(); + + return new PumpResponse(com_channel_type, response_identifier, was_successful, is_on); +} diff --git a/nucleo-wb55-ble/commands/PumpCommand.hpp b/nucleo-wb55-ble/commands/PumpCommand.hpp new file mode 100644 index 0000000..1f090e0 --- /dev/null +++ b/nucleo-wb55-ble/commands/PumpCommand.hpp @@ -0,0 +1,48 @@ +/* + * PumpCommand.hpp + * + * Created on: Jul 27, 2021 + * Author: Andreas Berthoud + */ + +#ifndef PUMPCOMMAND_HPP_ +#define PUMPCOMMAND_HPP_ + +#include "Request.hpp" +#include "Response.hpp" + + +class PumpResponse : public Response { +public: + PumpResponse(com_channel_type_t com_channel_type, uint16_t response_identifier, bool was_successful, bool is_on); + + CommandId get_command_id() override { return COMMAND_PUMP_RESPONSE; } + +private: + bool was_successful = false; + bool is_on = false; +}; + +class PumpRequest : public Request { +public: + PumpRequest(com_channel_type_t com_channel_type, uint8_t * payload_ptr, uint16_t size); + + PumpResponse * execute_request(com_channel_type_t com_channel_type, uint16_t response_identifier) override; + + CommandId get_command_id() override { return COMMAND_PUMP_REQUEST; } + +private: + enum PumpCommand { + pump_command_turn_on, + pump_command_turn_off, + pump_command_get_state, + pump_command_max, + }; + + bool has_error = false; + PumpCommand pump_command = pump_command_turn_off; + uint16_t timeout; /* timeout in seconds until the pump is turned off again */ + +}; + +#endif /* PUMPCOMMAND_HPP_ */ diff --git a/nucleo-wb55-ble/commands/dispatch.cpp b/nucleo-wb55-ble/commands/dispatch.cpp index 8fd7932..0564f1c 100644 --- a/nucleo-wb55-ble/commands/dispatch.cpp +++ b/nucleo-wb55-ble/commands/dispatch.cpp @@ -10,6 +10,7 @@ #include "HeartbeatCommand.hpp" #include "LedCommand.hpp" #include "GPCommand.hpp" +#include "PumpCommand.hpp" void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t size, com_channel_type_t com_channel_type ) { switch (command_id) @@ -23,6 +24,9 @@ void handle_received_command(uint8_t command_id, uint8_t * payload_ptr, uint16_t case COMMAND_GP_REQUEST: push_command(new GPRequest(com_channel_type, payload_ptr, size)); break; + case COMMAND_PUMP_REQUEST: + push_command(new PumpRequest(com_channel_type, payload_ptr, size)); + break; default: break; diff --git a/nucleo-wb55-dongle-ble/shared_commands/commands.hpp b/nucleo-wb55-dongle-ble/shared_commands/commands.hpp index b26fcf3..78a0606 100644 --- a/nucleo-wb55-dongle-ble/shared_commands/commands.hpp +++ b/nucleo-wb55-dongle-ble/shared_commands/commands.hpp @@ -19,6 +19,8 @@ typedef enum : uint8_t { COMMAND_LED_RESPONSE = 0x5, COMMAND_GP_REQUEST = 0x6, COMMAND_GP_RESPONSE = 0x7, + COMMAND_PUMP_REQUEST = 0x8, + COMMAND_PUMP_RESPONSE = 0x9, } CommandId; #endif /* COMMANDS_HPP_ */