使用小爱同学语音控制电脑变关机

  • 前言
  • 实现原理
  • 准备
    • 注册巴法云账号
    • 接入巴法云
    • 接入米家
  • 编写程序
    • 连接TCP
    • 接收信息并运行关机指令
    • 发送指令订阅主题
    • 添加心跳机制
    • 后台运行
    • 阻止默认关闭窗口事件
  • 完整代码

前言

小爱同学应该已经是家喻户晓的了,现在一直用来控制家里的家电。于是乎突发奇想想用来操作电脑上的软件会怎么样,比如打开某个程序不用再去寻找,直接喊小爱同学打开,真的很方便,现在先来实现一个最简单的,用小爱同学来控制电脑关机。当然只是关机,开机还需要通过设置主板来实现,等后续研究成功了再记录吧。

实现原理

其实很简单,只要通过小爱同学给电脑发送一条指令,然后电脑收到此指令后就运行shutdown -s -t 10指令,其中10是关机的时间,单位为秒。要想立即关机可以使用shutdown -h.取消关机使用shutdown -a。通过以上即可指令即可自由的控制电脑什么时候关机。
现在问题是要怎样让电脑收到小爱同学的指令呢,通过百度查到可以使用巴法云,操作及其简单。

准备

注册巴法云账号

https://bemfa.com/通过以上地址进入巴法云官网,点击注册账号后登录,然后进入控制台,可以看到以下页面:

注意你的私匙是控制电脑的关键

接入巴法云

通过官方接入文档可以看到巴法云支持多种接入方式,再Winform中最简单的就是通过TCP方式接入。
接入前需要先点击新建一个主题,这里我们创建一个TCP创客云的主题,命名为Computer001.
这里需要注意接入米家需要注意主题的命名,官方文档介绍如下:

巴法云物联网平台默认接入米家,仅支持以下类型的设备:插座、灯泡、风扇、传感器、空调、开关、窗帘。

用户可以自主选择是否接入米家,根据主题名字判定。
当主题名字后三位是001时为插座设备。
当主题名字后三位是002时为灯泡设备。
当主题名字后三位是003时为风扇设备。
当主题名字后三位是004时为传感器设备。
当主题名字后三位是005时为空调设备。
当主题名字后三位是006时为开关设备。
当主题名字后三位是009时为窗帘设备。

我这里使用了001,小爱同学可以传送回来的指令为off或者no,代表插座的开关。

创建主题后最好更改一下昵称,点一下你主题的昵称的位置即可修改。这是昵称是接入米家后用来控制的设备名称。

接入米家

下载米家APP,登录后在下方找到我的,点击其他平台设备

点击添加,然后找到巴法

绑定后会显示在其他设备的列表中,并且点击进去会显示刚刚创建的主题


现在设备已经接入米家了,但是如果现在叫小爱同学控制,小爱同学会说不在线。此时我们可以使用串口工具测试一下是否可以接收到指令。
按照官方教程,先下载串口调试工具

打开工具后界面如下:

端口好为TCPClient,远程地址更改为·bemfa.com,端口为8344,然后点击连接。现在需要订阅你创建的那个主题,也就是让你的设备处于在线状态。
在左下角的文本框中输入

cmd=1&uid=xxxxxxxxxxxxxxxxxxxxxxx&topic=xxx1,xxx2,xxx3,xxx4\r\n

注意更改uid与topic,uid为你的私匙,topic为主题名称,多个主题使用逗号相隔。记得\r\n需要带上。
输入 指令点击发送,就会返回如下命令:

同时在巴法的控制台可以看到你的主题订阅数变为1

现在可以对着小爱同学说小爱同学 关闭电脑,在调试界面会出现如下返回


至此你的小爱同学已经连接到巴法云了,接下来开始写代码处理这个信息。

编写程序

连接TCP

创建一个Winform程序,窗口如下:

在load方法中赋值uid与topic
Form1_Load

          private void Form1_Load(object sender, EventArgs e){textBox1.Text = uid;textBox2.Text = "computer001";button1_Click(sender, e);                  }

button1_Click方法为点击按钮的事件。

主要方法代码如下:

     // 连接巴法云TCP服务器private void TcpL(){IPHostEntry hostEntry = Dns.GetHostEntry("bemfa.com");IPEndPoint ipEndPoint = new IPEndPoint(hostEntry.AddressList[0], 8344);//IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.31.114"), 777);try{tcpClient.Connect(ipEndPoint);Console.WriteLine("Connected");ShowMsg("Connect Success!");Thread c_thread = new Thread(Received);c_thread.IsBackground = true;c_thread.Start();Send($"cmd=1&uid={textBox1.Text}&topic={textBox2.Text}\r\n");  }catch (Exception ex){ShowMsg(ex.ToString());}}

