Bläddra i källkod

南瑞网关备份

xhj 1 dag sedan
förälder
incheckning
63318283cc

BIN
.ninja_deps


+ 49 - 97
.ninja_log

@@ -2,28 +2,28 @@
 229	19702	7725187506183551	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/report/MyIec61850Server.cpp.o	8c8a43e9c83cbe39
 249	4681	7691620005960781	modules/gateway-basic/CMakeFiles/gateway-basic.dir/src/utils/ThreadUtils.cpp.o	5d6f9aa9d944d2fb
 61	4766	7713956890633987	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/insulated-switch-server/insulated_switch_server.cpp.o	6debb6056819d6de
-112	13421	7693237478779411	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/FlowerOperatorRepository.cpp.o	233fc5403da47fc5
+26721	36829	7725188575712118	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/FlowerOperatorRepository.cpp.o	233fc5403da47fc5
 286	5142	7691620006330796	modules/gateway-basic/CMakeFiles/gateway-basic.dir/src/utils/TimeUtils.cpp.o	95636d2c4ca71b0b
 103	5356	7725187504936335	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/executant/GPIOExecutant.cpp.o	893c68b9cd60acae
 129	6628	7691620004759231	modules/gateway-basic/CMakeFiles/gateway-basic.dir/src/utils/JsonUtils.cpp.o	9cf481573112ce8e
 168	9496	7691620005149262	modules/gateway-basic/CMakeFiles/gateway-basic.dir/src/utils/RedisUtils.cpp.o	f7d32068021064aa
 80	7925	7691620004303970	modules/gateway-basic/CMakeFiles/gateway-basic.dir/src/service/RedisService.cpp.o	fde1f11b47c774fb
-86	13556	7693237478529220	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/FlowerNodeRepository.cpp.o	494298649b2ef9bc
+26615	36970	7725188574646189	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/FlowerNodeRepository.cpp.o	494298649b2ef9bc
 70	5181	7725187504608639	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/executant/BasicExecutant.cpp.o	d7958f5e095708f6
 212	11890	7691620005580642	modules/gateway-basic/CMakeFiles/gateway-basic.dir/src/utils/StringUtils.cpp.o	3455906afd556d5d
-490	26034	7693234381769501	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/FlowerOperatorController.cpp.o	9e70dc771e46a6ed
+268	27595	7725188311167611	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/FlowerOperatorController.cpp.o	9e70dc771e46a6ed
 11892	13391	7691620122386315	deploy/library/libgateway-basic.so	a41b40461b2daf81
-196	11613	7725187505858399	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/main.cpp.o	4edd25c30a70ee81
+99	6352	7757302508858335	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/main.cpp.o	4edd25c30a70ee81
 347	9070	7725187507379451	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleDeviceCommunicationRepository.cpp.o	2dafd0bf2b8e5e58
 390	9119	7725187507805560	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleDeviceProtocolRepository.cpp.o	5ec11890d69fb2d0
 9168	14931	7725187595579157	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleCommunicationService.cpp.o	e5ce0e16cfd3b4d0
 5182	9548	7725187555720389	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/CalculateService.cpp.o	c90b26f4dff37da2
-22623	24113	7693234603094503	modules/gateway-server/CMakeFiles/gateway-server.dir/src/main.cpp.o	4bd0c13801b7615a
+22179	23990	7725188530283234	modules/gateway-server/CMakeFiles/gateway-server.dir/src/main.cpp.o	4bd0c13801b7615a
 421	9167	7725187508110820	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleDeviceRepository.cpp.o	f1a247a78d6186d7
 137	17598	7725187505268349	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/executant/ModbusExecutant.cpp.o	b381e1cf0fe99883
 9120	22758	7725187595099164	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/QueueService.cpp.o	88acd5ec7d4bacae
 493	10777	7725187508830844	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleTaskFormatterRepository.cpp.o	b31a3da0e8ff7f9f
-25623	32153	7693234633098131	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceRepository.cpp.o	6a9c6dc336f49823
+26423	37263	7725188572724291	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceRepository.cpp.o	6a9c6dc336f49823
 521	10721	7725187509101241	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleTaskRepository.cpp.o	c8fce6244c833d55
 5358	15060	7725187557482505	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/FlowerExecutorService.cpp.o	99db711d5addf15e
 9549	14986	7725187599386908	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleDeviceCommunicationService.cpp.o	6e4ed4e4ef97649f
@@ -32,126 +32,78 @@
 10722	16616	7725187611128028	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleDeviceProtocolService.cpp.o	2b6875a00b33dc78
 10778	16911	7725187611678045	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleDeviceService.cpp.o	2752b0acd445c9c7
 11614	17862	7725187620043144	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleProtocolService.cpp.o	de175f9c3841b6ba
-61	13507	7693237478271719	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/ExecutorRepository.cpp.o	c7a99916ca640505
+26558	37789	7725188574076137	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/ExecutorRepository.cpp.o	c7a99916ca640505
 9071	19046	7725187594613623	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/FormatterExecutorService.cpp.o	e19a30a4e763f3d4
 16912	18285	7725187673022106	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/utils/HashUtils.cpp.o	99a36625c566d329
 305	24032	7725187506953958	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleCommunicationRepository.cpp.o	2f30878c2bf5c9f2
 264	21977	7725187506543455	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/report/TaskReportService.cpp.o	fdb5dbe067f415ad
-133	22622	7693234378187973	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DashboardDeviceHistoryController.cpp.o	609d7e8616d2e027
-195	25622	7693234378813505	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceCommunicationController.cpp.o	7869e4aafe3f0751
+98	22178	7725188309464513	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DashboardDeviceHistoryController.cpp.o	609d7e8616d2e027
+125	26422	7725188309744696	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceCommunicationController.cpp.o	7869e4aafe3f0751
 14932	22603	7725187653229656	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleTaskFormatterService.cpp.o	cd4625953f7043b0
 15061	23558	7725187654512454	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/TaskExecutorService.cpp.o	bcd1dbd7090d01c0
 462	23939	7725187508520832	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/repository/ScheduleProtocolRepository.cpp.o	3aaf10c249eda0fa
-16617	26786	7725187670071892	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
+76	7438	7753830528873798	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
 12869	30079	7725187632592549	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/service/ScheduleService.cpp.o	1eb6b9ea730c9467
-293	11083	7693237480593128	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/CommunicationService.cpp.o	2041fa7ba093b046
-3518	4591	7719367612661229	deploy/bin/gateway-scheduler	399acf951fc7de84
-191	15276	7693237479564856	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/TaskRepository.cpp.o	6e0681073bd91793
-365	21180	7693234380520195	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/ExecutorController.cpp.o	a7fc8017e09a004f
-623	22319	7693234383107329	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/RedisCacheController.cpp.o	590f8c53ce8621cf
-687	22890	7693234383750874	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/RedisReportCacheController.cpp.o	989a2c9c28564ed7
-89	23665	7693234377752850	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DashboardDeviceController.cpp.o	31ad4be0c512f625
-422	26024	7693234381119309	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/FlowerNodeController.cpp.o	40608f0dbb6a72bf
-257	26130	7693234379438543	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceController.cpp.o	bf3ea8515f11c96f
-25568	31778	7693234632552893	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceProtocolRepository.cpp.o	7eac28e6cf344653
-319	25567	7693234380087887	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceProtocolController.cpp.o	50cbbd9e87268343
-50	26659	7693234377358677	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/CommunicationController.cpp.o	838a5e0d6eb18825
-557	26601	7693234382448718	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/ProtocolController.cpp.o	8335f95c50e52873
-217	13696	7693237479825949	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/UserRepository.cpp.o	8848a32b5b9e5dd3
-824	28361	7693234385106085	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/TaskFormatterController.cpp.o	e6cbc0e76c930217
-756	29480	7693234384434539	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/TaskController.cpp.o	90d044655ee89d22
-24114	30895	7693234618004503	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceCommunicationRepository.cpp.o	2ec071e68ac3bd88
-23666	30893	7693234613528271	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DashboardDeviceHistoryRepository.cpp.o	2e93b71537372f8
-165	15157	7693237479307511	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/TaskFormatterRepository.cpp.o	89cfe1dd34b3b8ac
-319	10605	7693237480853071	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DashboardDeviceHistoryService.cpp.o	fc9e49560a5e31d1
-370	10815	7693237481363335	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DeviceCommunicationService.cpp.o	bcefd60e0924624c
-10608	16910	7693237583744507	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DeviceProtocolService.cpp.o	5c7ae9502624e799
-10816	16990	7693237585829003	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DeviceService.cpp.o	1385ef52e5633e59
-11085	15547	7693237588517311	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/ExecutorService.cpp.o	c0a13ca6c85a5bf6
-15158	25660	7693237629253438	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/RedisReportCacheService.cpp.o	56450d89e102d75c
-102	6034	7711605324284050	modules/gateway-server/CMakeFiles/gateway-server.dir/src/server/BasicServer.cpp.o	3a059b9bc50684e9
-13422	19258	7693237611878386	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/FlowerNodeService.cpp.o	de3b010aaccdaf3f
-21183	37230	7693234588695689	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/UserController.cpp.o	59ff219136851c98
-242	18913	7693237480079505	modules/gateway-server/CMakeFiles/gateway-server.dir/src/server/BasicRouter.cpp.o	6b318a01684442a5
-13508	19365	7693237612751093	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/FlowerOperatorService.cpp.o	52d4734515aa9129
-13697	19358	7693237614634081	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/RedisCacheService.cpp.o	728b74b27c194261
-13557	20253	7693237613232217	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/ProtocolService.cpp.o	5666432150f2aa35
-22891	39137	7693234605765311	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/CommunicationRepository.cpp.o	32644d195faed402
-15548	20990	7693237633138437	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/UserService.cpp.o	a1eb9022e1ce919
-15277	22541	7693237630437118	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/TaskFormatterService.cpp.o	2b681b720ee5565d
-137	25667	7693237479032802	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/ProtocolRepository.cpp.o	c85c732f030cc6f6
-15424	22892	7693237631909631	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/TaskService.cpp.o	e3eabcaf25bac6e2
-345	21002	7693237481111927	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DashboardDeviceService.cpp.o	7dd237d8a43ca343
-6036	8182	7711605383631211	deploy/bin/gateway-server	ce0929752e1db5b2
-54	371	7725187999211506	build.ninja	6a763902b4018f1
-65	14786	7711585551315968	modules/gateway-server/CMakeFiles/gateway-server.dir/src/large_screen_display/devices_info.cpp.o	690840fd0b4fbc98
-167	1893	7725187505568479	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/lora_server/LoRaServer.cpp.o	fc2812624c6741a
-13	152	7691619997487718	clean	92ade73078083541
-50	3515	7719367577978767	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/insulated-switch-server/SerialWriterThread.cpp.o	d98f59d899431c04
-57	7365	7725188101122027	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/command_poller/command_poller.cpp.o	29745cbcddd17a4d
-7366	8359	7725188174212089	deploy/bin/gateway-scheduler	c90563d061dbec8d
+35402	42378	7725188662507020	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/CommunicationService.cpp.o	2041fa7ba093b046
+7439	8598	7753830602489860	deploy/bin/gateway-scheduler	e5555994825e06a
+30149	41771	7725188609983642	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/TaskRepository.cpp.o	6e0681073bd91793
 213	20577	7725188310616391	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/ExecutorController.cpp.o	a7fc8017e09a004f
 323	22121	7725188311717568	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/RedisCacheController.cpp.o	590f8c53ce8621cf
-98	22178	7725188309464513	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DashboardDeviceHistoryController.cpp.o	609d7e8616d2e027
-71	22366	7725188309194582	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DashboardDeviceController.cpp.o	31ad4be0c512f625
 353	22667	7725188312022802	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/RedisReportCacheController.cpp.o	989a2c9c28564ed7
-22179	23990	7725188530283234	modules/gateway-server/CMakeFiles/gateway-server.dir/src/main.cpp.o	4bd0c13801b7615a
-154	26009	7725188310026383	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceController.cpp.o	bf3ea8515f11c96f
-125	26422	7725188309744696	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceCommunicationController.cpp.o	7869e4aafe3f0751
+71	22366	7725188309194582	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DashboardDeviceController.cpp.o	31ad4be0c512f625
 239	26557	7725188310877600	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/FlowerNodeController.cpp.o	40608f0dbb6a72bf
-43	26614	7725188308914707	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/CommunicationController.cpp.o	838a5e0d6eb18825
+154	26009	7725188310026383	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceController.cpp.o	bf3ea8515f11c96f
+26011	35401	7725188568596042	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceProtocolRepository.cpp.o	7eac28e6cf344653
 184	26720	7725188310326401	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/DeviceProtocolController.cpp.o	50cbbd9e87268343
+43	26614	7725188308914707	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/CommunicationController.cpp.o	838a5e0d6eb18825
 296	27272	7725188311447583	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/ProtocolController.cpp.o	8335f95c50e52873
-268	27595	7725188311167611	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/FlowerOperatorController.cpp.o	9e70dc771e46a6ed
+31526	41103	7725188623757179	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/UserRepository.cpp.o	8848a32b5b9e5dd3
 415	30148	7725188312642795	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/TaskFormatterController.cpp.o	e6cbc0e76c930217
 386	31525	7725188312342786	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/TaskController.cpp.o	90d044655ee89d22
-22669	33975	7725188535180953	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DashboardDeviceHistoryRepository.cpp.o	2e93b71537372f8
 23991	34087	7725188548395078	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceCommunicationRepository.cpp.o	2ec071e68ac3bd88
-26011	35401	7725188568596042	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceProtocolRepository.cpp.o	7eac28e6cf344653
-26721	36829	7725188575712118	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/FlowerOperatorRepository.cpp.o	233fc5403da47fc5
-26615	36970	7725188574646189	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/FlowerNodeRepository.cpp.o	494298649b2ef9bc
-26423	37263	7725188572724291	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DeviceRepository.cpp.o	6a9c6dc336f49823
-26558	37789	7725188574076137	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/ExecutorRepository.cpp.o	c7a99916ca640505
+22669	33975	7725188535180953	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/DashboardDeviceHistoryRepository.cpp.o	2e93b71537372f8
 27596	38848	7725188584454149	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/TaskFormatterRepository.cpp.o	89cfe1dd34b3b8ac
-31526	41103	7725188623757179	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/UserRepository.cpp.o	8848a32b5b9e5dd3
-30149	41771	7725188609983642	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/TaskRepository.cpp.o	6e0681073bd91793
-35402	42378	7725188662507020	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/CommunicationService.cpp.o	2041fa7ba093b046
 36830	42561	7725188676795909	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DashboardDeviceHistoryService.cpp.o	fc9e49560a5e31d1
 37264	42982	7725188681136671	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DeviceCommunicationService.cpp.o	bcefd60e0924624c
 37790	43639	7725188686394202	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DeviceProtocolService.cpp.o	5c7ae9502624e799
 38848	44572	7725188696974536	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DeviceService.cpp.o	1385ef52e5633e59
 41104	45365	7725188719530531	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/ExecutorService.cpp.o	c0a13ca6c85a5bf6
+43640	54484	7725188744895154	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/RedisReportCacheService.cpp.o	56450d89e102d75c
+78	10901	7751307274501560	modules/gateway-server/CMakeFiles/gateway-server.dir/src/server/BasicServer.cpp.o	3a059b9bc50684e9
 41772	47217	7725188726216776	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/FlowerNodeService.cpp.o	de3b010aaccdaf3f
