442 Commits

Author SHA1 Message Date
随遇而安
780e5477d8 update README.md. 2022-06-20 04:46:15 +00:00
kerwincui
f302f8c8bc 配置文件改善 2022-06-18 23:46:35 +08:00
kerwincui
468ec83bfe 设备名称的bug处理 2022-06-18 23:23:48 +08:00
kerwincui
c2d884e910 设备日志界面优化 2022-06-18 23:15:04 +08:00
kerwincui
381ff00ea4 TDengine测试和优化 2022-06-18 23:14:43 +08:00
kerwincui
452c5a5903 界面优化 2022-06-18 12:28:42 +08:00
kerwincui
3795bc067b 固件版本类型调整为float 2022-06-17 01:45:20 +08:00
kerwincui
5b8f1f39f3 改进esp8266的OTA升级 2022-06-17 01:43:55 +08:00
kerwincui
0e2dd62f9c 树莓派改进ota升级 2022-06-17 01:42:19 +08:00
kerwincui
5fca93c76a esp32固件改进ota升级 2022-06-17 01:42:01 +08:00
kerwincui
1b11ffc4c8 Merge remote-tracking branch 'origin/master' into version1.2 2022-06-17 00:32:43 +08:00
kerwincui
cb338037d2 bug修复 2022-06-17 00:31:48 +08:00
kerwincui
19a6b28cb8 更新sql,增加固件状态 2022-06-16 23:44:22 +08:00
kerwincui
b9f56459d4 固件升级完善 2022-06-16 23:41:30 +08:00
kerwincui
a574bcc5aa 固件升级完善 2022-06-16 23:41:15 +08:00
kerwincui
b2fb001618 设备认证改为认证方式 2022-06-16 16:18:26 +08:00
kerwincui
5ebdb8d05e 设备摘要bug修复 2022-06-16 16:18:09 +08:00
kerwincui
13663aad63 授权界面优化 2022-06-16 01:10:50 +08:00
kerwincui
4f9ac0dca5 设备删除优化 2022-06-16 00:56:42 +08:00
kerwincui
6562746f1e 界面优化 2022-06-16 00:56:29 +08:00
kerwincui
fb75e72a43 细节调整 2022-06-15 23:09:21 +08:00
kerwincui
5cef61cc04 界面优化 2022-06-15 20:50:18 +08:00
kerwincui
e70385bd26 界面优化 2022-06-15 20:36:23 +08:00
kerwincui
f7b6883dff 图片显示优化 2022-06-15 20:30:17 +08:00
kerwincui
82d3f73eeb 分组更新问题 2022-06-15 19:12:23 +08:00
kerwincui
c9434d4be7 授权码改进 2022-06-15 17:08:15 +08:00
kerwincui
422ebf51d8 设备授权码改进 2022-06-15 16:59:42 +08:00
kerwincui
a908ca60a9 设备授权码改进 2022-06-15 16:59:27 +08:00
kerwincui
c883ec828f 后端支持我的分组筛选 2022-06-15 15:27:47 +08:00
kerwincui
b87a1dc6f0 设备分组筛选和细节优化 2022-06-15 15:27:24 +08:00
kerwincui
146d84dcab 设备认证bug处理 2022-06-14 23:45:25 +08:00
kerwincui
e32153c222 细节调整 2022-06-14 21:07:09 +08:00
随遇而安
1c56c7709b update README.md. 2022-06-14 13:03:22 +00:00
随遇而安
d0f48cfd77 update README.md. 2022-06-14 13:01:07 +00:00
随遇而安
fc34514bb3 update README.md. 2022-06-14 12:57:56 +00:00
kerwincui
a640f3f17e 解决设备列表分页问题 2022-06-14 16:48:01 +08:00
kerwincui
d8990643f4 更新日志配置 2022-06-14 16:46:51 +08:00
kerwincui
98cb6da924 更新sql文件 2022-06-14 16:46:28 +08:00
kerwincui
54ca3ab0d2 设备编辑详情报错处理 2022-06-14 16:36:46 +08:00
kerwincui
2b79c5df16 修改配置文件 2022-06-14 15:06:36 +08:00
kerwincui
31867085ea bug处理 2022-06-12 14:59:43 +08:00
kerwincui
6df3279909 Merge remote-tracking branch 'origin/master' into version1.2 2022-06-12 12:50:56 +08:00
kerwincui
550a390703 更新SDK 2022-06-12 12:50:33 +08:00
kerwincui
8b42e52db0 界面调整 2022-06-12 12:13:23 +08:00
kerwincui
2b1b73abff 细节优化 2022-06-12 02:30:02 +08:00
kerwincui
9cd08b74d1 bug处理 2022-06-12 02:06:03 +08:00
随遇而安
8355faf39e update README.md. 2022-06-11 16:14:02 +00:00
随遇而安
228b741ba5 update README.md. 2022-06-11 16:12:24 +00:00
随遇而安
e286465946 update README.md. 2022-06-11 16:12:03 +00:00
随遇而安
2904f0b43d update README.md. 2022-06-11 16:11:37 +00:00
kerwincui
5f675aa796 用户中心调整 2022-06-11 23:26:22 +08:00
kerwincui
eeac05745f 设备日志改进 2022-06-11 16:41:19 +08:00
kerwincui
33a7ba9645 多租户测试调整 2022-06-11 02:32:48 +08:00
kerwincui
8571f899da 设备列表重复问题处理 2022-06-10 21:29:46 +08:00
kerwincui
34b0cd53ea 界面细节调整 2022-06-10 17:42:15 +08:00
kerwincui
fdb2d71d2e 首页地图单击跳转 2022-06-10 16:10:29 +08:00
kerwincui
a8f6dcf882 日志添加租户和用户信息 2022-06-10 15:10:58 +08:00
kerwincui
6f2800cdb8 设备筛选bug处理 2022-06-10 13:52:44 +08:00
kerwincui
72cd1e95fd 多租户的测试调整 2022-06-10 01:34:31 +08:00
kerwincui
b6af649c30 固件添加链接 2022-06-09 17:52:21 +08:00
kerwincui
44ed5a27b3 设备解绑功能完善 2022-06-09 17:09:07 +08:00
kerwincui
0052178b5a 设备界面优化 2022-06-09 14:10:55 +08:00
kerwincui
87f7a6eb86 设备列表bug修复 2022-06-09 13:28:29 +08:00
kerwincui
5660a399b8 授权码导出功能 2022-06-09 00:04:38 +08:00
kerwincui
9dd368c883 完善设备授权 2022-06-08 23:57:40 +08:00
kerwincui
f2b80eaf2f 物模型界面细节调整 2022-06-08 15:10:22 +08:00
kerwincui
f2af26998a 解决物模型修改枚举和数组界面不更新问题 2022-06-08 14:18:21 +08:00
kerwincui
952c2e09c0 细节优化 2022-06-08 12:41:34 +08:00
kerwincui
40d6a49bfc 界面和细节优化 2022-06-08 01:58:26 +08:00
kerwincui
267d60fb1a 设备授权界面调整 2022-06-07 17:56:23 +08:00
kerwincui
70098975d5 设备授权添加状态和筛选 2022-06-07 17:56:08 +08:00
kerwincui
54dc335b02 前端bug处理 2022-06-07 14:23:57 +08:00
kerwincui
d8e35ebfc3 后端TDengine统计分类数量 2022-06-07 14:23:42 +08:00
kerwincui
653eee4e76 设备统计接口 2022-06-06 17:45:36 +08:00
kerwincui
1aa94d3e50 设备统计界面 2022-06-06 17:45:16 +08:00
kerwincui
e6ccf6ee58 分组中添加设备前端 2022-06-06 15:52:48 +08:00
kerwincui
1f7a127499 分组中添加设备 2022-06-06 15:52:32 +08:00
kerwincui
24f2e65f2b 设备修改定位字段名称,添加设备摘要 2022-06-06 13:11:06 +08:00
kerwincui
c9a036043e 完成多租户测试 2022-06-05 17:41:12 +08:00
kerwincui
edf36d3dd1 bug修复 2022-06-05 17:40:54 +08:00
kerwincui
39e7e78b3a 通知公告和新闻咨询完善 2022-06-05 15:57:06 +08:00
kerwincui
12b88d2a93 图片和文件上传优化 2022-06-05 14:51:10 +08:00
kerwincui
ba128edd40 设备添加初始化信息 2022-06-05 13:17:46 +08:00
kerwincui
ed1401ccb8 认证匹配加密认证和简单认证 2022-06-05 13:07:32 +08:00
kerwincui
4632e69def 界面调整 2022-06-05 01:18:23 +08:00
kerwincui
b7b693b6d6 界面优化 2022-06-05 00:18:42 +08:00
kerwincui
6e0becee7c 多租户调整 2022-06-05 00:18:29 +08:00
kerwincui
3fea5132ce 新闻和通知的多租户修改 2022-06-04 19:40:12 +08:00
kerwincui
c3d3d524de 添加信息栏 2022-06-04 17:00:42 +08:00
kerwincui
5423f2fb7f 界面调整 2022-06-04 13:27:49 +08:00
kerwincui
d6c69594b9 登录界面调整 2022-06-04 13:27:02 +08:00
kerwincui
f8eb314bd0 租户只能查看自己的产品、固件、分组和产品下设备以及系统定义的物模型和分类 2022-06-04 13:19:15 +08:00
kerwincui
dad1d22d69 接口 2022-06-04 00:55:52 +08:00
kerwincui
cb2aa585c4 多租户前端调整 2022-06-04 00:52:24 +08:00
kerwincui
46aa17f320 多租户接口调整 2022-06-04 00:51:14 +08:00
kerwincui
4999c2abcb 后端多租户调整 2022-06-03 17:21:51 +08:00
kerwincui
168d987779 前端多租户调整 2022-06-03 17:21:31 +08:00
kerwincui
c9623a5ec6 权限调整 2022-06-03 14:29:50 +08:00
kerwincui
f281ccc1da 界面和权限调整 2022-06-03 12:39:28 +08:00
kerwincui
e36c9849a8 界面调整 2022-06-01 14:37:33 +08:00
kerwincui
b78bf54e21 界面响应式调整 2022-05-31 22:51:59 +08:00
kerwincui
c226922f07 产品和设备编辑界面调整 2022-05-31 17:21:38 +08:00
kerwincui
1cf1a60583 登录和注册界面调整 2022-05-31 16:55:33 +08:00
kerwincui
1f9636ac96 代码优化 2022-05-30 23:07:18 +08:00
kerwincui
c768af6cf9 Arduino开发的SDK更新 2022-05-30 21:39:11 +08:00
kerwincui
1a5c9b8c39 树莓派sdk更新 2022-05-30 21:33:48 +08:00
kerwincui
96715753b0 登录注册界面调整 2022-05-30 17:47:19 +08:00
kerwincui
b6cd6975f8 设备定位优化 2022-05-30 17:01:23 +08:00
kerwincui
aab50e5a78 产品模块完善 2022-05-30 16:08:39 +08:00
kerwincui
ed5b747844 Merge remote-tracking branch 'origin/master' into version1.2 2022-05-30 14:14:49 +08:00
kerwincui
8fb9d5dba9 代码优化 2022-05-30 14:13:52 +08:00
kerwincui
6a3fab6198 docker构建测试失败,emqx安装不了 2022-05-30 03:38:09 +08:00
kerwincui
9b23b5e712 emqx安装失败 2022-05-30 03:31:19 +08:00
kerwincui
ad0cd5dd11 测试dockerfile 2022-05-30 03:27:20 +08:00
kerwincui
d057601c72 测试dockerfile 2022-05-30 03:24:04 +08:00
kerwincui
68fbd6caa0 测试镜像构建 2022-05-30 03:05:02 +08:00
kerwincui
a8f0c72a3f 测试构建 2022-05-30 02:46:24 +08:00
kerwincui
bc4686e598 测试构建 2022-05-30 02:41:35 +08:00
kerwincui
b7a5b69619 测试 2022-05-30 02:33:35 +08:00
kerwincui
4a251eccc4 测试 2022-05-30 02:29:27 +08:00
kerwincui
e944b695b1 构建镜像测试 2022-05-30 02:27:49 +08:00
kerwincui
24a0d67a33 构建镜像测试 2022-05-30 02:25:41 +08:00
随遇而安
89a85a295e update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 18:24:37 2022-05-29 18:24:37 +00:00
kerwincui
9790bff15c 测试构建docker镜像 2022-05-30 02:24:00 +08:00
kerwincui
dd8747f66b 测试镜像构建 2022-05-30 02:10:23 +08:00
随遇而安
e1b0231490 update pipeline-vue.yml for Gitee Go updated_at:2022-05-29 17:37:26 2022-05-29 17:37:27 +00:00
随遇而安
17dbdcb66a update pipeline-java.yml for Gitee Go updated_at:2022-05-29 17:36:56 2022-05-29 17:36:56 +00:00
随遇而安
badd1e414f update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 17:36:29 2022-05-29 17:36:29 +00:00
kerwincui
b6d02938fd 更新流水线配置 2022-05-30 01:34:31 +08:00
随遇而安
8e2e910b5f update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 17:25:50 2022-05-29 17:25:50 +00:00
kerwincui
1337db3dff 测试流水线docker构建镜像 2022-05-30 01:21:05 +08:00
随遇而安
36dab8cd5a update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 17:17:26 2022-05-29 17:17:27 +00:00
随遇而安
cf1fa1a0f1 update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 17:13:31 2022-05-29 17:13:31 +00:00
kerwincui
a116e4d44b 测试流水线docker构建镜像 2022-05-30 01:12:17 +08:00
随遇而安
fe122ce31a update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 16:33:22 2022-05-29 16:33:22 +00:00
随遇而安
dc59b81841 update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 16:30:44 2022-05-29 16:30:44 +00:00
kerwincui
34571698ee 删除输出目录 2022-05-29 23:54:23 +08:00
随遇而安
ed1a940238 update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 15:20:36 2022-05-29 15:20:36 +00:00
随遇而安
51b9389128 update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 15:09:50 2022-05-29 15:09:50 +00:00
随遇而安
84573a7283 update pipeline-vue.yml for Gitee Go updated_at:2022-05-29 14:51:32 2022-05-29 14:51:33 +00:00
随遇而安
2883c0c553 update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 14:31:24 2022-05-29 14:31:24 +00:00
随遇而安
497f480cad update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 14:17:34 2022-05-29 14:17:35 +00:00
随遇而安
aa9efa0121 update pipeline-vue.yml for Gitee Go updated_at:2022-05-29 14:15:13 2022-05-29 14:15:13 +00:00
随遇而安
d8010fce1e update pipeline-java.yml for Gitee Go updated_at:2022-05-29 14:14:03 2022-05-29 14:14:03 +00:00
随遇而安
076a5c2905 update pipeline-docker.yml for Gitee Go updated_at:2022-05-29 14:01:03 2022-05-29 14:01:03 +00:00
随遇而安
5866624317 add pipeline-docker.yml for Gitee Go created_at:2022-05-29 14:00:25 2022-05-29 14:00:25 +00:00
随遇而安
c9bc4ba0e2 update pipeline-vue.yml for Gitee Go updated_at:2022-05-29 13:47:32 2022-05-29 13:47:32 +00:00
随遇而安
be2fcad8dc update pipeline-java.yml for Gitee Go updated_at:2022-05-29 13:44:57 2022-05-29 13:44:57 +00:00
随遇而安
f06383e46b update .workflow/pipeline-java.yml. 2022-05-29 13:34:25 +00:00
随遇而安
16d3d26a31 重命名 .workflow/pipeline-deploy.yml 为 .workflow/pipeline-java.yml 2022-05-29 13:34:08 +00:00
随遇而安
2e0fd23695 add pipeline-vue.yml for Gitee Go created_at:2022-05-29 13:33:16 2022-05-29 13:33:16 +00:00
随遇而安
0bec7efd5c update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 13:22:32 2022-05-29 13:22:33 +00:00
随遇而安
f3a80259eb update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 13:07:06 2022-05-29 13:07:06 +00:00
随遇而安
d25592232b update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 13:01:53 2022-05-29 13:01:53 +00:00
随遇而安
042761259e update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 12:50:08 2022-05-29 12:50:08 +00:00
随遇而安
7f524eb48b update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 12:44:07 2022-05-29 12:44:07 +00:00
随遇而安
bcca79dfc1 update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 12:39:09 2022-05-29 12:39:09 +00:00
随遇而安
5c40f81e3d update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 12:34:15 2022-05-29 12:34:15 +00:00
kerwincui
1f54ec3a85 添加构建目录 2022-05-29 20:33:18 +08:00
kerwincui
4429882b60 测试持续集成 2022-05-29 20:15:28 +08:00
随遇而安
00e11e7cb6 update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 12:00:30 2022-05-29 12:00:31 +00:00
随遇而安
2714fc076f update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 11:55:44 2022-05-29 11:55:44 +00:00
随遇而安
d7fc72e45d update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 10:36:29 2022-05-29 10:36:29 +00:00
随遇而安
214a55898c update pipeline-deploy.yml for Gitee Go updated_at:2022-05-29 10:33:26 2022-05-29 10:33:26 +00:00
随遇而安
90b1eb2da0 add pipeline-deploy.yml for Gitee Go created_at:2022-05-29 10:10:48 2022-05-29 10:10:48 +00:00
随遇而安
391a5310e0 update app/README.md. 2022-05-28 18:02:39 +00:00
随遇而安
b339724a25 update README.md. 2022-05-28 15:12:49 +00:00
kerwincui
ea403c0be5 Merge remote-tracking branch 'origin/master' into version1.2 2022-05-25 16:22:39 +08:00
随遇而安
6ed91b856a update README.md. 2022-05-25 02:27:10 +00:00
kerwincui
17ef0b28ef yml文件还原 2022-05-24 19:41:14 +08:00
随遇而安
f793b62627 !36 修复查询日志和监控数据报错问题
Merge pull request !36 from xxmfl/master
2022-05-24 11:39:47 +00:00
wxy001
2788764430 2022年5月24日19:20:31 修复查询设备日志和检测数据报错问题 2022-05-24 19:20:54 +08:00
随遇而安
d31fae1077 !35 增加启动时创建TDengine数据库和日志表
Merge pull request !35 from xxmfl/master
2022-05-24 07:33:31 +00:00
wxy001
14197e7436 2022年5月24日14:34:18 增加初始化时创建数据库功能 2022-05-24 15:28:39 +08:00
wxy001
4dde2bd121 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	springboot/wumei-iot/src/main/java/com/ruoyi/iot/tdengine/init/ApplicationStarted.java
2022-05-24 15:15:52 +08:00
wxy001
6c58e34bec 2022年5月24日14:34:18 增加初始化时创建数据库功能 2022-05-24 14:34:39 +08:00
kerwincui
f07b05eaa1 Merge remote-tracking branch 'origin/master' into version1.2 2022-05-24 13:58:57 +08:00
随遇而安
315f9f8d18 update springboot/wumei-admin/src/main/resources/application-druid.yml. 2022-05-24 05:23:24 +00:00
kerwincui
ca688aa975 备注信息 2022-05-24 13:21:59 +08:00
随遇而安
d25d81967d update README.md. 2022-05-24 04:28:07 +00:00
kerwincui
8a1db44119 提示信息调整 2022-05-24 12:21:00 +08:00
随遇而安
1970b9f007 update README.md. 2022-05-24 04:16:43 +00:00
随遇而安
416935e530 update README.md. 2022-05-24 04:14:00 +00:00
kerwincui
6fc2a47527 还原配置 2022-05-24 10:29:06 +08:00
随遇而安
ba91433bb1 !33 将TDEngine相关配置移到同一个包中
Merge pull request !33 from xxmfl/master
2022-05-24 02:25:27 +00:00
wxy001
f783503b51 2022年5月24日01:05:38 还原ApplicationStart,讲TDengine相关类型和配置归于同一个包 2022-05-24 01:53:27 +08:00
wxy001
5219a0c766 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	springboot/wumei-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java
#	springboot/wumei-iot/src/main/java/com/ruoyi/iot/mqtt/EmqxService.java
#	springboot/wumei-iot/src/main/java/com/ruoyi/iot/tdengine/config/TDengineConfig.java
#	springboot/wumei-iot/src/main/resources/mapper/tdengine/DatabaseMapper.xml
#	springboot/wumei-iot/src/main/resources/mapper/tdengine/TDDeviceLogMapper.xml
2022-05-24 01:18:18 +08:00
wxy001
d032413a56 2022年5月24日01:05:38 还原ApplicationStart,讲TDengine相关类型和配置归于同一个包 2022-05-24 01:06:40 +08:00
随遇而安
8fb4f017e5 !32 增加时序数据库TDengine支持
Merge pull request !32 from xxmfl/master
2022-05-23 03:40:19 +00:00
wxy001
c43459e987 增加时序数据库TDengine存储设备日志和设备监测数据 2022-05-23 00:48:30 +08:00
wxy001
81232fbb04 2022年5月22日23:48:54 增加TDengine存储日志功能,
提供基础的新增和查询功能
2022-05-22 23:50:01 +08:00
kerwincui
34d6a676ea 设备定位方式界面 2022-05-22 01:33:38 +08:00
kerwincui
eb755f7e6f 图表样式调整 2022-05-21 10:45:01 +08:00
kerwincui
177a8fbba8 更新统计的最大数量 2022-05-20 23:54:42 +08:00
kerwincui
28ead10408 监测统计进行日期范围查询 2022-05-20 21:54:42 +08:00
wxy001
44f682c3ba 2022年5月20日19:30:44
1.集成TDengine作为日志和监测数据存储库使用
2.实现简单的新增和查询功能接口
2022-05-20 19:32:14 +08:00
kerwincui
1113ed0c50 统计 2022-05-20 17:55:02 +08:00
kerwincui
6e052c64ab 统计添加时间筛选 2022-05-20 17:54:44 +08:00
kerwincui
a2bbaeb15a 产品和设备图片同步问题处理 2022-05-20 15:54:14 +08:00
kerwincui
317c728f37 解决设备激活时间查询报错问题 2022-05-20 15:20:18 +08:00
kerwincui
767fdebe2c 解决新增、编辑产品和设备的缓存问题 2022-05-20 15:19:46 +08:00
kerwincui
475cb507cf 设备认证bug处理 2022-05-19 17:51:22 +08:00
kerwincui
eaf2eac028 字符串比较错误处理 2022-05-19 17:08:07 +08:00
kerwincui
9412466747 解决加密认证解密失败bug 2022-05-19 16:50:44 +08:00
kerwincui
b98b326674 解决分类新闻列表查询报错 2022-05-19 16:50:13 +08:00
kerwincui
dbc229b1b7 登录页修改文字 2022-05-19 16:49:02 +08:00
kerwincui
8ea10bb813 设备认证统一 2022-05-19 10:56:02 +08:00
kerwincui
7e00d8c0d6 解决多租户导致设备不显示问题 2022-05-18 20:57:05 +08:00
随遇而安
86940906ca update app/README.md. 2022-05-18 12:55:16 +00:00
随遇而安
568e4fbb25 update README.md. 2022-05-17 13:13:16 +00:00
随遇而安
2094e117c1 update README.md. 2022-05-17 07:28:10 +00:00
kerwincui
ccb0da2779 实时监测的bug修复 2022-05-16 18:55:55 +08:00
kerwincui
32f284b3c4 后端启动bug处理 2022-05-16 16:15:31 +08:00
kerwincui
3172f37090 暂时注释授权码的判断 2022-05-15 17:40:22 +08:00
kerwincui
85e3f1f6c8 还原设备实时监测代码,取消注释。 2022-05-15 17:38:35 +08:00
随遇而安
c82e65eea4 update sdk/RaspberryPi/README.md. 2022-05-14 02:58:44 +00:00
随遇而安
a0e8628e8a update sdk/RaspberryPi/README.md. 2022-05-14 02:56:57 +00:00
kerwincui
1b6f4ae53c 文档更新 2022-05-14 10:55:21 +08:00
随遇而安
7f91d1cbaa update sdk/RaspberryPi/README.md. 2022-05-14 02:50:59 +00:00
随遇而安
4018b2b02b update sdk/RaspberryPi/更多参考教程.txt. 2022-05-14 02:50:08 +00:00
kerwincui
ddd3b77182 修改文档 2022-05-14 10:49:08 +08:00
随遇而安
59cc0ad683 update sdk/RaspberryPi/README.md. 2022-05-14 02:46:27 +00:00
kerwincui
6511c32b02 更新markdown 2022-05-14 10:44:45 +08:00
kerwincui
d523a1bf1f 更新markdown文件 2022-05-14 10:39:55 +08:00
随遇而安
b65a19ad7f !31 增加对树莓派SDK的说明文件
Merge pull request !31 from YBZX/master
2022-05-14 02:31:35 +00:00
YBZX
3b75b121c4 增加对树莓派sdk说明文件 2022-05-13 15:59:09 +08:00
kerwincui
747eac3879 emq管理的权限控制调整 2022-05-13 13:43:50 +08:00
随遇而安
881bc88f5c update README.md. 2022-05-13 04:52:09 +00:00
随遇而安
23fe83f85c !30 开发完成的树莓派sdk
Merge pull request !30 from YBZX/master
2022-05-13 03:55:27 +00:00
kerwincui
0a59ea9478 规则引擎界面调整 2022-05-13 00:48:19 +08:00
YBZX
091782d000 添加树莓派sdk 2022-05-13 00:09:05 +08:00
kerwincui
bc147649c7 调整客户端界面 2022-05-12 18:07:39 +08:00
kerwincui
1b345cbbdd 第三方登录页面调整 2022-05-12 17:48:34 +08:00
kerwincui
70173b9b82 首页修改 2022-05-12 17:05:41 +08:00
kerwincui
bd4dd405d2 首页修改 2022-05-12 16:39:38 +08:00
kerwincui
bc694b8a6f 设备列表取消订阅 2022-05-12 14:25:42 +08:00
kerwincui
cd63e1eba4 注册和登录页面修改 2022-05-12 14:25:18 +08:00
kerwincui
303d6dc6b0 添加ios包文件 2022-05-10 14:10:21 +08:00
kerwincui
50e478317c apk更新 2022-05-09 20:14:16 +08:00
随遇而安
72467de6b9 update app/README.md. 2022-05-09 12:13:08 +00:00
随遇而安
0997fb4eed update app/README.md. 2022-05-09 12:12:23 +00:00
随遇而安
a6b2bed0f8 update app/README.md. 2022-05-09 12:11:25 +00:00
随遇而安
118c4814fb update app/README.md. 2022-05-09 12:10:24 +00:00
随遇而安
14f49580b9 update README.md. 2022-05-09 11:47:09 +00:00
kerwincui
1625cd0628 修改图片目录 2022-05-09 16:34:21 +08:00
随遇而安
e18d1de429 update README.md. 2022-05-09 06:35:27 +00:00
随遇而安
24b1fa84e5 update README.md. 2022-05-06 17:58:39 +00:00
随遇而安
7b715ea6e3 update app/README.md. 2022-05-06 17:58:20 +00:00
随遇而安
64c5834901 update README.md. 2022-05-06 17:57:22 +00:00
随遇而安
4217347366 update app/README.md. 2022-05-01 06:43:12 +00:00
随遇而安
cbc180ac9f update app/README.md. 2022-05-01 06:42:50 +00:00
随遇而安
2fad6d3213 重命名 sdk/arduino 为 sdk/Arduino 2022-05-01 06:29:57 +00:00
kerwincui
992e6503fd 删除无用文件 2022-05-01 14:29:25 +08:00
kerwincui
be51ff7e4d 添加目录 2022-05-01 14:27:47 +08:00
kerwincui
025c127707 添加新闻的分类Id查询 2022-04-28 15:23:11 +08:00
随遇而安
b016b32154 update README.md. 2022-04-28 06:37:44 +00:00
随遇而安
c26a7183ae update README.md. 2022-04-27 14:50:56 +00:00
随遇而安
a9e2013138 update README.md. 2022-04-27 14:47:49 +00:00
随遇而安
69e527416c !29 分享设备列表
Merge pull request !29 from woaibjb/master
2022-04-27 14:45:25 +00:00
hp
224d4e1f7e 分享设备列表接口以及sql修改 2022-04-27 18:56:51 +08:00
随遇而安
4a5d29e87e !28 设备分享
Merge pull request !28 from woaibjb/master
2022-04-27 06:16:55 +00:00
hp
cabc91f3bc 分享单个或全部设备功能实现,用户设备列表接口调整,新增别人分享给自己的设备 2022-04-27 13:05:36 +08:00
随遇而安
f5c4042f58 update README.md. 2022-04-27 04:46:27 +00:00
随遇而安
b020aa4561 update README.md. 2022-04-27 04:13:28 +00:00
随遇而安
9236004a26 update README.md. 2022-04-27 04:12:50 +00:00
随遇而安
c5b544771b update README.md. 2022-04-27 04:10:01 +00:00
随遇而安
909bc54249 update README.md. 2022-04-24 15:29:18 +00:00
随遇而安
5d49f84949 update README.md. 2022-04-24 15:27:50 +00:00
随遇而安
08b3607123 !27 qq解绑和重新绑定+ 优化登录管理界面UI
Merge pull request !27 from LemonTree/json_social_login
2022-04-24 15:23:36 +00:00
kerwincui
e86407130c 更新esp8266的SDK 2022-04-24 21:20:27 +08:00
LemonTree
afa550986a [功能]:1、跳转url 放到配置文件里面 2、优化登录管理界面 3、添加qq登录解绑和重新绑定功能 4、个人中心增加 qq绑定信息 展示view 2022-04-24 19:10:35 +08:00
LemonTree
6a5d0169a7 Merge branch 'master' into json_social_login 2022-04-24 18:26:30 +08:00
随遇而安
b6ccc1531e !26 规则引擎页面 ,错误修复
Merge pull request !26 from sxh/master
2022-04-22 08:36:20 +00:00
sxh
17438df5da 规则引擎前端错误修改 2022-04-22 16:33:33 +08:00
随遇而安
08a9aad8ab !25 EMQX模块前端优化
Merge pull request !25 from sxh/master
2022-04-22 06:29:11 +00:00
sxh
7a83ba8984 EMQX模块前端优化 2022-04-22 14:25:04 +08:00
kerwincui
83d3e58bb3 更新sql文件 2022-04-22 01:36:20 +08:00
kerwincui
e9f94c4344 配置文件修改 2022-04-22 01:31:23 +08:00
kerwincui
412bc8e5d0 界面调整 2022-04-22 01:27:20 +08:00
随遇而安
d443ebe790 update README.md. 2022-04-21 05:27:39 +00:00
随遇而安
480d82e422 update README.md. 2022-04-21 05:20:04 +00:00
随遇而安
c3185f324f update README.md. 2022-04-21 05:00:32 +00:00
随遇而安
3015b7d576 update README.md. 2022-04-21 04:58:58 +00:00
随遇而安
5a0b0ae6e2 update README.md. 2022-04-21 04:54:28 +00:00
随遇而安
6a5dc2a6c5 !24 Emqx管理功能完善
Merge pull request !24 from sxh/master
2022-04-21 04:47:03 +00:00
sxh
a236687ecd 新增以下内容1.客户端查看详情和断开连接,2.规则引擎的增删改查,3.资源的增删改查, 2022-04-21 12:43:59 +08:00
sxh
d8435da52c 细节完善 2022-04-21 09:14:21 +08:00
sxh
b0c2ed9b13 增加客户端查看详情和断开连接;规则引擎的增删改查;资源的增删改查 2022-04-21 09:01:01 +08:00
随遇而安
45a497af97 update README.md. 2022-04-20 12:11:55 +00:00
LemonTree
6510c04154 [功能]:1、只在iot使用 去除外层依赖 2022-04-20 19:58:11 +08:00
随遇而安
d8650dcaa1 !21 qq第三方登录开发
Merge pull request !21 from LemonTree/json_social_login
2022-04-20 11:54:32 +00:00
LemonTree
9bdcf7a60d [功能]:1、添加http通用接口forest 2、引入justoauth 处理第三方登录 3、大致完成qq登录代码 4、前端界面修改适配第三方登录逻辑 2022-04-20 18:31:04 +08:00
LemonTree
bb2cdebac3 [功能]:1、添加http通用接口forest 2、引入justoauth 处理第三方登录 3、大致完成qq登录代码 4、前端界面修改适配第三方登录逻辑 2022-04-20 18:30:27 +08:00
随遇而安
28bfe461dc update app/README.md. 2022-04-20 06:40:52 +00:00
kerwincui
5326e8543e bug修复 2022-04-18 14:21:36 +08:00
kerwincui
513b10d939 修改响应式界面 2022-04-17 00:44:48 +08:00
kerwincui
47d702ee76 更新sql 2022-04-17 00:44:10 +08:00
随遇而安
e44a2fe9fd update vue/src/views/iot/device/mqtt-client.vue. 2022-04-16 15:56:32 +00:00
随遇而安
9d2f87496b update vue/vue.config.js. 2022-04-16 15:55:40 +00:00
kerwincui
e2a1b673d6 添加设备重置接口 2022-04-16 23:46:39 +08:00
kerwincui
5152eb5239 登录界面修改 2022-04-16 23:45:53 +08:00
kerwincui
5b277fa130 mqtt完善 2022-04-16 21:31:09 +08:00
kerwincui
a8ab4bf2e2 修复bug 2022-04-16 20:38:37 +08:00
kerwincui
2abaae21b0 界面颜色调整 2022-04-16 16:56:52 +08:00
kerwincui
1a8d39f92d 响应式布局 2022-04-16 16:51:23 +08:00
kerwincui
a0a3987209 修改为响应式布局 2022-04-16 16:42:56 +08:00
随遇而安
63c3f0b6a2 !20 代码规范化
Merge pull request !20 from redamancy_zxp/master
2022-04-16 06:15:26 +00:00
redamancy-qian
36afa809c4 代码规范化 2022-04-16 13:57:26 +08:00
随遇而安
00d9340825 !19 update vue/src/views/iot/group/device-list.vue.
Merge pull request !19 from redamancy_zxp/N/A
2022-04-16 05:29:37 +00:00
redamancy_zxp
4de11c5f96 update vue/src/views/iot/group/device-list.vue.
修改分组添加设备可以看见其他的设备
2022-04-16 05:10:52 +00:00
随遇而安
d95e625297 update README.md. 2022-04-16 04:53:03 +00:00
随遇而安
31a64b6638 !18 多租户修改3
Merge pull request !18 from redamancy_zxp/master
2022-04-16 04:11:34 +00:00
redamancy-qian
f052bda831 zhaothird 2022-04-16 00:48:53 +08:00
随遇而安
4bc2b41a38 !17 update springboot/wumei-iot/src/main/resources/mapper/iot/FirmwareMapper.xml.
Merge pull request !17 from redamancy_zxp/N/A
2022-04-15 03:43:50 +00:00
redamancy_zxp
843492ccba update springboot/wumei-iot/src/main/resources/mapper/iot/FirmwareMapper.xml.
对于租户固件查询处做出修改,保证租户只能查看系统定义的固件和自己创建的固件
2022-04-15 03:39:53 +00:00
随遇而安
81e9ef6373 update sdk/arduino/Arduino-ESP8266/Helper.cpp. 2022-04-14 17:52:32 +00:00
随遇而安
9b1ecf7bf3 update sdk/arduino/Arduino-ESP32/Helper.h. 2022-04-14 17:51:54 +00:00
随遇而安
2651004e1c update sdk/arduino/Arduino-ESP32/Arduino-ESP32.ino. 2022-04-14 17:51:33 +00:00
随遇而安
eb2e3b911f update sdk/arduino/Arduino-ESP32/Helper.cpp. 2022-04-14 17:51:15 +00:00
随遇而安
1d4361b2cf update sdk/arduino/Arduino-ESP32/Helper.cpp. 2022-04-14 17:50:43 +00:00
kerwincui
3ac00be115 添加esp32的支持 2022-04-15 01:38:27 +08:00
随遇而安
2009fe796c !16 多租户修改2
Merge pull request !16 from redamancy_zxp/master
2022-04-14 15:48:02 +00:00
redamancy-qian
1a5df34c4f zhaoSecond 2022-04-14 23:38:46 +08:00
kerwincui
217f2d2773 界面修改 2022-04-14 20:32:44 +08:00
kerwincui
81f1ca8a23 新增App资讯相关接口 2022-04-14 20:32:28 +08:00
kerwincui
6b759faeb9 更新前端配置 2022-04-14 00:49:19 +08:00
kerwincui
3163364da3 后端新增新闻模块 2022-04-14 00:49:19 +08:00
kerwincui
69c4111f02 完善前端 2022-04-14 00:49:19 +08:00
随遇而安
8c50fe34a0 update app/README.md. 2022-04-12 04:04:09 +00:00
随遇而安
cd067db4a7 update app/README.md. 2022-04-12 04:03:19 +00:00
随遇而安
e9790da1a2 !10 授权码页面微调
Merge pull request !10 from kami0314/master
2022-04-11 09:53:42 +00:00
kami
3e65de2837 授权码页面微调 2022-04-11 17:17:20 +08:00
kerwincui
fe2ab6da14 界面调整 2022-04-11 15:10:53 +08:00
随遇而安
7a89e5646f update README.md. 2022-04-11 06:25:26 +00:00
随遇而安
1cddbd94bc !9 新增授权码功能
Merge pull request !9 from kami0314/master
2022-04-11 05:57:33 +00:00
kami
95da9027e6 +f;新增授权码功能
1、产品表添加 is_authorize 是否启用授权码字段;
2、产品授权码功能:基础增删改查、批量生成授权码、绑定设备。
2022-04-11 13:45:27 +08:00
随遇而安
0afd5fab02 update README.md. 2022-04-10 16:27:09 +00:00
随遇而安
68ed6c1c24 update README.md. 2022-04-10 15:52:22 +00:00
随遇而安
8ec1311675 update README.md. 2022-04-10 05:10:58 +00:00
随遇而安
27882d8f23 update README.md. 2022-04-10 05:08:20 +00:00
随遇而安
5623a6dd64 update README.md. 2022-04-10 05:05:19 +00:00
随遇而安
736d269c3b update app/README.md. 2022-04-10 04:41:35 +00:00
随遇而安
5bb5fbf334 update app/README.md. 2022-04-10 04:07:48 +00:00
随遇而安
3bdaeb0c29 update README.md. 2022-04-10 04:06:16 +00:00
随遇而安
4f383d9d77 update README.md. 2022-04-10 04:05:19 +00:00
随遇而安
4e0d01d5ea update app/README.md. 2022-04-09 19:41:33 +00:00
随遇而安
7f4a87722b update README.md. 2022-04-09 19:39:09 +00:00
随遇而安
1e6d392a24 update README.md. 2022-04-09 19:38:05 +00:00
随遇而安
0998dae5d4 update README.md. 2022-04-09 19:36:54 +00:00
随遇而安
446119aa5e update README.md. 2022-04-09 19:35:51 +00:00
随遇而安
182689204d update app/README.md. 2022-04-09 19:32:55 +00:00
随遇而安
8fdfcf1251 update app/README.md. 2022-04-09 19:30:54 +00:00
随遇而安
873fe19f9e update README.md. 2022-04-09 17:54:02 +00:00
kerwincui
462d5d38f8 Revert "!8 APP显示新闻模块"
This reverts commit e28c829613, reversing
changes made to 734f3e7f9d.
2022-04-09 18:53:14 +08:00
随遇而安
e28c829613 !8 APP显示新闻模块
Merge pull request !8 from sxh/master
2022-04-09 07:17:33 +00:00
sxh
af30a8d2cd 新增新闻模块(新闻分类和新闻资讯),采取多对一的模式,前端富文本新增三个依赖(支持图片拖放与缩放) 2022-04-09 14:59:05 +08:00
随遇而安
734f3e7f9d update app/README.md. 2022-04-09 05:52:59 +00:00
随遇而安
e2df0340cf update app/README.md. 2022-04-09 05:48:14 +00:00
随遇而安
e80e04351e update README.md. 2022-04-09 04:55:24 +00:00
kerwincui
cffa1ec5e8 添加apk 2022-04-09 12:49:58 +08:00
随遇而安
e6d67faaf9 update README.md. 2022-04-08 06:46:29 +00:00
kerwincui
8dde2fea92 修复bug 2022-04-08 13:23:30 +08:00
kerwincui
77178e05e8 更新图片上传组件 2022-04-08 11:24:37 +08:00
kerwincui
0521511dfd 暂时注释oauth配置 2022-04-08 11:24:09 +08:00
kerwincui
f646a360ad 添加配置 2022-04-07 01:36:43 +08:00
kerwincui
187e0e2244 修复前端bug 2022-04-07 01:35:59 +08:00
随遇而安
ee56d4ab64 update README.md. 2022-04-06 05:47:39 +00:00
随遇而安
c8207a007b update README.md. 2022-04-06 05:41:37 +00:00
随遇而安
c8a2c752c4 update README.md. 2022-04-04 07:55:11 +00:00
随遇而安
d3a8ec0a1e update README.md. 2022-04-04 07:53:55 +00:00
随遇而安
abf4229bae update README.md. 2022-04-04 07:52:41 +00:00
随遇而安
775da3c22b update README.md. 2022-04-04 07:30:16 +00:00
随遇而安
c1891dc005 update README.md. 2022-04-04 07:04:46 +00:00
随遇而安
9ab21a2d8d update README.md. 2022-04-02 05:24:40 +00:00
随遇而安
0d31f3aef9 update README.md. 2022-03-27 14:20:27 +00:00
随遇而安
02f7bd8969 update README.md. 2022-03-27 05:35:10 +00:00
随遇而安
ba0ee06f63 update README.md. 2022-03-27 05:29:02 +00:00
随遇而安
f649065d6c update README.md. 2022-03-25 12:21:01 +00:00
随遇而安
b91a823c95 update README.md. 2022-03-25 12:06:08 +00:00
随遇而安
00d5bd9bb5 update README.md. 2022-03-25 12:04:58 +00:00
随遇而安
28aa2f32bc update README.md. 2022-03-25 11:59:36 +00:00
随遇而安
5170305537 update vue/src/views/monitor/cache/index.vue. 2022-03-24 09:13:30 +00:00
随遇而安
9d923b3a08 update README.md. 2022-03-23 07:44:57 +00:00
随遇而安
41a6fdb6cd update README.md. 2022-03-23 07:42:41 +00:00
kerwincui
e3c0946553 更新yml配置 2022-03-23 14:42:02 +08:00
kerwincui
977261156b 更新配置 2022-03-23 14:27:22 +08:00
kerwincui
ff37b79f4d 忽略配置 2022-03-23 14:25:56 +08:00
kerwincui
06e7186e13 删除无用的配置 2022-03-23 14:24:19 +08:00
kerwincui
6b5ae7d2f6 更新忽略文件 2022-03-23 14:23:38 +08:00
kerwincui
5852c2ae20 更新配置 2022-03-23 14:18:44 +08:00
kerwincui
5c79a1d839 删除无用的配置文件 2022-03-23 14:17:09 +08:00
随遇而安
ad1a7a0c4c update springboot/wumei-admin/src/main/resources/application.yml. 2022-03-23 05:42:45 +00:00
随遇而安
4bbcb17f9f update springboot/wumei-admin/src/main/resources/application.yml. 2022-03-23 05:05:44 +00:00
随遇而安
be5b940a9f !7 线程池配置
Merge pull request !7 from guanshubiao/master
2022-03-23 04:56:57 +00:00
guanshubiao
600c3a4f0e 线程池的配置 2022-03-23 12:53:46 +08:00
kerwincui
503c0dddd6 update spring boot yml config 2022-03-23 00:20:43 +08:00
随遇而安
f118ab4cc7 !6 mqtt异步客户端+接收主题的业务在线程池处理
Merge pull request !6 from guanshubiao/master
2022-03-22 16:16:40 +00:00
guanshubiao
c3a991cf9c Merge remote-tracking branch 'origin/master'
# Conflicts:
#	springboot/wumei-admin/src/main/resources/application.yml
2022-03-22 23:53:35 +08:00
随遇而安
9793885107 update README.md. 2022-03-22 13:46:29 +00:00
随遇而安
401cb9846d update README.md. 2022-03-22 13:43:52 +00:00
随遇而安
8d8b2d2bb0 update README.md. 2022-03-22 13:43:02 +00:00
随遇而安
4cb4d209cf update README.md. 2022-03-22 13:41:40 +00:00
kerwincui
f34697803f 更新图片 2022-03-22 20:24:19 +08:00
kerwincui
b205f9a922 更新配置文件 2022-03-22 17:32:50 +08:00
随遇而安
bb94b3f003 update springboot/wumei-admin/src/main/resources/application.yml. 2022-03-22 09:28:21 +00:00
kerwincui
3253ef9ab4 docker配置文件更新 2022-03-22 17:03:10 +08:00
kerwincui
7a7e9827ca 更新sql 2022-03-22 17:02:56 +08:00
kerwincui
d5367fc414 修复实时监测报错问题 2022-03-22 17:02:46 +08:00
guanshubiao
940a9eda63 1.添加异步客户端MqttAsyncClient,创建client加锁,确保client唯一
2.添加线程池处理接收主题的业务事件
2022-03-22 16:06:36 +08:00
kerwincui
36f98dc3cb 更新图片 2022-03-22 10:54:04 +08:00
kerwincui
47c94df5cf 更新配置文件 2022-03-21 17:59:15 +08:00
kerwincui
389fb975c3 更新图片 2022-03-21 00:05:47 +08:00
kerwincui
cdb13035ea 添加docker相关文件 2022-03-20 23:57:07 +08:00
kerwincui
d05dd8fc62 添加Docker相关文件 2022-03-20 12:59:49 +08:00
随遇而安
6c7b3549ce update README.md. 2022-03-20 02:14:42 +00:00
随遇而安
7eb45e1590 update vue/.env.staging. 2022-03-19 14:23:56 +00:00
随遇而安
24049b5e54 update vue/.env.production. 2022-03-19 14:23:39 +00:00
随遇而安
8ed517e181 update vue/.env.development. 2022-03-19 14:23:24 +00:00
随遇而安
1f3326f16f update README.md. 2022-03-18 17:58:24 +00:00
随遇而安
9b38ba2fce update README.md. 2022-03-18 17:56:25 +00:00
随遇而安
6a35304341 update README.md. 2022-03-18 17:53:41 +00:00
随遇而安
5a39be4df6 update README.md. 2022-03-18 17:53:10 +00:00
随遇而安
e47b417f4e update README.md. 2022-03-18 17:50:12 +00:00
kerwincui
23edf7e794 接收设备消息的异常处理 2022-03-18 22:02:20 +08:00
kerwincui
1bc1fbb354 修复设备显示和Webhook时间戳问题 2022-03-18 20:28:15 +08:00
随遇而安
d81d612b1c !4 修复mqtt相关bug
Merge pull request !4 from guanshubiao/master
2022-03-18 12:14:31 +00:00
guanshubiao
3cd360e429 修复bug1-mqtt断开重连时,topic没有订阅。
修复bug2-上报property数据,如果数据解析异常,客户端将断开。
2022-03-18 14:45:07 +08:00
随遇而安
9b2c23f51a !3 修改bug
Merge pull request !3 from guanshubiao/master
2022-03-17 16:02:07 +00:00
guanshubiao
7d06b42ea6 修改bug-添加认证失败处理类 导致启用自定义认证会导致oauth授权地址不能访问 2022-03-17 23:33:48 +08:00
随遇而安
ef8e262d08 update README.md. 2022-03-17 06:36:50 +00:00
随遇而安
4eb4b43673 update README.md. 2022-03-17 06:35:13 +00:00
kerwincui
cb2bb065f9 添加图片 2022-03-17 13:26:09 +08:00
kerwincui
78fe543e5b 更新图片 2022-03-17 13:20:59 +08:00
随遇而安
759323313b update README.md. 2022-03-17 05:19:21 +00:00
kerwincui
89ecf1f29a 更新图片 2022-03-17 13:16:36 +08:00
随遇而安
5122c3f932 update README.md. 2022-03-17 05:05:15 +00:00
kerwincui
c28dc9c663 添加图片 2022-03-17 13:04:05 +08:00
随遇而安
012b373289 update README.md. 2022-03-17 04:55:44 +00:00
随遇而安
9c10303c47 update README.md. 2022-03-17 04:52:34 +00:00
随遇而安
50399c2271 update README.md. 2022-03-17 04:47:18 +00:00
随遇而安
1adcfae81d update README.md. 2022-03-17 04:45:14 +00:00
kerwincui
3486bff376 更新图片 2022-03-17 12:29:55 +08:00
304 changed files with 25615 additions and 5090 deletions

