void MessageProcessor::send(const ControllerMessage& msg_in, const ControllerMessageDescriptor& msg_desc, int msec_delta) { if (m_config && !m_config->empty()) { ControllerMessage msg = msg_in; #if 0 if (m_rumble_test) { log_debug("rumble: " << msg.get_abs(XBOX_AXIS_LT) << " " << msg.get_abs(XBOX_AXIS_RT)); set_rumble(static_cast<uint8_t>(msg.get_abs(XBOX_AXIS_LT)), static_cast<uint8_t>(msg.get_abs(XBOX_AXIS_RT))); } #endif // handling switching of configurations if (m_config_toggle_button != -1) { bool last = m_oldmsg.get_key(m_config_toggle_button); bool cur = msg.get_key(m_config_toggle_button); if (cur && cur != last) { // reset old mapping to zero to not get stuck keys/axis m_config->get_config()->get_emitter().reset_all_outputs(); // switch to the next input mapping m_config->next_config(); log_info("switched to config: " << m_config->get_current_config()); } } // run the controller message through all modifier for(std::vector<ModifierPtr>::iterator i = m_config->get_config()->get_modifier().begin(); i != m_config->get_config()->get_modifier().end(); ++i) { (*i)->update(msec_delta, msg, m_desc); } m_config->get_config()->get_emitter().update(msec_delta); // send current Xbox state to uinput if (msg != m_oldmsg) { // Only send a new event out if something has changed, // this is useful since some controllers send events // even if nothing has changed, deadzone can cause this // too m_oldmsg = msg; m_config->get_config()->get_emitter().send(msg); } } }
void ButtonmapModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { // update all filters in all mappings for(std::vector<ButtonMappingPtr>::iterator i = m_buttonmap.begin(); i != m_buttonmap.end(); ++i) { for(std::vector<ButtonFilterPtr>::iterator j = (*i)->filters.begin(); j != (*i)->filters.end(); ++j) { (*j)->update(msec_delta); } } std::bitset<256> state = msg.get_key_state(); for(std::vector<ButtonMappingPtr>::iterator i = m_buttonmap.begin(); i != m_buttonmap.end(); ++i) { int key_out = (*i)->rhs.get_key(); bool value = (*i)->lhs.get(msg); // apply the button filter for(std::vector<ButtonFilterPtr>::iterator j = (*i)->filters.begin(); j != (*i)->filters.end(); ++j) { value = (*j)->filter(value); } state[key_out] = value || state[key_out]; } msg.set_key_state(state); }
void Acc2AxisModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { float ax = msg.get_abs_float(m_acc_x); float ay = msg.get_abs_float(m_acc_y); float az = msg.get_abs_float(m_acc_z); float rx = (atan2f(az, ax) - static_cast<float>(M_PI)/2.0f) * -1.0f; float ry = (atan2f(az, ay) - static_cast<float>(M_PI)/2.0f) * -1.0f; // FIXME: to simplistic, need a better way to normalize the angles // normalize the range from [-pi/2, 3/2pi] to [-pi,pi] if (rx > static_cast<float>(M_PI)) rx -= static_cast<float>(M_PI*2.0); if (ry > static_cast<float>(M_PI)) ry -= static_cast<float>(M_PI*2.0); ry *= -1.0f; // full range is M_PI, but we use M_PI/2 as beyond that point // precision is lacking rx = static_cast<float>(rx/(M_PI/2.0)); ry = static_cast<float>(ry/(M_PI/2.0)); rx = Math::clamp(-1.0f, rx, 1.0f); ry = Math::clamp(-1.0f, ry, 1.0f); //log_tmp("Rot: " /*<< ax << " " << ay << " " << az << " -- " */<< rx << " " << ry); msg.set_abs_float(m_axis_x, rx); msg.set_abs_float(m_axis_y, ry); }
void EventEmitter::send(const ControllerMessage& msg) { m_btn_map.send(msg.get_key_state()); m_abs_map.send(msg.get_key_state(), msg.get_abs_state(), msg.get_abs_min(), msg.get_abs_max()); m_uinput.sync(); }
void SquareAxisModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { int x = msg.get_abs(m_xaxis); int y = msg.get_abs(m_yaxis); squarify_axis(x, y); msg.set_abs(m_xaxis, x); msg.set_abs(m_yaxis, y); }
void DeviceManager::setSensorValueAndSignal( const std::string &dataType, int dataTypeId, Sensor *sensor, const ControllerMessage &msg, time_t timestamp) const { if (!msg.hasParameter(dataType)) { return; } sensor->setValue(dataTypeId, msg.getParameter(dataType), timestamp); EventUpdateData *eventData = new EventUpdateData(); eventData->messageType = L"TDSensorEvent"; eventData->protocol = sensor->protocol(); eventData->model = sensor->model(); eventData->sensorId = sensor->id(); eventData->dataType = dataTypeId; eventData->value = TelldusCore::charToWstring(sensor->value(dataTypeId).c_str()); eventData->timestamp = static_cast<int>(timestamp); d->deviceUpdateEvent->signal(eventData); }
std::string ProtocolMandolyn::decodeData(const ControllerMessage &dataMsg) { std::string data = dataMsg.getParameter("data"); uint32_t value = (uint32_t)TelldusCore::hexTo64l(data); // parity not used // bool parity = value & 0x1; value >>= 1; double temp = static_cast<double>(value & 0x7FFF) - static_cast<double>(6400); temp = temp/128.0; value >>= 15; uint8_t humidity = (value & 0x7F); value >>= 7; // battOk not used // bool battOk = value & 0x1; value >>= 3; uint8_t channel = (value & 0x3)+1; value >>= 2; uint8_t house = value & 0xF; std::stringstream retString; retString << "class:sensor;protocol:mandolyn;id:" << house*10+channel << ";model:temperaturehumidity;" << "temp:" << std::fixed << std::setprecision(1) << temp << ";humidity:" << static_cast<int>(humidity) << ";"; return retString.str(); }
void CompatModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { if (m_dpad) { msg.set_abs(m_dpad_x, (-1 * msg.get_key(m_dpad_left)) + (+1 * msg.get_key(m_dpad_right)), -1, 1); msg.set_abs(m_dpad_y, (-1 * msg.get_key(m_dpad_up)) + (+1 * msg.get_key(m_dpad_down)), -1, 1); } if (m_trigger) { msg.set_abs(m_abs_trigger, msg.get_abs(m_rt) - msg.get_abs(m_lt), -msg.get_abs_max(m_lt), msg.get_abs_max(m_lt)); } }
void RotateAxisModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { float x = msg.get_abs_float(m_xaxis); float y = msg.get_abs_float(m_yaxis); if (m_mirror) { x = -x; } float length = sqrtf(x*x + y*y); float angle = atan2f(y, x) + m_angle; msg.set_abs_float(m_xaxis, cosf(angle) * length); msg.set_abs_float(m_yaxis, sinf(angle) * length); }
void DeviceManager::handleSensorMessage(const ControllerMessage &msg) { TelldusCore::MutexLocker sensorListLocker(&d->lock); Sensor *sensor = 0; for (std::list<Sensor *>::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { TelldusCore::MutexLocker sensorLocker(*it); if (!TelldusCore::comparei((*it)->protocol(), msg.protocol())) { continue; } if (!TelldusCore::comparei((*it)->model(), msg.model())) { continue; } if ((*it)->id() != msg.getInt64Parameter("id")) { continue; } sensor = *it; break; } if (!sensor) { sensor = new Sensor(msg.protocol(), msg.model(), msg.getInt64Parameter("id")); d->sensorList.push_back(sensor); } TelldusCore::MutexLocker sensorLocker(sensor); time_t t = time(NULL); setSensorValueAndSignal("temp", TELLSTICK_TEMPERATURE, sensor, msg, t); setSensorValueAndSignal("humidity", TELLSTICK_HUMIDITY, sensor, msg, t); setSensorValueAndSignal("rainrate", TELLSTICK_RAINRATE, sensor, msg, t); setSensorValueAndSignal("raintotal", TELLSTICK_RAINTOTAL, sensor, msg, t); setSensorValueAndSignal("winddirection", TELLSTICK_WINDDIRECTION, sensor, msg, t); setSensorValueAndSignal("windaverage", TELLSTICK_WINDAVERAGE, sensor, msg, t); setSensorValueAndSignal("windgust", TELLSTICK_WINDGUST, sensor, msg, t); }
int Controller::nullInputTrans(vector<MessageTuple*>& outMsgs, bool& high_prob, int startIdx ) { outMsgs.clear(); high_prob = true ; if( startIdx < 0 ) return -1; else if( startIdx >= 0 ) { // check for initiation size_t i = 0 ; int count = startIdx; while( i < _busy.size() ) { if( _busy[i] == -1 && _actives[i] == true ) { if (count) count--; else { // merge start event int f = _nbrs[i].front().first ; int b = _nbrs[i].front().second ; // create response int dstId = machineToInt(Lock_Utils::getLockName((int)i)); int dstMsgId = messageToInt("init"); ControllerMessage* initMsg = new ControllerMessage(0,dstId, 0,dstMsgId,macId()); initMsg->addParams(_time, f, b); outMsgs.push_back(initMsg); // Change state _busy[i] = _time ; _time++; return startIdx + 1; } } ++i ; } // the startIdx exceeds the number of available vehicles return -1; } return -1; }
std::string ProtocolWaveman::decodeData(ControllerMessage& dataMsg) { unsigned long allData = 0; unsigned int house = 0; unsigned int unit = 0; unsigned int method = 0; sscanf(dataMsg.getParameter("data").c_str(), "%lx", &allData); method = allData & 0xF00; method >>= 8; unit = allData & 0xF0; unit >>= 4; unit++; house = allData & 0xF; if(house < 0 || house > 16 || unit < 1 || unit > 16){ //not waveman return ""; } house = house + 'A'; //house from A to P if(method != 6 && lastArctecCodeSwitchWasTurnOff == 1){ lastArctecCodeSwitchWasTurnOff = 0; return ""; //probably a stray turnon or bell (perhaps: only certain time interval since last, check that it's the same house/unit... Will lose //one turnon/bell, but it's better than the alternative... } if(method == 6){ lastArctecCodeSwitchWasTurnOff = 1; } std::stringstream retString; retString << "class:command;protocol:waveman;model:codeswitch;house:" << char(house); if(method == 0){ retString << ";unit:" << unit << ";method:turnoff;"; } else if(method == 14){ retString << ";unit:" << unit << ";method:turnon;"; } else { //not waveman return ""; } return retString.str(); }
std::string ProtocolFineoffset::decodeData(const ControllerMessage &dataMsg) { std::string data = dataMsg.getParameter("data"); if (data.length() < 8) { return ""; } // Checksum currently not used // uint8_t checksum = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); data = data.substr(0, data.length()-2); uint8_t humidity = (uint8_t)TelldusCore::hexTo64l(data.substr(data.length()-2)); data = data.substr(0, data.length()-2); uint16_t value = (uint16_t)TelldusCore::hexTo64l(data.substr(data.length()-3)); double temperature = (value & 0x7FF)/10.0; value >>= 11; if (value & 1) { temperature = -temperature; } data = data.substr(0, data.length()-3); uint16_t id = (uint16_t)TelldusCore::hexTo64l(data) & 0xFF; std::stringstream retString; retString << "class:sensor;protocol:fineoffset;id:" << id << ";model:"; if (humidity <= 100) { retString << "temperaturehumidity;humidity:" << static_cast<int>(humidity) << ";"; } else if (humidity == 0xFF) { retString << "temperature;"; } else { return ""; } retString << "temp:" << std::fixed << std::setprecision(1) << temperature << ";"; return retString.str(); }
void SplitAxisModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { float value = msg.get_abs_float(m_axis); if (value < 0) { msg.set_abs_float(m_out_lhs, -value * 2.0f - 1.0f); msg.set_abs_float(m_out_rhs, -1.0f); } else if (value > 0) { msg.set_abs_float(m_out_lhs, -1.0f); msg.set_abs_float(m_out_rhs, value * 2.0f - 1.0f); } else { msg.set_abs_float(m_out_lhs, -1.0f); msg.set_abs_float(m_out_rhs, -1.0f); } }
void set_float(ControllerMessage& msg, float value) { msg.set_abs_float(get_abs(), value); }
std::string ProtocolSartano::decodeData(const ControllerMessage &dataMsg) { uint64_t allDataIn; uint16_t allData = 0; unsigned int code = 0; unsigned int method1 = 0; unsigned int method2 = 0; unsigned int method = 0; allDataIn = dataMsg.getInt64Parameter("data"); uint16_t mask = (1<<11); for(int i = 0; i < 12; ++i) { allData >>= 1; if((allDataIn & mask) == 0) { allData |= (1<<11); } mask >>= 1; } code = allData & 0xFFC; code >>= 2; method1 = allData & 0x2; method1 >>= 1; method2 = allData & 0x1; if(method1 == 0 && method2 == 1) { method = 0; // off } else if(method1 == 1 && method2 == 0) { method = 1; // on } else { return ""; } if(code > 1023) { // not sartano return ""; } std::stringstream retString; retString << "class:command;protocol:sartano;model:codeswitch;code:"; mask = (1<<9); for(int i = 0; i < 10; i++) { if((code & mask) != 0) { retString << 1; } else { retString << 0; } mask >>= 1; } retString << ";method:"; if(method == 0) { retString << "turnoff;"; } else { retString << "turnon;"; } return retString.str(); }
void Button2AxisModifier::update(int msec_delta, ControllerMessage& msg, const ControllerMessageDescriptor& desc) { bool lhs = msg.get_key(m_lhs_btn); bool rhs = msg.get_key(m_rhs_btn); if (lhs && !rhs) { msg.set_abs(m_axis, msg.get_abs_min(m_axis), msg.get_abs_min(m_axis), msg.get_abs_max(m_axis)); } else if (!lhs && rhs) { msg.set_abs(m_axis, msg.get_abs_max(m_axis), msg.get_abs_min(m_axis), msg.get_abs_max(m_axis)); } else { msg.set_abs(m_axis, (msg.get_abs_max(m_axis) - msg.get_abs_min(m_axis))/2, msg.get_abs_min(m_axis), msg.get_abs_max(m_axis)); } }
float get_float(const ControllerMessage& msg) { return msg.get_abs_float(get_abs()); }
int get(const ControllerMessage& msg) { return msg.get_abs(get_abs()); }
void set(ControllerMessage& msg, int value) { msg.set_key(get_key(), value); }
int get(const ControllerMessage& msg) { return msg.get_key(m_key); }
void set(ControllerMessage& msg, int value, int min, int max) { msg.set_abs(get_abs(), value, min, max); }