work1

Dependencies:   mbed MAX44009 mbed-os Si7021

app/AppCommand.cpp

Committer:
danaeb
Date:
2020-05-28
Revision:
2:25f27478fdf9
Parent:
1:3656b45f17a8

File content as of revision 2:25f27478fdf9:

#include "AppCommand.h"
#include "mbed_trace.h"

#include "AppMain.h"
#include "CommandParser.h"
#include "SensorManager.h"
#include "Calendar.h"
#include "Sensor.h"
#include "rtc.h"
#include "tools.h"

#define TRACE_GROUP "acmd"

using namespace liboo;

CommandParser   *AppCommand::_parser = NULL;
SensorManager   *AppCommand::_sensor_manager = NULL;
Calendar        *AppCommand::_calendar = NULL;
bool AppCommand::_is_intialized = false;
bool AppCommand::_is_pump_on = false;

void AppCommand::configure(SensorManager* sensor_manager,
                            Calendar *calendar){
    _parser = new CommandParser;
    _sensor_manager = sensor_manager;
    _is_pump_on = false;
    //_calendar = calendar;

    if(!_is_intialized){
        CommandCallback *cc;
        _is_intialized = true;

        // set rtc time
        cc = new CommandCallback("set time", 0b10000000, 0b00000000, _rtc_set_time);
        _parser->register_command_callback(cc);

        cc = new CommandCallback("set pump", 0b00000001, 0b00000000, _set_pump);
        _parser->register_command_callback(cc);

#if 0
        // reset calendar
        cc = new CommandCallback("reset calendar", 0b00110000, 0b00000000,
                                    _calendar_reset);
        _parser->register_command_callback(cc);

        // add time slot
        cc = new CommandCallback("add time slot", 0b00100000, 0b01000000,
                                   _calendar_add_time_slot);
        _parser->register_command_callback(cc);

        // configure active sensors
        cc = new CommandCallback("sensor", 0b00001000, 0b01110111,
                                 _sensor_configure_active);
        _parser->register_command_callback(cc);

        // disable enable calendar
        cc = new CommandCallback("calendar", 0b01000000, 0b00111110, _calendar_state);
        _parser->register_command_callback(cc);
#endif
    }
}

void AppCommand::process_command(u8 command_id, u8 *command_data, u16 command_size){
    _parser->execute(command_id, command_data, command_size);
}

bool AppCommand::get_pump_state(){
    return _is_pump_on;
}

u16 AppCommand::_rtc_set_time(u8 command_id, u8* command_data, u16 command_data_size){
    u16 ret = 0;
    tr_info("command set time");
    if(command_data_size < 4){
        return ret;
    }

    s32 offset;
    u32 current_time;
    offset = *((u32*)command_data);

    Rtc *rtc = Rtc::get_instance();
    tr_info("\t offset : %ld", offset);
    rtc->apply_offset(offset);

    // check calendar in case we need to change latch state.
    current_time = rtc->get_time();
    tr_info("\t time: %lu", current_time);
    //_calendar->check(current_time);

    ret = 4;
    return ret;
}

u16 AppCommand::_set_pump(u8 command_id, u8* command_data, u16 command_data_size){
    u16 ret = 0;
    tr_info("command set pump");
    if(command_data_size < 1){
        return ret;
    }

    uint8_t state = *command_data;

    PowerManager *pm = PowerManager::get_instance();
    if(state == 1){
        tr_debug("turn on !!!");
        pm->lock_and_turn_on_motor();
        _is_pump_on = true;
    }
    else {
        tr_debug("turn off !!!");
        pm->unlock_and_turn_off_motor();
        _is_pump_on = false;
    }

    ret = 1;
    return ret;
}

u16 AppCommand::_calendar_reset(u8 command_id, u8* command_data,
                                u16 command_data_size){
    tr_info("command reset calendar");
    //_calendar->reset(false);
    return 0;
}

u16 AppCommand::_calendar_state(u8 command_id, u8* command_data,
                                u16 command_data_size){
    PRINT(" disable calendar\r\n");
    if(command_id & 0x01){
        //_calendar->enable();
    }
    else{
        //_calendar->disable();
    }
    return 0;
}