View File

@@ -1,13 +0,0 @@
### 该问题是怎么引起的?
### 重现步骤
### 报错信息

View File

@@ -1,14 +0,0 @@
### 相关的Issue
### 原因(目的、解决的问题等)
### 描述(做了什么,变更了什么)
### 测试用例(新增、改动、可能影响的功能)

View File

@@ -0,0 +1,95 @@
version: '1.0'
name: pipeline-docker
displayName: 构建镜像
triggers:
trigger: auto
push:
branches:
precise:
- master
commitMessages:
include:
- ^deploy-docker
stages:
- name: stage-5ecf171c
displayName: 项目打包
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: build@maven
name: build_maven
displayName: Maven 构建后端
jdkVersion: '8'
mavenVersion: 3.6.1
commands:
- cd ./springboot
- mvn -B clean package -Dmaven.test.skip=true
artifacts:
- name: BUILD_JAVA
path:
- ./springboot/wumei-admin/target/wumei-admin.jar
settings: []
strategy:
retry: '0'
- step: build@nodejs
name: build_nodejs
displayName: Nodejs 构建前端
nodeVersion: 14.16.0
commands:
- cd ./vue
- npm install --registry=https://registry.npm.taobao.org \
- '&& rm -rf ./dist && npm run build:prod'
artifacts:
- name: BUILD_VUE
path:
- ./vue/dist
strategy:
retry: '0'
- name: stage-f5631c9e
displayName: 上传打包文件
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: publish@general_artifacts
name: publish_general_artifacts_java
displayName: 上传后端制品
dependArtifact: BUILD_JAVA
artifactName: springboot
strategy:
retry: '0'
- step: publish@general_artifacts
name: publish_general_artifacts_vue
displayName: 上传前端制品
dependArtifact: BUILD_VUE
artifactName: vue
strategy:
retry: '0'
- name: stage-59a550ac
displayName: 构建镜像
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: build@docker
name: build_docker
displayName: 镜像构建
type: cert
certificate: kerwincui-docker
tag: kerwincui/wumei-smart:1.01
dockerfile: ./docker/Dockerfile
context: ./docker
artifacts:
- ${BUILD_JAVA}
- ${BUILD_VUE}
isCache: true
strategy:
retry: '0'
permissions:
- role: admin
members:
- kerwincui

