天猫精灵对接智能设备

why to do:
  我之前一直很喜欢智能家居,可惜的是现在市场上成品的智能家居实在是太贵了,屌丝的码农是在背不起每月高额的房贷和装修费用的基础上,再买成品的智能设备(像某米那样一个智能开关,竟然卖那么贵,小弟实在是承受不起啊)。
  我现在想的很简单,就是家里的窗帘(每个卧室一个,客厅做一个双轨)、灯的开关、厨房的凉霸、还有几处插座面板做成智能的,然后在入户门口做个按钮就是按一下可以关闭屋内所有的灯。
  这是我家的户型图
  服务器:我之前买了一个群辉,用群辉中docker做的homeassistant
  窗帘电机:我从瀚思彼岸上买的,感觉价格挺实惠*5
  主灯:我买的yeelight,感觉在灯里面的价格还是挺靠谱的,主要他的开关可以调光,这个我很喜欢
  射灯:这块用的也是瀚思彼岸上买的开关
  插座开关:因为我在装修的时候把插座放到了电视后面,我这就做了个智能开关(2个),主要还得控制机顶盒还有我的高清视频播放器
  天猫精灵(去年双十一屯了几个方糖)
  由于新家还没有装修完,我这边就先做了个简单试验,把系统中基本的功能做完了,后期装修完成了,再好好弄弄,但是目前天猫精灵和homeassistant对接,网上确实有不少,可我是一个java码农,虽说对php了解的也还可以,但是肯定不如java啊,这个确实就比较少了,所以我在这里简单写写吧,希望java小伙伴们,可以多多提出建议哈。

how to do:
  天猫精灵有自己的开放平台:https://open.aligenie.com/
  1.添加技能  在这里插入图片描述
在这里插入图片描述
  这个可以参考天猫精灵给的文档,我觉得写得挺简单的。
  我这边就提出几个比较重要的点,说一下吧:
  1.需要域名和https的证书(可以在阿里云上购买,证书有一个免费一年的)
  2.自己搭建的中转服务需要在外网访问
  3.homeassistant也需要在外网能访问,这里我自己打了一套ngrok,感觉效果还是不错的
  4.java方面,我用的spring boot这里写一些关键的,这个就是
  OAuth2SecurityConfiguration