-42378	47790	7725188732283142	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/FlowerOperatorService.cpp.o	52d4734515aa9129
 20580	48004	7725188514326331	modules/gateway-server/CMakeFiles/gateway-server.dir/src/controller/UserController.cpp.o	59ff219136851c98
+33976	49462	7725188648257125	modules/gateway-server/CMakeFiles/gateway-server.dir/src/server/BasicRouter.cpp.o	6b318a01684442a5
+42378	47790	7725188732283142	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/FlowerOperatorService.cpp.o	52d4734515aa9129
 42983	48164	7725188738331704	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/RedisCacheService.cpp.o	728b74b27c194261
 42561	48819	7725188734105513	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/ProtocolService.cpp.o	5666432150f2aa35
-33976	49462	7725188648257125	modules/gateway-server/CMakeFiles/gateway-server.dir/src/server/BasicRouter.cpp.o	6b318a01684442a5
 22367	50837	7725188532164392	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/CommunicationRepository.cpp.o	32644d195faed402
 47218	51387	7725188780669705	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/UserService.cpp.o	a1eb9022e1ce919
 44573	51487	7725188754230705	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/TaskFormatterService.cpp.o	2b681b720ee5565d
-34088	52115	7725188649372675	modules/gateway-server/CMakeFiles/gateway-server.dir/src/server/BasicServer.cpp.o	3a059b9bc50684e9
-45366	52295	7725188762161434	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/TaskService.cpp.o	e3eabcaf25bac6e2
-22122	52567	7725188529716814	modules/gateway-server/CMakeFiles/gateway-server.dir/src/large_screen_display/devices_info.cpp.o	690840fd0b4fbc98
 27273	52577	7725188581229401	modules/gateway-server/CMakeFiles/gateway-server.dir/src/repository/ProtocolRepository.cpp.o	c85c732f030cc6f6
+45366	52295	7725188762161434	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/TaskService.cpp.o	e3eabcaf25bac6e2
 36971	52763	7725188678200433	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/DashboardDeviceService.cpp.o	7dd237d8a43ca343
-43640	54484	7725188744895154	modules/gateway-server/CMakeFiles/gateway-server.dir/src/service/RedisReportCacheService.cpp.o	56450d89e102d75c
-54484	56043	7725188853327859	deploy/bin/gateway-server	ce0929752e1db5b2
-98	7832	7726074126907727	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-7834	9100	7726074204270162	deploy/bin/gateway-scheduler	c90563d061dbec8d
-83	8456	7726087408301884	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-8458	9820	7726087492052829	deploy/bin/gateway-scheduler	c90563d061dbec8d
-96	7780	7727758019514187	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-7781	8979	7727758096357330	deploy/bin/gateway-scheduler	c90563d061dbec8d
-74	7091	7729529801569994	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-7092	8273	7729529871752258	deploy/bin/gateway-scheduler	c90563d061dbec8d
-55	7828	7729531708395979	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-7831	9038	7729531786173204	deploy/bin/gateway-scheduler	c90563d061dbec8d
-52	7962	7729532129738239	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-7965	9192	7729532208861542	deploy/bin/gateway-scheduler	c90563d061dbec8d
-52	6947	7729536897285531	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-6949	8079	7729536966247412	deploy/bin/gateway-scheduler	c90563d061dbec8d
-54	7352	7729539108870658	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-7354	8478	7729539181873181	deploy/bin/gateway-scheduler	c90563d061dbec8d
-49	6866	7729543992649734	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
-6868	7972	7729544060835295	deploy/bin/gateway-scheduler	c90563d061dbec8d
+16463	19600	7751307438361229	deploy/bin/gateway-server	ce0929752e1db5b2
+54	371	7757302674107115	build.ninja	6a763902b4018f1
+47	16461	7751307274201575	modules/gateway-server/CMakeFiles/gateway-server.dir/src/large_screen_display/devices_info.cpp.o	690840fd0b4fbc98
+167	1893	7725187505568479	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/lora_server/LoRaServer.cpp.o	fc2812624c6741a
+13	152	7691619997487718	clean	92ade73078083541
+213	6286	7748694629899444	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/insulated-switch-server/SerialWriterThread.cpp.o	d98f59d899431c04
+75	8926	7753819348327524	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/command_poller/command_poller.cpp.o	29745cbcddd17a4d
+41	5964	7732221865376050	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/DatabaseWorker_.cpp.o	2cdfb72b11842543
+50	1765	7757302793436221	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/system_monitor/system_monitor.cpp.o	f9631c21458b145
+1768	2814	7757302810607747	deploy/bin/gateway-scheduler	3b94ad598465b14e
+91	2197	7757309718017080	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/system_monitor/system_monitor.cpp.o	f9631c21458b145
+61	5218	7757309717717013	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/main.cpp.o	4edd25c30a70ee81
+5219	6524	7757309769284666	deploy/bin/gateway-scheduler	3b94ad598465b14e
+51	4986	7757310340281585	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/main.cpp.o	4edd25c30a70ee81
+4988	6045	7757310389639037	deploy/bin/gateway-scheduler	3b94ad598465b14e
+82	6574	7762519071202865	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
+6576	7801	7762519136132029	deploy/bin/gateway-scheduler	3b94ad598465b14e
+84	6692	7762534125098544	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
+6693	7889	7762534191191561	deploy/bin/gateway-scheduler	3b94ad598465b14e
+60	7912	7762535250431378	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
+7915	9217	7762535328978523	deploy/bin/gateway-scheduler	3b94ad598465b14e
+55	6603	7762550821031357	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
+6606	7704	7762550886535674	deploy/bin/gateway-scheduler	3b94ad598465b14e
+52	7061	7762562480761987	modules/gateway-scheduler/CMakeFiles/gateway-scheduler.dir/src/tcp_server/TcpServer.cpp.o	a1f99320b3b8c883
+7063	8174	7762562550874171	deploy/bin/gateway-scheduler	3b94ad598465b14e

+ 2 - 2
Testing/Temporary/LastTest.log

@@ -1,3 +1,3 @@
-Start testing: Jun 30 10:40 中国标准时间
+Start testing: Aug 08 08:54 中国标准时间
 ----------------------------------------------------------
-End testing: Jun 30 10:40 中国标准时间
+End testing: Aug 08 08:54 中国标准时间

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 20 - 0
build.ninja


+ 292 - 0
modules/gateway-scheduler/src/command_poller/command_poller.cpp

