背景介绍

hi 大家好,我是三合,作为一个非著名懒人,智能家居简直刚需,在上一篇文章他来了他来了,.net开源智能家居之苹果HomeKit的c#原生sdk【Homekit.Net】1.0.0发布,快来打造你的私人智能家居吧中有靓仔提到,没有苹果设备,有一说一,苹果手机很贵,并且原生支持苹果HomeKit的智能家居设备也很贵,同时没几款可选的,还是米家的智能家居设备性价比更高同时品类更丰富,作为一个资深米粉,手机从红米note到小米6,小米8,再到小米10,接着如今全屋智能家居基本都是米家的,我对小米可谓爱的深沉,欢迎大家选购智能家居设备的时候优先选择小米,因为他真的很棒(手动狗头,雷军义父,请打钱谢谢)。但米家也有缺点,那就是米家并没有提供c#的sdk让我们能原生调用api,只能通过米家app操控设备,没有api这可玩性就太低了,神说:要有光,于是我今天便带着[MiHome.Net]来了,这个库主要参考了python的【python-miio】和【hass-xiaomi-miot】这2个项目。有了原生api就有了无限可能,大家可以尽情的发挥想象力去搞事了,接下来,我将介绍他的用法。

米家中的一些基本概念

米家中每一个智能家居设备称为一个设备(Device),每个设备拥有多个服务(Services),每个服务又有多个属性(Property)以及(0-N)个方法(Action,大家把方法理解为封装好的函数即可,我们可以直接调用方法来完成一些操作),所有设备都有设备信息服务,这个服务里包含了多个基本属性,包括设备型号,设备制造商,设备序列号等,并且设备根据功能还有另外一些独有的服务,我们以一个开关为例,开关本身就是一个设备,他拥有一个服务叫Switch,这个服务下面,有一个属性叫Switch Status,也就是开关,我们给这个属性赋值true,就代表开,赋值false,就代表关,同时米家设备支持2种操控方式,基于云端和基于本地,这两者的主要区别就在于云端需要设备以及手机有互联网连接,用户的操作指令是先发送到小米服务器,然后小米服务器下达指令给到智能设备,而基于本地则不同,他是直接通过ip和token,将指令发送给智能设备,这个过程,只需要局域网即可。所有米家智能家居设备都支持云端操作,但不是所有设备都支持本地操作,主要看设备情况。

MiHome.Net存在的意义

使用本依赖包,用户可以通过云端或者本地的方式用c#原生api来操作米家智能家居设备。

Getting Started

Nuget

接下来我将演示如何使用【MiHome.Net】,你可以运行以下命令在你的项目中安装 MiHome.Net 。

PM> Install-Package MiHome.Net

支持框架

net 6,net 8

api使用讲解

本库基于依赖注入,首先新建一个控制台应用,引入MiHome.Net的nuget包,接着添加小米米家的驱动服务,需要配置米家账号和密码,代码如下:

 var hostBuilder = Host.CreateDefaultBuilder();
//添加小米米家的驱动服务,需要小米账号和密码
hostBuilder.ConfigureServices(it => it.AddMiHomeDriver(x =>
{
x.UserName = "<这里填写米家账号>";
x.Password = "<这里填写米家米家>";
}));
var host = hostBuilder.Build();
var miHomeDriver = host.Services.GetService<IMiHomeDriver>();

获取到米家驱动服务以后,我们首先通过云端的方式调用接口,列出家庭里所有的智能家居设备,接着通过米家app里自己设置的设备名称找出自己想要操作的智能家居设备,我这里演示的是一个【米家智能插座2】,

我将3D打印出来的月球灯连到了这个插座上,并在米家app里将这个插座命名为月球灯,这样就将月球灯接入了智能家居。继续讲解api,接下来通过设备型号获取设备规格,这一步的目的,主要是了解我们要操作的智能家居设备都有哪些服务,哪些方法,哪些属性,并获得它们的id,因为我们操作智能家居需要用到设备id(即did),服务id(即siid),属性id(即piid),方法id(即aiid),代码如下:

  //列出家庭里所有的智能家居设备
var deviceList = await miHomeDriver.Cloud.GetDeviceListAsync();
//通过米家app里自己设置的智能家居名称找出自己想要操作的智能家居设备
var moonLight = deviceList.FirstOrDefault(it => it.Name == "月球灯");
//通过设备型号获取设备规格
var result = await miHomeDriver.Cloud.GetDeviceSpec(moonLight.Model);