View File

@@ -0,0 +1,64 @@
version: '1.0'
name: pipeline-java
displayName: 部署后端
triggers:
trigger: auto
push:
branches:
precise:
- master
commitMessages:
include:
- ^deploy-server
stages:
- name: stage-2c3f9607
displayName: 构建后端
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: build@maven
name: build_maven
displayName: Maven 构建
jdkVersion: '8'
mavenVersion: 3.6.1
commands:
- cd ./springboot
- mvn -B clean package -Dmaven.test.skip=true
artifacts:
- name: BUILD_JAVA
path:
- ./springboot/wumei-admin/target/wumei-admin.jar
settings: []
strategy:
retry: '0'
- name: stage-b6625c4a
displayName: 部署后端
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: deploy@agent
name: deploy_agent
displayName: 主机部署
hostGroupID: alicloud
deployArtifact:
- source: build
name: springboot
target: ~/gitee_go/deploy
dependArtifact: BUILD_JAVA
script: |-
# 请在此输入部署脚本如启动Java应用如下
# nohup java -jar test.jar > nohup.out &
echo 'Hello Gitee!'
touch springboot
strategy:
retry: '0'
strategy:
blocking: true
permissions:
- role: admin
members:
- kerwincui

View File

@@ -0,0 +1,60 @@
version: '1.0'
name: pipeline-vue
displayName: 部署前端
triggers:
trigger: auto
push:
branches:
precise:
- master
commitMessages:
include:
- ^deploy-vue
stages:
- name: stage-3761fd9a
displayName: 构建前端
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: build@nodejs
name: build_nodejs
displayName: Nodejs 构建
nodeVersion: 14.16.0
commands:
- cd ./vue
- npm install --registry=https://registry.npm.taobao.org \
- '&& rm -rf ./dist && npm run build:prod'
artifacts:
- name: BUILD_VUE
path:
- ./vue/dist
strategy:
retry: '0'
- name: stage-79a96375
displayName: 部署前端
strategy: naturally
trigger: auto
executor:
- kerwincui
steps:
- step: deploy@agent
name: deploy_agent
displayName: 主机部署
hostGroupID: alicloud
deployArtifact:
- source: build
name: vue
target: ~/gitee_go/deploy
dependArtifact: BUILD_VUE
script: |-
# 请在此输入部署脚本如启动Java应用如下
# nohup java -jar test.jar > nohup.out &
echo 'Hello Gitee!' && touch vuetest
touch vue
strategy:
retry: '0'
permissions:
- role: admin
members: []

140
README.md
View File