@Order(1)
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {@Autowiredprivate ClientDetailsService clientDetailsService;@Autowiredprivate RedisConnectionFactory redisConnection;@Autowiredprivate BootUserDetailService userDetailService;@Overrideprotected void configure(HttpSecurity http) throws Exception {http// 必须配置,不然OAuth2的http配置不生效----不明觉厉.requestMatchers().antMatchers(  "/test/**","/auth/login","/auth/authorize","/oauth/**","/plugs/**","/gate").and().authorizeRequests()// 自定义页面或处理url是,如果不配置全局允许,浏览器会提示服务器将页面转发多次.antMatchers("/test/**","/auth/login","/plugs/**","/gate").permitAll().anyRequest().authenticated().and().csrf().disable();//跨域关闭// 表单登录http.formLogin()// 登录页面.loginPage("/auth/login")// 登录处理url.loginProcessingUrl("/auth/authorize");}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailService);}@Override@Beanpublic AuthenticationManager authenticationManagerBean() throws Exception {return super.authenticationManagerBean();}@Override@Beanpublic AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}}

AuthorizationServerConfiguration


@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {@Autowiredprivate AuthenticationManager authenticationManager;/*** 保存令牌数据栈*/@Autowiredprivate TokenStore tokenStore;@Autowiredprivate PasswordEncoder passwordEncoder;@Autowiredprivate BootUserDetailService userDetailService;@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {// 允许表单登录security.allowFormAuthenticationForClients();}@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {String secret = passwordEncoder.encode("*******");clients.inMemory() // 使用in-memory存储.withClient("client")// client_id.secret(secret)// client_secret.authorizedGrantTypes("refresh_token", "authorization_code")// 该client允许的授权类型.redirectUris("https://open.bot.tmall.com/oauth/callback").accessTokenValiditySeconds(60*60*24)//token过期时间.refreshTokenValiditySeconds(60*60*24)//refresh过期时间.scopes("all");// 允许的授权范围}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.authenticationManager(authenticationManager).tokenStore(tokenStore).userDetailsService(userDetailService);endpoints.pathMapping("/oauth/confirm_access","/custom/confirm_access");}@Beanpublic TokenStore tokenStore(RedisConnectionFactory redisConnectionFactory) {// return new InMemoryTokenStore(); //使用内存存储令牌 tokeStorereturn new RedisTokenStore(redisConnectionFactory);//使用redis存储令牌}}

HassIntegerFaceController(和homeassitant交互)

public class HassIntegerFaceController {@Value("${kyz.hassLongToken}")private String hassLongToken;@Value("${kyz.hassUrl}")private String hassUrl;@Beanpublic RestTemplate restTemplate(RestTemplateBuilder builder) {// Do any additional configuration herereturn builder.build();}@Autowiredprivate RestTemplate restTemplate;@Autowiredprivate RedisUtil redisUtil;@Autowired()private UserService userService;@RequestMapping(value = "/add", method = RequestMethod.GET)public String add() {return getDeviceInfo().toString();}/*** 获取设备列表** @return*/public List<Map<String, Object>> getDeviceInfo() {// header填充RequestCallback requestCallback = getRequestCallback();ResponseExtractor<ResponseEntity<JSONArray>> responseExtractor = restTemplate.responseEntityExtractor(JSONArray.class);// 执行execute(),发送请求ResponseEntity<JSONArray> response = restTemplate.execute(hassUrl + "/api/states", HttpMethod.GET, requestCallback, responseExtractor);JSONArray jsonArray = response.getBody();JSONArray jsonArrayCover = new JSONArray();Map<String, Object> haDevice = new HashMap<>();List<Map<String, Object>> haDeviceList = new ArrayList<>();for (int i = 0; i < jsonArray.size(); i++) {JSONObject temp = jsonArray.getJSONObject(i);if (temp.getString("entity_id").startsWith("cover")) {jsonArrayCover.add(jsonArray.getJSONObject(i));haDevice = new HashMap<>();haDevice.put("deviceId", temp.getString("entity_id"));haDevice.put("friendly_name", temp.getJSONObject("attributes").getString("friendly_name"));haDevice.put("type", temp.getString("cover"));haDevice.put("state", temp.getString("state"));haDevice.put("deviceType", "curtain");redisUtil.set("ha_state_" + temp.getString("entity_id"), temp.getString("state"));haDeviceList.add(haDevice);}if (temp.getString("entity_id").startsWith("switch")) {jsonArrayCover.add(jsonArray.getJSONObject(i));haDevice = new HashMap<>();haDevice.put("deviceId", temp.getString("entity_id"));haDevice.put("friendly_name", temp.getJSONObject("attributes").getString("friendly_name"));haDevice.put("type", temp.getString("switch"));haDevice.put("state", temp.getString("state"));haDevice.put("deviceType", "switch");redisUtil.set("ha_state_" + temp.getString("entity_id"), temp.getString("state"));haDeviceList.add(haDevice);}if (temp.getString("entity_id").startsWith("light")) {jsonArrayCover.add(jsonArray.getJSONObject(i));haDevice = new HashMap<>();haDevice.put("deviceId", temp.getString("entity_id"));haDevice.put("friendly_name", temp.getJSONObject("attributes").getString("friendly_name"));haDevice.put("type", temp.getString("light"));haDevice.put("state", temp.getString("state"));haDevice.put("deviceType", "light");redisUtil.set("ha_state_" + temp.getString("entity_id"), temp.getString("state"));haDeviceList.add(haDevice);}}return haDeviceList;}/*** 控制控制** @return*/public Integer deviceControl(String deviceType, String entityId, String state, String postion) {// header填充RequestCallback requestCallback = getRequestCallback();ResponseExtractor<ResponseEntity<String>> responseExtractor = restTemplate.responseEntityExtractor(String.class);MultiValueMap<String, String> paramMap = new LinkedMultiValueMap<>();String url = "";// 执行execute(),发送请求switch (deviceType) {case "cover":paramMap.add("entity_id", "cover." + entityId);if (state.equalsIgnoreCase("open") || state.equalsIgnoreCase("close") || state.equalsIgnoreCase("pause")) {url = "/api/services/cover/" + state + "_cover";} else if (state.equalsIgnoreCase("position")) {paramMap.add("position", postion);url = "/api/services/cover/set_cover_position";}break;case "switch":paramMap.add("entity_id", "switch." + entityId);if (state.equalsIgnoreCase("open")) {url = "/api/services/" + deviceType + "/turn_on";} else if (state.equalsIgnoreCase("close")) {url = "/api/services/" + deviceType + "/turn_off";}break;case "light":paramMap.add("entity_id", "light." + entityId);if (state.equalsIgnoreCase("open")) {url = "/api/services/" + deviceType + "/turn_on";} else if (state.equalsIgnoreCase("close")) {url = "/api/services/" + deviceType + "/turn_off";}break;case "fan":paramMap.add("entity_id", "switch." + entityId);if (state.equalsIgnoreCase("open")) {url = "/api/services/" + deviceType + "/turn_on";} else if (state.equalsIgnoreCase("close")) {url = "/api/services/" + deviceType + "/turn_off";}break;default:}ResponseEntity<String> response = restTemplate.execute(hassUrl + url, HttpMethod.POST, requestCallback, responseExtractor, paramMap);return response.getStatusCodeValue();}/*** 定义hedader** @return*/private RequestCallback getRequestCallback() {LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();headers.add("Authorization", "Bearer " + hassLongToken);headers.add("Content-Type", "application/json");// 获取单例RestTemplateHttpEntity request = new HttpEntity(headers);return restTemplate.httpEntityCallback(request, JSONArray.class);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/49377.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从零玩转系列之SpringBoot3-核心原理

一、简介 1.前置知识 ● Java17 ● Spring、SpringMVC、MyBatis ● Maven、IDEA 2.环境要求 环境&工具版本(or later)SpringBoot3.1.xIDEA2023.xJava17Maven3.5Tomcat10.0Servlet5.0GraalVM Community22.3Native Build Tools0.9.19 二、SpringBoot3-核心原理 1.事件和监听器…

SpringBoot3【⑤ 核心原理】

1. 事件和监听器 1. 生命周期监听 场景&#xff1a;监听应用的生命周期 1. 监听器-SpringApplicationRunListener 自定义SpringApplicationRunListener来监听事件&#xff1b; 1.1. 编写SpringApplicationRunListener 这个接口的实现类 1.2. 在 META-INF/spring.factories …

开发必备,开源 or 免费的 AI 编程助手

AI 大模型的火热&#xff0c;让开发圈近来如虎添翼&#xff0c;各种各样基于 AI 技术的开发者工具和新范式不断涌现&#xff0c;尤其是 Github 和 OpenAI 共同推出的 Copilot X &#xff0c;更是一骑绝尘。本文推荐一些开源 or 免费的 AI 编程工具&#xff0c;不妨试着用起来。…

超过5000人的2年研究表明,这一活动破坏你的身心健康

Tips 原文作者&#xff1a;Minda Zetlin 原文出处&#xff1a;A 2-Year Study of More Than 5,000 People Shows This 1 Activity Destroys Your Emotional and Physical Health 阅读时&#xff0c;把文中的 Fackbook 换成微信。 国外主要用 Facebook&#xff1b; 国内主要是微…

申请阿里云服务器并搭建公网可支持数据上传下载的HTTP服务器

1. 前言 拥有一台自己的云服务器可以做很多事情。阿里云服务器毫无疑问是国内最好的。 阿里云服务器可以用于各种互联网应用的搭建和运行&#xff0c;提供稳定、高性能的服务。 阿里云服务器的用途&#xff0c;包括但不限于以下几个方面&#xff1a; 网站托管&#xff1a;可以将…

谷歌眼镜秀出时尚风采:对面的女孩看过来

摘要&#xff1a;在近日举办的纽约时尚周上&#xff0c;让身材火辣的模特带上谷歌的眼镜&#xff0c;行走在T台之上。主打时尚牌&#xff0c;进一步加固谷歌眼镜在大众消费阶层的印象&#xff0c;尤其是女性消费者。谷歌眼镜创始人Sebastian Thrun指出&#xff1a;谷歌眼镜特别…

学生台灯什么牌子好对眼睛好?专业护眼灯的学生台灯分享

据报告统计&#xff0c;2022年我国儿童青少年总体近视率为52.7%&#xff0c;其中6岁儿童为14.3%&#xff0c;小学生为35.6%&#xff0c;初中生为71.1%&#xff0c;高中生为80.5%&#xff0c;这些数据让人不寒而栗&#xff01; 专家表示&#xff0c;导致儿童青少年近视的因素&am…

【UGP VR眼镜排行榜】2018VR眼镜眼镜哪个好?什么VR眼镜值得买?综合推荐十大热品

科技的发展&#xff0c;高科技产品层出不穷&#xff0c;VR眼镜的出现使人们足不出户也能享受到高品质的观影感受。VR(Virtual Reality&#xff09;即虚拟现实&#xff0c;简称VR.虚拟现实头戴显示器设备&#xff0c;简称VR头显VR眼镜.现在&#xff0c;VR眼镜已不是什么稀奇的东…

《谷歌眼镜》新书作者:眼镜需要成为AR的载体吗?

近10年前&#xff0c;谷歌推出了首款AR眼镜Google Glass&#xff0c;尽管这款产品并没有如预期般取得成功&#xff0c;但它为后续AR硬件技术的发展奠定了基础。我们知道&#xff0c;从微软HoloLens开始&#xff0c;AR头显/眼镜产品更侧重于B端应用&#xff0c;面向C端发售的很少…

Karl Guttag:现有Micro LED/LCoS+光波导AR眼镜对比解析

轻量化是未来AR眼镜的发展趋势&#xff0c;为了缩减尺寸&#xff0c;AR眼镜厂商尝试了多种方案&#xff0c;长期来看Micro LED光机在小型化上更有优势&#xff0c;但现阶段LCoS光机的图像表现更好。在CES 2023期间&#xff0c;DigiLens、Lumus、Vuzix、OPPO、Avegant也展出了不…

偏光太阳镜测试图片软件,[专题]真假偏光太阳镜简单、实用辨别方法!

偏光太阳镜主要是通过镜片的平衡排列的结晶体原理&#xff0c;只让与晶体平衡的光波通过&#xff0c;而向其它角度震动的光波会一律被阻挡的方法(如同百叶窗的原理)制作而成。 正是利用这种原理&#xff0c;偏光太阳镜便可以有效地排除和滤除光束中的偏振光&#xff0c;使光线能…

智能眼镜的两种显示方式

to管理员&#xff1a;哪一个是广告&#xff0c;全是广告&#xff01;难不成网友的链接都不能给了&#xff1f;&#xff01;你们的评判标识是什么&#xff1f; 就现有的技术而言&#xff0c;受限于通讯及周边模块、电源的限制&#xff0c;眼镜只适合于作为显示器使用。 眼镜显示…

谷歌眼镜

谷歌眼镜(Google Project Glass)是由谷歌公司于2012年4月发布的一款“拓展现实”眼镜&#xff0c;它具有和智能手机一样的功能&#xff0c;可以通过声音控制拍照&#xff0c;视频通话和辨明方向以及上网冲浪、处理文字信息和电子邮件等。 查看精彩图册 目录 产品简介 发布信息…

微信小程序开发制作 | 小程序开发者工具功能介绍

小程序开发者工具是微信官方提供的用于开发和调试小程序的工具。它支持 Windows 和 Mac 两种操作系统&#xff0c;并提供了许多实用的功能&#xff0c;使得小程序开发者能够快速地开发和调试小程序。 下面是小程序开发者工具的主要功能介绍&#xff1a; 1.编辑器&#xff1a;…

微信里的小程序怎么制作

自小程序普及以来&#xff0c;除了公司企业&#xff0c;很多的个体户商家都会想了解微信里的小程序怎么制作的&#xff0c;毕竟小程序能解决很多经营上的需求。那么就给大家讲解微信里的小程序怎么制作的流程&#xff0c;希望大家对此能有了解。 流程一、制作小程序前准备 我…

微信小程序开发之——制作表格

一 概述 表格样式一表格样式二 二 绘制过程 外层设置display:table&#xff0c;并设置border-collapse表格边框模型表头设置display:table-row&#xff0c;单元格设置为display:table-cell每一行单元格同表头设置 三 示例代码 3.1 table.wxml(布局文件) <view class&qu…

发明了万维网的他,如今却想亲手推翻它

本文转载自 差评 他有个计划&#xff0c;一个推翻现有互联网&#xff0c;重建数字世界的计划。 看到这句话时&#xff0c;相信很多差友和差评君的第一反应一个样&#xff1a;这谁也太狂了吧&#xff1f;几个菜啊&#xff0c;喝成这样&#xff1f; 毕竟&#xff0c;就算是马云…

计算机中文核心投递经历

中文核心投递录用经历 这篇文章主要记录了我在研究生期间从论文投递到录用的一个心酸过程&#xff0c;因为文章质量不是很高&#xff0c;所以投递过程中也是多次被拒稿。接下来介绍一下我的经历&#xff0c;为后来人提供一些经验。 这篇文章我是从2021年9月份开始着手写&#…

计算机专业留学动机信范文,出国留学,如何写好动机信(Motivation Letter)?

一篇好的动机信最重要的是简洁易懂,用最简洁的语言展示申请者最突出的优点。 浙大毕业后在美国(UIUC)和欧洲(KTH, CTH, EPFL, NTNU)留学,PhD。另外由于在之前的工作中也参与系里招生,帮老板评审申请材料,参与系里招生会议。经手的材料主要有以下几种:需要做论文的硕士,…

易水寒 服务器 位置,她彻底在他所在的城市消失了,他开始有些烦躁

封笑笑死了&#xff0c;她彻底在易水寒所在的城市消失了&#xff0c;连同名字身份都成了再也不会属于这个世界的东西。 易水寒开始有些烦躁&#xff0c;罗云若和罗家那些有意无意的提示让他觉得自己的自由和思维正在被束缚&#xff0c;这种感觉是他最厌恶的。 而罗云若似乎也变…