u16 AppCommand::_calendar_add_time_slot(u8 command_id, u8* command_data, u16 command_data_size){
    u16 processed_size = 0;


    tr_info("command add time slot");
    // compute start time offset
    // the start offset can be changed even if no time slot are present
    s8 start_time_offset;
    start_time_offset = (command_id & 0x0F);
    start_time_offset -= 8;
    //_calendar->set_start_time_offset(start_time_offset);


    // several time slot can be embedded in one command
    // each time slot is coded on 4 bytes so the command size must have
    // a multiplicity of 4
    if(command_data_size < 4 || (command_data_size % 4 != 0)){
        return processed_size;
    }
    u8 i = 0;
    while(command_data_size - processed_size != 0){
        bool use_stop_day = false;
        u16 duration;
        u16 start_time;
        u8 start_day;
        u8 stop_day;
        u8 day_cycle;

        u32 data;

        // /4 because we are incrementing u32 pointer
        // so 1 increment means +4 address
        data = *((u32*)command_data + processed_size/4);


        start_time = (data      & 0x000000FF);
        duration = ((data       & 0x0001FF00) >> 8);
        day_cycle = ((data      & 0x001E0000) >> (8+9));
        start_day = ((data      & 0x03E00000) >> (8+9+4));
        use_stop_day = ((data   & 0x80000000) > 0);

        if(use_stop_day){
            stop_day = ((data & 0x7C000000) >> (8+9+4+5));
        }
        else{
            // trick to make it work when start day is 0:
            // 0+32-1 = 31
            // if start day is 31:
            // 31+32-1 % 32 = 62 % 32 = 30
            //
            stop_day = (start_day + 32 - 1) % 32;
        }

        // received start time is by 10 minutes time slots
        // and calendar uses 5 minutes time slots
        start_time *= 2;

        tr_info("\t command number: %d\r\n"
                "\t\t start day: %d\r\n"
                "\t\t stop day: %d\r\n"
                "\t\t day cycle: %d\r\n"
                "\t\t start time: %d:%d\r\n"
                "\t\t duration %d",
                    i, start_day, stop_day, day_cycle,
                    (start_time*5)/60, ((start_time*5) % 60), duration);
        //
        // true -> add time slot
        //_calendar->set_time_slot(true, start_day, stop_day, day_cycle, start_time, duration);
        processed_size += 4;
        ++i;
    }
    Rtc *rtc = Rtc::get_instance();

    // check calendar in case we need to change latch state.
    u32 current_time = rtc->get_time();
    //_calendar->check(current_time);

    return processed_size;

}
u16 AppCommand::_sensor_configure_active(u8 command_id, u8* command_data, u16 command_data_size){
    u16 ret = 0;
    tr_info("command config sensor");
    if(command_data_size < 2){
        return ret;
    }
#if 0
    u16 data = ((u16*)command_data)[0];

    bool is_sensor_enable;

    is_sensor_enable = ((data & 0x0001) > 0);
    _sensor_configure(SENSOR_ID_TENSIOMETER_1, is_sensor_enable);

    is_sensor_enable = ((data & 0x0002) > 0);
    _sensor_configure(SENSOR_ID_TENSIOMETER_2, is_sensor_enable);

    is_sensor_enable = ((data & 0x0004) > 0);
    _sensor_configure(SENSOR_ID_TENSIOMETER_3, is_sensor_enable);

    is_sensor_enable = ((data & 0x0008) > 0);
    _sensor_configure(SENSOR_ID_PRESSURE_1, is_sensor_enable);

    is_sensor_enable = ((data & 0x0010) > 0);
    _sensor_configure(SENSOR_ID_PRESSURE_2, is_sensor_enable);

    is_sensor_enable = ((data & 0x0020) > 0);
    _sensor_configure(SENSOR_ID_PRESSURE_3, is_sensor_enable);

    is_sensor_enable = ((data & 0x0040) > 0);
    _sensor_configure(SENSOR_ID_PRESSURE_PIPE, is_sensor_enable);

    is_sensor_enable = ((data & 0x0080) > 0);
    _sensor_configure(SENSOR_ID_IMPULSE, is_sensor_enable);

    is_sensor_enable = ((data & 0x0100) > 0);
    _sensor_configure(SENSOR_ID_SOIL_TEMPERATURE, is_sensor_enable);

    is_sensor_enable = ((data & 0x0200) > 0);
    _sensor_configure(SENSOR_ID_BOARD_HUMIDITY, is_sensor_enable);

    is_sensor_enable = ((data & 0x0400) > 0);
    _sensor_configure(SENSOR_ID_BOARD_TEMPERATURE, is_sensor_enable);

    is_sensor_enable = ((data & 0x0800) > 0);
    _sensor_configure(SENSOR_ID_BAT, is_sensor_enable);

    u8 redundancy = ((data & 0xF000) >> 12)+1;
    AppMain::set_history_size(redundancy);

#endif

    ret = 2;
    return ret;
}

void AppCommand::_sensor_configure(u8 sensor_id, bool on_off){
    if(on_off){
        tr_debug(" \tenable sensor %d", sensor_id);
        _sensor_manager->enable_sensor(sensor_id);
    }
    else{
        tr_debug(" \tdisable sensor %d", sensor_id);
        _sensor_manager->disable_sensor(sensor_id);
    }
}