Exemplo n.º 1
0
int state_machine::process_event(int event, void* ev_data)
{
	if (lock_in_process(event, ev_data) == -1) {
		return 0;
	}

BULLSEYE_EXCLUDE_BLOCK_END
	// if we got here: State machine is free
	if ((event > m_max_events) || (event < 0)) {
		sm_logdbg("ERROR: illegal event num %d", event);
		unlock_in_process();
		return -1;
	}
BULLSEYE_EXCLUDE_BLOCK_END
	sm_state_info_t* p_sm_state_info = &m_p_sm_table[get_curr_state()];
	int next_state = p_sm_state_info->event_info[event].next_state;
	m_info.new_state = next_state;
	m_info.event = event;
	m_info.ev_data = ev_data;

	// Run print event info function
	if (m_new_event_notify_func) {
		m_new_event_notify_func(get_curr_state(), event, m_info.app_hndl);
	}

	// Run leave function
	if ((next_state != get_curr_state()) && (next_state != SM_ST_STAY) && p_sm_state_info->leave_func) {
		p_sm_state_info->leave_func(m_info); 
	}

	// Run the action function
	if (p_sm_state_info->event_info[event].trans_func) {
		p_sm_state_info->event_info[event].trans_func(m_info);
	}

	// Move to next state
	if ((next_state !=  get_curr_state()) && (next_state != SM_ST_STAY)) {

		// Run entry function
		if (m_p_sm_table[next_state].entry_func) {
			m_p_sm_table[next_state].entry_func(m_info); 
		}

		// Update current state
		m_info.old_state = next_state;
	}

	unlock_in_process();
	return 0;
}
int cthd_cdev::thd_cdev_exponential_controller(int set_point, int target_temp,
		int temperature, int state, int zone_id) {

	curr_state = get_curr_state();
	if ((min_state < max_state && curr_state < min_state)
			|| (min_state > max_state && curr_state > min_state))
		curr_state = min_state;
	max_state = get_max_state();
	thd_log_debug("thd_cdev_set_%d:curr state %d max state %d\n", index,
			curr_state, max_state);
	if (state) {
		if ((min_state < max_state && curr_state < max_state)
				|| (min_state > max_state && curr_state > max_state)) {
			int state = curr_state + inc_dec_val;
			if (trend_increase) {
				if (curr_pow == 0)
					base_pow_state = curr_state;
				++curr_pow;
				state = base_pow_state + int_2_pow(curr_pow) * inc_dec_val;
				thd_log_info(
						"cdev index:%d consecutive call, increment exponentially state %d\n",
						index, state);
				if ((min_state < max_state && state >= max_state)
						|| (min_state > max_state && state <= max_state)) {
					state = max_state;
					curr_pow = 0;
					curr_state = max_state;
				}
			} else {
				curr_pow = 0;
			}
			trend_increase = true;
			if ((min_state < max_state && state > max_state)
					|| (min_state > max_state && state < max_state))
				state = max_state;
			thd_log_debug("op->device:%s %d\n", type_str.c_str(), state);
			set_curr_state(state, zone_id);
		}
	} else {
		curr_pow = 0;
		trend_increase = false;
		if (((min_state < max_state && curr_state > min_state)
				|| (min_state > max_state && curr_state < min_state))
				&& auto_down_adjust == false) {
			int state = curr_state - inc_dec_val;
			if ((min_state < max_state && state < min_state)
					|| (min_state > max_state && state > min_state))
				state = min_state;
			thd_log_debug("op->device:%s %d\n", type_str.c_str(), state);
			set_curr_state(state, zone_id);
		} else {
			thd_log_debug("op->device: force min %s %d\n", type_str.c_str(),
					min_state);
			set_curr_state(min_state, zone_id);
		}
	}

	thd_log_info(
			"Set : threshold:%d, temperature:%d, cdev:%d(%s), curr_state:%d, max_state:%d\n",
			set_point, temperature, index, type_str.c_str(), get_curr_state(),
			max_state);

	thd_log_debug("<<thd_cdev_set_state %d\n", state);

	return THD_SUCCESS;
}
int cthd_cdev::thd_cdev_set_state(int set_point, int target_temp,
		int temperature, int state, int zone_id, int trip_id,
		int target_value) {

	time_t tm;
	int ret;

	time(&tm);
	thd_log_debug(">>thd_cdev_set_state index:%d state:%d :%d:%d:%d\n", index,
			state, zone_id, trip_id, target_value);
	if (last_state == state && (tm - last_action_time) <= debounce_interval) {
		thd_log_debug(
				"Ignore: delay < debounce interval : %d, %d, %d, %d, %d\n",
				set_point, temperature, index, get_curr_state(), max_state);
		return THD_SUCCESS;
	}
	last_state = state;
	if (state) {
		zone_mask |= (1 << zone_id);
		trip_mask |= (1 << trip_id);

		if (target_value != TRIP_PT_INVALID_TARGET_STATE) {
			zone_trip_limits_t limit;
			bool found = false;

			for (unsigned int i = 0; i < zone_trip_limits.size(); ++i) {
				if (zone_trip_limits[i].zone == zone_id
						&& zone_trip_limits[i].trip == trip_id) {
					found = true;
					break;
				}
			}
			if (!found) {
				limit.zone = zone_id;
				limit.trip = trip_id;
				limit.target_value = target_value;
				thd_log_debug("Added zone %d trip %d clamp %d\n", limit.zone,
						limit.trip, limit.target_value);
				zone_trip_limits.push_back(limit);
				std::sort(zone_trip_limits.begin(), zone_trip_limits.end(),
						sort_clamp_values);
			}
			set_curr_state_raw(target_value, zone_id);
			curr_state = target_value;
			last_action_time = tm;
			thd_log_info(
					"Set : threshold:%d, temperature:%d, cdev:%d(%s), curr_state:%d, max_state:%d\n",
					set_point, temperature, index, type_str.c_str(),
					get_curr_state(), max_state);
			return THD_SUCCESS;
		}
	} else {

		if (zone_mask & (1 << zone_id)) {
			if (trip_mask & (1 << trip_id)) {
				trip_mask &= ~(1 << trip_id);
				zone_mask &= ~(1 << zone_id);
			}
		}

		if (zone_trip_limits.size() > 0) {
			int length = zone_trip_limits.size();
			int i;

			// Just remove the current zone requesting to turn off
			for (i = 0; i < length; ++i) {
				if (zone_trip_limits[i].zone == zone_id
						&& zone_trip_limits[i].trip == trip_id) {
					zone_trip_limits.erase(zone_trip_limits.begin() + i);
					thd_log_debug("Erased  [%d: %d\n", zone_id, trip_id);
					break;
				}
			}
			zone_trip_limits_t limit;

			if (zone_trip_limits.size() == 0) {
				limit.target_value = get_min_state();
				limit.zone = zone_id;
				limit.trip = trip_id;
			} else {
				limit = zone_trip_limits[zone_trip_limits.size() - 1];
			}

			if (cmp_current_state(limit.target_value) < 0) {
				thd_log_info(
						"new active zone; next in line  %d trip %d clamp %d\n",
						limit.zone, limit.trip, limit.target_value);
				set_curr_state_raw(limit.target_value, zone_id);
				thd_log_info(
						"Set : threshold:%d, temperature:%d, cdev:%d(%s), curr_state:%d, max_state:%d\n",
						set_point, temperature, index, type_str.c_str(),
						get_curr_state(), max_state);
			}
			return THD_SUCCESS;

		} else if (zone_mask != 0 || trip_mask != 0) {
			thd_log_debug(
					"skip to reduce current state as this is controlled by two zone or trip actions and one is still on %lx:%lx\n",
					zone_mask, trip_mask);
			return THD_SUCCESS;
		}
	}
	last_action_time = tm;

	curr_state = get_curr_state();
	if (curr_state == get_min_state()) {
		control_begin();
	}
	if (pid_enable) {
		pid_ctrl.set_target_temp(target_temp);
		ret = pid_ctrl.pid_output(temperature);
		ret += get_curr_state();
		if (ret > get_max_state())
			ret = get_max_state();
		if (ret < get_min_state())
			ret = get_min_state();
		set_curr_state_raw(ret, zone_id);
		thd_log_debug("Set : %d, %d, %d, %d, %d\n", set_point, temperature,
				index, get_curr_state(), max_state);
		ret = THD_SUCCESS;
	} else {
		ret = thd_cdev_exponential_controller(set_point, target_temp,
				temperature, state, zone_id);
	}
	if (curr_state == get_max_state()) {
		control_end();
	}

	return ret;
}