@@ -0,0 +1,292 @@
+//
+// Created by lenovo on 2025/6/20.
+//
+// command_poller.cpp
+#include "command_poller.h"
+
+#include <sqlite3.h>
+
+#include <chrono>
+#include <iostream>
+#include <nlohmann/json.hpp>
+#include <string>
+#include <thread>
+
+#include "gateway-server/src/large_screen_display/devices_info.h"
+#include "nlohmann/json.hpp"
+
+CommandPoller::CommandPoller(TcpServer& server)
+    : tcpServer(server), running(true), last_id(0) {}
+
+
+CommandPoller::~CommandPoller() {
+  stop();
+}
+
+void CommandPoller::start() {
+  if (!cmd_thread.joinable()) {
+    cmd_thread = std::thread(&CommandPoller::pollCommands, this);
+  }
+}
+
+void CommandPoller::stop() {
+  running = false;
+  if (cmd_thread.joinable()) {
+    cmd_thread.join();
+  }
+}
+
+
+struct DeviceCommand {
+  std::string device_name;
+  std::string json_command;
+};
+
+void boradcast_cmd(uint8_t *message, size_t message_len, TcpServer& tcpServer) {
+  std::cout << "boradcast_cmd 命令帧: ";
+  for (size_t i = 0; i < message_len; ++i) {
+    printf("%02X ", message[i]);
+  }
+  std::cout << std::endl;
+
+  const auto& addrs = tcpServer.get_connected_clients();
+
+  for (const auto& client : addrs) {
+    std::cout << "IP: " << client.ip << ", 端口: " << client.port << std::endl;
+
+    ssize_t sent = send(client.sockfd, message, message_len, MSG_NOSIGNAL);
+    if (sent < 0) {
+      std::cerr << "发送失败到客户端 " << client.ip << ":" << client.port << std::endl;
+      tcpServer.remove_connected_clients(client.ip); // 删除该客户端
+    } else {
+      std::cout << "已发送消息到 " << client.ip << ":" << client.port << std::endl;
+    }
+  }
+}
+
+
+
+// 计算CRC16的表格(预先计算以提高效率)
+static uint16_t crc16_table[256];
+
+// 初始化CRC16表格
+static void init_crc16_table() {
+  uint16_t polynomial = 0xA001;
+  for (uint16_t i = 0; i < 256; i++) {
+    uint16_t crc = i;
+    for (uint8_t j = 0; j < 8; j++) {
+      if (crc & 0x0001) {
+        crc = (crc >> 1) ^ polynomial;
+      } else {
+        crc >>= 1;
+      }
+    }
+    crc16_table[i] = crc;
+  }
+}
+
+// 计算给定数据缓冲区的CRC16校验值
+static uint16_t calculate_crc16(uint8_t *data, size_t length) {
+  uint16_t crc = 0xFFFF; // 初始值
+  for (size_t i = 0; i < length; i++) {
+    uint8_t table_index = (crc ^ data[i]) & 0xFF;
+    crc = (crc >> 8) ^ crc16_table[table_index];
+  }
+  return crc;
+}
+
+
+vector<uint8_t> modbus_cmd_generate(uint16_t dev_number, uint16_t reg_addr, uint16_t val){
+  std::vector<uint8_t> res;
+
+  res.push_back(static_cast<uint8_t>(dev_number));       // 地址
+  res.push_back(0x06);                                    // 功能码:写单个寄存器
+
+  // 寄存器起始地址(高位在前)
+  res.push_back(static_cast<uint8_t>((reg_addr >> 8) & 0xFF)); // 高位
+  res.push_back(static_cast<uint8_t>(reg_addr & 0xFF));        // 低位
+
+  // 写入的数据(高位在前)
+  res.push_back(static_cast<uint8_t>((val >> 8) & 0xFF));      // 高位
+  res.push_back(static_cast<uint8_t>(val & 0xFF));             // 低位
+
+  // 计算 CRC
+  uint16_t crc = calculate_crc16(res.data(), res.size());
+  printf("crc %d", crc);
+
+  // 添加 CRC(先低字节,后高字节)
+  res.push_back(static_cast<uint8_t>(crc & 0xFF));         // CRC Low
+  res.push_back(static_cast<uint8_t>((crc >> 8) & 0xFF));   // CRC High
+
+  return res;
+
+}
+
+void CommandPoller::pollCommands() {
+  sqlite3* db = nullptr;
+  sqlite3_stmt* stmt;
+  int rc = sqlite3_open("/usr/local/bin/database/sqlite/device_cmd.db", &db);
+  if (rc != SQLITE_OK) {
+    std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
+    sqlite3_close(db);
+    return;
+  }
+  init_crc16_table();
+
+  const char* sql = "SELECT MAX(id) FROM device_commands;";
+
+  rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
+  if (rc == SQLITE_OK) {
+    if (sqlite3_step(stmt) == SQLITE_ROW) {
+      last_id = sqlite3_column_int(stmt, 0); // 获取最大 id
+    } else {
+      last_id = 0; // 没有记录时默认为 0
+    }
+    sqlite3_finalize(stmt);
+  } else {
+    std::cerr << "获取最大ID失败: " << sqlite3_errmsg(db) << std::endl;
+    last_id = 0;
+  }
+
+
+  std::cout << "开始轮询 SQLite 命令数据库..." << std::endl;
+
+  while (running) {
+    std::unique_lock<std::mutex> lock(db_mutex);
+
+    const char* sql = "SELECT id, device_name, json_command FROM device_commands WHERE id > ? ORDER BY id ASC;";
+
+    rc = sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr);
+    if (rc != SQLITE_OK) {
+      std::cerr << "SQL 准备失败: " << sqlite3_errmsg(db) << std::endl;
+      continue;
+    }
+
+    sqlite3_bind_int(stmt, 1, last_id);
+
+    std::vector<DeviceCommand> new_commands;
+    bool has_new = false;
+    while (sqlite3_step(stmt) == SQLITE_ROW) {
+      int id = sqlite3_column_int(stmt, 0);
+      const unsigned char* device_name = sqlite3_column_text(stmt, 1);
+      const unsigned char* json_command = sqlite3_column_text(stmt, 2);
+
+      new_commands.emplace_back(
+          DeviceCommand{
+              reinterpret_cast<const char*>(device_name),
+              reinterpret_cast<const char*>(json_command)
+          }
+      );
+
+      if (id > last_id) {
+        last_id = id;
+      }
+
+      has_new = true;
+    }
+
+    sqlite3_finalize(stmt);
+
+    if (has_new) {
+      std::cout << "发现新命令:" << std::endl;
+      for(auto & com:  new_commands){
+        size_t pos = com.device_name.rfind('-'); // 从后往前找 '-'
+        int dev_number;
+        if (pos != std::string::npos) {
+          std::string number_str = com.device_name.substr(pos + 1);
+          dev_number = std::stoi(number_str); // 转为整数
+        } else {
+          std::cerr << "未找到 '-' 字符" << std::endl;
+        }
+        vector<uint8_t> message;
+
+        if(com.device_name.find("空调") != std::string::npos){
+          std::cout << "空调 " << dev_number << std::endl;
+          // 解析 JSON
+          json j = json::parse(com.json_command);
+          // 获取各个字段
+          std::string swi   = j.value("开关", "未找到");
+          std::string mode   = j.value("模式", "未找到");
+          std::string temp   = j.value("设定温度", "未找到");
+          std::string vel   = j.value("风速", "未找到");
+          std::string direction   = j.value("风向", "未找到");
+          std::string report_period   = j.value("上报周期", "未找到");
+          // 打印结果
+
+          if (swi != "未找到") {
+            message = modbus_cmd_generate(dev_number, 2, std::atoi(swi.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+          if (mode != "未找到") {
+            message = modbus_cmd_generate(dev_number, 3, std::atoi(mode.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+          if (temp != "未找到") {
+            message = modbus_cmd_generate(dev_number, 4, std::atoi(temp.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+          if (vel != "未找到") {
+            message = modbus_cmd_generate(dev_number, 5, std::atoi(vel.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+          if (direction != "未找到") {
+            message = modbus_cmd_generate(dev_number, 6, std::atoi(direction.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+          if (report_period != "未找到") {
+            message = modbus_cmd_generate(dev_number, 7, std::atoi(report_period.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+        }else if(com.device_name.find("智能门锁") != std::string::npos){
+          std::cout << "智能门锁 " << dev_number << std::endl;
+          // 解析 JSON
+          json j = json::parse(com.json_command);
+          // 获取各个字段
+          std::string swi   = j.value("门控制", "未找到");
+          std::string report_period   = j.value("上报周期", "未找到");
+          if (swi != "未找到") {
+            message = modbus_cmd_generate(dev_number, 3, std::atoi(swi.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+          if (report_period != "未找到") {
+            message = modbus_cmd_generate(dev_number, 4, std::atoi(report_period.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+
+        }else if(com.device_name.find("照明") != std::string::npos
+                   || com.device_name.find("风机") != std::string::npos){
+          std::cout << "控制命令的设备号" << dev_number << std::endl;
+          // 解析 JSON
+          json j = json::parse(com.json_command);
+          // 获取各个字段
+          std::string swi   = j.value("开关", "未找到");
+          std::string report_period   = j.value("上报周期", "未找到");
+          if (swi != "未找到") {
+            message = modbus_cmd_generate(dev_number, 2, std::atoi(swi.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+          if (report_period != "未找到") {
+            message = modbus_cmd_generate(dev_number, 3, std::atoi(report_period.c_str()));
+            boradcast_cmd(message.data(), message.size(), tcpServer);
+          }
+        }else{
+          std::cout << "其他 " << dev_number << std::endl;
+        }
+      }
+      std::cout << "已处理所有新命令。" << std::endl;
+    }
+
+    lock.unlock();
+
+    std::this_thread::sleep_for(std::chrono::seconds(5)); // 每5秒检查一次
+  }
+
+  sqlite3_close(db);
+  std::cout << "SQLite 轮询线程退出。" << std::endl;
+}

+ 35 - 0
modules/gateway-scheduler/src/command_poller/command_poller.h

@@ -0,0 +1,35 @@
+//
+// Created by lenovo on 2025/6/20.
+//
+
+// command_poller.hpp
+#ifndef COMMAND_POLLER_HPP
+#define COMMAND_POLLER_HPP
+
+#include <thread>
+#include <atomic>
+#include <mutex>
+#include "gateway-scheduler/src/tcp_server/TcpServer.h"
+
+class CommandPoller {
+ public:
+  explicit CommandPoller(TcpServer& server);
+  ~CommandPoller();
+
+  void start();
+  void stop();
+
+
+ private:
+  std::thread cmd_thread;
+  std::atomic<bool> running;
+  int last_id;
+  std::mutex db_mutex;
+
+  void pollCommands();
+
+  TcpServer& tcpServer;
+
+};
+
+#endif // COMMAND_POLLER_HPP

+ 222 - 0
modules/gateway-scheduler/src/insulated-switch-server/SerialWriterThread.cpp

@@ -0,0 +1,222 @@
+//
+// Created by lenovo on 2025/6/11.
+//
+
+#include "SerialWriterThread.h"
+#include <iostream>
+#include <string>
+#include <vector>
+#include <experimental/filesystem>
+
+#include <algorithm>
+#include <map>
+#include <fstream>
+#include <sstream>
+#include <hiredis/hiredis.h>
+#include <sqlite3.h>
+#include <chrono>  // 时间相关头文件
+#include <iostream>
+#include <iomanip>
+
+using namespace std;
+
+string device_info_path = "./outputs/";
+
+std::vector<std::string> readSingleLineCSV(const std::string& filename) {
+  std::ifstream file(filename);
+  if (!file.is_open()) {
+    throw std::runtime_error("无法打开文件: " + filename);
+    return {};
+  }
+
+  std::string line;
+  if (!std::getline(file, line)) {
+    return {};  // 返回空向量表示文件为空
+  }
+
+  std::vector<string> row;
+  std::stringstream ss(line);
+  std::string cell;
+
+  while (std::getline(ss, cell, ',')) {
+    //    std::cout << cell << std::endl;
+    try {
+      // 移除首尾空格
+      cell.erase(0, cell.find_first_not_of(" \t"));
+      cell.erase(cell.find_last_not_of(" \t") + 1);
+
+      // 移除引号(如果有)
+      if (cell.size() >= 2 && cell.front() == '"' && cell.back() == '"') {
+        cell = cell.substr(1, cell.size() - 2);
+      }
+
+      // 转换为double
+      //      row.push_back(std::stod(cell));
+      //      std::ostringstream oss;
+      //      oss << std::fixed << std::setprecision(2) << std::stod(cell);
+      row.push_back(cell);
+    } catch (const std::exception& e) {
+      throw std::runtime_error("转换失败: '" + cell + "' 不是有效的浮点数");
+      return {};
+    }
+  }
+
+  return row;
+}
+
+// 获取指定路径下以特定前缀开头的最新文件
+std::string getLatestFileWithPrefix(const std::string& path, const std::string& prefix) {
+  std::vector<fs::directory_entry> matching_files;
+
+  // 遍历目录,收集所有匹配前缀的文件
+  for (const auto& entry : fs::directory_iterator(path)) {
+    std::string filename = entry.path().filename().string();
+    if (filename.rfind(prefix, 0) == 0) { // 检查是否以prefix开头
+      matching_files.push_back(entry);
+    }
+  }
+
+  if (matching_files.empty()) {
+    return ""; // 没有找到匹配的文件
+  }
+
+  // 按最后修改时间排序(最新的排在前面)
+  std::sort(matching_files.begin(), matching_files.end(),
+            [](const fs::directory_entry& a, const fs::directory_entry& b) {
+              return fs::last_write_time(a) > fs::last_write_time(b);
+            });
+
+  return matching_files.front().path().string();
+}
+
+
+struct Measure {
+  string point;
+  string value;
+};
+
+struct Device {
+  string device_name;
+  vector<Measure> measures;
+};
+
+
+void get_latest_device_info(int deviceid, std::vector<Device> &devices){
+  std::string file = getLatestFileWithPrefix(device_info_path, to_string(deviceid)+"_");
+  Device device = {};
+  std::string name;
+  if(deviceid == 1)
+    name = "触头感知监测终端A";
+  else if(deviceid == 2)
+    name = "触头感知监测终端B";
+  else if(deviceid == 3)
+    name = "触头感知监测终端C";
+
+  if (!file.empty()) {
+    std::cout << "Latest file with prefix '" << deviceid << "': " << file << std::endl;
+    auto data = readSingleLineCSV(file);
+    if(!data.empty()) {
+      float max_val = std::max({std::stof(data[3]), std::stof(data[4]), std::stof(data[5]), std::stof(data[6]), std::stof(data[2])});
+      std::ostringstream oss, oss1, oss2;
+      oss << std::fixed << std::setprecision(2) << max_val;
+      Measure measure1 = {"温度", oss.str()};
+      oss1 << std::fixed << std::setprecision(2) << std::stof(data[9]);
+      Measure measure2 = {"压力", oss1.str()};
+      oss2 << std::fixed << std::setprecision(2) << std::stof(data[10]);
+      Measure measure3 = {"电池电压", oss2.str()};
+      std::vector<Measure> measures = {measure1, measure2, measure3};
+      devices.push_back({name, measures});
+    }else{
+      fs::remove(file);
+    }
+  } else {
+    std::cout << "No file found with prefix '" << "1_" << "'" << std::endl;
+  }
+}
+
+
+// 构造函数:设置默认目录或从配置中读取
+SerialWriterThread::SerialWriterThread()
+    : directory_("/path/to/watch"), running_(false) {
+  // 可以在这里从配置文件或环境变量读取目录路径
+}
+
+SerialWriterThread::~SerialWriterThread() {
+  stop();
+}
+void SerialWriterThread::start() {
+  if (running_) return;
+  running_ = true;
+  worker_thread_ = std::thread(&SerialWriterThread::run, this);
+}
+
+void SerialWriterThread::stop() {
+  if (!running_) return;
+  running_ = false;
+  if (worker_thread_.joinable()) {
+    worker_thread_.join();
+  }
+}
+
+void readFileContentAndWriteSerial(int device) {
+  std::map<int, std::pair<std::string, std::string>> gpioPaths = {
+      {1, {"/sys/class/gpio/gpio32/value", "/sys/class/gpio/gpio33/value"}},
+      {2, {"/sys/class/gpio/gpio147/value", "/sys/class/gpio/gpio8/value"}},
+      {3, {"/sys/class/gpio/gpio148/value",  "/sys/class/gpio/gpio40/value"}}
+  };
+  // 获取最新文件
+  fs::path latestFile = getLatestFileWithPrefix(device_info_path, to_string(device) + "_");
+  if (!latestFile.empty()) {
+    auto data = readSingleLineCSV(latestFile);
+    if(!data.empty()) {
+      float tempture = std::max({std::stof(data[3]), std::stof(data[4]), std::stof(data[5]), std::stof(data[6]), std::stof(data[2])});
+      float pressure = std::stof(data[9]);
+
+      std::ofstream pressureFile(gpioPaths[device].first);
+      std::ofstream temptureFile(gpioPaths[device].second);
+      if (!pressureFile.is_open()) {
+        std::cerr << "无法打开GPIO " << gpioPaths[device].first;
+        return;
+      }
+      if (!temptureFile.is_open()) {
+        std::cerr << "无法打开GPIO " << gpioPaths[device].second;
+        return;
+      }
+      if(pressure < 45.0f){
+        pressureFile << 1;
+//        std::cout << gpioPaths[device].first << "   : 1" << std::endl;
+      }else{
+        pressureFile << 0;
+//        std::cout << gpioPaths[device].first << "   : 0" << std::endl;
+      }
+      if(tempture > 105.0f){
+        temptureFile << 1;
+//        std::cout << gpioPaths[device].second << "   : 1" << std::endl;
+      }else{
+        temptureFile << 0;
+//        std::cout << gpioPaths[device].second << "   : 0" << std::endl;
+      }
+      temptureFile.flush();
+      temptureFile.close();
+      pressureFile.flush();
+      pressureFile.close();
+    }
+  }
+}
+
+void SerialWriterThread::run() {
+  while (running_) {
+
+    readFileContentAndWriteSerial(1);
+    readFileContentAndWriteSerial(2);
+    readFileContentAndWriteSerial(3);
+
+    std::this_thread::sleep_for(std::chrono::milliseconds(check_interval_ms_));
+  }
+}
+
+
+struct GpioPaths {
+  std::string pressure;
+  std::string temperature;
+};

+ 49 - 0
modules/gateway-scheduler/src/insulated-switch-server/SerialWriterThread.h

@@ -0,0 +1,49 @@
+//
+// Created by lenovo on 2025/6/11.
+//
+
+#ifndef EMBEDDED_GATEWAY_SERIALWRITERTHREAD_H
+#define EMBEDDED_GATEWAY_SERIALWRITERTHREAD_H
+
+
+
+#include <string>
+#include <thread>
+#include <atomic>
+#include <experimental/filesystem>
+namespace fs = std::experimental::filesystem;
+
+using namespace std;
+
+class SerialWriterThread {
+ public:
+  // 构造函数
+  explicit SerialWriterThread();
+
+  // 析构函数
+  virtual ~SerialWriterThread();
+
+  // 启动线程
+  void start();
+
+  // 停止线程
+  void stop();
+
+
+ private:
+  std::string directory_;           // 目录路径
+  std::thread worker_thread_;       // 工作线程
+  std::atomic<bool> running_;       // 线程运行标志
+  int check_interval_ms_ = 1000;    // 默认检查间隔为1秒
+
+  // 线程主循环
+  void run();
+
+  // 读取文件内容
+//  void readFileContentAndWriteSerial(int device);
+};
+
+
+
+
+#endif  // EMBEDDED_GATEWAY_SERIALWRITERTHREAD_H

+ 123 - 0
modules/gateway-scheduler/src/logger/Logger.h

@@ -0,0 +1,123 @@
+//
+// Created by lenovo on 2025/7/28.
+//
+
+#ifndef EMBEDDED_GATEWAY_LOGGER_H
+#define EMBEDDED_GATEWAY_LOGGER_H
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <mutex>
+#include <ctime>
+#include <cstdarg>
+#include <memory>
+
+// 日志级别枚举
+enum class LogLevel {
+  Debug,
+  Info,
+  Warn,
+  Error
+};
+
+// 将日志级别转换为字符串
+inline const char* logLevelToString(LogLevel level) {
+  switch (level) {
+    case LogLevel::Debug: return "Debug";
+    case LogLevel::Info:  return "Info";
+    case LogLevel::Warn:  return "Warn";
+    case LogLevel::Error: return "Error";
+    default: return "UNKNOWN";
+  }
+}
+
+// 获取当前时间戳字符串
+inline std::string getCurrentTimestamp() {
+  auto now = std::time(nullptr);
+  char buf[20];
+  std::strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", std::localtime(&now));
+  return std::string(buf);
+}
+
+// 日志类
+class Logger {
+ public:
+  // 单例模式
+  static Logger& getInstance() {
+    static Logger instance;
+    return instance;
+  }
+
+  // 设置日志输出文件
+  void setLogFile(const std::string& filename) {
+    if (logFile.is_open()) {
+      logFile.close();
+    }
+    logFile.open(filename, std::ios::out | std::ios::app);
+    if (!logFile.is_open()) {
+      std::cerr << "无法打开日志文件: " << filename << std::endl;
+    }
+  }
+
+  // 设置当前日志级别(低于这个级别的日志不会输出)
+  void setLogLevel(LogLevel level) {
+    currentLevel = level;
+  }
+
+  // 核心日志函数(支持格式化)
+  void log(LogLevel level, const char* format, ...) {
+    if (level < currentLevel) {
+      return; // 忽略低于当前级别的日志
+    }
+
+    std::lock_guard<std::mutex> lock(mutex);
+
+    // 构建日志消息
+    std::string timestamp = getCurrentTimestamp();
+    std::string levelStr = logLevelToString(level);
+
+    // 格式化消息
+    va_list args;
+    va_start(args, format);
+    int size = std::vsnprintf(nullptr, 0, format, args);
+    va_end(args);
+
+    std::unique_ptr<char[]> buffer(new char[size + 1]);
+    va_start(args, format);
+    std::vsnprintf(buffer.get(), size + 1, format, args);
+    va_end(args);
+
+    std::string message(buffer.get());
+
+    // 输出到控制台和文件
+    std::string logEntry = "[" + timestamp + "] [" + levelStr + "] " + message + "\n";
+
+    std::cout << logEntry; // 控制台输出
+    if (logFile.is_open()) {
+      logFile << logEntry;
+      logFile.flush(); // 立即刷新缓冲区
+    }
+  }
+
+ private:
+  Logger() : currentLevel(LogLevel::Debug) {}
+  ~Logger() {
+    if (logFile.is_open()) {
+      logFile.close();
+    }
+  }
+
+  Logger(const Logger&) = delete;
+  Logger& operator=(const Logger&) = delete;
+
+  std::ofstream logFile;
+  LogLevel currentLevel;
+  std::mutex mutex;
+};
+
+// 宏定义,简化日志调用
+#define LOG_Debug(msg, ...) Logger::getInstance().log(LogLevel::Debug, msg, ##__VA_ARGS__)
+#define LOG_Info(msg, ...)  Logger::getInstance().log(LogLevel::Info, msg, ##__VA_ARGS__)
+#define LOG_Warn(msg, ...)  Logger::getInstance().log(LogLevel::Warn, msg, ##__VA_ARGS__)
+#define LOG_Error(msg, ...) Logger::getInstance().log(LogLevel::Error, msg, ##__VA_ARGS__)
+#endif  // EMBEDDED_GATEWAY_LOGGER_H

+ 10 - 0
modules/gateway-scheduler/src/main.cpp

@@ -10,6 +10,8 @@
 #include "gateway-scheduler/src/lora_server/LoRaServer.h"
 #include "gateway-scheduler/src/insulated-switch-server/insulated_switch_server.h"
 #include "gateway-scheduler/src/command_poller/command_poller.h"
+#include "gateway-scheduler/src/logger/Logger.h"
+#include "gateway-scheduler/src/system_monitor/system_monitor.h"
 
 void terminate() { std::exit(1); }
 
@@ -18,6 +20,8 @@ using namespace server::service;
 int main(int argc, char* argv[]) {
   std::set_terminate(terminate);
   MESSAGE_PRINT(" scheduler starting");
+  Logger::getInstance().setLogFile("gateway-scheduler.log");
+
   try {
 
     int port = 8888;
@@ -37,6 +41,12 @@ int main(int argc, char* argv[]) {
 //      return 1;
 //    }
 //
+
+    SystemMonitor monitor(20000);
+    monitor.start();
+
+
+
     while(true){
       sleep(1);
     }

+ 115 - 0
modules/gateway-scheduler/src/system_monitor/system_monitor.cpp

@@ -0,0 +1,115 @@
+//
+// Created by lenovo on 2025/8/1.
+//
+// system_monitor.cpp
+#include "system_monitor.h"
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include <thread>
+#include <chrono>
+#include <map>
+#include <vector>
+#include "../logger/Logger.h"
+
+SystemMonitor::SystemMonitor(int interval_ms)
+    : interval_ms_(interval_ms), running_(false) {}
+
+void SystemMonitor::start() {
+  if (running_) return;
+  running_ = true;
+  monitor_thread_ = std::thread(&SystemMonitor::run, this);
+}
+
+void SystemMonitor::stop() {
+  running_ = false;
+  if (monitor_thread_.joinable()) {
+    monitor_thread_.join();
+  }
+}
+
+double SystemMonitor::getCpuUsage() {
+  std::ifstream file("/proc/stat");
+  std::string line;
+  std::getline(file, line);
+  std::istringstream iss(line);
+  std::string cpu;
+  long user, nice, system, idle, iowait, irq, softirq, steal;
+  iss >> cpu >> user >> nice >> system >> idle >> iowait >> irq >> softirq >> steal;
+
+  long total = user + nice + system + idle + iowait + irq + softirq + steal;
+  long idleTime = idle + iowait;
+
+  static long prevTotal = 0, prevIdle = 0;
+  if (prevTotal == 0) {
+    prevTotal = total;
+    prevIdle = idleTime;
+    return 0.0;
+  }
+
+  long deltaTotal = total - prevTotal;
+  long deltaIdle = idleTime - prevIdle;
+  prevTotal = total;
+  prevIdle = idleTime;
+
+  return (deltaTotal - deltaIdle) * 100.0 / deltaTotal;
+}
+
+double SystemMonitor::getMemoryUsage() {
+  std::map<std::string, long> meminfo;
+  std::ifstream file("/proc/meminfo");
+  std::string line, key;
+  long value;
+  while (std::getline(file, line)) {
+    std::istringstream iss(line);
+    iss >> key >> value;
+    key.pop_back();  // 去掉冒号
+    meminfo[key] = value;
+  }
+
+  long total = meminfo["MemTotal"];
+  long available = meminfo["MemAvailable"];
+  long used = total - available;
+  return (used * 100.0) / total;
+}
+
+double SystemMonitor::getCpuTemperature() {
+  std::vector<std::string> paths = {
+      "/sys/class/thermal/thermal_zone0/temp",
+      "/sys/class/thermal/thermal_zone1/temp",
+      "/sys/class/thermal/thermal_zone2/temp",
+      "/sys/class/thermal/thermal_zone3/temp"
+  };
+
+  for (const auto& path : paths) {
+    std::ifstream file(path);
+    if (file.is_open()) {
+      double temp = 0;
+      if (file >> temp) {
+        return temp / 1000.0;  // 转为摄氏度
+      }
+    }
+  }
+  return -1.0;  // 获取失败
+}
+
+void SystemMonitor::run() {
+  std::cout << "System Monitor Thread Started.\n";
+  // 预热:第一次 CPU 使用率无效
+  getCpuUsage();
+  while (running_) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms_));
+
+    double cpu_usage = getCpuUsage();
+    double mem_usage = getMemoryUsage();
+    double cpu_temp = getCpuTemperature();
+
+    std::cout.precision(2);
+    std::cout << std::fixed
+              << "[System Stats] CPU: " << cpu_usage << "% | "
+              << "Memory: " << mem_usage << "% | "
+              << "Temp: " << cpu_temp << "°C" << std::endl;
+    LOG_Debug("[System Stats] CPU: %f% | Memory: %f% | Temp: %f°C", cpu_usage, mem_usage, cpu_temp);
+  }
+  std::cout << "System Monitor Thread Stopped.\n";
+}

+ 53 - 0
modules/gateway-scheduler/src/system_monitor/system_monitor.h

@@ -0,0 +1,53 @@
+//
+// Created by lenovo on 2025/8/1.
+//
+
+#ifndef EMBEDDED_GATEWAY_SYSTEM_MONITOR_H
+#define EMBEDDED_GATEWAY_SYSTEM_MONITOR_H
+
+// system_monitor.h
+#pragma once
+
+#include <atomic>
+#include <thread>
+#include <string>
+
+/**
+ * SystemMonitor
+ * 用于周期性采集 CPU 使用率、内存使用率、CPU 温度
+ */
+class SystemMonitor {
+ public:
+  /**
+     * 构造函数
+     * @param interval_ms 采集间隔(毫秒)
+   */
+  explicit SystemMonitor(int interval_ms = 20000);
+
+  /**
+     * 启动监控线程
+   */
+  void start();
+
+  /**
+     * 停止监控线程
+   */
+  void stop();
+
+ private:
+  int interval_ms_;
+  std::atomic<bool> running_;
+  std::thread monitor_thread_;
+
+  // 私有成员函数:采集逻辑
+  double getCpuUsage();
+  double getMemoryUsage();
+  double getCpuTemperature();
+
+  // 线程主函数
+  void run();
+};
+
+
+
+#endif  // EMBEDDED_GATEWAY_SYSTEM_MONITOR_H

+ 138 - 0
modules/gateway-scheduler/src/tcp_server/DatabaseWorker .cpp

@@ -0,0 +1,138 @@
+#include "DatabaseWorker.h"
+using namespace std;
+#include <iostream>
+
+void DatabaseQueue::push(const nlohmann::json& data) {
+  std::lock_guard<std::mutex> lock(queue_mutex);
+  data_queue.push(data);
+  queue_cv.notify_one();
+}
+
+bool DatabaseQueue::pop(nlohmann::json& data) {
+  std::unique_lock<std::mutex> lock(queue_mutex);
+  queue_cv.wait(lock, [this]() { return !data_queue.empty() || !running; });
+
+  if (!running && data_queue.empty()) {
+    return false;
+  }
+
+  data = data_queue.front();
+  data_queue.pop();
+  return true;
+}
+
+void DatabaseQueue::stop() {
+  std::lock_guard<std::mutex> lock(queue_mutex);
+  running = false;
+  queue_cv.notify_all();
+}
+
+
+
+void DatabaseWorker::initialize_database(sqlite3*& db) {
+  const char* sql_create_table =
+      "CREATE TABLE IF NOT EXISTS history_data ("
+      "id INTEGER PRIMARY KEY AUTOINCREMENT,"
+      "data TEXT NOT NULL,"
+      "time TEXT NOT NULL,"
+      "device_id INTEGER NOT NULL,"
+      "device_name TEXT NOT NULL,"
+      "gateway_id INTEGER NOT NULL,"
+      "status TEXT NOT NULL);"
+      "PRAGMA busy_timeout = 5000;";
+
+  char* zErrMsg = nullptr;
+  int rc = sqlite3_exec(db, sql_create_table, nullptr, 0, &zErrMsg);
+  if (rc != SQLITE_OK) {
+    fprintf(stderr, "SQL error: %s\n", zErrMsg);
+    sqlite3_free(zErrMsg);
+  }
+}
+
+
+void DatabaseWorker::process_data(const nlohmann::json& json_data, int dev_addr, const std::string& device_name) {
+  sqlite3* db;
+  int rc = sqlite3_open("/usr/local/bin/database/sqlite/history_data.db", &db);
+  if (rc) {
+    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
+    return;
+  }
+
+  initialize_database(db);
+
+  const char* sql_insert = "INSERT INTO history_data (data, time, device_id, device_name, gateway_id, status) VALUES (?, ?, ?, ?, ?, ?);";
+  sqlite3_stmt* stmt;
+
+  rc = sqlite3_prepare_v2(db, sql_insert, -1, &stmt, 0);
+  if (rc != SQLITE_OK) {
+    fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
+    sqlite3_close(db);
+    return;
+  }
+
+  // 绑定数据
+  std::string sql_data = json_data["data"].dump();
+  sqlite3_bind_text(stmt, 1, sql_data.c_str(), -1, SQLITE_STATIC);
+
+  // 获取当前时间
+  time_t rawtime;
+  time(&rawtime);
+  struct tm* timeinfo = localtime(&rawtime);
+  char time_str[30];
+  strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", timeinfo);
+  sqlite3_bind_text(stmt, 2, time_str, -1, SQLITE_STATIC);
+
+  sqlite3_bind_int(stmt, 3, dev_addr);
+  sqlite3_bind_text(stmt, 4, device_name.c_str(), -1, SQLITE_STATIC);
+  sqlite3_bind_int(stmt, 5, 0);
+  sqlite3_bind_text(stmt, 6, "run", -1, SQLITE_STATIC);
+
+  // 执行插入
+  rc = sqlite3_step(stmt);
+  if (rc != SQLITE_DONE) {
+    fprintf(stderr, "Failed to execute insert: %s\n", sqlite3_errmsg(db));
+  }
+
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+}
+
+
+void DatabaseWorker::run() {
+  while (true) {
+//    std::cout << "DatabaseWorker::run " << std::endl;
+    nlohmann::json data;
+    int dev_addr;
+    std::string device_name;
+
+    if (!queue.pop(data)) {
+      break;
+    }
+
+    std::cout << "data: " << data.dump() << std::endl;
+//    std::this_thread::sleep_for(std::chrono::seconds(2));
+
+
+    try {
+      dev_addr = data["dev_addr"];
+      device_name = data["device_name"];
+      process_data(data, dev_addr, device_name);
+    } catch (const std::exception& e) {
+      fprintf(stderr, "Error processing data: %s\n", e.what());
+    }
+  }
+}
+
+DatabaseWorker::DatabaseWorker(DatabaseQueue& q)
+    : queue(q) {
+  std::cout << "DatabaseWorker init " << std::endl;
+  worker_thread = std::thread(&DatabaseWorker::run, this);
+  worker_thread.detach();  // 或 join()
+}
+
+DatabaseWorker::~DatabaseWorker() {
+//  db_queue.stop();  // 停止队列
+//  if (worker_thread.joinable()) {
+//    worker_thread.join();
+//  }
+}

+ 39 - 0
modules/gateway-scheduler/src/tcp_server/DatabaseWorker.h

@@ -0,0 +1,39 @@
+#ifndef DATABASE_WORKER_H
+#define DATABASE_WORKER_H
+
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+#include <nlohmann/json.hpp>
+#include <sqlite3.h>
+#include <thread>
+
+class DatabaseQueue {
+ private:
+  std::queue<nlohmann::json> data_queue;
+  std::mutex queue_mutex;
+  std::condition_variable queue_cv;
+  bool running = true;
+
+ public:
+  void push(const nlohmann::json& data);
+  bool pop(nlohmann::json& data);
+  void stop();
+};
+
+class DatabaseWorker {
+ private:
+  DatabaseQueue& queue;
+  std::thread worker_thread;
+
+  void initialize_database(sqlite3*& db);
+  void process_data(const nlohmann::json& json_data, int dev_addr, const std::string& device_name);
+
+ public:
+  explicit DatabaseWorker(DatabaseQueue& q);
+//  DatabaseWorker();
+  ~DatabaseWorker();
+  void run();
+};
+
+#endif // DATABASE_WORKER_H

+ 501 - 381
modules/gateway-scheduler/src/tcp_server/TcpServer.cpp

@@ -7,6 +7,9 @@
 #include <hiredis/hiredis.h>
 #include <sqlite3.h>
 
+#include "DatabaseWorker.h"
+#include "../logger/Logger.h"
+
 // 回调函数,用于处理查询结果
 static int sql_callback(void *NotUsed, int argc, char **argv, char **azColName) {
     for (int i = 0; i < argc; i++) {
@@ -50,9 +53,14 @@ static uint16_t calculate_crc16(uint8_t *data, size_t length) {
 
 
 
-
 // 构造函数
-TcpServer::TcpServer(int port) : conn_num(0), running(true) {
+TcpServer::TcpServer(int port)
+    :
+      db_queue(),                     // 默认构造 db_queue
+      db_worker(db_queue),           // 用 db_queue 初始化 db_worker
+      running(true),
+      conn_num(0)
+{
     server_fd = socket(AF_INET, SOCK_STREAM, 0);
     if (server_fd < 0) {
         perror("Socket creation failed");
@@ -81,7 +89,7 @@ TcpServer::TcpServer(int port) : conn_num(0), running(true) {
     }
 
     // Listen for incoming connections
-    if (listen(server_fd, 3) < 0) {
+    if (listen(server_fd, SOMAXCONN) < 0) {
         perror("Listen failed");
         close(server_fd);
         throw std::runtime_error("Listen failed");
@@ -106,14 +114,13 @@ TcpServer::~TcpServer() {
     close(server_fd);
 }
 
+
 // 启动服务器
 void TcpServer::start_server() {
     std::cout << "Starting server..." << std::endl;
     // 初始化CRC16表格
     init_crc16_table();
 
-
-
     accept_thread = std::thread([this]() {
         while (this->running) {
           char client_ip[INET_ADDRSTRLEN];
@@ -121,6 +128,7 @@ void TcpServer::start_server() {
           if (new_socket < 0) {
               // 打印错误信息
               std::cerr << "Accept failed with error: " << strerror(errno) << std::endl;
+              std::cout << "当前连接数量: " << this->conn_num << std::endl;
               if (errno == EINTR) {
                   // 如果是信号中断,继续等待连接
                   continue;
@@ -136,20 +144,36 @@ void TcpServer::start_server() {
             std::string ip_str(client_ip);
 
             std::cout << "客户端已连接: " << ip_str << ":" << client_port << std::endl;
+
             {
               std::lock_guard<std::mutex> lock(mtx_client_addrs);
+
+              if (ip_str == "172.16.111.60" || ip_str == "172.16.111.61" || ip_str == "172.16.111.62") {
+                for (auto it = client_addrs.begin(); it != client_addrs.end();) {
+                  if (it->ip == ip_str) {
+                    it = client_addrs.erase(it);  // 删除当前元素,返回下一个迭代器
+                  } else {
+                    ++it;  // 不删,继续往后走
+                  }
+                }
+              }
               client_addrs.push_back({ip_str, client_port, new_socket});
+
             }
 
             {
                 std::lock_guard<std::mutex> lock(mtx);
                 this->conn_num++;
-                std::cout << "Current connection count: " << this->conn_num << std::endl;
+                LOG_Debug("客户端已连接:%s %d 当前连接数量:%d", ip_str.c_str(), client_port, this->conn_num);
+                std::cout << "当前连接数量: " << this->conn_num << std::endl;
+
+//                LOG_Debug("", this->conn_num); // 不会输出
             }
 
-            // Create a new thread to handle the client
-//            threads.emplace_back(&TcpServer::handle_client, this, new_socket);
-            std::thread(&TcpServer::handle_client, this, new_socket).detach();
+            threads.emplace_back([this, new_socket, ip_str]() {
+              handle_client(new_socket, ip_str);
+            });
+//            std::thread(&TcpServer::handle_client, this, new_socket).detach();
         }
     });
     accept_thread.detach();  // 让接受线程独立运行
@@ -160,406 +184,502 @@ std::vector<ClientAddr> TcpServer::get_connected_clients() {
   std::lock_guard<std::mutex> lock(mtx_client_addrs);
   return client_addrs;
 }
+void TcpServer::remove_connected_clients(std::string ip) {
+  std::lock_guard<std::mutex> lock(mtx_client_addrs);
+  auto it = client_addrs.begin();
+  while (it != client_addrs.end()) {
+    if (it->ip == ip) {
+//      close(it->sockfd);  // 关闭 socket
+      it = client_addrs.erase(it); // 删除元素并更新迭代器
+    } else {
+      ++it;
+    }
+  }
+}
+
+
+
+nlohmann::json decode_modbus_msg(const uint8_t * buffer, std::string& device_name){
+  int dev_addr = buffer[0];
+  int fun_code = buffer[1];
+  int data_len = buffer[2];
+  int dev_type = buffer[6];
+
+  nlohmann::json json_save;
+
+  if(dev_type == 9) {
+    std::cout << "门锁" << std::endl;
+  }
+  if(dev_type == 10) {
+    std::cout << "噪声" << std::endl;
+  }
+  if(dev_type == 12) {
+    std::cout << "蓄电池" << std::endl;
+  }
+  std::string postfix = "NARI-";
+  // 公共字段
+  json_save["status"] = "run";
+  json_save["gateway_id"] = 0;
+  std::string dev_name = "device_" + std::to_string(dev_addr);
+  if (dev_type == 1) { // 温湿度
+    device_name = "温湿度-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "温湿度-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 温度对象
+    nlohmann::json temp_data;
+    temp_data["name"] = "温度";
+    temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
+    temp_data["format"] = "℃";
+    temp_data["format_id"] = 40;
+    json_save["data"].push_back(temp_data);
+
+    // 湿度对象
+    nlohmann::json humidity_data;
+    humidity_data["name"] = "湿度";
+    humidity_data["value"] = ((buffer[9] << 8) + buffer[10]);
+    humidity_data["format"] = "%RH";
+    humidity_data["format_id"] = 40;
+    json_save["data"].push_back(humidity_data);
+  } else if (dev_type == 2) { // 水浸
+    device_name = "水浸-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "水浸-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 水浸对象
+    nlohmann::json water_data;
+    water_data["name"] = "水浸状态";
+    water_data["value"] = ((buffer[7] << 8) + buffer[8]); // 0 表示无水浸,1 表示有水浸
+                                                           //          if((buffer[7] << 8) + buffer[8] == 0)
+                                                           //            water_data["value"] = "正常";
+                                                           //          else
+                                                           //            water_data["value"] = "告警";
+    water_data["format"] = "";
+    water_data["format_id"] = 0;
+    json_save["data"].push_back(water_data);
+
+  } else if (dev_type == 3) { // 烟感
+    device_name = "烟感-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "烟感-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 烟感对象
+    nlohmann::json smoke_data;
+    smoke_data["name"] = "报警状态";
+    smoke_data["value"] = (buffer[7] << 8) + buffer[8];
+    //          if((buffer[7] << 8) + buffer[8] == 0)
+    //            smoke_data["value"] = "正常";
+    //          else
+    //            smoke_data["value"] = "告警";
+    smoke_data["format"] = "";
+    smoke_data["format_id"] = 0;
+    json_save["data"].push_back(smoke_data);
+  }else if (dev_type == 7) {
+    device_name = "空调-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "空调-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 开关对象
+    nlohmann::json switch_data;
+    switch_data["name"] = "开关";
+    switch_data["value"] = ((buffer[7] << 8) + buffer[8]);
+    switch_data["format"] = "";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+    // 模式对象
+    nlohmann::json mode_data;
+    mode_data["name"] = "模式";
+    mode_data["value"] = ((buffer[9] << 8) + buffer[10]);
+    mode_data["format"] = "";
+    mode_data["format_id"] = 0;
+    json_save["data"].push_back(mode_data);
+    // 模式对象
+    nlohmann::json set_temperature_data;
+    set_temperature_data["name"] = "设定温度";
+    set_temperature_data["value"] = ((buffer[11] << 8) + buffer[12]);
+    set_temperature_data["format"] = "℃";
+    set_temperature_data["format_id"] = 40;
+    json_save["data"].push_back(set_temperature_data);
+    // 模式对象
+    nlohmann::json wind_speed_data;
+    wind_speed_data["name"] = "风速";
+    wind_speed_data["value"] = ((buffer[13] << 8) + buffer[14]);
+    wind_speed_data["format"] = "";
+    wind_speed_data["format_id"] = 40;
+    json_save["data"].push_back(wind_speed_data);
+    // 模式对象
+    nlohmann::json wind_direction_data;
+    wind_direction_data["name"] = "风向";
+    wind_direction_data["value"] = ((buffer[15] << 8) + buffer[16]);
+    wind_direction_data["format"] = "";
+    wind_direction_data["format_id"] = 0;
+    json_save["data"].push_back(wind_direction_data);
+
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[17] << 8) + buffer[18]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else if (dev_type == 6) { // 照明
+    device_name = "照明-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "照明-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    //开关
+    nlohmann::json switch_data;
+    switch_data["name"] = "开关";
+    switch_data["value"] = (buffer[7] << 8) + buffer[8];
+    switch_data["format"] = "";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[9] << 8) + buffer[10]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else if (dev_type == 8) { // 门磁
+    device_name = "门磁-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "门磁-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    //开关
+    nlohmann::json switch_data;
+    switch_data["name"] = "开关";
+    switch_data["value"]  = (buffer[7] << 8) + buffer[8];
+    switch_data["format"] = "";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[9] << 8) + buffer[10]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else if (dev_type == 5) { // 风机
+    device_name = "风机-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "风机-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    //开关
+    nlohmann::json switch_data;
+    switch_data["name"] = "开关";
+    switch_data["value"] = (buffer[7] << 8) + buffer[8];
+    switch_data["format"] = "";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[9] << 8) + buffer[10]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else if (dev_type == 9) { // 智能门锁
+    device_name = "智能门锁-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "智能门锁-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    //开关
+    nlohmann::json switch_data;
+    switch_data["name"] = "门状态";
+    switch_data["value"] = (buffer[7] << 8) + buffer[8];
+    switch_data["format"] = "";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+
+    switch_data["name"] = "门控制";
+    switch_data["value"] = (buffer[9] << 8) + buffer[10];
+    switch_data["format"] = "";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+
+    switch_data["name"] = "上报周期";
+    switch_data["value"] = (buffer[11] << 8) + buffer[12];
+    switch_data["format"] = "s";
+    switch_data["format_id"] = 0;
+    json_save["data"].push_back(switch_data);
+  }else if (dev_type == 4) { // 双气
+    device_name = "双气-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "双气-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 氧气浓度
+    nlohmann::json temp_data;
+    temp_data["name"] = "氧气浓度";
+    temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
+    temp_data["format"] = "%";
+    temp_data["format_id"] = 0;
+    json_save["data"].push_back(temp_data);
+
+    // SF6浓度
+    nlohmann::json humidity_data;
+    humidity_data["name"] = "SF6浓度";
+    humidity_data["value"] = ((buffer[9] << 8) + buffer[10])/10.0;
+    humidity_data["format"] = "ppm";
+    humidity_data["format_id"] = 0;
+    json_save["data"].push_back(humidity_data);
+
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[11] << 8) + buffer[12]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else if (dev_type == 10) { // 噪声
+    device_name = "噪声-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "噪声-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 噪声值
+    nlohmann::json temp_data;
+    temp_data["name"] = "噪声值";
+    temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
+    temp_data["format"] = "db";
+    temp_data["format_id"] = 40;
+    json_save["data"].push_back(temp_data);
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[9] << 8) + buffer[10]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else if (dev_type == 11) { // 噪声
+    device_name = "臭氧-" + postfix + std::to_string(dev_addr);
+    json_save["device_name"] = "臭氧-" + postfix + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 臭氧浓度
+    nlohmann::json temp_data;
+    temp_data["name"] = "臭氧浓度";
+    temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
+    temp_data["format"] = "0.1ppm";
+    temp_data["format_id"] = 40;
+    json_save["data"].push_back(temp_data);
+
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[11] << 8) + buffer[12]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }
+  else if (dev_type == 12) { // 蓄电池
+    device_name = "蓄电池-" + std::to_string(dev_addr);
+    json_save["device_name"] = "蓄电池-" + std::to_string(dev_addr);
+    json_save["device_id"] = dev_addr;
+
+    // 开关对象
+    nlohmann::json group_voltage;
+    group_voltage["name"] = "组电压";
+    group_voltage["value"] = (((buffer[7] << 8) + buffer[8]))/10.0;
+    group_voltage["format"] = "V";
+    group_voltage["format_id"] = 0;
+    json_save["data"].push_back(group_voltage);
+    // 模式对象
+    nlohmann::json group_current;
+    group_current["name"] = "组电流";
+    group_current["value"] = ((buffer[9] << 8) + buffer[10]) / 100.0;
+    group_current["format"] = "A";
+    group_current["format_id"] = 0;
+    json_save["data"].push_back(group_current);
+
+    for(int i = 0; i <= 8; i++) {
+      nlohmann::json sigle_voltage;
+      sigle_voltage["name"] = "电池-" + std::to_string(i+1) + " 电压";
+      sigle_voltage["value"] = ((buffer[11 + i * 2] << 8) + buffer[12 + i * 2]) / 1000.0;
+      sigle_voltage["format"] = "V";
+      sigle_voltage["format_id"] = 40;
+      json_save["data"].push_back(sigle_voltage);
+    }
+    // 模式对象
+    for(int i = 0; i <= 8; i++) {
+      nlohmann::json sigle_temp;
+      sigle_temp["name"] = "电池-" + std::to_string(i+1) + " 温度";
+      sigle_temp["value"] = ((buffer[29 + i * 2] << 8) + buffer[30 + i * 2]) / 100.0;
+      sigle_temp["format"] = "℃";
+      sigle_temp["format_id"] = 40;
+      json_save["data"].push_back(sigle_temp);
+    }
+    // 模式对象
+    for(int i = 0; i <= 8; i++) {
+      nlohmann::json sigle_resistance;
+      sigle_resistance["name"] = "电池-" + std::to_string(i+1) + " 内阻";
+      sigle_resistance["value"] = ((buffer[47 + i * 2] << 8) + buffer[48 + i * 2]) / 1000.0;
+      sigle_resistance["format"] = "mΩ";
+      sigle_resistance["format_id"] = 0;
+      json_save["data"].push_back(sigle_resistance);
+    }
+
+    for(int i = 0; i <= 8; i++) {
+      nlohmann::json sigle_volumn;
+      sigle_volumn["name"] = "电池-" + std::to_string(i+1) + " 容量";
+      sigle_volumn["value"] = ((buffer[65 + i * 2] << 8) + buffer[66 + i * 2]) / 100.0;
+      sigle_volumn["format"] = "";
+      sigle_volumn["format_id"] = 0;
+      json_save["data"].push_back(sigle_volumn);
+    }
+    // 上报周期
+    nlohmann::json report_period;
+    report_period["name"] = "上报周期";
+    report_period["value"] = ((buffer[83] << 8) + buffer[84]);
+    report_period["format"] = "s";
+    report_period["format_id"] = 0;
+    json_save["data"].push_back(report_period);
+  }else{
+    std::cout << "未知设备类型: " << dev_type << std::endl;
+  }
+
+
+//  std::cout << "devaice_name:  " << dev_name << std::endl;
+//  std::cout << "json_save: "<< json_save.dump(1) << std::endl;
+  return json_save;
+}
+
 
 // 处理客户端连接
-void TcpServer::handle_client(int client_socket) {
+void TcpServer::handle_client(int client_socket, const std::string& ip) {
     uint8_t buffer[BUFFER_SIZE];
     while (true) {
-      memset(buffer, 0, BUFFER_SIZE);
-      int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
-      if (bytes_received <= 0) {
-          // Client disconnected or error
-          std::cout << "Client disconnected or error occurred. bytes_received = " << bytes_received << std::endl;
+      // 检测连接状态
+      fd_set read_fds;
+      FD_ZERO(&read_fds);
+      FD_SET(client_socket, &read_fds);
+
+      struct timeval timeout = {1, 0};  // 1秒超时
+      int activity = select(client_socket + 1, &read_fds, nullptr, nullptr, &timeout);
+
+      if (activity < 0 && errno != EINTR) {
+        close(client_socket);
+        this->conn_num--;
+        std::cout << "连接已断开: " << this->conn_num << std::endl;
+        LOG_Debug("%s 连接已断开,当前连接数量:%d", ip.c_str(), this->conn_num);
+        break;  // 出错退出
+      }
+
+      if (FD_ISSET(client_socket, &read_fds)) {
+        memset(buffer, 0, BUFFER_SIZE);
+        int bytes_received = recv(client_socket, buffer, BUFFER_SIZE, 0);
+        if (bytes_received <= 0) {
           close(client_socket);
-          this->conn_num --;
-          std::cout << "Current connection count: " << this->conn_num << std::endl;
+          this->conn_num--;
+          std::cout << "连接已断开,当前连接数量是: " << this->conn_num << std::endl;
+          LOG_Debug("%s 连接已断开,当前连接数量:%d", ip.c_str(), this->conn_num);
           break;
-      }
-      std::cout << "Received from client, size = " << bytes_received << " data = ";
-      for(int i = 0;i < bytes_received; i++){
+        }
+        std::cout << "接收到对端消息, size = " << bytes_received << " data = ";
+        for (int i = 0; i < bytes_received; i++) {
           printf("0x%02x ", buffer[i]);
-      }
-      printf("\n");
-      if(bytes_received < 11){
-          std::cout << "too short msg!" << std::endl;
+        }
+        printf("\n");
+        if (bytes_received < 11) {
+          std::cout << "消息太短,丢弃!" << std::endl;
           continue;
-      }
+        }
 
-      // if(calculate_crc16(buffer, bytes_received - 2)){
-      uint16_t CRC = calculate_crc16(buffer, bytes_received - 2);
-      if(((buffer[bytes_received - 1]<<8) !=  (CRC&(0xff<<8))) || (buffer[bytes_received - 2] != (CRC&0xff))){
-          std::cout << "error crc msg!" << std::endl;
+        // if(calculate_crc16(buffer, bytes_received - 2)){
+        uint16_t CRC = calculate_crc16(buffer, bytes_received - 2);
+        if (((buffer[bytes_received - 1] << 8) != (CRC & (0xff << 8))) || (buffer[bytes_received - 2] != (CRC & 0xff))) {
+          std::cout << "crc错误,丢弃!" << std::endl;
           continue;
-      }
-      std::cout << "CRC = " <<  CRC <<std::endl;
+        }
+        //      std::cout << "CRC = " <<  CRC <<std::endl;
 
-      int dev_addr = buffer[0];
-      int fun_code = buffer[1];
-      int data_len = buffer[2];
-      int dev_type = buffer[6];
-      std::string device_name;
+        std::string deviceName;
+        int dev_addr = buffer[0];
 
-      nlohmann::json json_save;
+        nlohmann::json json_save = decode_modbus_msg(buffer, deviceName);
 
-      if(dev_type == 9) {
-        std::cout << "门锁" << std::endl;
-      }
-      if(dev_type == 10) {
-        std::cout << "噪声" << std::endl;
-      }
-      if(dev_type == 12) {
-        std::cout << "蓄电池" << std::endl;
-      }
-      // 公共字段
-      json_save["status"] = "run";
-      json_save["gateway_id"] = 0;
-      std::string dev_name = "device_" + std::to_string(dev_addr);
-      if (dev_type == 1) { // 温湿度
-          device_name = "温湿度-" + std::to_string(dev_addr);
-          json_save["device_name"] = "温湿度-" + std::to_string(dev_addr);
-          json_save["device_id"] = dev_addr;
-
-          // 温度对象
-          nlohmann::json temp_data;
-          temp_data["name"] = "温度";
-          temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
-          temp_data["format"] = "℃";
-          temp_data["format_id"] = 40;
-          json_save["data"].push_back(temp_data);
-
-          // 湿度对象
-          nlohmann::json humidity_data;
-          humidity_data["name"] = "湿度";
-          humidity_data["value"] = ((buffer[9] << 8) + buffer[10]);
-          humidity_data["format"] = "%RH";
-          humidity_data["format_id"] = 40;
-          json_save["data"].push_back(humidity_data);
-      } else if (dev_type == 2) { // 水浸
-          device_name = "水浸-" + std::to_string(dev_addr);
-          json_save["device_name"] = "水浸-" + std::to_string(dev_addr);
-          json_save["device_id"] = dev_addr;
-
-          // 水浸对象
-          nlohmann::json water_data;
-          water_data["name"] = "水浸状态";
-  //            water_data["value"] = ((buffer[7] << 8) + buffer[8]); // 0 表示无水浸,1 表示有水浸
-          if((buffer[7] << 8) + buffer[8] == 0)
-            water_data["value"] = "正常";
-          else
-            water_data["value"] = "告警";
-          water_data["format"] = "";
-          water_data["format_id"] = 0;
-          json_save["data"].push_back(water_data);
-
-      } else if (dev_type == 3) { // 烟感
-          device_name = "烟感-" + std::to_string(dev_addr);
-          json_save["device_name"] = "烟感-" + std::to_string(dev_addr);
-          json_save["device_id"] = dev_addr;
-
-          // 烟感对象
-          nlohmann::json smoke_data;
-          smoke_data["name"] = "报警状态";
-          if((buffer[7] << 8) + buffer[8] == 0)
-            smoke_data["value"] = "正常";
-          else
-            smoke_data["value"] = "告警";
-          smoke_data["format"] = "";
-          smoke_data["format_id"] = 0;
-          json_save["data"].push_back(smoke_data);
-      }else if (dev_type == 7) {
-        device_name = "空调-" + std::to_string(dev_addr);
-        json_save["device_name"] = "空调-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        // 开关对象
-        nlohmann::json switch_data;
-        switch_data["name"] = "开关";
-        switch_data["value"] = ((buffer[7] << 8) + buffer[8]);
-        switch_data["format"] = "";
-        switch_data["format_id"] = 0;
-        json_save["data"].push_back(switch_data);
-        // 模式对象
-        nlohmann::json mode_data;
-        mode_data["name"] = "模式";
-        mode_data["value"] = ((buffer[9] << 8) + buffer[10]);
-        mode_data["format"] = "";
-        mode_data["format_id"] = 0;
-        json_save["data"].push_back(mode_data);
-        // 模式对象
-        nlohmann::json set_temperature_data;
-        set_temperature_data["name"] = "设定温度";
-        set_temperature_data["value"] = ((buffer[11] << 8) + buffer[12]);
-        set_temperature_data["format"] = "℃";
-        set_temperature_data["format_id"] = 40;
-        json_save["data"].push_back(set_temperature_data);
-        // 模式对象
-        nlohmann::json wind_speed_data;
-        wind_speed_data["name"] = "风速";
-        wind_speed_data["value"] = ((buffer[13] << 8) + buffer[14]);
-        wind_speed_data["format"] = "";
-        wind_speed_data["format_id"] = 40;
-        json_save["data"].push_back(wind_speed_data);
-        // 模式对象
-        nlohmann::json wind_direction_data;
-        wind_direction_data["name"] = "风向";
-        wind_direction_data["value"] = ((buffer[15] << 8) + buffer[16]);
-        wind_direction_data["format"] = "";
-        wind_direction_data["format_id"] = 0;
-        json_save["data"].push_back(wind_direction_data);
-      }else if (dev_type == 6) { // 照明
-        device_name = "照明-" + std::to_string(dev_addr);
-        json_save["device_name"] = "照明-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        //开关
-        nlohmann::json switch_data;
-        switch_data["name"] = "开关";
-        switch_data["value"] = (buffer[7] << 8) + buffer[8];
-        switch_data["format"] = "";
-        switch_data["format_id"] = 0;
-        json_save["data"].push_back(switch_data);
-      }else if (dev_type == 8) { // 门磁
-        device_name = "门磁-" + std::to_string(dev_addr);
-        json_save["device_name"] = "门磁-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        //开关
-        nlohmann::json switch_data;
-        switch_data["name"] = "开关";
-        switch_data["value"]  = (buffer[7] << 8) + buffer[8];
-        switch_data["format"] = "";
-        switch_data["format_id"] = 0;
-        json_save["data"].push_back(switch_data);
-      }else if (dev_type == 5) { // 风机
-        device_name = "风机-" + std::to_string(dev_addr);
-        json_save["device_name"] = "风机-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        //开关
-        nlohmann::json switch_data;
-        switch_data["name"] = "开关";
-        switch_data["value"] = (buffer[7] << 8) + buffer[8];
-        switch_data["format"] = "";
-        switch_data["format_id"] = 0;
-        json_save["data"].push_back(switch_data);
-      }else if (dev_type == 9) { // 智能门锁
-        device_name = "智能门锁-" + std::to_string(dev_addr);
-        json_save["device_name"] = "智能门锁-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        //开关
-        nlohmann::json switch_data;
-        switch_data["name"] = "门状态";
-        switch_data["value"] = (buffer[9] << 8) + buffer[10];
-        switch_data["format"] = "";
-        switch_data["format_id"] = 0;
-        json_save["data"].push_back(switch_data);
-
-        switch_data["name"] = "门控制";
-        switch_data["value"] = (buffer[9] << 8) + buffer[10];
-        switch_data["format"] = "";
-        switch_data["format_id"] = 0;
-        json_save["data"].push_back(switch_data);
-      }else if (dev_type == 4) { // 双气
-        device_name = "双气-" + std::to_string(dev_addr);
-        json_save["device_name"] = "双气-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        // 氧气浓度
-        nlohmann::json temp_data;
-        temp_data["name"] = "氧气浓度";
-        temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
-        temp_data["format"] = "%";
-        temp_data["format_id"] = 0;
-        json_save["data"].push_back(temp_data);
-
-        // SF6浓度
-        nlohmann::json humidity_data;
-        humidity_data["name"] = "SF6浓度";
-        humidity_data["value"] = ((buffer[9] << 8) + buffer[10])/10.0;
-        humidity_data["format"] = "ppm";
-        humidity_data["format_id"] = 0;
-        json_save["data"].push_back(humidity_data);
-      }else if (dev_type == 10) { // 噪声
-        device_name = "噪声-" + std::to_string(dev_addr);
-        json_save["device_name"] = "噪声-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        // 噪声值
-        nlohmann::json temp_data;
-        temp_data["name"] = "噪声值";
-        temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
-        temp_data["format"] = "db";
-        temp_data["format_id"] = 40;
-        json_save["data"].push_back(temp_data);
-      }else if (dev_type == 11) { // 噪声
-        device_name = "臭氧-" + std::to_string(dev_addr);
-        json_save["device_name"] = "臭氧-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        // 臭氧浓度
-        nlohmann::json temp_data;
-        temp_data["name"] = "臭氧浓度";
-        temp_data["value"] = ((buffer[7] << 8) + buffer[8])/10.0;
-        temp_data["format"] = "0.1ppm";
-        temp_data["format_id"] = 40;
-        json_save["data"].push_back(temp_data);
-      }else if (dev_type == 12) { // 蓄电池
-        device_name = "蓄电池-" + std::to_string(dev_addr);
-        json_save["device_name"] = "蓄电池-" + std::to_string(dev_addr);
-        json_save["device_id"] = dev_addr;
-
-        // 开关对象
-        nlohmann::json group_voltage;
-        group_voltage["name"] = "组电压";
-        group_voltage["value"] = (((buffer[7] << 8) + buffer[8]))/10.0;
-        group_voltage["format"] = "V";
-        group_voltage["format_id"] = 0;
-        json_save["data"].push_back(group_voltage);
-        // 模式对象
-        nlohmann::json group_current;
-        group_current["name"] = "组电流";
-        group_current["value"] = ((buffer[9] << 8) + buffer[10]) / 100.0;
-        group_current["format"] = "A";
-        group_current["format_id"] = 0;
-        json_save["data"].push_back(group_current);
-
-        for(int i = 0; i <= 8; i++) {
-          nlohmann::json sigle_voltage;
-          sigle_voltage["name"] = "电池-" + std::to_string(i+1) + " 电压";
-          sigle_voltage["value"] = ((buffer[11 + i * 2] << 8) + buffer[12 + i * 2]) / 1000.0;
-          sigle_voltage["format"] = "V";
-          sigle_voltage["format_id"] = 40;
-          json_save["data"].push_back(sigle_voltage);
-        }
-        // 模式对象
-        for(int i = 0; i <= 8; i++) {
-          nlohmann::json sigle_temp;
-          sigle_temp["name"] = "电池-" + std::to_string(i+1) + " 温度";
-          sigle_temp["value"] = ((buffer[29 + i * 2] << 8) + buffer[30 + i * 2]) / 100.0;
-          sigle_temp["format"] = "℃";
-          sigle_temp["format_id"] = 40;
-          json_save["data"].push_back(sigle_temp);
-        }
-        // 模式对象
-        for(int i = 0; i <= 8; i++) {
-          nlohmann::json sigle_resistance;
-          sigle_resistance["name"] = "电池-" + std::to_string(i+1) + " 内阻";
-          sigle_resistance["value"] = ((buffer[47 + i * 2] << 8) + buffer[48 + i * 2]) / 1000.0;
-          sigle_resistance["format"] = "mΩ";
-          sigle_resistance["format_id"] = 0;
-          json_save["data"].push_back(sigle_resistance);
-        }
 
-        for(int i = 0; i <= 8; i++) {
-          nlohmann::json sigle_volumn;
-          sigle_volumn["name"] = "电池-" + std::to_string(i+1) + " 容量";
-          sigle_volumn["value"] = ((buffer[65 + i * 2] << 8) + buffer[66 + i * 2]) / 100.0;
-          sigle_volumn["format"] = "";
-          sigle_volumn["format_id"] = 0;
-          json_save["data"].push_back(sigle_volumn);
-        }
-      }else{
-        std::cout << "未知设备类型: " << dev_type << std::endl;
-        return;
-      }
+        // 添加额外信息
+        json_save["dev_addr"] = dev_addr;
+        json_save["device_name"] = deviceName;
+        // 放入队列
+        db_queue.push(json_save);
 
-      std::cout << "devaice_name  " << dev_name << "json_save "<< json_save.dump(1) << std::endl;
 
-      sqlite3 *db;
-      char *zErrMsg = 0;
-      int rc;
 
-      // 打开数据库连接
-      rc = sqlite3_open("/usr/local/bin/database/sqlite/history_data.db", &db);
-      if (rc) {
-          fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
+        sqlite3_stmt* stmt = nullptr;
+        sqlite3* db = nullptr;
+        const std::string dbPath = "/usr/local/bin/database/sqlite/device_position.db";
+
+        // 直接打开数据库(不会自动创建目录或建表)
+        if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
+          std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
+          continue;
+        }
+        // 检查设备是否已存在
+        std::string checkSQL = "SELECT COUNT(*) FROM device_position WHERE name = ?;";
+        if (sqlite3_prepare_v2(db, checkSQL.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
+          std::cerr << "Prepare failed: " << sqlite3_errmsg(db) << std::endl;
           sqlite3_close(db);
-          return;
-      }
+          continue;
+        }
 
-      // 创建表
-      const char *sql_create_table =
-          "CREATE TABLE IF NOT EXISTS history_data ("
-          "id INTEGER PRIMARY KEY AUTOINCREMENT,"
-          "data TEXT NOT NULL,"
-          "time TEXT NOT NULL,"
-          "device_id INTEGER NOT NULL,"
-          "device_name TEXT NOT NULL,"
-          "gateway_id INTEGER NOT NULL,"
-          "status TEXT NOT NULL);"
-          "PRAGMA busy_timeout = 5000;";
-
-      rc = sqlite3_exec(db, sql_create_table, sql_callback, 0, &zErrMsg);
-      if (rc != SQLITE_OK) {
-          fprintf(stderr, "SQL error: %s\n", zErrMsg);
-          sqlite3_free(zErrMsg);
-      } else {
-          printf("Table created successfully\n");
-      }
+        sqlite3_bind_text(stmt, 1, deviceName.c_str(), -1, SQLITE_STATIC);
 
-  // 插入数据
-      const char *sql_insert_data =
-          "INSERT INTO history_data (data, time, device_id, device_name, gateway_id, status) VALUES (?, ?, ?, ?, ?, ?);";
+        bool exists = false;
+        if (sqlite3_step(stmt) == SQLITE_ROW) {
+          exists = (sqlite3_column_int(stmt, 0) > 0);
+        }
+        sqlite3_finalize(stmt);
 
-      // 准备插入语句
-      sqlite3_stmt *stmt;
-      rc = sqlite3_prepare_v2(db, sql_insert_data, -1, &stmt, 0);
-      if (rc != SQLITE_OK) {
-          fprintf(stderr, "Failed to prepare statement: %s\n", sqlite3_errmsg(db));
-          sqlite3_close(db);
-          return;
-      }
+        if (exists) {
+          std::cout << "设备 [" << deviceName << "] 已存在,跳过插入。 ip=" << ip << std::endl;
 
-      // 定义要插入的数据
-      std::string sql_data = json_save["data"].dump();
-      rc = sqlite3_bind_text(stmt, 1, sql_data.c_str(),  -1, SQLITE_STATIC);
-
-      // 获取当前时间
-      time_t rawtime;
-      struct tm *timeinfo;
-      // 获取当前时间的时间戳
-      time(&rawtime);
-      // 将时间戳转换为本地时间
-      timeinfo = localtime(&rawtime);
-      // 提取年、月、日、时、分、秒
-      int year = 1900 + timeinfo->tm_year;  // tm_year 是从 1900 年开始的年数
-      int month = 1 + timeinfo->tm_mon;     // tm_mon 是从 0 开始的月份(0-11)
-      int day = timeinfo->tm_mday;          // tm_mday 是一个月中的第几天(1-31)
-      int hour = timeinfo->tm_hour;         // tm_hour 是小时(0-23)
-      int minute = timeinfo->tm_min;        // tm_min 是分钟(0-59)
-      int second = timeinfo->tm_sec;        // tm_sec 是秒(0-59)
-
-        // 打印时间信息
-        char time[30] = {};
-        sprintf(time,"%d-%02d-%02d %02d:%02d:%02d", 
-            year, month, day, hour, minute, second);
-        rc = sqlite3_bind_text(stmt, 2, time,  -1, SQLITE_STATIC);
-
-        rc = sqlite3_bind_int(stmt, 3, dev_addr);
-        rc = sqlite3_bind_text(stmt, 4, device_name.c_str(),  -1, SQLITE_STATIC);
-        rc = sqlite3_bind_int(stmt, 5, 0);
-        rc = sqlite3_bind_text(stmt, 6, "run", -1, SQLITE_STATIC);
-        if (rc != SQLITE_OK) {
-            fprintf(stderr, "Failed to bind parameters: %s\n", sqlite3_errmsg(db));
-            sqlite3_finalize(stmt);
+          if(ip == "172.16.111.60" || ip == "172.16.111.61" || ip == "172.16.111.62"
+              || ip == "172.16.111.64" || ip == "172.16.111.63" || ip == "172.16.111.65" || ip == "172.16.111.68" || ip == "172.16.111.70") {
             sqlite3_close(db);
-            return;
+            close(client_socket);
+            this->conn_num--;
+            std::cout << "连接已经断开: " << ip << "当前连接数量:" << this->conn_num << std::endl;
+            LOG_Debug("%s 连接已断开,当前连接数量:%d", ip.c_str(), this->conn_num);
+            break;
+          }
+          sqlite3_close(db);
+          continue;
         }
-        rc = sqlite3_step(stmt);
-        if (rc != SQLITE_DONE) {
-            fprintf(stderr, "Failed to execute insert: %s\n", sqlite3_errmsg(db));
+
+        // 插入新设备
+        std::string insertSQL = "INSERT INTO device_position (name, x, y) VALUES (?, 0.5, 0.25);";
+        if (sqlite3_prepare_v2(db, insertSQL.c_str(), -1, &stmt, nullptr) != SQLITE_OK) {
+          std::cerr << "Insert prepare failed: " << sqlite3_errmsg(db) << std::endl;
+          sqlite3_close(db);
+          continue;
         }
-        // 清理语句
-        sqlite3_finalize(stmt);
 
+        sqlite3_bind_text(stmt, 1, deviceName.c_str(), -1, SQLITE_STATIC);
 
-      // 关闭数据库连接
-      sqlite3_close(db);
+        if (sqlite3_step(stmt) != SQLITE_DONE) {
+          std::cerr << "插入失败: " << sqlite3_errmsg(db) << std::endl;
+          sqlite3_finalize(stmt);
+          sqlite3_close(db);
+          continue;
+        }
+        sqlite3_finalize(stmt);
+        sqlite3_close(db);
+        std::cout << "设备 [" << deviceName << "] 插入成功。" << std::endl;
 
+        if(ip == "172.16.111.60" || ip == "172.16.111.61" || ip == "172.16.111.62" || ip == "172.16.111.64"
+            || ip == "172.16.111.64" || ip == "172.16.111.63" || ip == "172.16.111.65" || ip == "172.16.111.68" || ip == "172.16.111.70") {
+          close(client_socket);
+          this->conn_num--;
+          std::cout << "连接已经断开: " << ip << "当前连接数量:" << this->conn_num << std::endl;
+          LOG_Debug("%s 连接已经断开 当前连接数量:%d", ip.c_str(), this->conn_num);
+          break;
+        }
 
-      this->conn_num--;
-      break;
+      }
 
     }
-}
+}

+ 7 - 3
modules/gateway-scheduler/src/tcp_server/TcpServer.h

@@ -11,6 +11,7 @@
 #include <mutex>
 #include <stdexcept>
 #include <cerrno>
+#include "DatabaseWorker.h"
 #define BUFFER_SIZE 1024
 
 
@@ -23,7 +24,7 @@ struct ClientAddr{
 class TcpServer {
 private:
     int server_fd;
-    struct sockaddr_in address;
+    struct sockaddr_in address{};
     socklen_t addrlen;
     bool running;
     std::thread accept_thread;
@@ -32,17 +33,20 @@ private:
     std::mutex mtx;
     int conn_num;
 
+    DatabaseQueue db_queue;
+    DatabaseWorker db_worker;
 
     std::vector<ClientAddr> client_addrs; // 存储所有客户端地址
     std::mutex mtx_client_addrs;          // 线程锁保护 client_addrs
 
 public:
-    TcpServer(int port);
+    explicit TcpServer(int port);
     ~TcpServer();
 
     void start_server();
-    void handle_client(int client_socket);
+    void handle_client(int client_socket, const std::string& ip);
     std::vector<ClientAddr> get_connected_clients();
+    void remove_connected_clients(std::string ip);
 };
 
 

+ 281 - 33
modules/gateway-server/src/large_screen_display/devices_info.cpp

@@ -1,20 +1,20 @@
 
 
-
 #include "devices_info.h"
 
-#include <iostream>
-#include <string>
-#include <vector>
-#include <experimental/filesystem>
+#include <hiredis/hiredis.h>
+#include <sqlite3.h>
 
 #include <algorithm>
-#include <map>
+#include <chrono>  // 时间相关头文件
+#include <experimental/filesystem>
 #include <fstream>
+#include <iostream>
+#include <map>
 #include <sstream>
-#include <hiredis/hiredis.h>
-#include <sqlite3.h>
-#include <chrono>  // 时间相关头文件
+#include <string>
+#include <unordered_set>
+#include <vector>
 
 namespace fs = std::experimental::filesystem;  // 使用实验性版本
 
@@ -154,6 +154,10 @@ struct AlertData {
   std::string alert_type;
   std::string alert_value;
 };
+struct StatusData {
+  std::string device_name;
+  std::string state;
+};
 json createNariAbnormalStatus(){
   sqlite3* db;
   sqlite3_stmt* stmt;
@@ -168,7 +172,8 @@ json createNariAbnormalStatus(){
   // 查询所有相关数据
   const char* sql_select_data = "SELECT device_name, time, data FROM history_data "
       "WHERE (device_name LIKE '%水浸%' OR "
-      "device_name LIKE '%烟雾%' OR "
+      "device_name LIKE '%烟感%' OR "
+      "device_name LIKE '%门磁%' OR "
       "device_name LIKE '%温湿度%')";
 
   // 准备SQL语句
@@ -209,20 +214,31 @@ json createNariAbnormalStatus(){
             });
           }
         }
-        // 烟设备检查
-        else if (device_name.find("烟") != std::string::npos) {
+        // 烟设备检查
+        else if (device_name.find("烟") != std::string::npos) {
           if (item["name"] == "报警状态" && item["value"] == 1) {
             results.push_back({
                 device_name,
                 timestamp,
-                "烟告警",
+                "烟告警",
                 "告警"
             });
           }
         }
+        // 门磁设备检查
+        else if (device_name.find("门磁") != std::string::npos) {
+          if (item["name"] == "开关" && item["value"] == 1) {
+            results.push_back({
+                device_name,
+                timestamp,
+                "门状态",
+                "开启"
+            });
+          }
+        }
         // 温湿度设备检查
         else if (device_name.find("温湿度") != std::string::npos) {
-          if (item["name"] == "温度" && item["value"].get<double>() > 50) {
+          if (item["name"] == "温度" && item["value"].get<double>() > 38.0) {
             // 方法1:使用ostringstream格式化(推荐)
             std::ostringstream oss;
             oss << std::fixed << std::setprecision(1) << item["value"].get<double>();
@@ -299,8 +315,87 @@ json createNariAbnormalStatus(){
 
 }
 
+void delete_device_history(const string& deviceName){
+  std::cout << "delete_device_history '" << deviceName  << std::endl;
+  sqlite3* db;
+  int rc = sqlite3_open("/usr/local/bin/database/sqlite/history_data.db", &db);
+
+  if (rc) {
+    std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
+    return;
+  }
+
+  std::string sql = "DELETE FROM history_data WHERE device_name = '" + deviceName + "';";
+
+  char* errMsg = nullptr;
+  rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errMsg);
+
+  if (rc != SQLITE_OK) {
+    std::cerr << "SQL 错误: " << errMsg << std::endl;
+    sqlite3_free(errMsg);
+  } else {
+    std::cout << "已删除设备 '" << deviceName << "' 的所有记录。" << std::endl;
+  }
+
+  sqlite3_close(db);
+
+}
+
+
+void set_device_position(std::string name, float x, float y) {
+  sqlite3* db;
+  const std::string dbPath = "/usr/local/bin/database/sqlite/device_position.db";
+
+  // 打开数据库连接
+  if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
+    std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
+    sqlite3_close(db); // 即使失败也尝试关闭
+    return;
+  }
+
+  // SQL: 检查是否存在该设备
+  std::string check_sql = "SELECT COUNT(*) FROM device_position WHERE name = '" + name + "';";
+  sqlite3_stmt* stmt;
+
+  int rc = sqlite3_prepare_v2(db, check_sql.c_str(), -1, &stmt, nullptr);
+  if (rc != SQLITE_OK) {
+    std::cerr << "SQL 准备失败(检查设备): " << sqlite3_errmsg(db) << std::endl;
+    sqlite3_close(db);
+    return;
+  }
+
+  bool exists = false;
+  if (sqlite3_step(stmt) == SQLITE_ROW) {
+    exists = (sqlite3_column_int(stmt, 0) > 0);
+  }
+  sqlite3_finalize(stmt);
+
+  // 如果存在,更新;否则插入
+  std::string sql;
+  if (exists) {
+    sql = "UPDATE device_position SET x = " + std::to_string(x) +
+          ", y = " + std::to_string(y) +
+          " WHERE name = '" + name + "';";
+  } else {
+    sql = "INSERT INTO device_position(name, x, y) VALUES('" + name + "', " +
+          std::to_string(x) + ", " + std::to_string(y) + ");";
+  }
+
+  // 执行 SQL
+  char* errMsg = nullptr;
+  rc = sqlite3_exec(db, sql.c_str(), nullptr, nullptr, &errMsg);
+  if (rc != SQLITE_OK) {
+    std::cerr << "SQL 错误: " << errMsg << std::endl;
+    sqlite3_free(errMsg);
+  } else {
+    std::cout << "设备 " << name << " 的位置已更新: x=" << x << ", y=" << y << std::endl;
+  }
+
+  sqlite3_close(db);
+}
+// 获取所有设备的状态
+std::vector<Device>  get_device_status() {
 
-std::vector<Device> createNariDeviceInfo() {
   sqlite3* db = nullptr;
   sqlite3_stmt* stmt = nullptr;
   std::vector<HistoryData> results;
@@ -312,9 +407,9 @@ std::vector<Device> createNariDeviceInfo() {
     throw std::runtime_error("无法打开数据库: " + std::string(sqlite3_errmsg(db)));
   }
 
-//  std::cout << "===== 111开始查询每个设备的最新记录 =====" << std::endl;
+  std::cout << "===== get_device_status 开始查询每个设备的最新记录 =====" << std::endl;
 
-        // 使用窗口函数的SQL查询(SQLite 3.25.0+)
+  // 使用窗口函数的SQL查询(SQLite 3.25.0+)
   const char* sql_select_data  = R"(
         SELECT id, data, time, device_id, device_name, gateway_id, status
         FROM (
@@ -322,7 +417,152 @@ std::vector<Device> createNariDeviceInfo() {
                    ROW_NUMBER() OVER (PARTITION BY device_name ORDER BY time DESC) as rn
             FROM history_data
         )
-        WHERE rn = 1
+        WHERE rn = 1;
+      )";
+
+  // 准备SQL语句
+  rc = sqlite3_prepare_v2(db, sql_select_data, -1, &stmt, nullptr);
+  if (rc != SQLITE_OK) {
+    throw std::runtime_error("SQL准备失败: " + std::string(sqlite3_errmsg(db)));
+  }
+  // 执行查询
+  char *zErrMsg = 0;
+  rc = sqlite3_exec(db, sql_select_data, nullptr, 0, &zErrMsg);
+  if (rc != SQLITE_OK) {
+    fprintf(stderr, "SQL error: %s\n", zErrMsg);
+    sqlite3_free(zErrMsg);
+  }
+
+  // 执行查询
+  while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+    HistoryData record;
+
+    // 安全地获取每列数据
+    record.id = sqlite3_column_int(stmt, 0);
+
+    const unsigned char* data = sqlite3_column_text(stmt, 1);
+    record.data = data ? reinterpret_cast<const char*>(data) : "";
+
+    const unsigned char* time = sqlite3_column_text(stmt, 2);
+    record.time = time ? reinterpret_cast<const char*>(time) : "";
+
+    record.device_id = sqlite3_column_int(stmt, 3);
+
+    const unsigned char* name = sqlite3_column_text(stmt, 4);
+    record.device_name = name ? reinterpret_cast<const char*>(name) : "";
+
+    record.gateway_id = sqlite3_column_int(stmt, 5);
+
+    const unsigned char* status = sqlite3_column_text(stmt, 6);
+    record.status = status ? reinterpret_cast<const char*>(status) : "";
+
+
+    results.push_back(record);
+    json jsonArray = json::parse(record.data);
+    std::vector<Measure> measures;
+    for (const auto& item : jsonArray) {
+      Measure measure;
+
+      // 提取 name 和 value
+      measure.point = item["name"].get<std::string>();
+
+      // 处理 value,它可能是数字或字符串
+      if (item["value"].is_number()) {
+
+        std::ostringstream oss;
+        oss << std::fixed << std::setprecision(1) << item["value"].get<double>();
+        measure.value = oss.str() + " " + item["format"].get<std::string>();
+      } else {
+        measure.value = item["value"].get<std::string>() + " " + item["format"].get<std::string>();
+      }
+
+      measures.push_back(measure);
+    }
+
+
+    Device device = {record.device_name, record.time,  measures};
+    devices.push_back(device);
+  }
+
+  if (rc != SQLITE_DONE) {
+    throw std::runtime_error("查询执行错误: " + std::string(sqlite3_errmsg(db)));
+  }
+
+//  std::cout << "\n===== 查询完成,共找到 " << results.size() << " 条记录 =====" << std::endl;
+  std::cout << "get_device_status 查询完成" << std::endl;
+  // 释放资源
+  if (stmt) sqlite3_finalize(stmt);
+  if (db) sqlite3_close(db);
+  return devices;
+}
+
+
+json get_device_position() {
+  std::cout << "get_device_position in" << std::endl;
+
+  json result = json::array();
+
+  sqlite3* db;
+  const std::string dbPath = "/usr/local/bin/database/sqlite/device_position.db";
+
+  if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) {
+    std::cerr << "无法打开数据库: " << sqlite3_errmsg(db) << std::endl;
+    sqlite3_close(db);
+    return result; // 返回空数组
+  }
+
+  const char* sql = "SELECT id, name, x, y FROM device_position;";
+  sqlite3_stmt* stmt;
+
+  if (sqlite3_prepare_v2(db, sql, -1, &stmt, nullptr) != SQLITE_OK) {
+    std::cerr << "SQL 准备失败: " << sqlite3_errmsg(db) << std::endl;
+    sqlite3_close(db);
+    return result;
+  }
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+    json device;
+
+    device["id"] = sqlite3_column_int(stmt, 0);
+    device["name"] = reinterpret_cast<const char*>(sqlite3_column_text(stmt, 1));
+    device["x"] = sqlite3_column_double(stmt, 2);
+    device["y"] = sqlite3_column_double(stmt, 3);
+
+    result.push_back(device);
+  }
+
+//  std::cout << "\n===== get_device_position 查询完成,共找到 " << result.size() << " 条记录 =====" << std::endl;
+
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+
+  return result;
+}
+
+std::vector<Device> createNariDeviceInfo() {
+  sqlite3* db = nullptr;
+  sqlite3_stmt* stmt = nullptr;
+  std::vector<HistoryData> results;
+  std::vector<Device> devices;
+
+  // 打开数据库连接
+  int rc = sqlite3_open("/usr/local/bin/database/sqlite/history_data.db", &db);
+  if (rc != SQLITE_OK) {
+    throw std::runtime_error("无法打开数据库: " + std::string(sqlite3_errmsg(db)));
+  }
+
+//  std::cout << "===== 111开始查询每个设备的最新记录 =====" << std::endl;
+
+        // 使用窗口函数的SQL查询(SQLite 3.25.0+)
+  const char* sql_select_data  = R"(
+      SELECT id, data, time, device_id, device_name, gateway_id, status
+      FROM (
+          SELECT *,
+                 ROW_NUMBER() OVER (PARTITION BY device_name ORDER BY time DESC) as rn
+          FROM history_data
+          WHERE time >= datetime('now', 'localtime', '-10 minute')
+      )
+      WHERE rn = 1;
     )";
 
     // 准备SQL语句
@@ -362,13 +602,13 @@ std::vector<Device> createNariDeviceInfo() {
     record.status = status ? reinterpret_cast<const char*>(status) : "";
 
     // 打印记录
-    std::cout << "\n===== 设备 " << record.device_name << " 的最新记录 =====" << std::endl;
-    std::cout << "ID: " << record.id << std::endl;
-    std::cout << "数据: " << record.data << std::endl;
-    std::cout << "时间: " << record.time << std::endl;
-    std::cout << "设备ID: " << record.device_id << std::endl;
-    std::cout << "网关ID: " << record.gateway_id << std::endl;
-    std::cout << "状态: " << record.status << std::endl;
+//    std::cout << "\n===== 设备 " << record.device_name << " 的最新记录 =====" << std::endl;
+//    std::cout << "ID: " << record.id << std::endl;
+//    std::cout << "数据: " << record.data << std::endl;
+//    std::cout << "时间: " << record.time << std::endl;
+//    std::cout << "设备ID: " << record.device_id << std::endl;
+//    std::cout << "网关ID: " << record.gateway_id << std::endl;
+//    std::cout << "状态: " << record.status << std::endl;
 
     results.push_back(record);
     json jsonArray = json::parse(record.data);
@@ -393,7 +633,7 @@ std::vector<Device> createNariDeviceInfo() {
     }
 
 
-    Device device = {record.device_name, measures};
+    Device device = {record.device_name, record.time, measures};
     devices.push_back(device);
   }
 
@@ -453,7 +693,7 @@ void get_latest_device_info(int deviceid, std::vector<Device> &devices){
       oss2 << std::fixed << std::setprecision(2) << std::stof(data[10]);
       Measure measure3 = {"电池电压", oss2.str()};
       std::vector<Measure> measures = {measure1, measure2, measure3};
-      devices.push_back({name, measures});
+      devices.push_back({name, "2025", measures});
     }else{
       fs::remove(file);
     }
@@ -624,7 +864,7 @@ std::vector<Device> get_device_status(std::string dev_name){
       m.value = std::to_string(item.value("value", 0));  // 转换 value 为 string
       measures.push_back(m);
     }
-    res.push_back({dev_name + "-"+ to_string(device_id), measures});
+    res.push_back({dev_name + "-"+ to_string(device_id), time, measures});
   }
 
   if (rc != SQLITE_DONE) {
@@ -643,11 +883,13 @@ std::vector<Device> control_devices_status() {
   std::vector<Device> air_conditions = get_device_status("空调");
   std::vector<Device> fans = get_device_status("风机");
   std::vector<Device> lights = get_device_status("照明");
+  std::vector<Device> doors = get_device_status("智能门锁");
   std::vector<Device> all_devices;
 
   all_devices.insert(all_devices.end(), air_conditions.begin(), air_conditions.end());
   all_devices.insert(all_devices.end(), fans.begin(), fans.end());
   all_devices.insert(all_devices.end(), lights.begin(), lights.end());
+  all_devices.insert(all_devices.end(), doors.begin(), doors.end());
   return all_devices;
 
 }
@@ -694,9 +936,9 @@ std::vector<Device> control_devices_status() {
 //        water_leak["value"] = (j % 2 == 0) ? 1 : 0; // 动态值
 //        values_array.push_back(water_leak);
 //      } else if (device.find("烟感") != std::string::npos) {
-//        // 烟状态数据
+//        // 烟状态数据
 //        json smoke;
-//        smoke["name"] = "烟状态";
+//        smoke["name"] = "烟状态";
 //        smoke["value"] = (j % 2 == 0) ? 1 : 0; // 动态值
 //        values_array.push_back(smoke);
 //      }
@@ -980,10 +1222,15 @@ json createNariDeviceHistoryData() {
     throw std::runtime_error("无法打开数据库: " + std::string(sqlite3_errmsg(db)));
   }
 
-  std::cout << "===== createNariDeviceHistoryData =====" << std::endl;
+//  std::cout << "===== createNariDeviceHistoryData =====" << std::endl;
 
   // 使用窗口函数的SQL查询(SQLite 3.25.0+)
-  const char* sql_select_data = "SELECT data, time, device_name FROM history_data";
+  const char* sql_select_data = R"(
+    SELECT data, time, device_name
+    FROM history_data
+    ORDER BY time DESC
+    LIMIT 8000
+)";
   // 准备SQL语句
   rc = sqlite3_prepare_v2(db, sql_select_data, -1, &stmt, nullptr);
   if (rc != SQLITE_OK) {
@@ -1039,7 +1286,7 @@ json createNariDeviceHistoryData() {
     throw std::runtime_error("查询执行错误: " + std::string(sqlite3_errmsg(db)));
   }
 
-  std::cout << "\n===== 查询完成,共找到 " << results.size() << " 条记录 =====" << std::endl;
+//  std::cout << "\n===== 查询完成,共找到 " << results.size() << " 条记录 =====" << std::endl;
   // 释放资源
   if (stmt) sqlite3_finalize(stmt);
   if (db) sqlite3_close(db);
@@ -1107,6 +1354,7 @@ json deviceInfoToJson(const std::vector<Device>& devices) {
   for (const auto& device : devices) {
     json deviceJson;
     deviceJson["device_name"] = device.device_name;
+    deviceJson["time_stamp"] = device.time_stamp;
     json measuresJson = json::array();
     for (const auto& measure : device.measures) {
       json measureJson;

+ 5 - 0
modules/gateway-server/src/large_screen_display/devices_info.h

@@ -20,6 +20,7 @@ struct Measure {
 
 struct Device {
   string device_name;
+  string time_stamp;
   vector<Measure> measures;
 };
 struct AllowDevice {
@@ -57,5 +58,9 @@ json createDeviceHistoryData(const char* start_time, const char* end_time);
 json createNariDeviceHistoryData();
 json deviceHistoryToJson(const vector<DeviceHistory>& devices_history);
 json allowDeviceInfoToJson(const vector<AllowDevice>& devices);
+json get_device_position();
+void set_device_position(std::string name, float x, float y);
 void save_cmd_to_sqlite(const std::string& device_name, const std::string& json_body);
+void delete_device_history(const string& device);
+std::vector<Device>  get_device_status();
 #endif //DEVICES_INFO_H

+ 92 - 35
modules/gateway-server/src/server/BasicServer.cpp

@@ -55,32 +55,6 @@ BasicRoute generate_route(std::string path, std::string method) { /**/
 
 MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connection, const char* url,
                                        const char* method, const char* version, const char* upload_data, size_t* upload_data_size, void** req_cls) { /**/
-  // 打印 cls
-//  std::cout << "cls: " << cls << std::endl;
-//
-//  // 打印 connection(指针地址)
-//  std::cout << "connection: " << connection << std::endl;
-//
-//  // 打印 URL
-//  std::cout << "url: " << (url ? url : "<null>") << std::endl;
-//
-//  // 打印 HTTP 方法
-//  std::cout << "method: " << (method ? method : "<null>") << std::endl;
-//
-//  // 打印 HTTP 版本
-//  std::cout << "version: " << (version ? version : "<null>") << std::endl;
-//
-//  // 打印 upload_data 和 upload_data_size
-//  if (upload_data && *upload_data_size > 0) {
-//    std::cout << "upload_data: " << std::string(upload_data, *upload_data_size) << std::endl;
-//  } else {
-//    std::cout << "upload_data: <empty or null>" << std::endl;
-//  }
-//  std::cout << "upload_data_size: " << *upload_data_size << std::endl;
-//
-//  // 打印 req_cls
-//  std::cout << "req_cls: " << *req_cls << std::endl;
-
   if (*req_cls == NULL) {
     *req_cls = new BasicRequest();
     return MHD_YES;
@@ -117,7 +91,7 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
       if (url_string.find("/video") != std::string::npos) {
 //        std::cout << "largeScreenDisplay video" << std::endl;
       } else if (url_string.find("/history_data") != std::string::npos) {
-        std::cout << "largeScreenDisplay history_data " << url_string << std::endl;
+//        std::cout << "largeScreenDisplay history_data " << url_string << std::endl;
         // 获取 GET 参数
 //        const char *start_time = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "start_time");
 //        const char *end_time = MHD_lookup_connection_value(connection, MHD_GET_ARGUMENT_KIND, "end_time");
@@ -135,15 +109,15 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
 //        std::cout << response_json.dump(4) << std::endl;
         response = response_json.dump();
       } else if (url_string.find("/devices_info") != std::string::npos) {
-        std::cout << "largeScreenDisplay devices_info" << std::endl;
+//        std::cout << "largeScreenDisplay devices_info" << std::endl;
 //        auto devices = createDeviceInfo();
         auto devices = createNariDeviceInfo();
         Json response_json = deviceInfoToJson(devices);
 //         std::cout << response_json.dump() << std::endl;
-         std::cout <<  createNariAbnormalStatus().dump() << std::endl;
+//         std::cout <<  createNariAbnormalStatus().dump() << std::endl;
         response = response_json.dump();
       } else if (url_string.find("/abnormal_status") != std::string::npos) {
-        std::cout << "largeScreenDisplay abnormal_status" << std::endl;
+//        std::cout << "largeScreenDisplay abnormal_status" << std::endl;
 //        auto devices = getAbnormalStatus();
 //          auto devices = createDeviceInfo();
         Json devices = createNariAbnormalStatus();
@@ -151,6 +125,50 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
 //        std::cout << devices.dump() << std::endl;
         response = devices.dump();
       }
+      else if (url_string.find("/get_device_position") != std::string::npos) {
+        std::cout << "largeScreenDisplay get_device_position" << std::endl;
+
+        auto devices_position = get_device_position();
+//        std::cout << devices_position.dump() << std::endl;
+        response = devices_position.dump();
+
+      }
+      else if (url_string.find("/get_device_status") != std::string::npos) {
+        std::cout << "largeScreenDisplay get_device_status" << std::endl;
+
+        auto device_status = get_device_status();
+        Json response_json = deviceInfoToJson(device_status);
+//        std::cout << response_json.dump() << std::endl;
+        response = response_json.dump();
+
+      }
+      else if (url_string.find("/set_device_position") != std::string::npos) {
+        std::cout << "largeScreenDisplay set_device_position" << std::endl;
+        BasicRequest* request = (BasicRequest*)*req_cls;
+
+        // 检查是否有数据
+        if (request->data.empty()) {
+          std::cerr << "请求体为空" << std::endl;
+          response = R"({"status":"error","message":"Empty request body"})";
+        }
+        else {
+          // 打印接收到的数据
+          std::cout << "Received POST data: " << request->data << std::endl;
+
+          nlohmann::json j = nlohmann::json::parse(request->data);
+
+          std::string name = j.value("name", "");
+          float x = j.value("x", 0.0);
+          float y = j.value("y", 0.0);
+
+          set_device_position(name, x, y);
+
+//          if (!name.empty()) {
+//            std::cout << "设备名: " << name << ", x=" << x << ", y=" << y << std::endl;
+//          }
+        }
+
+      }
     }else if (url_string.find("/control-devices-status") != std::string::npos) {
       std::cout << "largeScreenDisplay control-devices-status" << std::endl;
       auto devices = control_devices_status();
@@ -158,14 +176,13 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
 //      std::cout << response_json.dump() << std::endl;
       response = response_json.dump();
     }else if (url_string.find("/allow-device") != std::string::npos) {
-      std::cout << "largeScreenDisplay allow-device" << std::endl;
+//      std::cout << "largeScreenDisplay allow-device" << std::endl;
       auto devices = allowDevice();
       Json response_json = allowDeviceInfoToJson(devices);
       std::cout << response_json.dump() << std::endl;
       response = response_json.dump();
     }else if (url_string.find("/add-allow-device") != std::string::npos) {
-
-      std::cout << "largeScreenDisplay add-allow-device" << std::endl;
+//      std::cout << "largeScreenDisplay add-allow-device" << std::endl;
       // 获取查询参数
       const char *query = MHD_lookup_connection_value(
           connection, MHD_GET_ARGUMENT_KIND, "sensorName");
@@ -175,7 +192,7 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
       }
     }else if (url_string.find("/delete-allow-device") != std::string::npos) {
 
-      std::cout << "largeScreenDisplay delete-allow-device" << std::endl;
+//      std::cout << "largeScreenDisplay delete-allow-device" << std::endl;
       // 获取查询参数
       const char *query = MHD_lookup_connection_value(
           connection, MHD_GET_ARGUMENT_KIND, "sensorName");
@@ -183,6 +200,46 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
         //        std::string sensorName = urldecode(query); // 解码
         std::cout << "设备名称: " << query << std::endl; // "空调-3"
       }
+    }else if (url_string.find("/clear-history-data") != std::string::npos) {
+      // 获取查询参数
+      if (*req_cls == NULL) {
+        // 第一次进入此连接,分配一个新的缓冲区
+        std::string *postData = new std::string();
+        *req_cls = postData;
+        return MHD_YES;
+      }
+
+      // 获取数据并追加到缓冲区
+      std::string *postData = static_cast<std::string*>(*req_cls);
+      if (*upload_data_size > 0 && upload_data != NULL) {
+        postData->append(upload_data, *upload_data_size);
+        *upload_data_size = 0; // 清空标志位
+        return MHD_YES;
+      }
+//      save_cmd_to_sqlite(device_name, *postData);
+
+      // 数据接收完毕,开始处理
+      std::string json_body = *postData;
+      // 打印原始JSON字符串用于调试
+//      std::cout << "json_body: " << json_body << std::endl;
+      // 返回成功响应
+      json jsonData = json::parse(json_body);
+
+      // 提取字段并打印
+      string device = jsonData.value("device_name", "");
+      std::cout << "设备名: " << device << std::endl;
+      delete_device_history(device);
+
+      std::string response_str = "{\"status\": \"success\"}";
+      struct MHD_Response *response = MHD_create_response_from_buffer(
+          response_str.size(), (void*)response_str.c_str(), MHD_RESPMEM_MUST_COPY);
+      MHD_add_response_header(response, "Content-Type", "application/json");
+      int ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
+      MHD_destroy_response(response);
+
+      delete postData; // 释放缓冲区
+      *req_cls = NULL;
+      return MHD_YES;
     }else if (url_string.find("/update-device") != std::string::npos){
       // 提取设备名称
       std::string device_name = url_string.substr(strlen("/api/update-device/"));
@@ -190,7 +247,7 @@ MHD_Result BasicServer::requestHandler(void* cls, struct MHD_Connection* connect
         device_name.pop_back();
       }
 
-      std::cout << "Device name: " << device_name << std::endl;
+//      std::cout << "Device name: " << device_name << std::endl;
 
       // 初始化 con_cls 缓冲区
       if (*req_cls == NULL) {

Vissa filer visades inte eftersom för många filer har ändrats