我这里将获取到的规格结果截图出来给大家讲解一下



从上图中可以看到,这个设备总共有8个服务,逐一点开后我发现我只需要了解switch服务(即开关服务)即可,它的iid为2(即siid为2),同时这个服务下有3个属性,逐一点开查看后我发现,我只需要了解Switch Status属性即可,他的iid为1(即piid为1),同时这个属性值的格式(Format)是bool类型,即这个属性值只能为true或者false,接下来我将演示如何获取开关状态,代码如下:

 //通过本地方式获取属性值
var r1 = await miHomeDriver.Local.GetPropertyAsync(moonLight.LocalIp, moonLight.Token, new GetPropertyPayload()
{
Siid = 2,
Piid = 1
});
//通过云端方式获取属性值
var r7 = await miHomeDriver.Cloud.GetPropertyAsync(new GetPropertyDto()
{
Did = moonLight.Did,
Siid = 2,
Piid = 1
});

如上代码所示,支持本地以及云端的方式获取属性值,本地获取的方式需要传入智能家居设备的ip,智能家居设备的token,这两者都是之前通过云端设备接口GetDeviceListAsync返回的,以及参数siid和piid,这两者是我们之前通过查看设备规格获得的,通过云端的方式获取属性值,则额外需要did(即设备id),它同样是通过云端设备接口GetDeviceListAsync返回的,本地或云端调用后我们就获取到了开关当前的状态,调用结果如下图,value值为false,即代表开关当前处于关闭状态



接下来我将演示如何设置开关状态,代码如下:

 //通过本地方式设置属性值
var r2 = await miHomeDriver.Local.SetPropertyAsync(moonLight.LocalIp, moonLight.Token, new SetPropertyPayload()
{
Siid = 2,
Piid = 1,
Value = true
}); //通过云端方式设置属性值
var r8 = await miHomeDriver.Cloud.SetPropertyAsync(new SetPropertyDto()
{
Did = moonLight.Did,
Siid = 2,
Piid = 1,
Value = true
});

如上代码所示,支持本地以及云端的方式设置属性值,参数和获取属性值差不多,只是多了一个value参数,代表我们要设置的值,这里根据设备规格中format为bool,我们将它设置为true,即代表开。同时这些操作也支持批量获取和批量设置,代码如下

  //通过本地方式批量获取属性值
var r3 = await miHomeDriver.Local.GetPropertiesAsync(moonLight.LocalIp, moonLight.Token, new List<GetPropertyPayload>(){new GetPropertyPayload()
{
Siid = 2,
Piid = 1
}}); //通过云端方式批量获取属性值
var r5 = await miHomeDriver.Cloud.GetPropertiesAsync(new List<GetPropertyDto>()
{
new GetPropertyDto()
{
Did = moonLight.Did,
Siid = 2,
Piid = 1
}
}); //通过本地方式批量设置属性值
var r4 = await miHomeDriver.Local.SetPropertiesAsync(moonLight.LocalIp, moonLight.Token, new List<SetPropertyPayload>(){new SetPropertyPayload()
{
Siid = 2,
Piid = 1,
Value =true
}}); //通过云端方式批量设置属性值
var r6 = await miHomeDriver.Cloud.SetPropertiesAsync(new List<SetPropertyDto>()
{
new SetPropertyDto()
{
Did = moonLight.Did,
Siid = 2,
Piid = 1,
Value = true
}
});

接下来我给大家演示如何通过云端或者本地的方式调用设备服务里的方法,因为米家智能插座2没啥方法可以调用,所以我将使用【Gosund智能排插CP5 Pro】和【小爱音箱Play增强版】来给大家演示调用,先来【Gosund智能排插CP5 Pro】,这个排插长这样



他上面的4个插座都支持独立控制,我个人非常喜欢,强烈推荐(手动狗头,厂家打钱!),接下来我将演示调用4个插座其中插座3的方法来控制插座3的开关,

和上面一样,我们首先查规格,代码如下

var cp5pro = deviceList.FirstOrDefault(it => it.Name == "Gosund智能排插CP5 Pro");
var result3 = await miHomeDriver.Cloud.GetDeviceSpec(cp5pro.Model);

