deviceBinding.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.DeviceBindingModel = void 0;
  4. const database_1 = require("../config/database");
  5. class DeviceBindingModel {
  6. static async getAll() {
  7. const query = `
  8. SELECT db.*, d.device_name as original_device_name, d.status as device_status,
  9. r.name as room_name, r.room_number, r.floor_id
  10. FROM device_bindings db
  11. LEFT JOIN devices d ON db.device_clientid = d.clientid
  12. LEFT JOIN rooms r ON db.room_id = r.id
  13. ORDER BY r.floor_id, r.room_number, db.device_name
  14. `;
  15. return await (0, database_1.executeQuery)(query);
  16. }
  17. static async getByRoomId(roomId) {
  18. const bindings = await (0, database_1.executeQuery)(`
  19. SELECT
  20. db.id,
  21. db.device_clientid as clientid,
  22. db.room_id,
  23. COALESCE(db.device_name, d.device_name, d.clientid) as device_name,
  24. db.device_type,
  25. db.properties,
  26. db.created_at,
  27. db.updated_at,
  28. d.status as device_status,
  29. d.firmware_version,
  30. d.last_ip_port,
  31. d.last_online_time,
  32. d.last_offline_time,
  33. d.rssi
  34. FROM device_bindings db
  35. LEFT JOIN devices d ON db.device_clientid COLLATE utf8mb4_unicode_ci = d.clientid COLLATE utf8mb4_unicode_ci
  36. WHERE db.room_id = ? COLLATE utf8mb4_unicode_ci
  37. ORDER BY db.device_name
  38. `, [roomId]);
  39. for (const binding of bindings) {
  40. const deviceId = binding.clientid;
  41. const tempData = await (0, database_1.executeQuery)(`
  42. SELECT value, timestamp
  43. FROM sensor_data
  44. WHERE device_id = ? AND data_type = 'temperature'
  45. ORDER BY timestamp DESC
  46. LIMIT 1
  47. `, [deviceId]);
  48. const relayData = await (0, database_1.executeQuery)(`
  49. SELECT value, timestamp
  50. FROM sensor_data
  51. WHERE device_id = ? AND data_type = 'relay'
  52. ORDER BY timestamp DESC
  53. LIMIT 1
  54. `, [deviceId]);
  55. if (tempData.length > 0) {
  56. binding.temperature = tempData[0].value;
  57. binding.temperature_timestamp = tempData[0].timestamp;
  58. }
  59. if (relayData.length > 0) {
  60. binding.relay_status = relayData[0].value === 'ON' ? true : false;
  61. binding.relay_timestamp = relayData[0].timestamp;
  62. }
  63. binding.value = {
  64. temperature: tempData.length > 0 ? tempData[0].value : null,
  65. relay: relayData.length > 0 ? (relayData[0].value === 'ON' ? true : false) : false
  66. };
  67. }
  68. return bindings;
  69. }
  70. static async getByDeviceClientId(clientId) {
  71. const query = `
  72. SELECT db.*, d.device_name as original_device_name, d.status as device_status,
  73. r.name as room_name, r.room_number, r.floor_id
  74. FROM device_bindings db
  75. LEFT JOIN devices d ON db.device_clientid = d.clientid
  76. LEFT JOIN rooms r ON db.room_id = r.id
  77. WHERE db.device_clientid = ?
  78. `;
  79. const bindings = await (0, database_1.executeQuery)(query, [clientId]);
  80. return bindings.length > 0 ? bindings[0] : null;
  81. }
  82. static async bindDevice(deviceClientId, roomId) {
  83. const existingBinding = await this.getByDeviceClientId(deviceClientId);
  84. if (existingBinding) {
  85. return this.updateBinding(existingBinding.id, { room_id: roomId });
  86. }
  87. const query = `
  88. INSERT INTO device_bindings (device_clientid, room_id)
  89. VALUES (?, ?)
  90. `;
  91. const values = [deviceClientId, roomId];
  92. const result = await (0, database_1.executeQuery)(query, values);
  93. return this.getByDeviceClientId(deviceClientId);
  94. }
  95. static async bindDeviceWithDetails(bindingData) {
  96. const existingBinding = await this.getByDeviceClientId(bindingData.device_clientid);
  97. if (existingBinding) {
  98. return this.updateBinding(existingBinding.id, bindingData);
  99. }
  100. const query = `
  101. INSERT INTO device_bindings (device_clientid, room_id, device_name, device_type, properties)
  102. VALUES (?, ?, ?, ?, ?)
  103. `;
  104. const values = [
  105. bindingData.device_clientid,
  106. bindingData.room_id,
  107. bindingData.device_name || null,
  108. bindingData.device_type || null,
  109. bindingData.properties ? JSON.stringify(bindingData.properties) : null
  110. ];
  111. const result = await (0, database_1.executeQuery)(query, values);
  112. return this.getByDeviceClientId(bindingData.device_clientid);
  113. }
  114. static async unbindDevice(deviceClientId) {
  115. const query = 'DELETE FROM device_bindings WHERE device_clientid = ?';
  116. const result = await (0, database_1.executeQuery)(query, [deviceClientId]);
  117. return result.affectedRows > 0;
  118. }
  119. static async updateBinding(id, updateData) {
  120. const fields = [];
  121. const values = [];
  122. if (updateData.room_id !== undefined) {
  123. fields.push('room_id = ?');
  124. values.push(updateData.room_id);
  125. }
  126. if (updateData.device_name !== undefined) {
  127. fields.push('device_name = ?');
  128. values.push(updateData.device_name);
  129. }
  130. if (updateData.device_type !== undefined) {
  131. fields.push('device_type = ?');
  132. values.push(updateData.device_type);
  133. }
  134. if (updateData.properties !== undefined) {
  135. fields.push('properties = ?');
  136. values.push(updateData.properties ? JSON.stringify(updateData.properties) : null);
  137. }
  138. fields.push('updated_at = NOW()');
  139. values.push(id);
  140. const query = `
  141. UPDATE device_bindings
  142. SET ${fields.join(', ')}
  143. WHERE id = ?
  144. `;
  145. await (0, database_1.executeQuery)(query, values);
  146. const bindingQuery = 'SELECT device_clientid FROM device_bindings WHERE id = ?';
  147. const binding = await (0, database_1.executeQuery)(bindingQuery, [id]);
  148. if (binding.length > 0) {
  149. return this.getByDeviceClientId(binding[0].device_clientid);
  150. }
  151. throw new Error('Failed to retrieve updated binding');
  152. }
  153. static async getAvailableDevices() {
  154. const query = `
  155. SELECT d.* FROM devices d
  156. LEFT JOIN device_bindings db ON d.clientid COLLATE utf8mb4_unicode_ci = db.device_clientid COLLATE utf8mb4_unicode_ci
  157. WHERE db.device_clientid IS NULL
  158. ORDER BY d.device_name, d.clientid
  159. `;
  160. return await (0, database_1.executeQuery)(query);
  161. }
  162. static async getRoomDevicesWithDetails(roomId) {
  163. const query = `
  164. SELECT
  165. d.clientid,
  166. d.device_name as original_device_name,
  167. d.status as device_status,
  168. d.firmware_version,
  169. d.last_ip_port,
  170. d.last_online_time,
  171. d.last_offline_time,
  172. d.online_duration,
  173. d.connect_count,
  174. d.rssi,
  175. db.device_name,
  176. db.device_type,
  177. db.properties,
  178. r.name as room_name,
  179. r.floor_id
  180. FROM device_bindings db
  181. LEFT JOIN devices d ON db.device_clientid COLLATE utf8mb4_unicode_ci = d.clientid COLLATE utf8mb4_unicode_ci
  182. LEFT JOIN rooms r ON db.room_id = r.id
  183. WHERE db.room_id = ?
  184. ORDER BY db.device_name
  185. `;
  186. return await (0, database_1.executeQuery)(query, [roomId]);
  187. }
  188. static async getDevicesByRoomId(roomId) {
  189. const query = `
  190. SELECT
  191. d.clientid,
  192. d.device_name,
  193. d.username,
  194. d.status,
  195. d.firmware_version,
  196. d.device_ip_port,
  197. d.last_ip_port,
  198. d.last_event_time,
  199. d.last_online_time,
  200. d.last_offline_time,
  201. d.online_duration,
  202. d.connect_count,
  203. d.rssi,
  204. d.created_at,
  205. d.updated_at,
  206. db.device_name as room_device_name,
  207. db.device_type as room_device_type,
  208. db.properties
  209. FROM device_bindings db
  210. LEFT JOIN devices d ON db.device_clientid COLLATE utf8mb4_unicode_ci = d.clientid COLLATE utf8mb4_unicode_ci
  211. WHERE db.room_id = ?
  212. ORDER BY d.device_name
  213. `;
  214. return await (0, database_1.executeQuery)(query, [roomId]);
  215. }
  216. static async getUnboundDevices() {
  217. const query = `
  218. SELECT
  219. d.clientid,
  220. d.device_name,
  221. d.username,
  222. d.status,
  223. d.firmware_version,
  224. d.device_ip_port,
  225. d.last_ip_port,
  226. d.last_event_time,
  227. d.last_online_time,
  228. d.last_offline_time,
  229. d.online_duration,
  230. d.connect_count,
  231. d.created_at,
  232. d.updated_at
  233. FROM devices d
  234. LEFT JOIN device_bindings db ON d.clientid COLLATE utf8mb4_unicode_ci = db.device_clientid COLLATE utf8mb4_unicode_ci
  235. WHERE db.device_clientid IS NULL
  236. ORDER BY d.device_name, d.clientid
  237. `;
  238. return await (0, database_1.executeQuery)(query);
  239. }
  240. static async getAllDevicesWithBindingStatus(page = 1, pageSize = 10, filters = {}) {
  241. const offset = (page - 1) * pageSize;
  242. const conditions = [];
  243. const params = [];
  244. if (filters.status) {
  245. conditions.push('d.status = ?');
  246. params.push(filters.status);
  247. }
  248. if (filters.room_id) {
  249. conditions.push('db.room_id = ?');
  250. params.push(filters.room_id);
  251. }
  252. if (filters.search) {
  253. const searchTerm = `%${filters.search}%`;
  254. conditions.push('(d.clientid LIKE ? OR d.device_name LIKE ? OR d.username LIKE ? OR r.name LIKE ?)');
  255. params.push(searchTerm, searchTerm, searchTerm, searchTerm);
  256. }
  257. const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
  258. const query = `
  259. SELECT
  260. d.*,
  261. db.id as binding_id,
  262. db.room_id,
  263. db.device_name as room_device_name,
  264. db.device_type as room_device_type,
  265. r.name as room_name,
  266. r.room_number,
  267. r.floor_id
  268. FROM devices d
  269. LEFT JOIN device_bindings db ON d.clientid COLLATE utf8mb4_unicode_ci = db.device_clientid COLLATE utf8mb4_unicode_ci
  270. LEFT JOIN rooms r ON db.room_id = r.id
  271. ${whereClause}
  272. ORDER BY d.device_name, d.clientid
  273. LIMIT ? OFFSET ?
  274. `;
  275. params.push(pageSize, offset);
  276. const countQuery = `
  277. SELECT COUNT(DISTINCT d.id) as total
  278. FROM devices d
  279. LEFT JOIN device_bindings db ON d.clientid COLLATE utf8mb4_unicode_ci = db.device_clientid COLLATE utf8mb4_unicode_ci
  280. LEFT JOIN rooms r ON db.room_id = r.id
  281. ${whereClause}
  282. `;
  283. const countParams = conditions.length > 0 ? params.slice(0, -2) : [];
  284. const [devices, countResult] = await Promise.all([
  285. (0, database_1.executeQuery)(query, params),
  286. (0, database_1.executeQuery)(countQuery, countParams)
  287. ]);
  288. for (const device of devices) {
  289. const deviceId = device.clientid;
  290. const tempData = await (0, database_1.executeQuery)(`
  291. SELECT value, timestamp
  292. FROM sensor_data
  293. WHERE device_id = ? AND data_type = 'temperature'
  294. ORDER BY timestamp DESC
  295. LIMIT 1
  296. `, [deviceId]);
  297. const relayData = await (0, database_1.executeQuery)(`
  298. SELECT value, timestamp
  299. FROM sensor_data
  300. WHERE device_id = ? AND data_type = 'relay'
  301. ORDER BY timestamp DESC
  302. LIMIT 1
  303. `, [deviceId]);
  304. if (tempData.length > 0) {
  305. device.temperature = tempData[0].value;
  306. device.temperature_timestamp = tempData[0].timestamp;
  307. }
  308. if (relayData.length > 0) {
  309. device.relay_status = relayData[0].value === 'ON' ? true : false;
  310. device.relay_timestamp = relayData[0].timestamp;
  311. }
  312. device.value = {
  313. temperature: tempData.length > 0 ? tempData[0].value : null,
  314. relay: relayData.length > 0 ? (relayData[0].value === 'ON' ? true : false) : false
  315. };
  316. }
  317. return {
  318. devices,
  319. total: countResult[0].total
  320. };
  321. }
  322. static async updateDeviceValue(deviceClientId, value) {
  323. const query = `
  324. UPDATE devices
  325. SET value = ?
  326. WHERE clientid = ?
  327. `;
  328. const result = await (0, database_1.executeQuery)(query, [value, deviceClientId]);
  329. return result.affectedRows > 0;
  330. }
  331. }
  332. exports.DeviceBindingModel = DeviceBindingModel;
  333. //# sourceMappingURL=deviceBinding.js.map