@@ -1,33 +1,32 @@
### 一、项目简介 ### 一、项目简介
1. 物美智能 [wumei-smart](http://wumei.live/) 是一个简单易用的生活物联网平台。可用于搭建物联网平台以及二次开发和学习。 #### 1. 物美智能 [wumei-smart](http://wumei.live/) 是一个简单易用的生活物联网平台。可用于搭建物联网平台以及二次开发和学习。
#### 2. 设备接入使用EMQX消息服务器加密认证后端采用Spring boot前端采用Vue移动端采用Uniapp数据库采用Mysql、TDengine和Redis设备端支持ESP32、ESP8266、树莓派等系统架构图如下
<img src="https://oscimg.oschina.net/oscnet/up-98eefff896394066a60d664b875a3d05d1d.png" max-width="800" />
#### 3. 项目可用于个人学习和使用,商业用途需要赞助项目,获得授权。[查看详情 >>](https://wumei.live/doc/pages/sponsor/)
#### 4. 参考设备
| [空气检测仪](https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-22657217218.2.355d14963FSV69&id=623332279126) | [Wifi通断器](https://item.taobao.com/item.htm?spm=a1z10.3-c.w4002-22657217231.57.74076af5XpmsRi&id=651305232489&qq-pf-to=pcqq.group) | [智能插座](https://item.taobao.com/item.htm?spm=a1z0d.6639537.1997196601.63.4cc47484zEjJ34&id=675275353501) | [智能开关](https://item.taobao.com/item.htm?spm=a1z0d.6639537.1997196601.72.4cc47484zEjJ34&id=675278061047) | [Wifi通断器](https://item.taobao.com/item.htm?spm=a1z0d.6639537.1997196601.31.4cc47484zEjJ34&id=662773208714) |
| :----: | :----------: |:----------: |:----------: |:----------: |
| ![](https://oscimg.oschina.net/oscnet/up-ad98a81677e5e68d660866770e3266ca4cf.png) | ![](https://oscimg.oschina.net/oscnet/up-c38ce010e18349cfa526600c60e49792738.png) | ![](https://oscimg.oschina.net/oscnet/up-4ce09be3599e3ff7ed91fe182572abd258b.jpg) | ![](https://oscimg.oschina.net/oscnet/up-c4a7971510127324d6566dd6ea95d571483.jpg) | ![](https://oscimg.oschina.net/oscnet/up-e99eb758dc5abe387e880dbcb30ee21c063.jpg) |
2. 设备接入使用EMQX消息服务器认证采用EMQX内置的Http插件对称加密认证。后端采用Spring boot前端采用Vue移动端采用Uniapp数据库采用Mysql、Redis和TDengine设备端支持硬件SDK生成例如ESP32、ESP8266、树莓派等设备模拟器采用Android和WPF框架不仅能模拟硬件设备还可以控制和监测电脑、手机。
3. 系统架构图
![系统架构图](https://github.com/kerwincui/wumei-smart/blob/master/document/sys.png?raw=true)
4. 使用流程
![使用流程图](https://raw.githubusercontent.com/kerwincui/wumei-smart/master/document/process.png)
### 二、功能 ### 二、功能
- 权限管理: 用户管理、部门管理、岗位管理、菜单管理、角色管理、字典和参数管理等 - 权限管理: 用户管理、部门管理、岗位管理、菜单管理、角色管理、字典和参数管理等
- 系统监控: 操作日志、登录日志、系统日志、在线用户、服务监控、连接池监控、缓存监控等 - 系统监控: 操作日志、登录日志、系统日志、在线用户、服务监控、连接池监控、缓存监控等
- 产品管理: 产品、产品物模型、产品分类、产品固件等 - 产品管理: 产品、产品物模型、产品分类、产品固件、授权码
- 设备管理: 控制、分组、定时、日志、统计、定位、OTA升级、影子模式、实时监测、加密认证等 - 设备管理: 控制、分组、定时、日志、统计、定位、分享、配置、OTA升级、影子模式、实时监测、加密认证等
- EMQ管理 Mqtt客户端、监听器、消息主题、消息订阅、插件管理 - EMQ管理 Mqtt客户端、监听器、消息主题、消息订阅、插件管理、规则引擎、资源
- 硬件 SDK 支持WIFI和MQTT连接、物模型响应、实时监测、定时上报监测数据、AES加密、NTP时间等 - 硬件 SDK 支持WIFI和MQTT连接、物模型响应、实时监测、定时上报监测数据、AES加密、NTP时间等
- 物模型管理: 属性(设备状态和监测数据),功能(执行特定任务),事件(设备主动上报给云端) - 物模型管理: 属性(设备状态和监测数据),功能(执行特定任务),事件(设备主动上报给云端)
- 其他功能多租户、统计、新闻资讯、通知公告、支持TDengine时序数据库
### 三、开发中功能 - 计划开发完善功能设备告警、场景联动、云云对接智能音箱、设备配网、第三方登录、短信登录、APP界面自定义、视频流处理
- 设备分享、设备告警、场景联动进度50%
- 智能音箱、多租户、APP界面自定义进度40%
- 时序数据库、分布式集群部署、Granfa监控进度30%
- 视频流处理进度0%
- 桌面端模拟器/监控进度5%
- 安卓端模拟器/监控进度0%
- App和小程序正在开发中......
### 四、技术栈 ### 四、技术栈
* 服务端 * 服务端
@@ -36,20 +35,14 @@
* Web端 * Web端
- 相关技术ES6、Vue、Vuex、Vue-router、Vue-cli、Axios、Element-ui等 - 相关技术ES6、Vue、Vuex、Vue-router、Vue-cli、Axios、Element-ui等
- 开发工具Visual Studio Code - 开发工具Visual Studio Code
* 移动端(android / ios / 微信小程序) * 移动端(Android / Ios / 微信小程序 / H5
- 相关技术uniapp、smartconfig - 相关技术uniapp、[uView](https://www.uviewui.com/)、[uChart](https://www.ucharts.cn/)
- 开发工具HBuilder - 开发工具HBuilder
* 硬件端 * 硬件端
- 相关技术: ESP-IDF、Arduino、FreeRTOS等 - 相关技术: ESP-IDF、Arduino、FreeRTOS等
- 开发工具Visual Studio Code 和 Arduino - 开发工具Visual Studio Code 和 Arduino
* 安卓端模拟器/监控
- 相关技术android
- 开发工具Android Studio
* 电脑端模拟器/监控
- 相关技术WPF
- 开发工具Visual Studio
### 五、硬件接入具体参考文档项目提供了示例SDK使用ESP8266芯片基于Arduino开发 ### 五、硬件接入
1. 设备认证 1. 设备认证
* 加密认证(推荐) * 加密认证(推荐)
* 简单认证 * 简单认证
@@ -58,31 +51,106 @@
* 发布物模型、设备信息、时钟同步相关Mqtt主题 * 发布物模型、设备信息、时钟同步相关Mqtt主题
* 订阅物模型、设备升级、时钟同步相关Mqtt主题 * 订阅物模型、设备升级、时钟同步相关Mqtt主题
###### 项目提供了示例SDK使用ESP8266芯片基于Arduino开发。设备烧录使用串口模块例如Ch340接线图如下
![烧录代码](https://oscimg.oschina.net/oscnet/up-ed61da9a62390de451715686d6a6b37c190.png)
### 六、项目目录 ### 六、项目目录
&nbsp;&nbsp;&nbsp;&nbsp; spring-boot ---------------------------------------------------- 后端<br/> &nbsp;&nbsp;&nbsp;&nbsp; spring-boot --------------- 后端<br/>
&nbsp;&nbsp;&nbsp;&nbsp; vue ------------------------------------------------------------- 前端<br /> &nbsp;&nbsp;&nbsp;&nbsp; vue ----------------------- 前端<br />
&nbsp;&nbsp;&nbsp;&nbsp; docker ---------------------------------------------------------- docker部署文件<br /> &nbsp;&nbsp;&nbsp;&nbsp; docker -------------------- docker部署文件<br />
&nbsp;&nbsp;&nbsp;&nbsp; sdk ------------------------------------------------------------- 硬件SDK<br /> &nbsp;&nbsp;&nbsp;&nbsp; sdk ----------------------- 硬件SDK<br />
&nbsp;&nbsp;&nbsp;&nbsp; download ------------------------------------------------------- 工具下载<br /> &nbsp;&nbsp;&nbsp;&nbsp; app ----------------------- 移动端打包文件
###### 移动端适配多端
|安卓/Android|苹果/IOS|微信小程序| 网页/H5|Vue2.0
| :---: | :---: | :---: | :---: |:---: |
| √ | √| √ | √ | √ |
### 七、相关文档 ### 七、相关文档
##### 权限管理基于ruoyi-vue系统Mqtt消息服务器基于EMQX4.0开源版SDK示例使用ESP8266 Core For Arduino开发 ##### 权限管理基于ruoyi-vue系统Mqtt消息服务器基于EMQX4.0开源版SDK示例使用ESP8266 Core For Arduino开发
* [项目文档(编写中...)](http://wumei.live/kerwincui/document/wiki/) * [项目文档](https://wumei.live/doc/)
* [物美智能官网](http://wumei.live/) * [物美智能官网](http://wumei.live/)
* [权限管理系统ruoyi-vue](https://gitee.com/y_project/RuoYi-Vue) * [权限管理系统ruoyi-vue](https://gitee.com/y_project/RuoYi-Vue)
* [Mqtt消息服务器EMQX4.0](https://github.com/emqx/emqx) * [Mqtt消息服务器EMQX4.0](https://github.com/emqx/emqx)
* [ESP8266 Core For Arduino](https://github.com/esp8266/Arduino) * [ESP8266 Core For Arduino](https://github.com/esp8266/Arduino)
* [uCharts高性能跨平台图表库](https://www.ucharts.cn)
* [TDengine时序数据库](https://www.taosdata.com/?zh)
##### Docker快速安装
* Mysql中创建wumei-smart数据库[导入Sql脚本](https://gitee.com/kerwincui/wumei-smart/tree/master/springboot/sql)
* 修改命令中的Mysql配置并执行
```
docker run \
--name wumei-smart \
--env DB_HOST=localhost:3306 \
--env DB_NAME=wumei-smart \
--env DB_USER=root \
--env DB_PASSWORD=wumei-smart \
--publish 80:80 \
--publish 1883:1883 \
--publish 8083:8083 \
--volume /var/wumei-smart/java/uploadPath:/var/wumei-smart/java/uploadPath \
--restart unless-stopped \
--detach \
kerwincui/wumei-smart:1.1
```
### 八、其他 ### 八、其他
* 互助交流群1073236354 * 互助交流群1073236354
* [演示地址>>](https://iot.wumei.live/) * [演示地址>>](https://iot.wumei.live/)
* 小程序演示
![](https://oscimg.oschina.net/oscnet/up-a6feaa7aa6ea54551bd9feb97ebfb0ff206.jpg)
##### 项目贡献者
|[小驿物联](https://gitee.com/iot-xiaoyi) |[Guanshubiao](https://gitee.com/guanshubiao)|[CrazyDull](https://gitee.com/crazyDull) |[Kami0314](https://github.com/kami0314)|[YBZX](https://github.com/YBZX)
|--|--|--|--|--|
| [SXH](https://gitee.com/sixiaohu) | [Redamancy_zxp](https://gitee.com/redamancy-zxp) | [LEE](https://gitee.com/yueming188) | [LemonTree](https://gitee.com/fishhunterplus) | [Tang](https://gitee.com/mexiaotang)
|--|--|--|--|--|
| [xxmfl](https://gitee.com/xxmfl) |
|--|
### 九、界面图片 ### 九、部分图片
* web端
![](https://oscimg.oschina.net/oscnet/up-75a392de73aff6110e7345399aed1cc78fb.png)
![](https://oscimg.oschina.net/oscnet/up-94aa4573358d29b485d71bb251964d2bfb3.png)
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-60ff517f5362f4c7b98bb4cb3df543e4ecb.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d9dd014cec34b6424eb6d768e362356a622.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-cefbaf28d2ea5438b17dbad53638852519b.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-20672c691106771f3a38168c0f6c6a7bf20.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-75e099216e1fa33f5e83989838ffd1b16fa.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-51d2ae913a83a542fc2c3b6f802dc34369f.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-287864587ec8116ee8be115a94d1d6f9302.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-2b0a744a83f939b6694dc33c7b80193029b.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-c8c388b20e70f6a668749aab94d214b8270.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-cc512e6367b55a3afa78bee7e1cd8c8cab9.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-457424f66db64e5e66d200d94a0d42358ad.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-bf47113b636fa96ceaf9607df795f8b3a17.png"/></td>
</tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-e05690366e11fb173cebafcba57b5567e38.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-f7856cca6a3dd60afafd1cb0e1ae67c596e.png"/></td>
</tr>
</table>

47
app/README.md Normal file
View File

@@ -0,0 +1,47 @@
<br />
* 项目可用于个人学习;商业使用请赞助该项目,获得授权;
* 赞助后还提供了小程序、APP源码和相关教程。[详情](https://wumei.live/doc/pages/sponsor/)
#### 移动端介绍
|安卓/Android|苹果/IOS|微信小程序| 网页/H5|Vue2.0
| :---: | :---: | :---: | :---: |:---: |
| √ | √| √ | √ | √ |
1. 项目使用uniapp开发适配小程序、安卓、苹果和H5其他平台未测试。
2. UI框架使用uView2.0
3. 组件使用easycom模式只要组件安装在项目的components目录下或uni_modules目录下并符合components/组件名称/组件名称.vue目录结构。就可以不用引用、注册直接在页面中使用。
4. 开发工具为Hbuilder3.3版本,版本不易过低。
###### 项目结构
```
├─apis // 接口管理
│ ├─modules // api模块化目录
│ │ └─device.js // 设备接口地址
│ ├─http.api.js // 接口定义文件
│ └─http.interceptor // 拦截器
├─common // 公共文件
│ ├─config // 环境配置 (设置baseurl等)
│ ├─extend // 扩展原型方法
│ ├─filters // 全局过滤器
│ └─tools // 全局公共方法
├─components // 项目组件库,组件放置这里,其他页面可直接使用
│ ├─cl-test // easycom测试组件
│ └─cl-icon // iconfont图标组件
├─pages // 页面目录
│ ├─public // 公共页面
│ └─tarbar // 底部导航栏页面
├─static // 图片目录
├─store // vuex
│ ├─$u.mixin // store全局混入方法
│ └─index // vuex 组件全局状态管理
├─uni_modules // 插件市场插件目录
│ └─uview-ui // uview-ui
```
<br /><br />

BIN
app/wumei.apk Normal file

Binary file not shown.

BIN
app/wumei.ipa Normal file

Binary file not shown.

72
docker/Dockerfile Normal file
View File

@@ -0,0 +1,72 @@
FROM openjdk:8u322-jre-slim-buster
ENV VERSION 1.1
ENV AUTHOR kerwincui
ENV INFO wumei smart open source living iot platform
ENV SERVERS nginx:1.14.2, redis-server:5.0.14, emqx:4.0, openjdk:8u322-jre-slim-buster
# mysql环境变量
ENV DB_HOST localhost
ENV DB_NAME wumei
ENV DB_USER root
ENV DB_PASSWORD admin
RUN apt-get update && \
echo "1. 安装网络工具和设置时区 =====================" && \
apt-get install wget -y --no-install-recommends && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "2. 更换国内源 =============================" && \
wget http://qiniu.xiwen.online/Debian10.list && \
mv Debian10.list /etc/apt/sources.list && \
apt update && apt upgrade -y && \
echo "3. 安装压缩工具 ============================" && \
apt install zip -y && \
echo "4. 安装nginx ==============================" && \
apt-get install nginx -y --no-install-recommends && \
echo "5. 安装redis ===============================" && \
apt-get install redis-server -y --no-install-recommends && \
echo "6. 修改redis配置 =============================" && \
sed -i "s/# requirepass foobared/requirepass wumei-smart/g" /etc/redis/redis.conf && \
sed -i "s/bind 127.0.0.1/# bind 127.0.0.1/g" /etc/redis/redis.conf
# echo "6. 安装 emqx =============================" && \
# apt update && apt install -y \
# apt-transport-https \
# ca-certificates \
# curl \
# gnupg-agent \
# software-properties-common && \
# echo "6.2 添加EMQX官方GPG秘钥 =============================" && \
# curl -fsSL https://repos.emqx.io/gpg.pub | apt-key add - && \
# echo "6.3 设置存储库 =============================" && \
# add-apt-repository \
# "deb [arch=amd64] https://repos.emqx.io/emqx-ce/deb/ubuntu/ \
# ./bionic \
# stable" && \
# echo "6.4 更新apt包索引 =============================" && \
# apt update && \
# echo "6.5 安装4.0版本 =============================" && \
# apt install emqx=4.0.0 -y --no-install-recommends
# 复制emqx和Nginx的配置文件
# COPY ./emqx4.0/emqx.conf /etc/emqx/emqx.conf
# COPY ./emqx4.0/emqx_auth_http.conf /etc/emqx/plugins/emqx_auth_http.conf
# COPY ./emqx4.0/emqx_web_hook.conf /etc/emqx/plugins/emqx_web_hook.conf
# COPY ./emqx4.0/loaded_plugins /var/lib/emqx/loaded_plugins
COPY ./nginx.conf /etc/nginx/nginx.conf
# 解压前端和后端文件并放置到对应位置
# 启动脚本
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
# 映射端口
EXPOSE 80 1883 8083

48
docker/description.txt Normal file
View File

@@ -0,0 +1,48 @@
# 服务启动
service nginx start
service redis-server start
service mysql start
emqx start
java -jar /var/wumei-smart/app.jar
# 镜像构建
docker build -t wumei-smart:1.0 .
# 复制文件到容器
docker cp wumei-smart/* container:/var/wumei-smart/
# 镜像导出导入
docker export container| docker import - kerwincui/wumei-smart:1.0
# 镜像推送
阿里云镜像registry.cn-chengdu.aliyuncs.com/kerwincui/wumei-smart:1.0
docker tag wumei-smart kerwincui/wumei-smart:1.0
docker push kerwinci/wumei-smart:1.0
# 容器运行
docker run \
--name wumei-smart \
--env DB_HOST=wumei.live:3306 \
--env DB_NAME=wumei-smart \
--env DB_USER=root \
--env DB_PASSWORD=wumei-smart \
--publish 80:80 \
--publish 1883:1883 \
--publish 8083:8083 \
--volume /var/wumei-smart/java/uploadPath:/var/wumei-smart/java/uploadPath \
--restart unless-stopped \
--detach \
kerwincui/wumei-smart:1.1
--publish 18083:18083 \
--publish 8084:8084 \
--publish 8883:8883 \
--publish 8081:8081 \
--publish 6379:6379 \
--publish 8080:8080 \
--volume /var/wumei-smart/java/logs:/var/wumei-smart/java/logs \
--volume /var/wumei-smart/nginx/nginx.conf:/etc/nginx/nginx.conf \
--volume /var/wumei-smart/nginx/error.log:/var/log/nginx/error.log \
--volume /var/wumei-smart/redis/redis.conf:/etc/redis/redis.conf \
--volume /var/wumei-smart/redis/redis-server.log:/var/log/redis/redis-server.log \
--volume /var/wumei-smart/emqx/emqx.conf:/etc/emqx/emqx.conf \
--volume /var/wumei-smart/emqx/log:/var/log/emqx \

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# start service
startTime=$(date "+%Y-%m-%d %H:%M:%S")
echo $startTime : wumei-smart is starting, please waiting ...
# 提取jar包配置文件
cd /var/wumei-smart/java
unzip app.jar BOOT-INF/classes/application-druid.yml
# 修改mysql配置
sed -i "s/{DB_HOST}/$DB_HOST/g" BOOT-INF/classes/application-druid.yml
sed -i "s/{DB_NAME}/$DB_NAME/g" BOOT-INF/classes/application-druid.yml
sed -i "s/{DB_USER}/$DB_USER/g" BOOT-INF/classes/application-druid.yml
sed -i "s/{DB_PASSWORD}/$DB_PASSWORD/g" BOOT-INF/classes/application-druid.yml
# 配置文件写入jar包并删除提取的配置
zip app.jar BOOT-INF/classes/application-druid.yml
rm -rf BOOT-INF
service nginx start
service redis-server start
emqx start
java -jar /var/wumei-smart/java/app.jar
while true
do
time=$(date "+%Y-%m-%d %H:%M:%S")
echo $time : wumei-smart is running...
sleep 3600
done

2061
docker/emqx4.0/emqx.conf Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,133 @@
##--------------------------------------------------------------------
## HTTP Auth/ACL Plugin
##--------------------------------------------------------------------
##------------------------------------------------------------------------------
## SSL options
## Path to the file containing PEM-encoded CA certificates. The CA certificates
## are used during server authentication and when building the client certificate chain.
##
## Value: File
## auth.http.ssl.cacertfile = /etc/emqx/certs/ca.pem
## The path to a file containing the client's certificate.
##
## Value: File
## auth.http.ssl.certfile = /etc/emqx/certs/client-cert.pem
## Path to a file containing the client's private PEM-encoded key.
##
## Value: File
## auth.http.ssl.keyfile = /etc/emqx/certs/client-key.pem
##--------------------------------------------------------------------
## HTTP Request Headers
##
## Example: auth.http.header.Accept-Encoding = *
##
## Value: String
## auth.http.header.Accept = */*
##--------------------------------------------------------------------
## Authentication request.
##
## Variables:
## - %u: username
## - %c: clientid
## - %a: ipaddress
## - %r: protocol
## - %P: password
## - %p: sockport of server accepted
## - %C: common name of client TLS cert
## - %d: subject of client TLS cert
##
## Value: URL
auth.http.auth_req = http://localhost:8080/iot/tool/mqtt/auth
## Value: post | get | put
auth.http.auth_req.method = post
## Value: Params
auth.http.auth_req.params = clientid=%c,username=%u,password=%P
##--------------------------------------------------------------------
## Superuser request.
##
## Variables:
## - %u: username
## - %c: clientid
## - %a: ipaddress
## - %r: protocol
## - %P: password
## - %p: sockport of server accepted
## - %C: common name of client TLS cert
## - %d: subject of client TLS cert
##
## Value: URL
# auth.http.super_req = http://127.0.0.1:8991/mqtt/superuser
## Value: post | get | put
# auth.http.super_req.method = post
## Value: Params
# auth.http.super_req.params = clientid=%c,username=%u
##--------------------------------------------------------------------
## ACL request.
##
## Variables:
## - %A: 1 | 2, 1 = sub, 2 = pub
## - %u: username
## - %c: clientid
## - %a: ipaddress
## - %r: protocol
## - %m: mountpoint
## - %t: topic
##
## Value: URL
# auth.http.acl_req = http://127.0.0.1:8991/mqtt/acl
## Value: post | get | put
# auth.http.acl_req.method = get
## Value: Params
# auth.http.acl_req.params = access=%A,username=%u,clientid=%c,ipaddr=%a,topic=%t,mountpoint=%m
##------------------------------------------------------------------------------
## Http Reqeust options
## Time-out time for the http request, 0 is never timeout.
##
## Value: Duration
## -h: hour, e.g. '2h' for 2 hours
## -m: minute, e.g. '5m' for 5 minutes
## -s: second, e.g. '30s' for 30 seconds
##
## Default: 0
## auth.http.request.timeout = 0
## Connection time-out time, used during the initial request
## when the client is connecting to the server
##
## Value: Duration
##
## Default is same with the timeout option
## auth.http.request.connect_timout = 0
## Re-send http reuqest times
##
## Value: integer
##
## Default: 3
auth.http.request.retry_times = 3
## The interval for re-sending the http request
##
## Value: Duration
##
## Default: 1s
auth.http.request.retry_interval = 1s
## The 'Exponential Backoff' mechanism for re-sending request. The actually
## re-send time interval is `interval * backoff ^ times`
##
## Value: float
##
## Default: 2.0
auth.http.request.retry_backoff = 2.0

View File

@@ -0,0 +1,22 @@
web.hook.api.url = http://localhost:8080/iot/tool/mqtt/webhook
## Encode message payload field
##
## Value: base64 | base62
##
## Default: undefined
## web.hook.encode_payload = base64
# web.hook.rule.client.connect.1 = {"action": "on_client_connect"}
# web.hook.rule.client.connack.1 = {"action": "on_client_connack"}
web.hook.rule.client.connected.1 = {"action": "on_client_connected"}
web.hook.rule.client.disconnected.1 = {"action": "on_client_disconnected"}
# web.hook.rule.client.subscribe.1 = {"action": "on_client_subscribe"}
# web.hook.rule.client.unsubscribe.1 = {"action": "on_client_unsubscribe"}
# web.hook.rule.session.subscribed.1 = {"action": "on_session_subscribed"}
# web.hook.rule.session.unsubscribed.1 = {"action": "on_session_unsubscribed"}
# web.hook.rule.session.terminated.1 = {"action": "on_session_terminated"}
# web.hook.rule.message.publish.1 = {"action": "on_message_publish"}
# web.hook.rule.message.delivered.1 = {"action": "on_message_delivered"}
# web.hook.rule.message.acked.1 = {"action": "on_message_acked"}

View File

@@ -0,0 +1,8 @@
{emqx_management,true}.
{emqx_recon,true}.
{emqx_retainer,true}.
{emqx_dashboard,true}.
{emqx_rule_engine,true}.
{emqx_bridge_mqtt,false}.
{emqx_auth_http,true}.
{emqx_web_hook,true}.

View File

@@ -0,0 +1,61 @@
FROM openjdk:8u322-jre-slim-buster
ENV VERSION 1.1
ENV AUTHOR kerwincui
ENV INFO wumei smart open source living iot platform
ENV SERVERS nginx:1.14.2, redis-server:5.0.14, emqx:4.0, openjdk:8u322-jre-slim-buster
# mysql环境变量
ENV DB_HOST localhost
ENV DB_NAME wumei
ENV DB_USER root
ENV DB_PASSWORD admin
RUN apt-get update && \
# 安装网络工具和设置时区
apt-get install wget -y --no-install-recommends && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
# 更换国内源
wget http://qiniu.xiwen.online/Debian10.list && \
mv Debian10.list /etc/apt/sources.list && \
apt update && apt upgrade -y && \
# 安装压缩工具
apt install zip -y && \
# 安装nginx和redis
apt-get install nginx -y --no-install-recommends && \
apt-get install redis-server -y --no-install-recommends && \
# 安装 emqx
apt update && apt install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg-agent \
software-properties-common && \
curl -fsSL https://repos.emqx.io/gpg.pub | apt-key add - && \
add-apt-repository \
"deb [arch=amd64] https://repos.emqx.io/emqx-ce/deb/ubuntu/ \
./bionic \
stable" && \
apt update && \
apt install emqx=4.0.0 -y --no-install-recommends && \
# 修改redis配置
sed -i "s/# requirepass foobared/requirepass wumei-smart/g" /etc/redis/redis.conf && \
sed -i "s/bind 127.0.0.1/# bind 127.0.0.1/g" /etc/redis/redis.conf
# 复制emqx和Nginx的配置文件
COPY ./emqx4.0/emqx.conf /etc/emqx/emqx.conf
COPY ./emqx4.0/emqx_auth_http.conf /etc/emqx/plugins/emqx_auth_http.conf
COPY ./emqx4.0/emqx_web_hook.conf /etc/emqx/plugins/emqx_web_hook.conf
COPY ./emqx4.0/loaded_plugins /var/lib/emqx/loaded_plugins
COPY ./nginx.conf /etc/nginx/nginx.conf
# 拷贝前后端压缩文件到容器,容器内解压后删除
COPY ./wumei-smart.tar /var/
RUN cd /var && tar -xvf wumei-smart.tar && rm wumei-smart.tar
# 启动脚本
COPY docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
# 映射端口
EXPOSE 80 1883 8083

View File

@@ -0,0 +1,48 @@
# 服务启动
service nginx start
service redis-server start
service mysql start
emqx start
java -jar /var/wumei-smart/app.jar
# 镜像构建
docker build -t wumei-smart:1.0 .
# 复制文件到容器
docker cp wumei-smart/* container:/var/wumei-smart/
# 镜像导出导入
docker export container| docker import - kerwincui/wumei-smart:1.0
# 镜像推送
阿里云镜像registry.cn-chengdu.aliyuncs.com/kerwincui/wumei-smart:1.0
docker tag wumei-smart kerwincui/wumei-smart:1.0
docker push kerwinci/wumei-smart:1.0
# 容器运行
docker run \
--name wumei-smart \
--env DB_HOST=wumei.live:3306 \
--env DB_NAME=wumei-smart \
--env DB_USER=root \
--env DB_PASSWORD=wumei-smart \
--publish 80:80 \
--publish 1883:1883 \
--publish 8083:8083 \
--volume /var/wumei-smart/java/uploadPath:/var/wumei-smart/java/uploadPath \
--restart unless-stopped \
--detach \
kerwincui/wumei-smart:1.1
--publish 18083:18083 \
--publish 8084:8084 \
--publish 8883:8883 \
--publish 8081:8081 \
--publish 6379:6379 \
--publish 8080:8080 \
--volume /var/wumei-smart/java/logs:/var/wumei-smart/java/logs \
--volume /var/wumei-smart/nginx/nginx.conf:/etc/nginx/nginx.conf \
--volume /var/wumei-smart/nginx/error.log:/var/log/nginx/error.log \
--volume /var/wumei-smart/redis/redis.conf:/etc/redis/redis.conf \
--volume /var/wumei-smart/redis/redis-server.log:/var/log/redis/redis-server.log \
--volume /var/wumei-smart/emqx/emqx.conf:/etc/emqx/emqx.conf \
--volume /var/wumei-smart/emqx/log:/var/log/emqx \

View File

@@ -0,0 +1,32 @@
#!/bin/bash
# start service
startTime=$(date "+%Y-%m-%d %H:%M:%S")
echo $startTime : wumei-smart is starting, please waiting ...
# 提取jar包配置文件
cd /var/wumei-smart/java
unzip app.jar BOOT-INF/classes/application-druid.yml
# 修改mysql配置
sed -i "s/{DB_HOST}/$DB_HOST/g" BOOT-INF/classes/application-druid.yml
sed -i "s/{DB_NAME}/$DB_NAME/g" BOOT-INF/classes/application-druid.yml
sed -i "s/{DB_USER}/$DB_USER/g" BOOT-INF/classes/application-druid.yml
sed -i "s/{DB_PASSWORD}/$DB_PASSWORD/g" BOOT-INF/classes/application-druid.yml
# 配置文件写入jar包并删除提取的配置
zip app.jar BOOT-INF/classes/application-druid.yml
rm -rf BOOT-INF
service nginx start
service redis-server start
emqx start
java -jar /var/wumei-smart/java/app.jar
while true
do
time=$(date "+%Y-%m-%d %H:%M:%S")
echo $time : wumei-smart is running...
sleep 3600
done

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,133 @@
##--------------------------------------------------------------------
## HTTP Auth/ACL Plugin
##--------------------------------------------------------------------
##------------------------------------------------------------------------------
## SSL options
## Path to the file containing PEM-encoded CA certificates. The CA certificates
## are used during server authentication and when building the client certificate chain.
##
## Value: File
## auth.http.ssl.cacertfile = /etc/emqx/certs/ca.pem
## The path to a file containing the client's certificate.
##
## Value: File
## auth.http.ssl.certfile = /etc/emqx/certs/client-cert.pem
## Path to a file containing the client's private PEM-encoded key.
##
## Value: File
## auth.http.ssl.keyfile = /etc/emqx/certs/client-key.pem
##--------------------------------------------------------------------
## HTTP Request Headers
##
## Example: auth.http.header.Accept-Encoding = *
##
## Value: String
## auth.http.header.Accept = */*
##--------------------------------------------------------------------
## Authentication request.
##
## Variables:
## - %u: username
## - %c: clientid
## - %a: ipaddress
## - %r: protocol
## - %P: password
## - %p: sockport of server accepted
## - %C: common name of client TLS cert
## - %d: subject of client TLS cert
##
## Value: URL
auth.http.auth_req = http://localhost:8080/iot/tool/mqtt/auth
## Value: post | get | put
auth.http.auth_req.method = post
## Value: Params
auth.http.auth_req.params = clientid=%c,username=%u,password=%P
##--------------------------------------------------------------------
## Superuser request.
##
## Variables:
## - %u: username
## - %c: clientid
## - %a: ipaddress
## - %r: protocol
## - %P: password
## - %p: sockport of server accepted
## - %C: common name of client TLS cert
## - %d: subject of client TLS cert
##
## Value: URL
# auth.http.super_req = http://127.0.0.1:8991/mqtt/superuser
## Value: post | get | put
# auth.http.super_req.method = post
## Value: Params
# auth.http.super_req.params = clientid=%c,username=%u
##--------------------------------------------------------------------
## ACL request.
##
## Variables:
## - %A: 1 | 2, 1 = sub, 2 = pub
## - %u: username
## - %c: clientid
## - %a: ipaddress
## - %r: protocol
## - %m: mountpoint
## - %t: topic
##
## Value: URL
# auth.http.acl_req = http://127.0.0.1:8991/mqtt/acl
## Value: post | get | put
# auth.http.acl_req.method = get
## Value: Params
# auth.http.acl_req.params = access=%A,username=%u,clientid=%c,ipaddr=%a,topic=%t,mountpoint=%m
##------------------------------------------------------------------------------
## Http Reqeust options
## Time-out time for the http request, 0 is never timeout.
##
## Value: Duration
## -h: hour, e.g. '2h' for 2 hours
## -m: minute, e.g. '5m' for 5 minutes
## -s: second, e.g. '30s' for 30 seconds
##
## Default: 0
## auth.http.request.timeout = 0
## Connection time-out time, used during the initial request
## when the client is connecting to the server
##
## Value: Duration
##
## Default is same with the timeout option
## auth.http.request.connect_timout = 0
## Re-send http reuqest times
##
## Value: integer
##
## Default: 3
auth.http.request.retry_times = 3
## The interval for re-sending the http request
##
## Value: Duration
##
## Default: 1s
auth.http.request.retry_interval = 1s
## The 'Exponential Backoff' mechanism for re-sending request. The actually
## re-send time interval is `interval * backoff ^ times`
##
## Value: float
##
## Default: 2.0
auth.http.request.retry_backoff = 2.0

View File

@@ -0,0 +1,22 @@
web.hook.api.url = http://localhost:8080/iot/tool/mqtt/webhook
## Encode message payload field
##
## Value: base64 | base62
##
## Default: undefined
## web.hook.encode_payload = base64
# web.hook.rule.client.connect.1 = {"action": "on_client_connect"}
# web.hook.rule.client.connack.1 = {"action": "on_client_connack"}
web.hook.rule.client.connected.1 = {"action": "on_client_connected"}
web.hook.rule.client.disconnected.1 = {"action": "on_client_disconnected"}
# web.hook.rule.client.subscribe.1 = {"action": "on_client_subscribe"}
# web.hook.rule.client.unsubscribe.1 = {"action": "on_client_unsubscribe"}
# web.hook.rule.session.subscribed.1 = {"action": "on_session_subscribed"}
# web.hook.rule.session.unsubscribed.1 = {"action": "on_session_unsubscribed"}
# web.hook.rule.session.terminated.1 = {"action": "on_session_terminated"}
# web.hook.rule.message.publish.1 = {"action": "on_message_publish"}
# web.hook.rule.message.delivered.1 = {"action": "on_message_delivered"}
# web.hook.rule.message.acked.1 = {"action": "on_message_acked"}

View File

@@ -0,0 +1,8 @@
{emqx_management,true}.
{emqx_recon,true}.
{emqx_retainer,true}.
{emqx_dashboard,true}.
{emqx_rule_engine,true}.
{emqx_bridge_mqtt,false}.
{emqx_auth_http,true}.
{emqx_web_hook,true}.

View File

@@ -0,0 +1,97 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64K;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
server {
listen 80;
server_name localhost;
location / {
rewrite ^(.*) https://$server_name$1 permanent;
}
}
server {
# 侦听443端口
listen 443 ssl;
# 定义访问域名
server_name localhost;
#证书文件名称
ssl_certificate domain_bundle.crt;
#私钥文件名称
ssl_certificate_key domain.key;
#SSL-START SSL相关配置请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#HTTP_TO_HTTPS_START
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
ssl_session_timeout 10m;
#请按照以下协议配置
ssl_protocols TLSv1.2 TLSv1.3;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
# web端
location / {
root /var/wumei-smart/vue;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
# 服务端接口
location /prod-api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/;
}
# emqx接口
location /api/v4/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8081/api/v4/;
}
# wss连接
location /mqtt {
proxy_pass http://localhost:8083/mqtt;
proxy_read_timeout 90s;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

View File

@@ -0,0 +1,55 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64K;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root /var/wumei-smart/vue;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/;
}
location /api/v4/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8081/api/v4/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

97
docker/nginx-ssl.conf Normal file
View File

@@ -0,0 +1,97 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64K;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
server {
listen 80;
server_name localhost;
location / {
rewrite ^(.*) https://$server_name$1 permanent;
}
}
server {
# 侦听443端口
listen 443 ssl;
# 定义访问域名
server_name localhost;
#证书文件名称
ssl_certificate domain_bundle.crt;
#私钥文件名称
ssl_certificate_key domain.key;
#SSL-START SSL相关配置请勿删除或修改下一行带注释的404规则
#error_page 404/404.html;
#HTTP_TO_HTTPS_START
if ($server_port !~ 443){
rewrite ^(/.*)$ https://$host$1 permanent;
}
ssl_session_timeout 10m;
#请按照以下协议配置
ssl_protocols TLSv1.2 TLSv1.3;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
# web端
location / {
root /var/wumei-smart/vue;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
# 服务端接口
location /prod-api/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/;
}
# emqx接口
location /api/v4/{
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8081/api/v4/;
}
# wss连接
location /mqtt {
proxy_pass http://localhost:8083/mqtt;
proxy_read_timeout 90s;
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-for $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'Upgrade';
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

55
docker/nginx.conf Normal file
View File

@@ -0,0 +1,55 @@
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
gzip on;
gzip_min_length 1k;
gzip_buffers 16 64K;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
server {
listen 80;
server_name localhost;
charset utf-8;
location / {
root /var/wumei-smart/vue;
try_files $uri $uri/ /index.html;
index index.html index.htm;
}
location /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8080/;
}
location /api/v4/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://localhost:8081/api/v4/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 368 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 474 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

BIN
document/images/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
document/images/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

BIN
document/images/device.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
document/images/flash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
document/images/group.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

BIN
document/images/index.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
document/images/message.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
document/images/model.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

BIN
document/images/monitor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
document/images/process.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

BIN
document/images/product.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 KiB

BIN
document/images/sys.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1,7 @@
{
"port": "COM3",
"configuration": "FlashFreq=80,UploadSpeed=921600",
"board": "esp32:esp32:nano32",
"output": "./build",
"sketch": "Arduino-Esp32.ino"
}

View File

@@ -0,0 +1,85 @@
/***********************************************************
* author: LaoHuang
* create: 2022-04-14
* emailrememberyousaid@163.com
* source:https://github.com/kerwincui/wumei-smart
* board:esp32 版本 1.0.6
***********************************************************/
#include "Helper.h"
long lastMqttConn; // 上次mqtt连接时间
long lastPublishMonitor; // 上次发布监测数据时间
long lastTimerMonitor; // 上次定时发布监测数据
/**
* 启动
*/
void setup()
{
//打开串行端口:
Serial.begin(115200);
printMsg("wumei smart device starting...");
connectWifi();
connectMqtt();
}
/**
* 循环执行
*/
void loop()
{
// Wifi掉线重连
if (WiFi.status() != WL_CONNECTED)
{
connectWifi();
}
// 非阻塞Mqtt重连间隔30秒
if (WiFi.status() == WL_CONNECTED)
{
long now = millis();
if (!mqttClient.connected())
{
if (now - lastMqttConn > 30000)
{
lastMqttConn = now;
connectMqtt();
}
}
else
{
mqttClient.loop();
}
}
// 非阻塞发布实时监测数据,间隔默认1秒
if(WiFi.status() == WL_CONNECTED && monitorCount>0){
long now = millis();
if (now - lastPublishMonitor > monitorInterval)
{
lastPublishMonitor = now;
monitorCount--;
publishMonitor();
}
}
// 非阻塞定时上报测试用60秒发布一次
if(WiFi.status() == WL_CONNECTED){
long now = millis();
if (now - lastTimerMonitor > 60000)
{
lastTimerMonitor = now;
printMsg("执行定时上报");
// 发布事件
publishEvent();
// 发布时钟同步
publishNtp();
// 发布属性(监测值)
String msg=randomPropertyData();
publishProperty(msg);
}
}
}

View File

@@ -0,0 +1,545 @@
/***********************************************************
* author: LaoHuang
* create: 2022-04-14
* emailrememberyousaid@163.com
* source:https://github.com/kerwincui/wumei-smart
* board:esp32 版本1.0.6
***********************************************************/
#include "Helper.h"
String g_time;
WiFiClient wifiClient;
PubSubClient mqttClient;
float rssi = 0;
char wumei_iv[17] = "wumei-smart-open";
int monitorCount = 0;
long monitorInterval = 1000;
//==================================== 这是需要配置的项 ===============================
// Wifi配置
char *wifiSsid = "wifi-ssid";
char *wifiPwd = "wifi-password";
// 设备信息配置
String deviceNum = "D6329VL54419L1Y0";
String userId = "1";
String productId = "2";
float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude=0;
float longitude=0;
// Mqtt配置
char *mqttHost = "wumei.live";
int mqttPort = 1883;
char *mqttUserName = "wumei-smart";
char *mqttPwd = "P5FJKZJHIR82GNB2";
char mqttSecret[17] = "K63C4EA3AI5TER97";
// 产品启用授权码,则授权码不能为空
String authCode="";
// NTP地址用于获取时间,可选的修改为自己部署项目的地址)
String ntpServer = "http://wumei.live:8080/iot/tool/ntp?deviceSendTime=";
//====================================================================================
// 订阅的主题
String prefix = "/" + productId + "/" + deviceNum;
String sOtaTopic = prefix + "/ota/get";
String sNtpTopic = prefix + "/ntp/get";
String sPropertyTopic = prefix + "/property/get";
String sFunctionTopic = prefix + "/function/get";
String sPropertyOnline = prefix + "/property-online/get";
String sFunctionOnline = prefix + "/function-online/get";
String sMonitorTopic = prefix + "/monitor/get";
// 发布的主题
String pInfoTopic = prefix + "/info/post";
String pNtpTopic = prefix + "/ntp/post";
String pPropertyTopic = prefix + "/property/post";
String pFunctionTopic = prefix + "/function/post";
String pMonitorTopic = prefix + "/monitor/post";
String pEventTopic = prefix + "/event/post";
// 物模型-属性处理
void processProperty(String payload)
{
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject object : doc.as<JsonArray>())
{
// 匹配云端定义的属性(不包含属性中的监测数据)
const char *id = object["id"];
const char *value = object["value"];
printMsg((String)id + "" + (String)value);
}
// 最后发布属性,服务端订阅存储(重要)
publishProperty(payload);
}
// 物模型-功能处理
void processFunction(String payload)
{
StaticJsonDocument<1024> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
for (JsonObject object : doc.as<JsonArray>())
{
// 匹配云端定义的功能
const char *id = object["id"];
const char *value = object["value"];
if (strcmp(id, "switch") == 0)
{
printMsg("开关 switch" + (String)value);
}
else if (strcmp(id, "gear") == 0)
{
printMsg("档位 gear" + (String)value);
}
else if (strcmp(id, "light_color") == 0)
{
printMsg("灯光颜色 light_color" + (String)value);
}
else if (strcmp(id, "message") == 0)
{
printMsg("屏显消息 message" + (String)value);
}
else if (strcmp(id, "report_monitor") == 0)
{
String msg = randomPropertyData();
printMsg("订阅到上报监测数据指令,上报数据:");
printMsg(msg);
publishProperty(msg);
}
}
// 最后发布功能,服务端订阅存储(重要)
publishFunction(payload);
}
// Mqtt回调
void callback(char *topic, byte *payload, unsigned int length)
{
blink();
printMsg("接收数据:");
String data = "";
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
data += (char)payload[i];
}
if (strcmp(topic, sOtaTopic.c_str()) == 0)
{
printMsg("订阅到设备升级指令...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
String newVersion = doc["version"];
String downloadUrl = doc["downloadUrl"];
printMsg("固件版本:"+newVersion);
printMsg("下载地址:"+downloadUrl);
}
else if (strcmp(topic, sNtpTopic.c_str()) == 0)
{
printMsg("订阅到NTP时间...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
float deviceSendTime = doc["deviceSendTime"];
float serverSendTime = doc["serverSendTime"];
float serverRecvTime = doc["serverRecvTime"];
float deviceRecvTime = millis();
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
printMsg("当前时间:" + String(now, 0));
}
else if (strcmp(topic, sPropertyTopic.c_str()) == 0 || strcmp(topic, sPropertyOnline.c_str()) == 0)
{
printMsg("订阅到属性指令...");
processProperty(data);
}
else if (strcmp(topic, sFunctionTopic.c_str()) == 0 || strcmp(topic, sFunctionOnline.c_str()) == 0)
{
printMsg("订阅到功能指令...");
processFunction(data);
}
else if (strcmp(topic, sMonitorTopic.c_str()) == 0)
{
printMsg("订阅到实时监测指令...");
StaticJsonDocument<128> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
monitorCount = doc["count"];
monitorInterval = doc["interval"];
}
}
// 连接wifi
void connectWifi()
{
printMsg("连接 ");
Serial.print(wifiSsid);
WiFi.mode(WIFI_STA);
WiFi.begin(wifiSsid, wifiPwd);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
printMsg("WiFi连接成功");
printMsg("IP地址: ");
Serial.print(WiFi.localIP());
}
// 连接mqtt
void connectMqtt()
{
printMsg("连接Mqtt服务器...");
// 生成mqtt认证密码(设备加密认证密码加密格式为mqtt密码 & 过期时间 & 授权码,其中授权码为可选)
String password = generationPwd();
String encryptPassword = encrypt(password, mqttSecret, wumei_iv);
printMsg("密码(已加密)" + encryptPassword);
mqttClient.setClient(wifiClient);
mqttClient.setServer(mqttHost, mqttPort);
mqttClient.setCallback(callback);
mqttClient.setBufferSize(1024);
mqttClient.setKeepAlive(10);
//连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
String clientId = "E&" + deviceNum + "&" + productId +"&" + userId;
bool connectResult = mqttClient.connect(clientId.c_str(), mqttUserName, encryptPassword.c_str());
if (connectResult)
{
printMsg("连接成功");
// 订阅(OTA、NTP、属性、功能、实时监测)
mqttClient.subscribe(sOtaTopic.c_str(), 1);
mqttClient.subscribe(sNtpTopic.c_str(), 1);
mqttClient.subscribe(sPropertyTopic.c_str(), 1);
mqttClient.subscribe(sFunctionTopic.c_str(), 1);
mqttClient.subscribe(sPropertyOnline.c_str(), 1);
mqttClient.subscribe(sFunctionOnline.c_str(), 1);
mqttClient.subscribe(sMonitorTopic.c_str(), 1);
printMsg("订阅主题:" + sOtaTopic);
printMsg("订阅主题:" + sNtpTopic);
printMsg("订阅主题:" + sPropertyTopic);
printMsg("订阅主题:" + sFunctionTopic);
printMsg("订阅主题:" + sPropertyOnline);
printMsg("订阅主题:" + sFunctionOnline);
printMsg("订阅主题:" + sMonitorTopic);
// 发布设备信息
publishInfo();
}
else
{
printMsg("连接失败, rc=");
Serial.print(mqttClient.state());
}
}
// 1.发布设备信息
void publishInfo()
{
StaticJsonDocument<256> doc;
doc["rssi"] = WiFi.RSSI();
doc["firmwareVersion"] = firmwareVersion;
doc["status"] = 3; // 1-未激活2-禁用3-在线4-离线)
doc["userId"] = (String)userId;
doc["longitude"] = longitude; //经度 可选
doc["latitude"] = latitude; // 纬度 可选
// 设备摘要,可选(自定义配置信息,不限数量)
JsonObject summary = doc.createNestedObject("summary");
summary["name"]="wumei-smart";
summary["chip"]="esp8266";
summary["author"]="kerwincui";
summary["version"]=1.6;
summary["create"]="2022-06-06";
printMsg("发布设备信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
mqttClient.publish(pInfoTopic.c_str(), output.c_str());
}
// 2.发布时钟同步信,用于获取当前时间(可选)
void publishNtp()
{
StaticJsonDocument<128> doc;
doc["deviceSendTime"] = millis();
printMsg("发布NTP信息:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
mqttClient.publish(pNtpTopic.c_str(), output.c_str());
}
// 3.发布属性
void publishProperty(String msg)
{
printMsg("发布属性:" + msg);
mqttClient.publish(pPropertyTopic.c_str(), msg.c_str());
}
// 4.发布功能
void publishFunction(String msg)
{
printMsg("发布功能:" + msg);
mqttClient.publish(pFunctionTopic.c_str(), msg.c_str());
}
// 5.发布事件
void publishEvent()
{
// 匹配云端的事件
StaticJsonDocument<512> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "height_temperature";
objTmeperature["value"] = "40";
objTmeperature["remark"] = "温度过高警告";
JsonObject objException = doc.createNestedObject();
objException["id"] = "exception";
objException["value"] = "异常消息消息内容XXXXXXXX";
objException["remark"] = "设备发生错误";
printMsg("发布事件:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
mqttClient.publish(pEventTopic.c_str(), output.c_str());
}
// 6.发布实时监测数据
void publishMonitor()
{
String msg = randomPropertyData();
// 发布为实时监测数据,不会存储
printMsg("发布实时监测数据:" + msg);
mqttClient.publish(pMonitorTopic.c_str(), msg.c_str());
}
// 随机生成监测值
String randomPropertyData()
{
// 匹配云端定义的监测数据,随机数代替监测结果
float randFloat = 0;
int randInt = 0;
StaticJsonDocument<1024> doc;
JsonObject objTmeperature = doc.createNestedObject();
objTmeperature["id"] = "temperature";
randFloat = random(1000, 3000);
objTmeperature["value"] = (String)(randFloat / 100);
objTmeperature["remark"] = (String)millis();
JsonObject objHumidity = doc.createNestedObject();
objHumidity["id"] = "humidity";
randFloat = random(3000, 6000);
objHumidity["value"] = (String)(randFloat / 100);
objHumidity["remark"] = (String)millis();
JsonObject objCo2 = doc.createNestedObject();
objCo2["id"] = "co2";
randInt = random(400, 1000);
objCo2["value"] = (String)(randInt);
objCo2["remark"] = (String)millis();
JsonObject objBrightness = doc.createNestedObject();
objBrightness["id"] = "brightness";
randInt = random(1000, 10000);
objBrightness["value"] = (String)(randInt);
objBrightness["remark"] = (String)millis();
printMsg("随机生成监测数据值:");
serializeJson(doc, Serial);
String output;
serializeJson(doc, output);
return output;
}
// 生成密码
String generationPwd()
{
String jsonTime = getTime();
printMsg("getTime()= " + jsonTime);
// 128字节内存池容量
StaticJsonDocument<128> doc;
// 解析JSON
DeserializationError error = deserializeJson(doc, jsonTime);
if (error)
{
printMsg("Json解析失败");
Serial.print(error.f_str());
return "";
}
// 获取当前时间
float deviceSendTime = doc["deviceSendTime"];
float serverSendTime = doc["serverSendTime"];
float serverRecvTime = doc["serverRecvTime"];
float deviceRecvTime = millis();
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
// 过期时间 = 当前时间 + 1小时
float expireTime = now + 1 * 60 * 60 * 1000;
// 密码加密格式为mqtt密码 & 过期时间 & 授权码(可选),如果产品启用了授权码就必须加上
String password="";
if(authCode == ""){
password = (String)mqttPwd + "&" + String(expireTime, 0);
}else{
password = (String)mqttPwd + "&" + String(expireTime, 0) + "&" + authCode;
}
printMsg("密码(未加密):" + password);
return password;
}
// HTTP获取时间
String getTime()
{
while (WiFi.status() == WL_CONNECTED)
{
HTTPClient http;
printMsg("获取时间...");
if (http.begin(wifiClient, (ntpServer + (String)millis()).c_str()))
{
// 发送请求
int httpCode = http.GET();
if (httpCode > 0)
{
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY)
{
g_time = http.getString();
printMsg("获取时间成功data:");
Serial.print(g_time);
return g_time;
}
}
else
{
printMsg("获取时间失败error:");
Serial.printf(http.errorToString(httpCode).c_str());
}
http.end();
}
else
{
printMsg("连接Http失败");
}
delay(500);
}
}
//打印提示信息
void printMsg(String msg)
{
Serial.print("\r\n[");
Serial.print(millis());
Serial.print("ms]");
Serial.print(msg);
}
// 控制指示灯闪烁
void blink()
{
printMsg("指示灯闪烁...");
pinMode(15, OUTPUT);
for (int i = 0; i < 2; i++)
{
digitalWrite(15, HIGH);
delay(200);
digitalWrite(15, LOW);
delay(200);
}
}
// 加密 (AES-CBC-128-pkcs5padding)
String encrypt(String plain_data, char *wumei_key, char *wumei_iv)
{
int i;
// pkcs7padding填充 Block Size : 16
int len = plain_data.length();
int n_blocks = len / 16 + 1;
uint8_t n_padding = n_blocks * 16 - len;
uint8_t data[n_blocks * 16];
memcpy(data, plain_data.c_str(), len);
for (i = len; i < n_blocks * 16; i++)
{
data[i] = n_padding;
}
uint8_t key[16], iv[16];
uint8_t crypt_data[3 * 16] = {0};
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
memset(crypt_data, 0, 48);
len = n_blocks * 16;
// 加密
mbedtls_aes_context aes_ctx;
mbedtls_aes_init(&aes_ctx);
mbedtls_aes_setkey_enc(&aes_ctx, key, 128);
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, len, iv, data, crypt_data);
// Base64编码
char encoded_data[base64_enc_len(len)];
base64_encode(encoded_data, (char *)crypt_data, len);
return String(encoded_data);
}
// 解密 (AES-CBC-128-pkcs5padding)
String decrypt(String encoded_data_str, char *wumei_key, char *wumei_iv)
{
int input_len = encoded_data_str.length();
char *encoded_data = const_cast<char *>(encoded_data_str.c_str());
int len = base64_dec_len(encoded_data, input_len);
uint8_t data[len];
base64_decode((char *)data, encoded_data, input_len);
uint8_t key[16], iv[16];
memcpy(key, wumei_key, 16);
memcpy(iv, wumei_iv, 16);
int n_blocks = len / 16;
uint8_t n_padding = data[n_blocks * 16 - 1];
len = n_blocks * 16 - n_padding;
char plain_data[len + 1];
//密文空间
mbedtls_aes_context aes_ctx;
mbedtls_aes_init(&aes_ctx);
//设置解密密钥
mbedtls_aes_setkey_dec(&aes_ctx, key, 128);
mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, 48, iv, (unsigned char *)encoded_data, (unsigned char *)plain_data);
mbedtls_aes_free(&aes_ctx);
// PKCS#7 Padding 填充
plain_data[len] = '\0';
return String(plain_data);
}

View File

@@ -0,0 +1,79 @@
/***********************************************************
* author: LaoHuang
* create: 2022-04-14
* emailrememberyousaid@163.com
* source:https://github.com/kerwincui/wumei-smart
* board:esp32 版本1.0.6
***********************************************************/
#ifndef _HELPER_H
#define _HELPER_H
#include <mbedtls/aes.h>
#include "Base64.h"
#include <WiFiClient.h>
//#include <Ethernet.h>
#include <HTTPClient.h>
#include <PubSubClient.h> // 版本2.8.0
#include <ArduinoJson.h> // 版本6.19.4
extern WiFiClient wifiClient;
extern PubSubClient mqttClient;
extern String deviceNum ; // 设备编号重要同时是Mqtt的clientId
extern String userId; // 用户ID
extern String productId; // 产品ID
extern float rssi; // 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
extern float firmwareVersion; // 固件版本
extern char *wifiSsid; // WIFI的SSID
extern char *wifiPwd; // WIFI的密码
extern char *mqttHost; // Mqtt消息服务器地址
extern int mqttPort; // Mqtt消息服务器端口
extern char *mqttUserName; // Mqtt消息服务器账号
extern char *mqttPwd; // Mqtt消息服务器密码
extern char mqttSecret[17]; // Mqtt秘钥,16位
extern char wumei_iv[17]; // AES加密偏移量固定值16位
extern String ntpServer; // NTP服务地址用于获取当前时间
extern int monitorCount; // 发布监测数据的最大次数
extern long monitorInterval; // 发布监测数据的间隔默认1000毫秒
// 连接wifi
void connectWifi();
// 连接mqtt
void connectMqtt();
// Mqtt回调
void callback(char *topic, byte *payload, unsigned int length);
// 发布设备信息
void publishInfo();
// 发布时钟同步信息
void publishNtp();
// 发布事件
void publishEvent();
// 发布实时监测数据
void publishMonitor();
// 随机生成监测值
String randomPropertyData();
// 发布属性
void publishProperty(String msg);
// 发布功能
void publishFunction(String msg);
// 属性处理
void processProperty(String payload);
// 功能处理
void processFunction(String payload);
// 生成密码
String generationPwd();
// 获取时间
String getTime();
// AES加密
String encrypt(String plain_data,char *wumei_key,char *wumei_iv);
// AES解密
String decrypt(String encoded_data_str,char *wumei_key,char *wumei_iv);
//打印提示信息
void printMsg(String tips);
// 控制指示灯闪烁
void blink();
#endif

View File

@@ -0,0 +1,137 @@
#include "Base64.h"
#if (defined(__AVR__))
#include <avr\pgmspace.h>
#else
#include <pgmspace.h>
#endif
const char PROGMEM b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
/* 'Private' declarations */
inline void a3_to_a4(unsigned char * a4, unsigned char * a3);
inline void a4_to_a3(unsigned char * a3, unsigned char * a4);
inline unsigned char b64_lookup(char c);
int base64_encode(char *output, char *input, int inputLen) {
int i = 0, j = 0;
int encLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while(inputLen--) {
a3[i++] = *(input++);
if(i == 3) {
a3_to_a4(a4, a3);
for(i = 0; i < 4; i++) {
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[i]]);
}
i = 0;
}
}
if(i) {
for(j = i; j < 3; j++) {
a3[j] = '\0';
}
a3_to_a4(a4, a3);
for(j = 0; j < i + 1; j++) {
output[encLen++] = pgm_read_byte(&b64_alphabet[a4[j]]);
}
while((i++ < 3)) {
output[encLen++] = '=';
}
}
output[encLen] = '\0';
return encLen;
}
int base64_decode(char * output, char * input, int inputLen) {
int i = 0, j = 0;
int decLen = 0;
unsigned char a3[3];
unsigned char a4[4];
while (inputLen--) {
if(*input == '=') {
break;
}
a4[i++] = *(input++);
if (i == 4) {
for (i = 0; i <4; i++) {
a4[i] = b64_lookup(a4[i]);
}
a4_to_a3(a3,a4);
for (i = 0; i < 3; i++) {
output[decLen++] = a3[i];
}
i = 0;
}
}
if (i) {
for (j = i; j < 4; j++) {
a4[j] = '\0';
}
for (j = 0; j <4; j++) {
a4[j] = b64_lookup(a4[j]);
}
a4_to_a3(a3,a4);
for (j = 0; j < i - 1; j++) {
output[decLen++] = a3[j];
}
}
output[decLen] = '\0';
return decLen;
}
int base64_enc_len(int plainLen) {
int n = plainLen;
return (n + 2 - ((n + 2) % 3)) / 3 * 4;
}
int base64_dec_len(char * input, int inputLen) {
int i = 0;
int numEq = 0;
for(i = inputLen - 1; input[i] == '='; i--) {
numEq++;
}
return ((6 * inputLen) / 8) - numEq;
}
inline void a3_to_a4(unsigned char * a4, unsigned char * a3) {
a4[0] = (a3[0] & 0xfc) >> 2;
a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4);
a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6);
a4[3] = (a3[2] & 0x3f);
}
inline void a4_to_a3(unsigned char * a3, unsigned char * a4) {
a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4);
a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2);
a3[2] = ((a4[2] & 0x3) << 6) + a4[3];
}
inline unsigned char b64_lookup(char c) {
if(c >='A' && c <='Z') return c - 'A';
if(c >='a' && c <='z') return c - 71;
if(c >='0' && c <='9') return c + 4;
if(c == '+') return 62;
if(c == '/') return 63;
return -1;
}

View File

@@ -0,0 +1,79 @@
/*
* Copyright (c) 2013 Adam Rudd.
* See LICENSE for more information
*/
#ifndef _BASE64_H
#define _BASE64_H
/* b64_alphabet:
* Description: Base64 alphabet table, a mapping between integers
* and base64 digits
* Notes: This is an extern here but is defined in Base64.c
*/
extern const char b64_alphabet[];
/* base64_encode:
* Description:
* Encode a string of characters as base64
* Parameters:
* output: the output buffer for the encoding, stores the encoded string
* input: the input buffer for the encoding, stores the binary to be encoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the encoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_encode(char *output, char *input, int inputLen);
/* base64_decode:
* Description:
* Decode a base64 encoded string into bytes
* Parameters:
* output: the output buffer for the decoding,
* stores the decoded binary
* input: the input buffer for the decoding,
* stores the base64 string to be decoded
* inputLen: the length of the input buffer, in bytes
* Return value:
* Returns the length of the decoded string
* Requirements:
* 1. output must not be null or empty
* 2. input must not be null
* 3. inputLen must be greater than or equal to 0
*/
int base64_decode(char *output, char *input, int inputLen);
/* base64_enc_len:
* Description:
* Returns the length of a base64 encoded string whose decoded
* form is inputLen bytes long
* Parameters:
* inputLen: the length of the decoded string
* Return value:
* The length of a base64 encoded string whose decoded form
* is inputLen bytes long
* Requirements:
* None
*/
int base64_enc_len(int inputLen);
/* base64_dec_len:
* Description:
* Returns the length of the decoded form of a
* base64 encoded string
* Parameters:
* input: the base64 encoded string to be measured
* inputLen: the length of the base64 encoded string
* Return value:
* Returns the length of the decoded form of a
* base64 encoded string
* Requirements:
* 1. input must not be null
* 2. input must be greater than or equal to zero
*/
int base64_dec_len(char *input, int inputLen);
#endif // _BASE64_H

View File

@@ -17,21 +17,26 @@ long monitorInterval = 1000;
//==================================== 这是需要配置的项 =============================== //==================================== 这是需要配置的项 ===============================
// Wifi配置 // Wifi配置
char *wifiSsid = "wifi账号"; char *wifiSsid = "wumei";
char *wifiPwd = "wifi密码"; char *wifiPwd = "wumei-smart";
// 设备信息配置 // 设备信息配置
String deviceNum = "D6329VL54419L1Y0"; String deviceNum = "D6329VL548866";
String userId = "1"; String userId = "1";
String productId = "2"; String productId = "41";
String firmwareVersion = "1.0"; float firmwareVersion = 1.0;
// 经度和纬度可选,如果产品使用设备定位,则必须传
float latitude=0;
float longitude=0;
// Mqtt配置 // Mqtt配置
char *mqttHost = "wumei.live"; char *mqttHost = "wumei.live";
int mqttPort = 1883; int mqttPort = 1883;
char *mqttUserName = "wumei-smart"; char *mqttUserName = "wumei-smart";
char *mqttPwd = "P5FJKZJHIR82GNB2"; char *mqttPwd = "PHYFED93WSFF1DAS";
char mqttSecret[17] = "K63C4EA3AI5TER97"; char mqttSecret[17] = "K2V5DE28XNUU3497";
// 产品启用授权码,则授权码不能为空
String authCode="";
// NTP地址用于获取时间,可选的修改为自己部署项目的地址) // NTP地址用于获取时间,可选的修改为自己部署项目的地址)
String ntpServer = "http://wumei.live:8080/iot/tool/ntp?deviceSendTime="; String ntpServer = "http://wumei.live:8080/iot/tool/ntp?deviceSendTime=";
@@ -131,6 +136,18 @@ void callback(char *topic, byte *payload, unsigned int length)
if (strcmp(topic, sOtaTopic.c_str()) == 0) if (strcmp(topic, sOtaTopic.c_str()) == 0)
{ {
printMsg("订阅到设备升级指令..."); printMsg("订阅到设备升级指令...");
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload);
if (error)
{
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.f_str());
return;
}
String newVersion = doc["version"];
String downloadUrl = doc["downloadUrl"];
printMsg("固件版本:"+newVersion);
printMsg("下载地址:"+downloadUrl);
} }
else if (strcmp(topic, sNtpTopic.c_str()) == 0) else if (strcmp(topic, sNtpTopic.c_str()) == 0)
{ {
@@ -198,7 +215,7 @@ void connectWifi()
void connectMqtt() void connectMqtt()
{ {
printMsg("连接Mqtt服务器..."); printMsg("连接Mqtt服务器...");
// 生成mqtt认证密码(密码 = mqtt密码 & 用户ID & 过期时间) // 生成mqtt认证密码(设备加密认证密码加密格式为mqtt密码 & 过期时间 & 授权码,其中授权码为可选)
String password = generationPwd(); String password = generationPwd();
String encryptPassword = encrypt(password, mqttSecret, wumei_iv); String encryptPassword = encrypt(password, mqttSecret, wumei_iv);
printMsg("密码(已加密)" + encryptPassword); printMsg("密码(已加密)" + encryptPassword);
@@ -207,8 +224,8 @@ void connectMqtt()
mqttClient.setCallback(callback); mqttClient.setCallback(callback);
mqttClient.setBufferSize(1024); mqttClient.setBufferSize(1024);
mqttClient.setKeepAlive(10); mqttClient.setKeepAlive(10);
//连接客户端ID = 设备编号 & 产品ID //连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
String clientId = deviceNum + "&" + productId; String clientId = "E&" + deviceNum + "&" + productId +"&" + userId;
bool connectResult = mqttClient.connect(clientId.c_str(), mqttUserName, encryptPassword.c_str()); bool connectResult = mqttClient.connect(clientId.c_str(), mqttUserName, encryptPassword.c_str());
if (connectResult) if (connectResult)
{ {
@@ -246,6 +263,15 @@ void publishInfo()
doc["firmwareVersion"] = firmwareVersion; doc["firmwareVersion"] = firmwareVersion;
doc["status"] = 3; // 1-未激活2-禁用3-在线4-离线) doc["status"] = 3; // 1-未激活2-禁用3-在线4-离线)
doc["userId"] = (String)userId; doc["userId"] = (String)userId;
doc["longitude"] = longitude; //经度 可选
doc["latitude"] = latitude; // 纬度 可选
// 设备摘要,可选(自定义配置信息)
JsonObject summary = doc.createNestedObject("summary");
summary["name"]="wumei-smart";
summary["chip"]="esp8266";
summary["author"]="kerwincui";
summary["version"]=1.6;
summary["create"]="2022-06-06";
printMsg("发布设备信息:"); printMsg("发布设备信息:");
serializeJson(doc, Serial); serializeJson(doc, Serial);
@@ -371,7 +397,13 @@ String generationPwd()
float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2; float now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2;
// 过期时间 = 当前时间 + 1小时 // 过期时间 = 当前时间 + 1小时
float expireTime = now + 1 * 60 * 60 * 1000; float expireTime = now + 1 * 60 * 60 * 1000;
String password = (String)mqttPwd + "&" + userId + "&" + String(expireTime, 0); // 密码加密格式为mqtt密码 & 过期时间 & 授权码(可选),如果产品启用了授权码就必须加上
String password="";
if(authCode==""){
password = (String)mqttPwd + "&" + String(expireTime, 0);
}else{
password = (String)mqttPwd + "&" + String(expireTime, 0)+ "&" + authCode;
}
printMsg("密码(未加密):" + password); printMsg("密码(未加密):" + password);
return password; return password;
} }

View File

@@ -23,7 +23,7 @@ extern String deviceNum ; // 设备编号重要同时是Mqtt的client
extern String userId; // 用户ID extern String userId; // 用户ID
extern String productId; // 产品ID extern String productId; // 产品ID
extern float rssi; // 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85] extern float rssi; // 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
extern String firmwareVersion; // 固件版本 extern float firmwareVersion; // 固件版本
extern char *wifiSsid; // WIFI的SSID extern char *wifiSsid; // WIFI的SSID
extern char *wifiPwd; // WIFI的密码 extern char *wifiPwd; // WIFI的密码
extern char *mqttHost; // Mqtt消息服务器地址 extern char *mqttHost; // Mqtt消息服务器地址

0
sdk/ESP-IDF/README.md Normal file
View File

45
sdk/RaspberryPi/README.md Normal file
View File

@@ -0,0 +1,45 @@
## 硬件端树莓派SDK说明
#### 一、运行环境
- Python 3.7.2 (其他python3的版本一般也可以)
- 开发板树莓派4b没有加入硬件相关代码安装好python3环境win下linux下都能运行
- 库 需要安装库
1. mqtt库
```
pip install paho-mqtt
```
2. ase加密库
```
# 前面两个卸载命令是为了防止一些安装环境问题
pip uninstall crypto
pip uninstall pycryptodome
pip install pycryptodome
```
3. 报错缺少xx库命令
```
pip install xx
```
#### 二、运行程序
```
python3 main_sdk.py
# 备注程序运行依赖aes.py文件保证该文件和main_sdk.py在同一目录
```
#### 三、开发参考资料:
- [Eclipse Paho MQTT Python Client 使用手册](https://www.cooooder.com/archives/20210303)
- 更多参考资料,下载目录中的文本文件查看

210
sdk/RaspberryPi/aes.py Normal file
View File

@@ -0,0 +1,210 @@
from Crypto.Cipher import AES
import base64
import binascii
# 数据类
class MData():
def __init__(self, data = b"",characterSet='utf-8'):
# data肯定为bytes
self.data = data
self.characterSet = characterSet
def saveData(self,FileName):
with open(FileName,'wb') as f:
f.write(self.data)
def fromString(self,data):
self.data = data.encode(self.characterSet)
return self.data
def fromBase64(self,data):
self.data = base64.b64decode(data.encode(self.characterSet))
return self.data
def fromHexStr(self,data):
self.data = binascii.a2b_hex(data)
return self.data
def toString(self):
return self.data.decode(self.characterSet)
def toBase64(self):
return base64.b64encode(self.data).decode() #decode()转成字符串形式,否则为字节型数据
def toHexStr(self):
return binascii.b2a_hex(self.data).decode()
def toBytes(self):
return self.data
def __str__(self):
try:
return self.toString()
except Exception:
return self.toBase64()
### 封装类
class AEScryptor():
def __init__(self,key,mode,iv = '',paddingMode= "NoPadding",characterSet ="utf-8"):
'''
构建一个AES对象
key: 秘钥,字节型数据
mode: 使用模式只提供两种AES.MODE_CBC, AES.MODE_ECB
iv iv偏移量字节型数据
paddingMode: 填充模式默认为NoPadding, 可选NoPaddingZeroPaddingPKCS5PaddingPKCS7Padding
characterSet: 字符集编码
'''
self.key = key
self.mode = mode
self.iv = iv
self.characterSet = characterSet
self.paddingMode = paddingMode
self.data = ""
def __ZeroPadding(self,data):
data += b'\x00'
while len(data) % 16 != 0:
data += b'\x00'
return data
def __StripZeroPadding(self,data):
data = data[:-1]
while len(data) % 16 != 0:
data = data.rstrip(b'\x00')
if data[-1] != b"\x00":
break
return data
def __PKCS5_7Padding(self,data):
needSize = 16-len(data) % 16
if needSize == 0:
needSize = 16
return data + needSize.to_bytes(1,'little')*needSize
def __StripPKCS5_7Padding(self,data):
paddingSize = data[-1]
return data.rstrip(paddingSize.to_bytes(1,'little'))
def __paddingData(self,data):
if self.paddingMode == "NoPadding":
if len(data) % 16 == 0:
return data
else:
return self.__ZeroPadding(data)
elif self.paddingMode == "ZeroPadding":
return self.__ZeroPadding(data)
elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
return self.__PKCS5_7Padding(data)
else:
print("不支持Padding")
def __stripPaddingData(self,data):
if self.paddingMode == "NoPadding":
return self.__StripZeroPadding(data)
elif self.paddingMode == "ZeroPadding":
return self.__StripZeroPadding(data)
elif self.paddingMode == "PKCS5Padding" or self.paddingMode == "PKCS7Padding":
return self.__StripPKCS5_7Padding(data)
else:
print("不支持Padding")
def setCharacterSet(self,characterSet):
'''
设置字符集编码
characterSet: 字符集编码
'''
self.characterSet = characterSet
def setPaddingMode(self,mode):
'''
设置填充模式
mode: 可选NoPaddingZeroPaddingPKCS5PaddingPKCS7Padding
'''
self.paddingMode = mode
def decryptFromBase64(self,entext):
'''
从base64编码字符串编码进行AES解密
entext: 数据类型str
'''
mData = MData(characterSet=self.characterSet)
self.data = mData.fromBase64(entext)
return self.__decrypt()
def decryptFromHexStr(self,entext):
'''
从hexstr编码字符串编码进行AES解密
entext: 数据类型str
'''
mData = MData(characterSet=self.characterSet)
self.data = mData.fromHexStr(entext)
return self.__decrypt()
def decryptFromString(self,entext):
'''
从字符串进行AES解密
entext: 数据类型str
'''
mData = MData(characterSet=self.characterSet)
self.data = mData.fromString(entext)
return self.__decrypt()
def decryptFromBytes(self,entext):
'''
从二进制进行AES解密
entext: 数据类型bytes
'''
self.data = entext
return self.__decrypt()
def encryptFromString(self,data):
'''
对字符串进行AES加密
data: 待加密字符串数据类型为str
'''
self.data = data.encode(self.characterSet)
return self.__encrypt()
def __encrypt(self):
if self.mode == AES.MODE_CBC:
aes = AES.new(self.key,self.mode,self.iv)
elif self.mode == AES.MODE_ECB:
aes = AES.new(self.key,self.mode)
else:
print("不支持这种模式")
return
data = self.__paddingData(self.data)
enData = aes.encrypt(data)
return MData(enData)
def __decrypt(self):
if self.mode == AES.MODE_CBC:
aes = AES.new(self.key,self.mode,self.iv)
elif self.mode == AES.MODE_ECB:
aes = AES.new(self.key,self.mode)
else:
print("不支持这种模式")
return
data = aes.decrypt(self.data)
# mData = MData(self.__stripPaddingData(data),characterSet=self.characterSet)
# return mData()
return MData(self.__stripPaddingData(data),characterSet=self.characterSet)
if __name__ == '__main__':
key = b"1234567812345678"
iv = b"0000000000000000"
aes = AEScryptor(key,AES.MODE_CBC,iv,paddingMode= "ZeroPadding",characterSet='utf-8')
data = "好好学习"
rData = aes.encryptFromString(data)
print("密文:",rData.toBase64())
rData = aes.decryptFromBase64(rData.toBase64())
print("明文:",rData)
# ————————————————
# 版权声明本文为CSDN博主「Hello_wshuo」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。
# 原文链接https://blog.csdn.net/chouzhou9701/article/details/122019967

345
sdk/RaspberryPi/main_sdk.py Normal file
View File

@@ -0,0 +1,345 @@
# /***********************************************************
# * author: xiaoY [物美智能 wumei-smart]
# * create: 2022-05-10
# * emailqimint@outlook.com
# * source:https://github.com/kerwincui/wumei-smart
# * board:raspberry 4b
# ***********************************************************/
import time
import requests
import json
from aes import AEScryptor,AES
import paho.mqtt.client as mqtt
import random
import threading #导入线程模块,用作定时器
#################################################################
# 需要连接好外部网络
#################################################################
# 作为python的AES的iv,应该为16位字节型数据
wumei_iv = b"wumei-smart-open"
#发布监测数据的最大次数
monitorCount =5
# 发布监测数据的间隔默认5秒。 使用esp8266单片机时服务器传来的间隔单位为毫秒本程序由于定时运行需要的是秒将转化为秒如需毫秒运行自行更改程序
monitorInterval =5
# NTP地址用于获取时间,可选的修改为自己部署项目的地址)
ntpServer = "http://120.24.218.158:8080/iot/tool/ntp?deviceSendTime="
# 连接成功标志位
g_rc=-1
#全局变量,管理定时监测
global t2
# 设备信息配置
deviceNum = "DW43CI6RM8GMG23H"
userId = "1"
productId = "4"
firmwareVersion = "1.0"
# 经度和纬度可选,如果产品使用设备定位,则必须传
latitude=0
longitude=0
# Mqtt配置
mqttHost = "120.24.218.158"
mqttPort = 1883
mqttUserName = "wumei-smart"
mqttPwd = "P261I5G3RY3MCIGG"
# 作为python的AES的key,应该为16位字节型数据
mqttSecret = b"K2IB784BM0O01GG6"
# 产品启用授权码则authCode不能为空
authCode=""
# 订阅的主题
prefix = "/" + productId + "/" + deviceNum
sOtaTopic = prefix + "/ota/get"
sNtpTopic = prefix + "/ntp/get"
sPropertyTopic = prefix + "/property/get"
sFunctionTopic = prefix + "/function/get"
sPropertyOnline = prefix + "/property-online/get"
sFunctionOnline = prefix + "/function-online/get"
sMonitorTopic = prefix + "/monitor/get"
# 发布的主题
pInfoTopic = prefix + "/info/post"
pNtpTopic = prefix + "/ntp/post"
pPropertyTopic = prefix + "/property/post"
pFunctionTopic = prefix + "/function/post"
pMonitorTopic = prefix + "/monitor/post"
pEventTopic = prefix + "/event/post"
# 初始化,连接 设备mqtt客户端Id格式为认证类型(E=加密、S=简单) & 设备编号 & 产品ID & 用户ID
clientId = "E&" + deviceNum + "&" + productId +"&" + userId
client=mqtt.Client(clientId)
#加密 (AES-CBC-128-pkcs5padding)
def encrypt(plain_data,wumei_key,wumei_iv):
aes=AEScryptor(wumei_key,AES.MODE_CBC,wumei_iv,paddingMode="PKCS5Padding",characterSet='utf-8')
rData=aes.encryptFromString(plain_data)
printMsg("密码(已加密)"+rData.toBase64())
return rData.toBase64()
#回调函数。当尝试与MQTT broker 建立连接时,触发该函数。
#client 是本次连接的客户端实例。
#userdata 是用户的信息,一般为空。但如果有需要,也可以通过 user_data_set 函数设置。
#flags 保存服务器响应标志的字典
#rc 是响应码。
# 0: 连接成功
# 1: 连接失败-不正确的协议版本
# 2: 连接失败-无效的客户端标识符
# 3: 连接失败-服务器不可用
# 4: 连接失败-错误的用户名或密码
# 5: 连接失败-未授权
# 6-255: 未定义.
#一般情况下我们只需要关注rc响应码是否为0就可以了。
def on_connect(client,userdata,flags,rc):
if rc==0:
printMsg("连接成功")
# 放在on_connect下可以保证重连重新订阅
# 订阅(OTA、NTP、属性、功能、实时监测)
client.subscribe(sOtaTopic, 1)
client.subscribe(sNtpTopic, 1)
client.subscribe(sPropertyTopic, 1)
client.subscribe(sFunctionTopic, 1)
client.subscribe(sPropertyOnline, 1)
client.subscribe(sFunctionOnline, 1)
client.subscribe(sMonitorTopic, 1)
printMsg("订阅主题:" + sOtaTopic)
printMsg("订阅主题:" + sNtpTopic)
printMsg("订阅主题:" + sPropertyTopic)
printMsg("订阅主题:" + sFunctionTopic)
printMsg("订阅主题:" + sPropertyOnline)
printMsg("订阅主题:" + sFunctionOnline)
printMsg("订阅主题:" + sMonitorTopic)
# 发布设备信息
publishInfo()
global g_rc
g_rc=0
else:
printMsg("连接失败rc="+str(rc))
printMsg("3秒后重连...")
time.sleep(3)
connectMqtt()
# 物模型-属性处理
def processProperty(payload):
data=json.loads(payload)
for item in data:
# 匹配云端定义的属性(不包含属性中的监测数据)
id = item["id"]
value=item["value"]
printMsg(str(id)+":"+str(value))
# 最后发布属性,服务端订阅存储(重要)
publishProperty(json.dumps(data))
# 物模型-功能处理
def processFunction(payload):
data=json.loads(payload)
for item in data:
# 匹配云端定义的功能
id = item["id"]
value=item["value"]
if(id=="switch"):
printMsg("开关 switch"+ str(value))
elif(id=="gear"):
printMsg("档位 gear"+ str(value))
elif(id=="light_color"):
printMsg("灯光颜色 light_color"+ str(value))
elif(id=="message"):
printMsg("屏显消息 message"+ str(value))
elif(id=="report_monitor"):
msg=randomPropertyData();
printMsg("订阅到上报监测数据指令,上报数据:")
printMsg(msg)
publishProperty(msg)
# 最后发布属性,服务端订阅存储(重要)
publishProperty(json.dumps(data))
# 回调函数在客户端订阅的主题上接收到消息时调用“message”变量是一个MQTT消息描述所有消息特征
def on_message(client,userdata,msg):
printMsg("接收数据:"+msg.topic+" "+str(msg.payload))
if(msg.topic==sOtaTopic):
printMsg("订阅到设备升级指令...")
jsonData=json.loads(msg.payload)
newVersion = jsonData["version"]
downloadUrl = jsonData["downloadUrl"]
printMsg("固件版本:"+newVersion)
printMsg("下载地址:"+downloadUrl)
elif(msg.topic==sNtpTopic):
printMsg("订阅到NTP时间...");
jsonData=json.loads(msg.payload)
deviceSendTime = jsonData["deviceSendTime"]
serverSendTime = jsonData["serverSendTime"]
serverRecvTime = jsonData["serverRecvTime"]
deviceRecvTime = round(time.time()*1000)
now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2
printMsg("当前时间:"+str(round(now)))
elif(msg.topic==sPropertyTopic or msg.topic==sPropertyOnline):
printMsg("订阅到属性指令...")
processProperty(msg.payload)
elif(msg.topic==sFunctionTopic or msg.topic==sFunctionOnline):
printMsg("订阅到功能指令...")
processFunction(msg.payload)
elif(msg.topic==sMonitorTopic):
# python全局变量的使用
global t2
global monitorCount
global monitorInterval
printMsg("订阅到实时监测指令...")
jsonData=json.loads(msg.payload)
monitorCount = jsonData["count"]
monitorInterval = jsonData["interval"]/1000
t2.cancel()
t2=threading.Timer(monitorInterval,timing_publishMonitor)
t2.start()
# 1.发布设备信息
def publishInfo():
# rssi值 树莓派中暂时不处理wifi信号问题
# 信号强度信号极好4格[-55— 0]信号好3格[-70— -55]信号一般2格[-85— -70]信号差1格[-100— -85]
# status值 1-未激活2-禁用3-在线4-离线)
doc={"rssi":1,"firmwareVersion":firmwareVersion,"status":3,"userId":userId,"longitude":longitude,"latitude":latitude,"summary":{"name":"device","chip":"esp8266","author":"kerwincui","version":1.6,"create":"2022 - 06 - 06"}}
# client.publish('raspberry/topic',payload=i,qos=0,retain=False)
jsonData=json.dumps(doc)
printMsg("发布设备信息:"+pInfoTopic+" "+jsonData)
client.publish(pInfoTopic,jsonData)
# 2.发布时钟同步信,用于获取当前时间(可选)
def publishNtp():
data={"deviceSendTime":round(time.time()*1000)}
jsonData=json.dumps(data)
printMsg("发布NTP信息"+jsonData)
client.publish(pNtpTopic,jsonData)
# 3.发布属性
# msg 接收格式json
def publishProperty(msg):
printMsg("发布属性:" + msg)
client.publish(pPropertyTopic, msg)
# 4.发布功能
def publishFunction( msg):
printMsg("发布功能:" + msg)
client.publish(pFunctionTopic, msg)
# 5.发布事件
def publishEvent():
objTmeperature={"id":"height_temperature","value":40,"remark":"温度过高警告"}
objException={"id":"exception","value":"异常消息消息内容XXXXXXXX","remark":"设备发生错误"}
data=[objTmeperature,objException]
jsonData=json.dumps(data)
printMsg("发布事件:"+jsonData)
client.publish(pEventTopic,jsonData)
# 6.发布实时监测数据
def publishMonitor():
msg=randomPropertyData()
# 发布为实时监测数据,不会存储
printMsg("发布实时监测数据:"+msg)
client.publish(pMonitorTopic,msg)
# 随机生成监测值
def randomPropertyData():
# 匹配云端定义的监测数据,随机数代替监测结果
# random.randint(0,10) #生成数据包括0,10
# random.uniform(30,60)生成数据为浮点型
objTmeperature={"id":"temperature","value":str(round(random.uniform(10,30),2)),"remark":""}
objHumidity={"id":"humidity","value":str(round(random.uniform(30,60),2)),"remark":""}
objCo2={"id":"co2","value":str(random.randint(400,1000)),"remark":""}
objBrightness={"id":"brightness","value":str(random.randint(1000,10000)),"remark":""}
printMsg("随机生成监测数据值:")
data=[objTmeperature,objHumidity,objCo2,objBrightness]
print(json.dumps(data))
return json.dumps(data)
#连接mqtt
def connectMqtt():
printMsg("连接Mqtt服务器")
# 生成mqtt认证密码(设备加密认证密码加密格式为mqtt密码 & 过期时间 & 授权码,其中授权码为可选)
password = generationPwd()
encryptPassword=encrypt(password,mqttSecret,wumei_iv)
client.username_pw_set(mqttUserName,encryptPassword)
client.on_connect=on_connect
client.on_message=on_message
client.connect(mqttHost,mqttPort,10)
#打印提示信息
def printMsg(msg):
print("[{}] {}".format(time.strftime("%Y-%m-%d %H:%M:%S"),msg))
# 生成密码
def generationPwd():
try:
doc=json.loads(getTime())
except:
printMsg("Json解析失败")
exit()
deviceSendTime = doc["deviceSendTime"]
serverSendTime = doc["serverSendTime"]
serverRecvTime = doc["serverRecvTime"]
deviceRecvTime = round(time.time()*1000)
now = (serverSendTime + serverRecvTime + deviceRecvTime - deviceSendTime) / 2
expireTime = int(now + 1 * 60 * 60 * 1000)
# 密码加密格式为mqtt密码 & 过期时间 & 授权码(可选),如果产品启用了授权码就必须加上
password=""
if(authCode == ""):
password = mqttPwd + "&" + str(expireTime, 0)
else:
password = mqttPwd + "&" + str(expireTime, 0) + "&" + authCode
printMsg("密码(未加密):" + password)
return password
# HTTP获取时间
def getTime():
try:
r=requests.get(ntpServer+str(round(time.time()*1000)))
if(r.status_code>0):
if(r.status_code==200 or r.status_code==301):
printMsg("获取时间成功data:"+r.text)
return r.text
else:
printMsg("获取时间失败error:"+r.status_code)
except:
printMsg("连接Http失败")
# 定时上报属性
def timing_publishProperty():
printMsg("执行定时上报")
#发布事件
publishEvent()
#发布时钟同步
publishNtp()
# 发布属性(监测值)
msg=randomPropertyData()
publishProperty(msg)
t1=threading.Timer(60,timing_publishProperty)
t1.start()
# 定时上报监测数据
def timing_publishMonitor():
global monitorCount
monitorCount=monitorCount-1
printMsg("执行监测")
publishMonitor()
if(monitorCount>0):
t2=threading.Timer(monitorInterval,timing_publishMonitor)
t2.start()
if __name__ == '__main__':
connectMqtt()
client.loop_start()
printMsg("等待连接MQTT")
while(g_rc!=0):
print("-",end=" ")
time.sleep(1)
t1=threading.Timer(60,timing_publishProperty)
t1.setDaemon(True) #当主线程被关闭后,子线程也关闭
t1.start()
t2=threading.Timer(monitorInterval,timing_publishMonitor)
t2.setDaemon(True) #当主线程被关闭后,子线程也关闭
t2.start()
while True:
time.sleep(10) #定时上报、检测上报都是线程执行,主线程可以做自己的任务

View File

@@ -0,0 +1,26 @@
Eclipse Paho MQTT Python Client 使用手册
https://www.cooooder.com/archives/20210303
Python 实现AES加密
https://zhuanlan.zhihu.com/p/261694311
python实现AES加密解密
https://blog.csdn.net/chouzhou9701/article/details/122019967
使用python time()方法
http://www.py.cn/jishu/jichu/20424.html
python 线程定时器Timer
https://zhuanlan.zhihu.com/p/91412537
浅谈Python的格式化输出
https://www.jb51.net/article/225609.htm
Python Request库入门
https://www.jianshu.com/p/d78982126318
Python JSON
https://www.runoob.com/python/python-json.html
Python random() 函数
https://www.runoob.com/python/func-number-random.html

View File

@@ -1,3 +0,0 @@
{
"C_Cpp.errorSquiggles": "Disabled"
}

View File

@@ -24,6 +24,7 @@ target/
*.iws *.iws
*.iml *.iml
*.ipr *.ipr
../.idea
### NetBeans ### ### NetBeans ###
nbproject/private/ nbproject/private/
@@ -39,6 +40,8 @@ nbdist/
*.xml.versionsBackup *.xml.versionsBackup
*.swp *.swp
own-*
!*/build/*.java !*/build/*.java
!*/build/*.html !*/build/*.html
!*/build/*.xml !*/build/*.xml

View File

@@ -33,6 +33,8 @@
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version> <jwt.version>0.9.1</jwt.version>
<justAuth.version>1.16.5</justAuth.version>
<forest.version>1.5.19</forest.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->
@@ -206,6 +208,8 @@
<version>${wumei.version}</version> <version>${wumei.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
<version>3.8.0</version> <version>3.8.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>war</packaging> <packaging>jar</packaging>
<artifactId>wumei-admin</artifactId> <artifactId>wumei-admin</artifactId>
<description> <description>

View File

@@ -1,15 +1,5 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
@@ -22,7 +12,13 @@ import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.iot.service.IUserSocialProfileService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/** /**
* 个人信息 业务处理 * 个人信息 业务处理
@@ -31,25 +27,27 @@ import com.ruoyi.system.service.ISysUserService;
*/ */
@RestController @RestController
@RequestMapping("/system/user/profile") @RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController public class SysProfileController extends BaseController {
{
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
@Autowired
private IUserSocialProfileService iUserSocialProfileService;
/** /**
* 个人信息 * 个人信息
*/ */
@GetMapping @GetMapping
public AjaxResult profile() public AjaxResult profile() {
{
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser(); SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user); AjaxResult ajax = AjaxResult.success(user);
ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
ajax.put("socialGroup", iUserSocialProfileService.selectUserSocialProfile(loginUser.getUserId()));
return ajax; return ajax;
} }

View File

@@ -1,57 +1,68 @@
# 数据源配置 # 数据源配置
spring: spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver driverClassName: com.mysql.cj.jdbc.Driver
druid: druid:
# 主库数据源 # 主库数据源
master: master:
url: jdbc:mysql://localhost/wumeismart?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 url: jdbc:mysql://localhost/wumei-smart?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root username: root
password: admin password: admin
# 从库数据源 # 从库数据源
slave: slave:
# 从数据源开关/默认关闭 # 从数据源开关/默认关闭
enabled: false enabled: false
url: url:
username: username:
password: password:
# 初始连接数
initialSize: 5 # TDengine数据库
# 最小连接池数量 tdengine-server:
minIdle: 10 # 默认不启用TDenginetrue=启用false=不启用
# 最大连接池数量 enabled: false
maxActive: 20 driverClassName: com.taosdata.jdbc.TSDBDriver
# 配置获取连接等待超时的时间 url: jdbc:TAOS://localhost:6030/wumei_smart_log?timezone=Asia/Beijing&charset=utf-8
maxWait: 60000 username: root
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 password: taosdata
timeBetweenEvictionRunsMillis: 60000 dbName: wumei_smart_log
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000 # 初始连接数
# 配置一个连接在池中最大生存的时间,单位是毫秒 initialSize: 5
maxEvictableIdleTimeMillis: 900000 # 最小连接池数量
# 配置检测连接是否有效 minIdle: 10
validationQuery: SELECT 1 FROM DUAL # 最大连接池数量
testWhileIdle: true maxActive: 20
testOnBorrow: false # 配置获取连接等待超时的时间
testOnReturn: false maxWait: 60000
webStatFilter: # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
enabled: true timeBetweenEvictionRunsMillis: 60000
statViewServlet: # 配置一个连接在池中最小生存的时间,单位是毫秒
enabled: true minEvictableIdleTimeMillis: 300000
# 设置白名单,不填则允许所有访问 # 配置一个连接在池中最大生存的时间,单位是毫秒
allow: maxEvictableIdleTimeMillis: 900000
url-pattern: /druid/* # 配置检测连接是否有效
# 控制台管理用户名和密码 validationQuery: SELECT 1 FROM DUAL
login-username: admin testWhileIdle: true
login-password: admin123 testOnBorrow: false
filter: testOnReturn: false
stat: webStatFilter:
enabled: true enabled: true
# 慢SQL记录 statViewServlet:
log-slow-sql: true enabled: true
slow-sql-millis: 1000 # 设置白名单,不填则允许所有访问
merge-sql: true allow:
wall: url-pattern: /druid/*
config: # 控制台管理用户名和密码
multi-statement-allow: true login-username: wumei-smart
login-password: wumei-smart
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true

View File

@@ -8,8 +8,8 @@ ruoyi:
copyrightYear: 2021 copyrightYear: 2021
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: true
# 文件路径 示例( Windows配置D:/wumei/uploadPathLinux配置 /home/ruoyi/uploadPath # 文件路径以uploadPath结尾 示例( Windows配置 D:/uploadPathLinux配置 /uploadPath
profile: D:\project\github\wumei-smart\springboot\uploadpath profile: /uploadPath
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: true addressEnabled: true
# 验证码类型 math 数组计算 char 字符验证 # 验证码类型 math 数组计算 char 字符验证
@@ -46,11 +46,11 @@ spring:
active: druid active: druid
# 文件上传 # 文件上传
servlet: servlet:
multipart: multipart:
# 单个文件大小 # 单个文件大小
max-file-size: 10MB max-file-size: 10MB
# 设置总上传的文件大小 # 设置总上传的文件大小
max-request-size: 20MB max-request-size: 20MB
# 服务模块 # 服务模块
devtools: devtools:
restart: restart:
@@ -63,9 +63,9 @@ spring:
# 端口默认为6379 # 端口默认为6379
port: 6379 port: 6379
# 数据库索引 # 数据库索引
database: 1 database: 0
# 密码 # 密码
password: admin password: wumei-smart
# 连接超时时间 # 连接超时时间
timeout: 10s timeout: 10s
lettuce: lettuce:
@@ -80,31 +80,38 @@ spring:
max-wait: -1ms max-wait: -1ms
# mqtt 配置 # mqtt 配置
mqtt: mqtt:
username: wumei-smart # 账号 username: wumei-smart # 账号
password: wumei-smart # 密码 password: wumei-smart # 密码
host-url: tcp://localhost:1883 # mqtt连接tcp地址 host-url: tcp://localhost:1883 # mqtt连接tcp地址
client-id: ${random.value} # 客户端Id不能相同采用随机数 ${random.value} client-id: ${random.int} # 客户端Id不能相同采用随机数 ${random.value}
default-topic: test # 默认主题 default-topic: test # 默认主题
timeout: 60000 # 超时时间 timeout: 30 # 超时时间
keepalive: 30 # 保持连接 keepalive: 30 # 保持连接
clearSession: true # 清除会话(设置为false,断开连接,重连后使用原来的会话 保留订阅的主题,能接收离线期间的消息)
task:
execution:
pool:
core-size: 10 # 最小连接数
max-size: 30 # 最大连接数
queue-capacity: 3000 # 最大容量
# token配置 # token配置
token: token:
# 令牌自定义标识 # 令牌自定义标识
header: Authorization header: Authorization
# 令牌密钥 # 令牌密钥
secret: abcdefghijklwumeismartrstuvwxyz secret: abcdefghijklwumeismartrstuvwxyz
# 令牌有效期默认30分钟1440为一天 # 令牌有效期默认30分钟1440为一天
expireTime: 1440 expireTime: 1440
# MyBatis配置 # MyBatis配置
mybatis: mybatis:
# 搜索指定包别名 # 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain typeAliasesPackage: com.ruoyi.**.domain
# 配置mapper的扫描找到所有的mapper.xml映射文件 # 配置mapper的扫描找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml mapperLocations: classpath*:mapper/**/*Mapper.xml
# 加载全局的配置文件 # 加载全局的配置文件
configLocation: classpath:mybatis/mybatis-config.xml configLocation: classpath:mybatis/mybatis-config.xml
# PageHelper分页插件 # PageHelper分页插件
pagehelper: pagehelper:

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<!-- 日志存放路径 --> <!-- 日志存放路径 -->
<property name="log.path" value="/home/wumei/logs" /> <property name="log.path" value="/logs" />
<!-- 日志输出格式 --> <!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />

View File

@@ -86,4 +86,9 @@ public class HttpStatus
* 接口未实现 * 接口未实现
*/ */
public static final int NOT_IMPLEMENTED = 501; public static final int NOT_IMPLEMENTED = 501;
/**
* 不弹窗显示
*/
public static final int NO_MESSAGE_ALERT = 502;
} }

View File

@@ -0,0 +1,22 @@
package com.ruoyi.common.core.domain.model;
/**
* 用户登录对象
*
* @author ruoyi
*/
public class BindLoginBody extends LoginBody
{
/**
* 绑定id
*/
private String bindId;
public String getBindId() {
return bindId;
}
public void setBindId(String bindId) {
this.bindId = bindId;
}
}

View File

@@ -0,0 +1,21 @@
package com.ruoyi.common.core.domain.model;
/**
* 用户注册对象
*
* @author ruoyi
*/
public class BindRegisterBody extends RegisterBody {
/**
* 绑定id
*/
private String bindId;
public String getBindId() {
return bindId;
}
public void setBindId(String bindId) {
this.bindId = bindId;
}
}

View File

@@ -213,7 +213,7 @@ public class RedisCache
* 删除Hash中的数据 * 删除Hash中的数据
* *
* @param key * @param key
* @param mapkey * @param hkey
*/ */
public void delCacheMapValue(final String key, final String hkey) public void delCacheMapValue(final String key, final String hkey)
{ {
@@ -243,4 +243,15 @@ public class RedisCache
{ {
return redisTemplate.keys(pattern); return redisTemplate.keys(pattern);
} }
/**
* 是否存在key
*
* @param key 缓存key
* @return true存在key falsekey不存在或者已过期
*/
public boolean containsKey(String key) {
return redisTemplate.hasKey(key);
}
} }

View File

@@ -0,0 +1,10 @@
package com.ruoyi.common.enums;
/**
* 第三方登录平台
*
* @author json
*/
public enum SocialPlatformType {
Wechat, QQ
}

View File

@@ -9,10 +9,13 @@ import javax.sql.DataSource;
import org.apache.ibatis.io.VFS; import org.apache.ibatis.io.VFS;
import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS; import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@@ -21,6 +24,7 @@ import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory; import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader; import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory; import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@@ -113,7 +117,8 @@ public class MyBatisConfig
return resources.toArray(new Resource[resources.size()]); return resources.toArray(new Resource[resources.size()]);
} }
@Bean @Bean(name = "mysqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
{ {
String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage"); String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
@@ -129,4 +134,16 @@ public class MyBatisConfig
sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation)); sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
return sessionFactory.getObject(); return sessionFactory.getObject();
} }
@Bean(name = "mysqlTransactionManager")
@Primary
public DataSourceTransactionManager mysqlTransactionManager(@Qualifier("dynamicDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "mysqlSqlSessionTemplate")
@Primary
public SqlSessionTemplate mysqlSqlSessionTemplate(@Qualifier("mysqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
} }

View File

@@ -93,14 +93,14 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// CSRF禁用因为不使用session // CSRF禁用因为不使用session
.csrf().disable() .csrf().disable()
// 认证失败处理类 TODO 启用自定义认证会导致oauth授权地址不能访问 // 认证失败处理类 TODO 启用自定义认证会导致oauth授权地址不能访问
//.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 基于token所以不需要session // 基于token所以不需要session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求 // 过滤请求
.authorizeRequests() .authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage","/iot/tool/register","/iot/tool/ntp", .antMatchers("/login", "/register", "/captchaImage","/iot/tool/register","/iot/tool/ntp","/iot/tool/download",
"/iot/tool/mqtt/auth","/iot/tool/mqtt/webhook").anonymous() "/iot/tool/mqtt/auth","/iot/tool/mqtt/webhook","/auth/**/**").anonymous()
.antMatchers( .antMatchers(
HttpMethod.GET, HttpMethod.GET,
"/", "/",
@@ -116,18 +116,18 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
.antMatchers("/*/api-docs").anonymous() .antMatchers("/*/api-docs").anonymous()
.antMatchers("/druid/**").anonymous() .antMatchers("/druid/**").anonymous()
/************ oauth ************************/ /************ oauth ************************/
// 静态资源文件 // // 静态资源文件
.antMatchers("/oauth/logout/**","/oauth/css/**","/oauth/fonts/**").permitAll() // .antMatchers("/oauth/logout/**","/oauth/css/**","/oauth/fonts/**").permitAll()
// 智能音箱控制器由资源服务器管理 // // 智能音箱控制器由资源服务器管理
.antMatchers("/oauth/speaker/**").permitAll() // .antMatchers("/oauth/speaker/**").permitAll()
.anyRequest().authenticated() .anyRequest().authenticated()
.and() // .and()
.formLogin() // .formLogin()
.loginPage("/oauth/login") // .loginPage("/oauth/login")
.permitAll() // .permitAll()
.and() // .and()
.logout().logoutUrl("/oauth/logout") // .logout().logoutUrl("/oauth/logout")
.permitAll() // .permitAll()
/************* oauth **************************/ /************* oauth **************************/
.and() .and()
.headers().frameOptions().disable(); .headers().frameOptions().disable();

View File

@@ -27,8 +27,18 @@ public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, S
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
throws IOException throws IOException
{ {
int code = HttpStatus.UNAUTHORIZED; // if (isAjaxRequest(request)){
String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); int code = HttpStatus.UNAUTHORIZED;
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI());
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg)));
// }else {
// response.sendRedirect("/oauth/login");
// }
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String ajaxFlag = request.getHeader("X-Requested-With");
return ajaxFlag != null && "XMLHttpRequest".equals(ajaxFlag);
} }
} }

View File

@@ -6,6 +6,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
@@ -47,6 +48,9 @@ public class SysLoginService
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@Autowired
private UserDetailsServiceImpl userDetailsServiceImpl;
/** /**
* 登录验证 * 登录验证
* *
@@ -64,6 +68,16 @@ public class SysLoginService
{ {
validateCaptcha(username, code, uuid); validateCaptcha(username, code, uuid);
} }
return socialLogin(username,password);
}
/**
* 第三方验证后,调用登录方法
* @param username 用户名
* @param password 密码
* @return token
*/
public String socialLogin(String username, String password){
// 用户验证 // 用户验证
Authentication authentication = null; Authentication authentication = null;
try try
@@ -92,6 +106,25 @@ public class SysLoginService
return tokenService.createToken(loginUser); return tokenService.createToken(loginUser);
} }
/**
* 跳转登录认证接口
* @param username
* @param encodePwd
* @return
*/
public String redirectLogin(String username,String encodePwd){
UserDetails userDetails=userDetailsServiceImpl.loadUserByUsername(username);
if(!userDetails.getPassword().equals(encodePwd)){
throw new UserPasswordNotMatchException();
}
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
LoginUser loginUser = (LoginUser) userDetails;
recordLoginInfo(loginUser.getUserId());
// 生成token
return tokenService.createToken(loginUser);
}
/** /**
* 校验验证码 * 校验验证码
* *

Some files were not shown because too many files have changed in this diff Show More