获得的规格如下图



如上图可以看出,插座3有一个方法(即action)叫toggle,这个方法主要就是改变插座3当前的状态,如果原来是关,调用即为开,如果原来是开,调用即为关,同时iid为1(即aiid为1),服务id为5(即siid为5),入参in为空数组,即不需要传入参数,out也为空数组,表示调用没有返回,不多说了,上代码:

//使用云端方式调用Gosund智能排插CP5 Pro中4个开关中第3个开关的toggle方法
var r11 = await miHomeDriver.Cloud.CallActionAsync(new CallActionInputDto()
{
Did = cp5pro.Did,
Aiid = 1,
Siid = 5,
In = new List<string>() { }
}); //使用本地方式调用Gosund智能排插CP5 Pro中4个开关中第3个开关的toggle方法
var r10 = await miHomeDriver.Local.CallActionAsync(cp5pro.LocalIp, cp5pro.Token, new CallActionPayload()
{
Siid = 5,
Aiid = 1,
In = new List<string>() { }
});

如上代码所示,和设置/获取属性不同,调用方法是通过服务id(即siid)和方法id(即aiid)以及入参in来实现的。

接下来演示调用【小爱音箱Play增强版】的服务方法来播放自定义文本,先上图



和上面一样,我们首先查规格,代码如下

var xiaoAi = deviceList.FirstOrDefault(it => it.Name == "小爱音箱Play增强版");
var result2 = await miHomeDriver.Cloud.GetDeviceSpec(xiaoAi.Model);

获得的规格如下图

如上图可以看出,小爱音箱有一个方法(即action)叫Play Text,这个方法用来播放自定义语音,同时iid为3(即aiid为3),服务id为5(即siid为5),入参in为数组,需要传入一个参数,即我们的自定义文本,out为空数组,表示调用没有返回,同时这个方法只支持云端调用,不支持本地调用,为啥我知道?因为我试过了,本地方法没反应,这个应该是需要服务器把文本转为语音,再回传到小爱音箱来播放,不多说了,上代码:

 //使用小爱音箱Play增强版播放我们的自定义文字
var r9 = await miHomeDriver.Cloud.CallActionAsync(new CallActionInputDto()
{
Did = xiaoAi.Did,
Aiid = 3,
Siid = 5,
In = new List<string>() { "门前大桥下,游过一群鸭" }
});

开源地址,欢迎star

本项目基于MIT协议开源,地址为

https://github.com/TripleView/MiHome.Net

同时感谢以下项目

  1. python-miio

  2. hass-xiaomi-miot

写在最后

如果各位靓仔觉得这个项目不错,欢迎一键三连(推荐,star,关注),有了【MiHome.Net】和【Homekit.Net】,想必各位靓仔应该能自己写程序将米家智能家居设备桥接到HomeKit生态里去了,反正我自己已经用了很久了,然后希望大家不要过于频繁的进行云端调用,以免对米家服务器造成不良影响。如果你也对智能家居很感兴趣,欢迎添加我的vx,hezp666。