接收信息并运行关机指令

        /// <summary>/// 接收信息/// </summary>private void Received(){NetworkStream networkStream = tcpClient.GetStream();EndPoint remoteEndPoint = tcpClient.Client.RemoteEndPoint;byte[] datas = new byte[1024];while (true){if (networkStream.DataAvailable){int len = networkStream.Read(datas, 0, 1024);string v = Encoding.UTF8.GetString(datas);string cmd = ParseQueryString(v, "cmd");string msg = ParseQueryString(v, "msg");if (cmd.Equals("2") && msg.IndexOf("off") == 0){//ShowMsg("电脑将于3s后关闭!");Process proc = new Process();proc.StartInfo.FileName = "cmd.exe"; // 启动命令行程序proc.StartInfo.UseShellExecute = false; // 不使用Shell来执行,用程序来执行proc.StartInfo.RedirectStandardError = true; // 重定向标准输入输出proc.StartInfo.RedirectStandardInput = true;proc.StartInfo.RedirectStandardOutput = true;proc.StartInfo.CreateNoWindow = true; // 执行时不创建新窗口proc.Start();string commandLine;//if (isCancel)//    commandLine = @"shutdown /a";  // 停止关机commandLine = @"shutdown /s /t 0";  // 立即关机proc.StandardInput.WriteLine(commandLine);return;}ShowMsg(Encoding.UTF8.GetString(datas));//Console.WriteLine($"From:{remoteEndPoint}:Received ({len})");}Thread.Sleep(1);}}

发送指令订阅主题

        /// <summary>/// 发送信息/// </summary>/// <param name="msg"></param>private void Send(string msg){NetworkStream networkStream = tcpClient.GetStream();EndPoint remoteEndPoint = tcpClient.Client.RemoteEndPoint;byte[] datas = new byte[1024];datas = Encoding.ASCII.GetBytes(msg);networkStream.Write(datas, 0, datas.Length);}

添加心跳机制

