You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
9.7 KiB

3 years ago
3 years ago
  1. #include "device_io_service.hpp"
  2. #include "iflytopcpp/core/components/stringutils.hpp"
  3. #include "iflytopcpp/core/components/timeutils.hpp"
  4. #include "iflytopcpp/core/zexception/zexception.hpp"
  5. using namespace iflytop;
  6. using namespace core;
  7. using namespace std;
  8. const static int ksubboarddeviceid = 0x01;
  9. const int kovertime = 33;
  10. #define EXEC_MODBUS(exptr) \
  11. int ret = exptr; \
  12. if (ret != 0) { \
  13. throw zexception( \
  14. fmt::format("[{}:{}] do {} fail, ret={},{}", __FUNCTION__, __LINE__, #exptr, ret, modbusStatusToStr(ret))); \
  15. }
  16. void DeviceIOService::initialize(string uartpath, int baudrate) {
  17. modbusMaster = shared_ptr<ModbusMaster>(new ModbusMaster());
  18. bool suc = modbusMaster->initializeTtyChannel(uartpath.c_str(), baudrate);
  19. if (!suc) {
  20. logger->error("modbusMaster initializeTtyChannel fail");
  21. }
  22. #if 0
  23. thread.reset(new Thread("input_device_state_monitor", [this]() { inputStateMonitorLoop(); }));
  24. idcard_read_thread.reset(new Thread("idcard_read", [this]() {idcardreadLoop();}));
  25. #endif
  26. }
  27. void DeviceIOService::relayControl(uint32_t type, bool value) {
  28. /**
  29. * @brief
  30. * 8(16Byte) | 0 ->15
  31. * 9(16Byte) | 16->31
  32. * 10(16Byte) | 0 ->15
  33. * 11(16Byte) | 16->31
  34. */
  35. uint32_t off = (uint32_t)type;
  36. uint32_t mask = 1 << off;
  37. uint32_t status = value ? mask : 0;
  38. uint16_t reg[4];
  39. MODBUS_SET_REG(reg[0], uint16_t(mask));
  40. MODBUS_SET_REG(reg[1], uint16_t(mask >> 16));
  41. MODBUS_SET_REG(reg[2], uint16_t(status));
  42. MODBUS_SET_REG(reg[3], uint16_t(status >> 16));
  43. EXEC_MODBUS(modbusMaster->modbus10(ksubboarddeviceid, 8, 4, reg, kovertime));
  44. }
  45. DeviceIOService::RelayDeviceState DeviceIOService::relayStateGet() {
  46. /**
  47. * @brief
  48. * 8(16Byte) | 0 ->15
  49. * 9(16Byte) | 16->31
  50. * 10(16Byte) | 0 ->15
  51. * 11(16Byte) | 16->31
  52. */
  53. DeviceIOService::RelayDeviceState state = {};
  54. Modbus03Rx modbus03rx;
  55. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, 10, 2, modbus03rx, kovertime));
  56. uint32_t regstate = uint32_t(modbus03rx.getReg(10)) | uint32_t(modbus03rx.getReg(11) << 16);
  57. state.state = regstate;
  58. return state;
  59. }
  60. uint16_t DeviceIOService::getReg(int index) {
  61. Modbus03Rx modbus03rx;
  62. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, index, 1, modbus03rx, kovertime));
  63. return modbus03rx.getReg(index);
  64. }
  65. DeviceIOService::InputDeviceState DeviceIOService::getinputState() {
  66. #if 0
  67. :
  68. Addr |
  69. ------------|-------------------------------
  70. 12(16Byte) |
  71. #endif
  72. DeviceIOService::InputDeviceState inputDeviceState;
  73. Modbus03Rx modbus03rx;
  74. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, 12, 1, modbus03rx, kovertime));
  75. uint32_t regstate = uint32_t(modbus03rx.getReg(12)) | 0;
  76. inputDeviceState.state = regstate;
  77. return inputDeviceState;
  78. }
  79. uint32_t DeviceIOService::getInterTemperature() { return getReg(16); }
  80. DeviceIOService::env_sensor_state_t DeviceIOService::getEnvSensorState() {
  81. Modbus03Rx modbus03rx;
  82. env_sensor_state_t env_sensor_state = {0};
  83. /**
  84. 48(16Byte) |
  85. 49(16Byte) |
  86. 50(16Byte) | temperature 湿=temperature/10
  87. 51(16Byte) | humidity 湿=humidity/10 (0->100%)
  88. 52(16Byte) |
  89. 53(16Byte) | pm2.5 ug/m³
  90. 54(16Byte) | pm10 ug/m³
  91. 55(16Byte) | co2 PPM
  92. 56(16Byte) | PPM
  93. 57(16Byte) | tvoc ppm
  94. 58(16Byte) | hcho mg/m3
  95. 59(16Byte) | light_intensity H
  96. 60(16Byte) | light_intensity L
  97. */
  98. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, 48, 13, modbus03rx, kovertime));
  99. env_sensor_state.wind_speed = modbus03rx.getReg(48);
  100. env_sensor_state.wind_direction = modbus03rx.getReg(49);
  101. env_sensor_state.temperature = modbus03rx.getReg(50);
  102. env_sensor_state.humidity = modbus03rx.getReg(51);
  103. env_sensor_state.noise = modbus03rx.getReg(52);
  104. env_sensor_state.pm2_5 = modbus03rx.getReg(53);
  105. env_sensor_state.pm10 = modbus03rx.getReg(54);
  106. env_sensor_state.co2 = modbus03rx.getReg(55);
  107. env_sensor_state.atmospheric_pressure = modbus03rx.getReg(56);
  108. env_sensor_state.tvoc = modbus03rx.getReg(57);
  109. env_sensor_state.hcho = modbus03rx.getReg(58);
  110. env_sensor_state.light_intensity = uint32_t(modbus03rx.getReg(59)) << 16 | uint32_t(modbus03rx.getReg(60));
  111. logger->debug(
  112. "getEnvSensorState, "
  113. "wind_speed={},wind_direction={},temperature={},humidity={},noise={},pm2_5={},pm10={},co2={},atmospheric_"
  114. "pressure={},tvoc={},hcho={}",
  115. env_sensor_state.wind_speed, env_sensor_state.wind_direction, env_sensor_state.temperature,
  116. env_sensor_state.humidity, env_sensor_state.noise, env_sensor_state.pm2_5, env_sensor_state.pm10,
  117. env_sensor_state.co2, env_sensor_state.atmospheric_pressure, env_sensor_state.tvoc, env_sensor_state.hcho);
  118. return env_sensor_state;
  119. }
  120. void DeviceIOService::fanGetState(int id, float& power, uint16_t& error) {
  121. int startindex = 0;
  122. if (id == 0) {
  123. startindex = 128;
  124. } else if (id == 1) {
  125. startindex = 136;
  126. } else {
  127. power = 0;
  128. error = 0;
  129. logger->error("fanGetState fail, id={},id is illegal", id);
  130. }
  131. Modbus03Rx modbus03rx;
  132. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, startindex, 2, modbus03rx, kovertime));
  133. power = modbus03rx.getReg(startindex);
  134. error = modbus03rx.getReg(startindex + 1);
  135. logger->debug("fanGetState, id={},power={},error={}", id, power, error);
  136. return;
  137. }
  138. void DeviceIOService::fanSetState(int id, float power) {
  139. logger->debug("fanSetState, id={},power={}", id, power);
  140. int startindex = 0;
  141. if (id == 0) {
  142. startindex = 128;
  143. } else if (id == 1) {
  144. startindex = 136;
  145. } else {
  146. logger->error("fanGetState fail, id={},id is illegal", id);
  147. return;
  148. }
  149. uint16_t reg[1];
  150. MODBUS_SET_REG(reg[0], uint16_t(power));
  151. EXEC_MODBUS(modbusMaster->modbus10(ksubboarddeviceid, startindex, 1, reg, kovertime));
  152. return;
  153. }
  154. void DeviceIOService::idcardread(bool& state, string& info) {
  155. /**
  156. * 64->127 | ,03,10
  157. * 64(16Byte) |
  158. * 65(16Byte) |
  159. * 65(16Byte) |
  160. * ..(16Byte) |
  161. * 127(16Byte) |
  162. */
  163. state = false;
  164. info = "";
  165. int datalen = 0;
  166. {
  167. Modbus03Rx modbus03rx;
  168. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, 64, 1, modbus03rx, kovertime));
  169. datalen = modbus03rx.getReg(64);
  170. }
  171. if (datalen == 0) {
  172. logger->debug("idcardread, state={},info={}", state, info);
  173. return;
  174. }
  175. int readreg = datalen / 2 + datalen % 2 != 0 ? 1 : 0;
  176. {
  177. Modbus03Rx modbus03rx;
  178. EXEC_MODBUS(modbusMaster->modbus03(ksubboarddeviceid, 65, readreg, modbus03rx, kovertime));
  179. info = StringUtils().bytesToString(modbus03rx.getRegBegin(), datalen);
  180. }
  181. state = true;
  182. logger->debug("idcardread, state={},info={}", state, info);
  183. return;
  184. }
  185. /*************************************************************************************
  186. * *
  187. * MODBUS直接调用接口 *
  188. * *
  189. *************************************************************************************/
  190. float DeviceIOService::fanGetState(int id) {
  191. float power = 0;
  192. uint16_t error = 0;
  193. fanGetState(id, power, error);
  194. if (error != 0) {
  195. return -1;
  196. }
  197. return power;
  198. }
  199. void DeviceIOService::inputStateMonitorLoop() {
  200. ThisThread thisThread;
  201. int loopperiod = 50;
  202. while (!thisThread.getExitFlag()) {
  203. try {
  204. uint32_t newkeystate = getinputState().state;
  205. for (size_t i = 0; i < 32; i++) {
  206. bool state = (newkeystate & (1 << i)) != 0;
  207. bool oldstate = (keystate & (1 << i)) != 0;
  208. if (state != oldstate) {
  209. logger->info("on {} state change, state={}", input_device_type2str(input_device_type_t(i)), state);
  210. onInputStateChange((input_device_type_t)i, state);
  211. }
  212. }
  213. keystate = newkeystate;
  214. loopperiod = 50;
  215. } catch (const std::exception& e) {
  216. /**
  217. * @brief 10
  218. */
  219. logger->error("[:{}] catch exception, {}", __LINE__, e.what());
  220. loopperiod = 10000;
  221. } catch (...) {
  222. logger->error("[:{}] catch exception, unknown error", __LINE__);
  223. loopperiod = 10000;
  224. }
  225. thisThread.sleepForMs(loopperiod);
  226. }
  227. }
  228. void DeviceIOService::idcardreadLoop() {
  229. ThisThread thisThread;
  230. int loopperiod = 50;
  231. while (!thisThread.getExitFlag()) {
  232. try {
  233. bool state;
  234. string info;
  235. idcardread(state, info);
  236. if (state) {
  237. logger->info("idcard read info:{}", info);
  238. onidcard(info);
  239. }
  240. loopperiod = 50;
  241. } catch (zexception& e) {
  242. logger->error("idcard read fail:{}", e.what());
  243. loopperiod = 10000;
  244. }
  245. thisThread.sleepForMs(loopperiod);
  246. }
  247. }