他又来了,.net开源智能家居之小米米家的c#原生sdk【MiHome.Net】1.0.0发布,快来打造你的私人智能家居吧的更多相关文章

  1. DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区

    DS Scheduler 0.7 发布,Linux 调度系统 - 开源中国社区 DS Scheduler 0.7 发布,Linux 调度系统

  2. PyRedisAdmin v1.0 Beta 发布,Redis 在线管理工具 - 开源中国社区

    PyRedisAdmin v1.0 Beta 发布,Redis 在线管理工具 - 开源中国社区 PyRedisAdmin v1.0 Beta 发布,Redis 在线管理工具

  3. Rudiments 0.42 发布,C++ 常用工具包 - 开源中国社区

    Rudiments 0.42 发布,C++ 常用工具包 - 开源中国社区 Rudiments 0.42 发布,C++ 常用工具包

  4. Pyocr 0.2 发布,Python 的 OCR 库 - 开源中国社区

    Pyocr 0.2 发布,Python 的 OCR 库 - 开源中国社区 Pyocr 0.2 发布,Python 的 OCR 库

  5. 这年头做开源项目,被冷嘲热讽,FreeSql 0.0.4

    FreeSql 项目大概在20天前想着要做的,今天发布0.0.4在群里被一位大神讽刺. 这位无名氏哥们的观点,先声明这不是找安慰的文章,更加不是报复打击的目的. 1 所以这个比EF好在哪里 2 毕竟E ...

  6. LitepalNewDemo【开源数据库ORM框架-LitePal2.0.0版本的使用】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本Demo使用的是LitePal2.0.0版本,对于旧项目如何升级到2.0.0版本,请阅读<赶快使用LitePal 2.0版本 ...

  7. 五年磨一剑:Java 开源博客 Solo 1.0.0 发布了!

    从 Solo 第一个版本发布至今,已经过去 5 年了.今天我们非常自豪地宣布,Solo 1.0.0 正式发布,感谢一直以来关注 B3log 开源的朋友! 目前 B3log 开源有三款产品: GitHu ...

  8. .NET Core下的开源分布式任务调度系统ScheduleMaster-v2.0低调发布

    从1月份首次公开介绍这个项目到现在也快4个月了,期间做了一些修修补补整体没什么大的改动.2.0算是发布之后第一个大的版本更新,带来了许多新功能新特性,也修复了一些已知的bug,在此感谢在博客.Issu ...

  9. itest(爱测试) 开源一站式敏捷测试管理平台&极简项目管理,重大升级(接口测试)6.0.0 发布

    itest 简介 itest 开源敏捷测试管理,testOps 践行者,极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试5合1,又有丰富的统计分析.可按测试包分配测试用例执行,也可建测试迭代 ...

  10. .Net orm 开源项目 FreeSql 2.0.0(满意的答卷)

    写在开头 2018年11月头脑发热到今天,一晃已经两年,当初从舒服区走向一个巨大的坑,回头一看后背一凉. 两年时间从无到有,经历数不清的日夜奋斗(有人问花了多长时间投入,答案:全职x2 + 两年无休息 ...

随机推荐

  1. 记录-JS简单实现购物车图片局部放大预览效果

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.实现效果 二.代码实现 代码不多,先看一下 HTML 里面结构很简单,初始化 MagnifyingGlass 对象来关联一个 IMG  ...

  2. 记录--uniapp map 制作一个简单的地图导航

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 先上效果 简易map 在图一的地图中可以看到 a点 连接 到 b点, 基本信息 以及 基本的控件(放大.缩小.回到某个指定的点),接下来我 ...

  3. Vue中点击按钮回到顶部(滚动效果)

    页面滚动到一定位置时,出现回到顶部按钮 代码如下HTML <div class="footer"> <div class="gotop" v- ...

  4. 【FastDFS】面试官:如何实现文件的大规模分布式存储?(全程实战)

    写在前面 在<[FastDFS]小伙伴们说在CentOS 8服务器上搭建FastDFS环境总报错?>一文中,详细的介绍了如何在CentOS 8服务器行搭建FastDFS环境.在生产环境中, ...

  5. KingbaseES V8R6集群运维案例--主库PITR恢复后备库无法连接到集群

    案例说明: KingbaseES V8R6集群,在主库执行PITR恢复后,clone备库:但是启动集群后,备库无法连接到主库,流复制状态和集群节点状态异常. 适用版本: KingbaseES V8R6 ...

  6. Scala 类和对象与Java的对比

    一.包 1 package com{ 2 3 import com.atguigu.scala.Inner 4 5 // 在外层包中定义单例对象 6 object Outer{ 7 var out: ...

  7. 【已解决】Hadoop_02 bash: start-all.sh: 未找到命令...Linux

    在配置hadoop时需要进到/etc/profile中修改hadoop路径 #配置Hadoop和Java环境 export JAVA_HOME=/JDK-1.8 #你自己Java的安装路径 expor ...

  8. #完全背包输出具体方案#AT4298 [ABC118D] Match Matching

    题目 分析 首先,用完全背包求出\(n\)根火柴能够组成的最大位数, 然后选择尽量大的数字拼凑即可 代码 #include <cstdio> #include <cctype> ...

  9. 使用OHOS SDK构建vorbis

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/xiph/vorbis ...

  10. docker笔记之安装

    本文于2017年上半年完成,发布在个人博客网站上. 考虑个人博客因某种原因无法修复,于是在博客园安家,之前发布的文章逐步搬迁过来. 最近由于工作关系,接触到了docker技术.为了对docker有更多 ...