通过多次测试发现,如果一分钟没有向服务器发送指定,那么就会自动断开连接。这里添加一段代码每隔30s向服务器请求一段数据。

        public void StartCommIdle(){//定时器配置Thread c_thread = new Thread(Heartbeat);c_thread.IsBackground = true;c_thread.Start();}public void Heartbeat(){try{while (true){Send($"ping\r\n");Thread.Sleep(30000);}}catch (Exception){TcpL();}}

要将StartCommIdle方法加载Tcp方法后面

后台运行

要想随时接收小爱同学的指令就需要一直打开此程序,如果电脑窗口多了这个界面还不能关掉就很烦,所以再添加一段代码用于将程序后台运行并将图标显示在任务栏中。


在winform的组件中添加notifyIcon
找到Icon属性设置图标
如果想再显示主界面可以添加菜单栏选项
添加contextMenuStrip组件,并设置他们的方法。

阻止默认关闭窗口事件

找到Form_Closing属性,

绑定如下方法,这样点击关闭按钮后程序不会退出,而是再后台运行。

        private void Form1_FormClosing(object sender, FormClosingEventArgs e){try{e.Cancel = true;this.Visible = false;}catch (Exception ex){MessageBox.Show(ex.Message);}}

如果想要关闭则在菜单栏中添加关闭方法:

        private void smi_exit_Click(object sender, EventArgs e){DialogResult result = MessageBox.Show("你确定要关闭吗!", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);if (result == DialogResult.OK){// 关闭所有的线程this.Dispose();this.Close();}}

显示主界面方法:

        private void Form1_FormShow(object sender, EventArgs e){this.Visible = true;}

至此,只要对着小爱同学说关闭电脑,电脑会马上关机。

完整代码

以下为完整代码,供参考,注意uid需要设置为自己的私钥。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Diagnostics;namespace TCPShutdown
{public partial class Form1 : Form{private TcpClient tcpClient = new TcpClient();private string uid = "";public Form1(){InitializeComponent();this.Hide();}private void TcpL(){IPHostEntry hostEntry = Dns.GetHostEntry("bemfa.com");IPEndPoint ipEndPoint = new IPEndPoint(hostEntry.AddressList[0], 8344);//IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("192.168.31.114"), 777);try{tcpClient.Connect(ipEndPoint);Console.WriteLine("Connected");ShowMsg("Connect Success!");Thread c_thread = new Thread(Received);c_thread.IsBackground = true;c_thread.Start();Send($"cmd=1&uid={textBox1.Text}&topic={textBox2.Text}\r\n");StartCommIdle();}catch (Exception ex){ShowMsg(ex.ToString());}}public void StartCommIdle(){//定时器配置Thread c_thread = new Thread(Heartbeat);c_thread.IsBackground = true;c_thread.Start();}public void Heartbeat(){try{while (true){Send($"ping\r\n");Thread.Sleep(30000);}}catch (Exception){TcpL();}}/// <summary>/// 接收信息/// </summary>private void Received(){NetworkStream networkStream = tcpClient.GetStream();EndPoint remoteEndPoint = tcpClient.Client.RemoteEndPoint;byte[] datas = new byte[1024];while (true){if (networkStream.DataAvailable){int len = networkStream.Read(datas, 0, 1024);string v = Encoding.UTF8.GetString(datas);string cmd = ParseQueryString(v, "cmd");string msg = ParseQueryString(v, "msg");if (cmd.Equals("2") && msg.IndexOf("off") == 0){ShowMsg("电脑将于3s后关闭!");Process proc = new Process();proc.StartInfo.FileName = "cmd.exe"; // 启动命令行程序proc.StartInfo.UseShellExecute = false; // 不使用Shell来执行,用程序来执行proc.StartInfo.RedirectStandardError = true; // 重定向标准输入输出proc.StartInfo.RedirectStandardInput = true;proc.StartInfo.RedirectStandardOutput = true;proc.StartInfo.CreateNoWindow = true; // 执行时不创建新窗口proc.Start();string commandLine;//if (isCancel)//    commandLine = @"shutdown /a";commandLine = @"shutdown /s /t 0";proc.StandardInput.WriteLine(commandLine);return;}ShowMsg(Encoding.UTF8.GetString(datas));//Console.WriteLine($"From:{remoteEndPoint}:Received ({len})");}Thread.Sleep(1);}}/// <summary>/// 发送信息/// </summary>/// <param name="msg"></param>private void Send(string msg){NetworkStream networkStream = tcpClient.GetStream();EndPoint remoteEndPoint = tcpClient.Client.RemoteEndPoint;byte[] datas = new byte[1024];datas = Encoding.ASCII.GetBytes(msg);networkStream.Write(datas, 0, datas.Length);}void ShowMsg(string str){this.Invoke(new Action(() =>{richTextBox1.AppendText(str + "\r\n");}));}void ShowNotice(string str){this.Invoke(new Action(() =>{textBox3.AppendText(str + "\r\n");}));}private void button1_Click(object sender, EventArgs e){TcpL();}private void Form1_Load(object sender, EventArgs e){textBox1.Text = uid;textBox2.Text = "computer001";button1_Click(sender, e);            }private void smi_exit_Click(object sender, EventArgs e){DialogResult result = MessageBox.Show("你确定要关闭吗!", "提示信息", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);if (result == DialogResult.OK){// 关闭所有的线程this.Dispose();this.Close();}}private void Form1_FormClosing(object sender, FormClosingEventArgs e){try{e.Cancel = true;this.Visible = false;}catch (Exception ex){MessageBox.Show(ex.Message);}}private void button2_Click(object sender, EventArgs e){this.Visible = false;//Send($"cmd=7&uid={uid}&type=1\r\n");}public static string ParseQueryString(string url, string key){if (string.IsNullOrWhiteSpace(url)){throw new ArgumentNullException("url");}//1.去除第一个前导?字符//var dic = string value = null;Dictionary<string, string> dictionary = url//2.通过&划分各个参数.Split(new char[] { '&' }, StringSplitOptions.RemoveEmptyEntries)//3.通过=划分参数key和value,且保证只分割第一个=字符.Select(param => param.Split(new char[] { '=' }, 2, StringSplitOptions.RemoveEmptyEntries))//4.通过相同的参数key进行分组.GroupBy(part => part[0], part => part.Length > 1 ? part[1] : string.Empty)//5.将相同key的value以,拼接.ToDictionary(group => group.Key, group => string.Join(",", group));dictionary.TryGetValue(key, out value);return value;}private void Form1_FormShow(object sender, EventArgs e){this.Visible = true;}}
}

仅供学习使用,如转发请标明出处,谢谢。

使用小爱同学语音控制电脑关机 - Winform C#相关推荐

  1. 基于Blinker的小爱同学语音控制【脱坑指南】

    基于Blinker的小爱同学语音控制ESP8266 前些天在使用esp8266时遇到很多小爱不能控制设备问题,现在来叙述我控制过程中所遇到的问题,以及到完整的小爱能成功控制Esp8266的过程. 1. ...

  2. ESP8266 快速对接小爱同学 语音控制

    ESP8266 快速对接小爱同学 一.环境资料 二.安装配置 三.下载Blinker手机APP,并更改符合小米小爱协议的代码 四.米家绑定Blinker点灯 一.环境资料 1. 硬件:ESP8266 ...

  3. 想用天猫精灵、小爱同学语音控制灯、窗帘、卷帘门、投影幕……实现你的智能家居梦?用十几元钱制作一个红外射频转发器试试吧

    使用场景 自从智能音箱出现以后,是不是想用智能音箱控制家里的电器和设备?但是购买接入天猫精灵和小爱同学的设备都很贵,比如一套普通的电动窗帘架300元左右,但是接入智能音箱控制的最少要700元.想尝试智 ...

  4. 【小米米家对接连载】 安信可 ESP8266-12S模块作为米家通用模块,直连小米米家平台,小爱同学语音控制;

    文章目录 一. 准备工作 二. 通过STM32代码设置产品model 三. STM32单片机不断发送get_down指令一直查询模块返回的状态 四. 模块核心指令的解答 五. 关于模块返回的参数说明 ...

  5. python控制小爱同学_神秘鸭,用Siri小爱同学语音助手控制你的电脑

    智能手机发展至今,智能可不仅是改变了沟通和上网形式,依据强大的算法核心,各种基于AI的智能语音助手屡见不鲜,其中苹果的Siri.小米的小爱同学.阿里的天猫精灵,极受欢迎.虽说现在的人工智能语音助手,仍 ...

  6. 电脑入米家,让小爱同学随意操控电脑开关机(需主机或软路由)

    电脑入米家,让小爱同学随意操控电脑开关机 前言 一.效果展示 二.环境准备 三.巴法平台获取密钥及添加设备: 1.注册巴法平台账号 2.获取密钥 3.添加设备 四.目标电脑设置(网络唤醒+免密SSH) ...

  7. win7关闭计算机控制,大吼:鹅要关机!Win7下语音控制电脑攻略

    Win7之家( www.win7china.com):大吼:鹅要关机!Win7下语音控制电脑攻略 记得若干年前非常真实的一幕,一位兄弟在宿舍津津有味玩着游戏,一舍友突然学他的方言口音大吼一声:鹅要关机 ...

  8. 【Homeassistant 的Node-red插件之小爱同学语音功能开通】

    目的:Homeassistant 的Node-red插件之小爱同学语音功能开通,实现播报任意带变量的文本 视频部分效果可见:https://www.bilibili.com/video/BV1id4y ...

  9. php控制电脑关机,window_Windows7系统语音识别功能控制电脑操作,记得若干年前非常真实的一幕 - phpStudy...

    记得若干年前非常真实的一幕,一位兄弟在宿舍津津有味玩着游戏,一舍友突然学他的方言口音大吼一声:鹅要关机!! 结果,Windows听话的关机了-- 其实,在很多科幻片中都有相同的一幕,主人公使用的电脑没 ...

最新文章

  1. Linux数据报文接收发送总结2
  2. Computer:现代计算机操作系统的四大基本特性(并发/共享/虚拟/异步)
  3. 《明解C语言》pdf
  4. Linux iperf 网络性能测试工具
  5. python基础(part11)-作用域LEGB
  6. SAP CRM呼叫中心里多重Contact person confirm的处理
  7. 表单隐藏域与display:none
  8. ubuntu meld比较文件差异
  9. 《Scikit-Learn与TensorFlow机器学习实用指南》第9章 启动并运行TensorFlow
  10. Go语言学习笔记——Go语言数据类型
  11. BZOJ1061: [Noi2008]志愿者招募(线性规划)
  12. rosweb,roslib,ROS2D.PolygonMarker 绘制多边形
  13. java大文件排序_java对大文件进行归并排序(利用胜者树)
  14. cmake install_CMAKE入门实战
  15. csrss.exe病毒查杀
  16. 让人耳目一新的四款高质量软件,简约又实用,每一款都值得收藏
  17. Theme Holo
  18. 网络棋牌游戏创造快乐心情
  19. Photoshop CS5软件安装教程
  20. gdp python 变迁动图_十分钟,用 Python 带你看遍 GDP 变迁

热门文章

  1. 用C语言学生成绩数据库排序功能设计,[c语言学生成绩管理系统]C语言学生成绩管理系统实验报告...
  2. OpenGL3.3法线贴图
  3. 3D游戏建模入门初级教学:制作纹理逼真的法线贴图
  4. 健身教练学习书籍推荐-结合知乎
  5. 大数据技术之Kafka(一)Kafka概述、Kafka快速入门、Kafka架构深入
  6. 旧电脑安装黑群晖(5.1-5022)
  7. 网站架构(页面静态化,图片服务器分离,负载均衡)方案全解析
  8. Python爬虫 之 seleniun模块
  9. Ubuntu18.04解决蓝牙耳机无法连接问题
  10. 《程序设计实践》第05练——指针Part(2/2)