You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1232 lines
672 KiB

<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>精益方法论</title>
<link href="/tech/work-methodology.html"/>
<url>/tech/work-methodology.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>持续学习; 持续思考; 持续实践; 让一切自然而然发生。</p></span><span class=".en"><p>Keep learning; Keep thinking; Keep practice; Let it happens spontaneously.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}else{tips.info({title: 'Info',position: 'topRight',message: '这是我的一点小感悟啦,希望接下来我能够坚持践行这一理念,让我的事业更进一步!'});}});</script><span class=".zh"><h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>自新冠疫情发生以来,我的生活受到了极大的影响。从最开始的留学生活的草草结束,到后来眼睛的疾病,再到美国签证被长时间行政审查而不得不延期研究生入学。经历了接近两年的各种磨难,我慢慢的成长着。从最开始的患有急性焦虑症并因此体验了英国NHS救护车,到现在的失学失业。在这个不确定性纷杂的世界中,我似乎逐渐摸索出了与之相处的方法。</p><p>为了摆脱内心的焦灼,最初,我曾尝试禅修。但由于种种原因,似乎效果并不佳。到后来我偶然发现,观看古生物发展史的纪录片,似乎对缓解我的心理焦虑有着一定的影响,但并不显著。然而,这个契机让我开始逐渐认识的我焦虑产生的根源。那大概便是对未来不确定性的困扰以及对我应对不确定性的策略的不自信。</p><p>经过长期的探索,我发现以下几点能够显著改善我的心里状况:</p><ul><li>睡觉,自然醒</li><li>重视三餐,吃自己喜欢的食物</li><li>每天至少去大自然(公园,树林)带半小时</li><li>10分钟以上的中度运动</li><li>充实地生活</li></ul><p>本文中,将重点阐述最后一条的具体内容和实施方法。</p><h2 id="详述"><a href="#详述" class="headerlink" title="详述"></a>详述</h2><p><strong>持续学习; 持续思考; 持续实践; 让一切自然而然发生。</strong> </p><p>这句话的意思是,不要让自己闲下来。当自己无事可做的时候,找自己当前最想做的方向或事情,比如英语或编程,然后做当前内心最倾向的流程,比如探索学习,思考整理,或者实践。让直觉来引导当前最适合做的具体事情。但在大的方向上,比如当前的工作重心应该是学英语还是练习算法,则要充分的研究规划好。</p></span><span class=".en"><h2 id="Preface"><a href="#Preface" class="headerlink" title="Preface"></a>Preface</h2><p>Since the outbreak of the new crown epidemic, my life has been greatly affected. From the beginning of the study abroad life hastily ended, to later eye diseases, and then to the United States visa was subject to a long administrative review and had to postpone graduate school enrollment. After nearly two years of various hardships, I slowly grew up. From the beginning, I suffered from acute anxiety disorder and experienced the British NHS ambulance, until now I am out of school and unemployed. In this uncertain world, I seem to have gradually figured out a way to get along with it.</p><p>In order to get rid of my inner anxiety, I tried meditation at first. But due to various reasons, it seems that the effect is not good. Later, I accidentally discovered that watching a documentary on the history of paleontology seemed to have a certain effect on alleviating my psychological anxiety, but it was not significant. However, this opportunity allowed me to gradually understand the source of my anxiety. That is probably the trouble with the uncertainty of the future and the lack of confidence in my strategy to deal with the uncertainty.</p><p>After long-term exploration, I found that the following points can significantly improve my mental condition:<br> -Sleep, wake up naturally<br> -Pay attention to three meals and eat your favorite food<br> -Go to nature (parks, woods) for at least half an hour every day<br> -More than 10 minutes of moderate exercise<br> -Live to the fullest</p><p>In this article, I will focus on the specific content and implementation methods of the last article.</p><h2 id="Detailed"><a href="#Detailed" class="headerlink" title="Detailed"></a>Detailed</h2><p><strong>Keep learning; keep thinking; keep practicing; let everything happen naturally.</strong></p><p>The meaning of this sentence is, don’t let yourself be idle. When you have nothing to do, look for the direction or thing you want to do most, such as English or programming, and then do the most inclined process in your heart, such as exploring and learning, thinking and organizing, or practicing. Let intuition guide the specific things that are best for doing right now. But in the general direction, such as whether the current work should focus on learning English or practicing algorithms, it is necessary to fully research and plan.</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> life </tag>
<tag> work </tag>
<tag> methdology </tag>
</tags>
</entry>
<entry>
<title></title>
<link href="/life/happiness.html"/>
<url>/life/happiness.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>顿悟 关于生活</p></span><span class=".en"><p>Idea About life</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>原来,没有人生来就留恋人世。所以,尽情去做一些让自己真正感到快乐幸福的事情吧!</p></span><span class=".en"><p>It turns out that no one is born with nostalgia for the world. So, you can only do something that makes you really happy and happy!</p></span>]]></content>
<categories>
<category> life </category>
</categories>
<tags>
<tag> idea </tag>
</tags>
</entry>
<entry>
<title>未来生活定位</title>
<link href="/life/life-orientation.html"/>
<url>/life/life-orientation.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>经过一年多的迷茫,我逐渐探明我的迷茫原因所在,进而结合社会大环境发展前景,制定出未来数年我的生活发展定位。</p></span><span class=".en"><p>Abstract in english</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="目前情况分析"><a href="#目前情况分析" class="headerlink" title="目前情况分析"></a>目前情况分析</h2><h3 id="我"><a href="#我" class="headerlink" title="我"></a>我</h3><p>经过十年多的努力耕耘,截止21年1月,我已经掌握了多种知识及技能,已经基本具备维持温饱的能力。至此,“努力学习养活自己”这一曾经的定位已不再是当前的主要矛盾。与此同时,“对美好生活的向往”逐渐浮现,成为当前的主要行为动机。然而,不幸的是,由于我过去的发展方式是“项目快感驱动”型,缺乏有效的监督,于是对身体造成了巨大的损伤。</p><h3 id="社会大环境"><a href="#社会大环境" class="headerlink" title="社会大环境"></a>社会大环境</h3><p>新冠后时代,世界进入“比烂时代”,预计会存在一个3年以上的长期消杠杆时期。考虑到物联网,人工智能领域当前的瓶颈问题,短期内恐难以有备受期待的科技革命发生。因此,消杠杆时期可能会更加漫长,达到5年甚至7年,直至新的一轮产业转型,世界大战,或者科技革命方能结束。在此期间,包括诸大互联网巨头在内,社会中的上升机会将大幅度减少,内卷情况将进一步恶化。但好消息是,消杠杆时期度过后,世界会进入新的高速发展时期,这时将会拥有诸多上升及创业机会(尤其是科技革命直接受益产业),重现“风口猪也上天”现象。</p><h2 id="发展方向"><a href="#发展方向" class="headerlink" title="发展方向"></a>发展方向</h2><p>所谓“厚积薄发”。如果说,积杠杆时期是爆发期,那么消杠杆时期则是漫长的积累期。在积累期,最佳的生存策略是闷声积累技能经验,为爆发期做准备。在此阶段,资产普遍大幅贬值,保值手段甚微。此时,将资产投资到提升自己实力上,似乎是最佳的保值策略。总言之,消杠杆时期的最佳策略是,蛰伏,闷声提升自己。万万不可迫于环境压力,打破自己的节奏。想一下,如果你是上司,你是希望你收下最听话天天加班的人升值,还是希望只做分内事但很有能力的人升职走掉。</p><p>“美好生活”是一个抽象的概念,这一现象实现的基础,首先便是要具有良好的身体状况。为此,未来一段时间我的首要任务,是尽可能恢复身体被破坏的部分,比如眼睛和腰。</p></span><span class=".en"></span>]]></content>
<categories>
<category> life </category>
</categories>
<tags>
<tag> life </tag>
<tag> analysis </tag>
<tag> orientation </tag>
</tags>
</entry>
<entry>
<title>acg.watch-我的私人视频网站</title>
<link href="/tech/acg-watch.html"/>
<url>/tech/acg-watch.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>此文将讨论acg.watch网站的定位,运营模式,以及潜在应用等。</p></span><span class=".en"><p>This article will discuss the positioning, operating mode, and potential applications of the acg.watch website.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="缘由"><a href="#缘由" class="headerlink" title="缘由"></a>缘由</h2><p>自从18年第一次尝试建站以来,追求流媒体播放服务一直是我所追求的目标。</p><h2 id="历史"><a href="#历史" class="headerlink" title="历史"></a>历史</h2><p>从2018年三月,我第一次通过腾讯云Win Server 2012实现了对摇曳露营第3集的发布,从而使其能够在网页上访问。到2018年9月,基于video.js,我第一次搭建了一个视频网站,使用华为云对象存储以及mysql数据库进行集中管理,并将其发布在video.yimian.xyz。2018年11月,配合树莓派3B以及一个红外摄像头,我通过推流实现了对宿舍的24小时监控。2019年2月,我购买了acg.watch这个域名,并将视频站转移至此。此后,我站视频被爬多次,由于华为云存储巨额的流量费用,我觉定暂时停止公开提供服务。2019年11月,在英国,我重构了视频站,不再使用华为云存储这个烧钱的服务,转而寻求onedrive存储方案。此外,新的视频站不再拥有后端,而是使用file-cache机制通过分析onedrive的视频目录自动生成数据集。2020年8月,随着ushio用户系统竣工,视频站开始支持为用户提供个性化服务,包括跨设备播放记录同步等。2021年1月,确定acg.watch的发展方向为<strong>多功能在线播放器</strong>,此外网站还将提供<strong>番剧搜寻功能</strong>。同时,考虑到版权问题,我之前私藏的所有视频全部转为私有,只有认证过的朋友们才有权限观看。</p><h2 id="网站地址"><a href="#网站地址" class="headerlink" title="网站地址"></a>网站地址</h2><ul><li><a href="http://video.yimian.xyz/" target="_blank" rel="noopener">http://video.yimian.xyz</a></li><li><a href="https://acg.watch/" target="_blank" rel="noopener">https://acg.watch</a></li></ul><h2 id="定位"><a href="#定位" class="headerlink" title="定位"></a>定位</h2><p>Acg.Watch视频站拥有三个发展定位:</p><ul><li>番剧资源辅助搜索</li><li>多功能视频播放器</li><li>IoTcat的私藏视频站</li></ul><h2 id="发展状态"><a href="#发展状态" class="headerlink" title="发展状态"></a>发展状态</h2><p>网站将持续开发,欢迎大家常来踩踩呀<em>(:з」∠)</em></p></span><span class=".en"><h2 id="Reason"><a href="#Reason" class="headerlink" title="Reason"></a>Reason</h2><p>Since the first attempt to build a website in 18 years, the pursuit of streaming media playback services has always been my goal.</p><h2 id="History"><a href="#History" class="headerlink" title="History"></a>History</h2><p>From March 2018, I realized the release of the third episode of Sway Camp through Tencent Cloud Win Server 2012 for the first time, so that it can be accessed on the web. By September 2018, based on video.js, I built a video website for the first time, used Huawei Cloud object storage and mysql database for centralized management, and published it on video.yimian.xyz. In November 2018, with the Raspberry Pi 3B and an infrared camera, I realized 24-hour monitoring of the dormitory through push streaming. In February 2019, I purchased the domain name acg.watch and transferred the video site to it. Since then, my site’s video has been crawled many times. Due to the huge traffic cost of Huawei Cloud storage, I feel that I will temporarily stop publicly providing services. In November 2019, in the United Kingdom, I restructured the video site and stopped using Huawei Cloud Storage, a money-burning service, and turned to onedrive storage solutions. In addition, the new video station no longer has a backend, but uses the file-cache mechanism to automatically generate a data set by analyzing onedrive’s video catalog. In August 2020, with the completion of the ushio user system, the video station began to provide users with personalized services, including cross-device playback and recording synchronization. In January 2021, the development direction of acg.watch is determined as a <strong>multifunctional online player</strong>, and the website will also provide a <strong>fan drama search function</strong>. At the same time, taking into account the copyright issue, all the videos that I have privately collected before are all turned into private ones, and only authenticated friends can watch them.</p><h2 id="Website-address"><a href="#Website-address" class="headerlink" title="Website address"></a>Website address</h2><ul><li><a href="http://video.yimian.xyz/" target="_blank" rel="noopener">http://video.yimian.xyz</a></li><li><a href="https://acg.watch/" target="_blank" rel="noopener">https://acg.watch</a></li></ul><h2 id="Positioning"><a href="#Positioning" class="headerlink" title="Positioning"></a>Positioning</h2><p>Acg.Watch video station has three development positions:</p><ul><li>Assisted search for fan drama resources</li><li>Multifunctional video player</li><li>IoTcat’s private video station</li></ul><h2 id="Development-status"><a href="#Development-status" class="headerlink" title="Development status"></a>Development status</h2><p>The website will continue to be developed, and you are welcome to step on it often_(:з」∠)_</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> website </tag>
<tag> video </tag>
</tags>
</entry>
<entry>
<title>Ushio-V2ray使用方法</title>
<link href="/tech/v2ray-instruction.html"/>
<url>/tech/v2ray-instruction.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>Ushio V2ray 使用方法。</p></span><span class=".en"><p>Ushio V2ray Instruction..</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><blockquote><p>本服务仅向以学术研究为目的学生提供!<br>本服务非盈利,但可能会根据您的使用情况收取少许费用,来平摊服务器的费用!</p></blockquote><h2 id="流程总览"><a href="#流程总览" class="headerlink" title="流程总览"></a>流程总览</h2><ul><li>用户注册</li><li>v2ray软件安装</li></ul><h2 id="用户注册"><a href="#用户注册" class="headerlink" title="用户注册"></a>用户注册</h2><p>在开始安装软件前,请先前往<a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz/</a>使用手机号进行账户注册。</p><blockquote><p>如确有使用需求,请在注册后将您的学生身份证明和注册手机号发送至<a href="mailto:i@iotcat.me">i@iotcat.me</a>,在我检查过您的需求合法性后将赋予您使用权限!</p></blockquote><h2 id="v2ray软件安装"><a href="#v2ray软件安装" class="headerlink" title="v2ray软件安装"></a>v2ray软件安装</h2><p>本文包含<a href="#Win10">Win10</a>,<a href="#Android">安卓</a>,<a href="#Ios">IOS/Ipad OS</a>的软件安装方法,请根据相应流程进行安装。</p><blockquote><p>如果您有任何疑惑,请在下方评论中提出!</p></blockquote><h3 id="Win10"><a href="#Win10" class="headerlink" title="Win10"></a>Win10</h3><p><strong>下载</strong></p><ul><li>使用浏览器访问<a href="https://onedrive.yimian.xyz/packages/programs/all/v2ray/Windows_v2rayN-Core.zip" target="_blank" rel="noopener">http://eee.dog/8bcc14</a>下载名为<code>Windows_v2rayN-Core.zip</code>的压缩文件。</li></ul><p><strong>解压</strong></p><ul><li><p>将下载的压缩文件解压到C盘根目录,如下图</p><blockquote><p>如果提示需要<strong>管理员权限</strong>,请一律选<strong>是</strong></p></blockquote><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_2eb9b63_1565x429_8_null_normal.jpeg" alt="解压文件图"></p></li></ul><p><strong>配置</strong></p><ul><li><p>请打开C盘中刚才解压的文件夹,找到名为<code>V2ray</code>或<code>V2rayN.exe</code>的程序,双击打开。如下图。<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_430e95a_1557x460_8_null_normal.jpeg" alt="V2rayN图"></p></li><li><p>找到右下角任务栏,找到下图中的图标,双击打开<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_3a35a1f_928x246_8_null_normal.jpeg" alt="V2rayN图标"></p></li><li><p>选中窗口上方的<strong>订阅</strong>,点击<strong>订阅设置</strong>如下图<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_4574629_1421x180_8_null_normal.jpeg" alt="订阅设置"></p></li><li><p>打开<a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz</a>并登录,待出现二维码后点击<strong>Copy</strong>。如下图<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_6d86c79_1254x711_8_null_normal.jpeg" alt="获取订阅地址"></p></li><li><p>回到订阅设置的窗口,将刚才复制的内容粘贴到<strong>地址URL框</strong>中,勾选<strong>启用</strong>,点击<strong>确定</strong>。如下图<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_50dc56e_867x752_8_null_normal.jpeg" alt="设置订阅地址"></p></li><li><p>点击主窗口上方的<strong>参数设置</strong>如下图</p></li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6a56090_1313x195_8_null_normal.jpeg" alt="参数设置"></p><ul><li>选择<strong>V2rayN设置</strong>,勾选<strong>开机自动启动</strong>,点击下方<strong>确定</strong>。如下图</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_0b74331_993x1020_8_null_normal.jpeg" alt="开机启动"></p><ul><li>回到主窗口,点击<strong>更新订阅</strong>如下图</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_396bcc7_1037x174_8_null_normal.jpeg" alt="更新订阅"></p><ul><li><p>此时,主窗口中会多出一个或几个服务器,如下图</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_4419a90_1196x216_8_null_normal.jpeg" alt="服务器列表"></p></li><li><p>关闭主窗口,右键右下角状态栏中的V2ray,选择<strong>服务器</strong>-&gt;<strong>Vmess-Los_Angeles(….</strong>。如下图<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_0266a2f_1067x288_8_null_normal.jpeg" alt="选择服务器"></p></li><li><p>右键右下角状态栏中的V2ray,选择<strong>Http代理</strong>-&gt;<strong>…(PAC模式)</strong>。如下图<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_8c3a651_1088x306_8_null_normal.jpeg" alt="PAC模式"></p></li></ul><p><strong>验证</strong></p><ul><li>浏览器打开<a href="https://www.google.com" target="_blank" rel="noopener">https://google.com</a>试一下能否访问。</li></ul><h3 id="Android"><a href="#Android" class="headerlink" title="Android"></a>Android</h3><p><strong>下载安装软件</strong></p><ul><li>浏览器打开<a href="https://onedrive.yimian.xyz/packages/programs/all/v2ray/Android_v2rayNG_1.3.1.apk" target="_blank" rel="noopener">http://eee.dog/6db2e3</a>下载V2ray安卓安装包</li><li>点开安装包进行安装</li></ul><p><strong>配置</strong></p><ul><li>使用手机浏览器,打开<a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz/</a>,进行登录</li><li>待页面显示出二维码,点击<strong>Copy</strong></li><li>打开安装的V2rayNG软件,点击左上角三条杠,展开左侧栏,点击<strong>订阅设置</strong></li><li>进入订阅设置页面后,点击右上角<strong>加号</strong></li><li>备注中填<strong>ushio</strong>, 地址url中填<strong>刚才复制的东西</strong>,点击右上角对勾。</li><li>回到主页面,点击左上角三条杠,展开左侧栏,点击<strong>设置</strong></li><li>进入设置页面后,点击<strong>分应用代理</strong></li><li>勾选<strong>分应用代理</strong>模式,然后在列表中勾选需要访问外网的app,如twitter, youtube等</li><li>回到主页面,点击右上角三个点,点击<strong>更新订阅</strong></li><li>点一下主页面列表中的<strong>Los_Angeles</strong>,使其左侧变绿</li><li>点击主页面右下角的V图标,使其变绿</li></ul><p><strong>验证</strong></p><ul><li>点击主页面下方<strong>已连接,点击测试连接</strong>语句,检测连接是否成功</li></ul><h3 id="Ios"><a href="#Ios" class="headerlink" title="Ios"></a>Ios</h3><ul><li>在系统设置中更改苹果账户的地区到中国大陆以外的地方,比如英国、美国等。</li><li>在app store购买并安装Shadowrocket软件</li><li>使用浏览器打开<a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz</a>,进行登录</li><li>待页面显示出二维码,点击<strong>Copy</strong></li><li>打开Shadowrocket软件</li><li>点击右上角加号</li><li>类型选择<strong>Subscribe</strong></li><li>URL中粘贴刚才复制的东西</li><li>点击右上角完成</li><li>点击首页中的api.yimian.xyz,点击<strong>Los_Angeles</strong></li><li>在首页第一行,勾选<strong>Los_Angeles</strong></li><li>使用浏览器访问<a href="https://www.google.com" target="_blank" rel="noopener">https://google.com</a>试一下</li></ul></span><span class=".en"><h2 id="Process-overview"><a href="#Process-overview" class="headerlink" title="Process overview"></a>Process overview</h2><ul><li>User registration</li><li>v2ray software installation</li></ul><h2 id="User-registration"><a href="#User-registration" class="headerlink" title="User registration"></a>User registration</h2><p>Before installing the software, please go to <a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz/</a> to register with your mobile phone number.</p><h2 id="v2ray-software-installation"><a href="#v2ray-software-installation" class="headerlink" title="v2ray software installation"></a>v2ray software installation</h2><p>This article contains software installation methods for <a href="#Win10">Win10</a>, <a href="#Android">Android</a>, <a href="#Ios">IOS/Ipad OS</a>, please install according to the corresponding process.</p><h3 id="Win10-1"><a href="#Win10-1" class="headerlink" title="Win10"></a>Win10</h3><p><strong>download</strong></p><ul><li>Use a browser to visit <a href="https://onedrive.yimian.xyz/packages/programs/all/v2ray/Windows_v2rayN-Core.zip" target="_blank" rel="noopener">http://eee.dog/8bcc14</a> and download the name <code>Windows_v2rayN-Core.zip</code>The compressed file.</li></ul><p><strong>Unzip</strong></p><ul><li><p>Decompress the downloaded compressed file to the root directory of drive C, as shown below</p><blockquote><p>If you are prompted to require <strong>administrative permissions</strong>, please select all <strong>yes</strong></p></blockquote><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_2eb9b63_1565x429_8_null_normal.jpeg" alt="Extracted file image"></p></li></ul><p><strong>Configuration</strong></p><ul><li><p>Please open the folder just unzipped in the C drive, find the program named <code>V2ray</code> or <code>V2rayN.exe</code>, and double-click to open it. As shown below.<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_430e95a_1557x460_8_null_normal.jpeg" alt="V2rayN picture"></p></li><li><p>Find the taskbar in the lower right corner, find the icon in the figure below, double-click to open<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_3a35a1f_928x246_8_null_normal.jpeg" alt="V2rayN icon"></p></li><li><p>Select <strong>Subscription</strong> at the top of the window, and click <strong>Subscription Settings</strong> as shown below<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_4574629_1421x180_8_null_normal.jpeg" alt="Subscription Settings"></p></li><li><p>Open <a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz</a> and log in. After the QR code appears, click <strong>Copy</strong>. As shown below<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_6d86c79_1254x711_8_null_normal.jpeg" alt="Get subscription address"></p></li><li><p>Go back to the subscription settings window, paste the content you just copied into the <strong>Address URL box</strong>, check <strong>Enable</strong>, and click <strong>OK</strong>. As shown below<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_50dc56e_867x752_8_null_normal.jpeg" alt="Set subscription address"></p></li><li><p>Click <strong>Parameter Settings</strong> at the top of the main window as shown below</p></li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6a56090_1313x195_8_null_normal.jpeg" alt="Parameter settings"></p><ul><li>Select <strong>V2rayN Settings</strong>, tick <strong>Autostart at boot</strong>, and click <strong>OK</strong> below. As shown below</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_0b74331_993x1020_8_null_normal.jpeg" alt="Start on boot"></p><ul><li>Back to the main window, click <strong>Update Subscription</strong> as shown below</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_396bcc7_1037x174_8_null_normal.jpeg" alt="Update Subscription"></p><ul><li><p>At this time, there will be one or more servers in the main window, as shown below</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_4419a90_1196x216_8_null_normal.jpeg" alt="Server list"></p></li><li><p>Close the main window, right-click V2ray in the status bar at the bottom right corner, and select <strong>Server</strong>-&gt;<strong>Vmess-Los_Angeles(….</strong>. As shown below<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_0266a2f_1067x288_8_null_normal.jpeg" alt="Select Server"></p></li><li><p>Right-click V2ray in the status bar at the bottom right corner, and select <strong>Http Proxy</strong>-&gt;<strong>…(PAC Mode)</strong>. As shown below<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_8c3a651_1088x306_8_null_normal.jpeg" alt="PAC Mode"></p></li></ul><p><strong>verification</strong></p><ul><li>Open <a href="https://www.google.com" target="_blank" rel="noopener">https://google.com</a> in your browser to check if you can access it.</li></ul><h3 id="Android-1"><a href="#Android-1" class="headerlink" title="Android"></a>Android</h3><p><strong>Download and install software</strong></p><ul><li>Open the browser <a href="https://onedrive.yimian.xyz/packages/programs/all/v2ray/Android_v2rayNG_1.3.1.apk" target="_blank" rel="noopener">http://eee.dog/6db2e3</a> to download the V2ray Android installation package</li><li>Click to open the installation package to install</li></ul><p><strong>Configuration</strong></p><ul><li>Use your mobile browser to open <a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz/</a> and log in</li><li>When the QR code is displayed on the page, click <strong>Copy</strong></li><li>Open the installed V2rayNG software, click the three bars in the upper left corner, expand the left column, and click <strong>Subscription Settings</strong></li><li>After entering the subscription settings page, click the <strong>plus sign</strong> in the upper right corner</li><li>Fill in <strong>ushio</strong> in the remarks, fill in the things you just copied in the address url, and click the tick in the upper right corner.</li><li>Back to the main page, click the three bars in the upper left corner, expand the left column, and click <strong>Settings</strong></li><li>After entering the settings page, click <strong>Sub App Proxy</strong></li><li>Check the <strong>Sub App Proxy</strong> mode, and then check the apps that need to access the Internet, such as twitter, youtube, etc.</li><li>Back to the main page, click the three dots in the upper right corner, and click <strong>Update Subscription</strong></li><li>Tap <strong>Los_Angeles</strong> in the main page list to make the left side green</li><li>Click the V icon in the lower right corner of the main page to make it green</li></ul><p><strong>verification</strong></p><ul><li>Click <strong>Connected at the bottom of the main page, click the test connection</strong> statement to check whether the connection is successful</li></ul><h3 id="Ios-1"><a href="#Ios-1" class="headerlink" title="Ios"></a>Ios</h3><ul><li>Change the Apple account area in the system settings to a place outside of mainland China, such as the United Kingdom, the United States, etc.</li><li>Purchase and install Shadowrocket software in the app store</li><li>Use a browser to open <a href="https://v2ray.yimian.xyz/" target="_blank" rel="noopener">https://v2ray.yimian.xyz</a> and log in</li><li>When the QR code is displayed on the page, click <strong>Copy</strong></li><li>Open the Shadowrocket software</li><li>Click the plus sign in the upper right corner</li><li>Type selection <strong>Subscribe</strong></li><li>Paste what you just copied in the URL</li><li>Click on the upper right corner to finish</li><li>Click api.yimian.xyz on the homepage, click <strong>Los_Angeles</strong></li><li>On the first line of the homepage, check <strong>Los_Angeles</strong></li><li>Use a browser to visit <a href="https://www.google.com" target="_blank" rel="noopener">https://google.com</a> to try</li></ul></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> v2ray </tag>
<tag> instruction </tag>
</tags>
</entry>
<entry>
<title>wIoT发展展望</title>
<link href="/tech/wiot2.html"/>
<url>/tech/wiot2.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>本文将讨论wiot项目下一步的发展目标与实施方法。</p></span><span class=".en"><p>This article will discuss the next development goals and implementation methods of the Wiot project.</p></span><a id="more"></a><script> session.onload(function(){ if(page.tran.getLang() == 'en'){ tips.warning({ title: 'Caution', position: 'topRight', message: 'This page was translated by Machine!!', buttons: [['<button>Show Chinese Page</button>', function (instance, toast) { page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]] }); } });</script><span class=".zh"><h3 id="wIoT"><a href="#wIoT" class="headerlink" title="wIoT"></a>wIoT</h3><p>wiot,一个基于NodeJS的分布式物联网操作系统。</p><h1 id="项目简介"><a href="#项目简介" class="headerlink" title="项目简介"></a>项目简介</h1><h2 id="立项初衷"><a href="#立项初衷" class="headerlink" title="立项初衷"></a>立项初衷</h2><p>本项目旨在帮助不熟悉固件编程的网络开发者实现出自己的物联网应用。</p><p>在开发传统的物联网程序时,我们需要一次又一次的编写,烧录,调试每一个开发板,以某种方式将其相连结,以提供某种服务。这样的方式非常繁琐,开发成本和门槛都比较高。此外,古老的C和C++语言缺少成熟的依赖管理工具,以至于我们在编写开发板时难以像开发python或nodeJS程序一样轻松便捷。</p><p>本项目试图提供一种方法,将烧录,调试开发板的流程自动化,并将逻辑编写的步骤移动到远程计算机的NodeJS界面上。通过此方式,我们进而得以将分布式物联网节点的功能进行集中化管理。此外,借助NodeJS成熟的依赖管理器npm,使得物联网应用的开发更加便捷高效。</p><p>至此,下到每一个物联网节点,上到各种类型的数据库、用户终端,都可以在同一个nodeJS界面上配置、操作。开发者将能够专注于物联网逻辑的开发,实现出更加丰富多彩的物联网应用。</p><h1 id="第一轮开发"><a href="#第一轮开发" class="headerlink" title="第一轮开发"></a>第一轮开发</h1><blockquote><p>第一轮开发完成于2019.5,详见<a href="https://www.eee.dog/tech/wiot.html">这篇博客</a></p></blockquote><p> 实现了对D1 MINI开发板对nodeJS的pin口映射,并支持诸如ota等一系列功能。</p><h1 id="第二轮开发"><a href="#第二轮开发" class="headerlink" title="第二轮开发"></a>第二轮开发</h1><blockquote><p>待进行,计划当做FYP项目</p></blockquote><hr><h2 id="架构想法"><a href="#架构想法" class="headerlink" title="架构想法"></a>架构想法</h2><p>在设计物联网系统时,我一直有一个愿景。历史必然性。打造手足。</p><p>wiot的目标是提供一套<br>系统架构在分类上分为静态的环境和动态的用户。实现上分为模块,服务和程序。</p><h3 id="模块"><a href="#模块" class="headerlink" title="模块"></a>模块</h3><p>类似于计算机操作系统中的驱动,模块负责将物理层面上的各种功能,比如led照明,抽象为操作系统层面的标准接口。</p><h3 id="服务"><a href="#服务" class="headerlink" title="服务"></a>服务</h3><p>服务是运行在边缘的docker中的守护进程。开发者通过调用模块,实现编写服务,实现各种各样的标准功能。</p><h3 id="程序"><a href="#程序" class="headerlink" title="程序"></a>程序</h3><p>程序是由用户定义的一套自定义逻辑,用于打造自定义场景。结合地理围栏公共服务LIS,调用环境服务提供的标准接口。</p><hr><h2 id="支持的开发版"><a href="#支持的开发版" class="headerlink" title="支持的开发版"></a>支持的开发版</h2><ul><li><a href="https://www.nodemcu.com/index_en.html" target="_blank" rel="noopener">NodeMCU</a></li></ul><h2 id="实现方法"><a href="#实现方法" class="headerlink" title="实现方法"></a>实现方法</h2><p>通过提供标准化的单片机固件以及自动化的烧录工具,wiot将各开发板的pin口功能进行抽象,整理,并映射为可调用的NodeJS接口。</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_b0a1fe7_1395x662_8_null_normal.jpeg" alt="wiot Architecture"></p><p>如上图所示,wiot架构主要包含三部分:Node节点,wiot Cloud Module云模块,wiot cli命令行程序。其中,Node节点为烧录好wiot固件的NodeMCU单片机,他们通过IEEE 802.11 WiFi进行分布式通信,并于某个节点接入路由器以连接wiot云模块。用户在自己的PC上使用NodeJS调用wiot依赖编写物联网程序。完成后,用户使用wiot cli对开发好的程序进行检查、测试和部署。被部署的物联网程序将运行在wiot云模块上,并可使用nodeJS的接口与其它云服务或数据库进行交互。</p><h3 id="Node节点"><a href="#Node节点" class="headerlink" title="Node节点"></a>Node节点</h3><p>Node节点使用的是NodeMCU开发板(基于ESP8266的扩展板)。在使用wiot-cli烧录wiot固件后,NodeMCU将成为wiot节点。</p><h4 id="模式"><a href="#模式" class="headerlink" title="模式"></a><strong>模式</strong></h4><p>wiot节点有四种模式:master模式、slave模式、bridge模式和debug模式。此模式只能在烧录固件时配置。master模式和bridge模式下,nodeMCU将同时开启STA和AP模式。slave模式下则只开启STA模式。master需要有稳定且无限制的电源供电,其功率较大(包含RSA, 协议转换等),不适合低功耗场景。bridge与slave则可以灵活调整功率,可用于低功耗场景。</p><p>debug模式下节点工作在STA和AP模式,用户可以使用手机等设备连接到此节点,并打开根目录网页。网页上将实时显示此节点当前所处位置的各种信息,比如收到各其它节点的信号强度等,适用于挑选部署场景。</p><h4 id="低功耗"><a href="#低功耗" class="headerlink" title="低功耗"></a><strong>低功耗</strong></h4><p>wiot节点支持低功耗(Low Power)状态。但此状态仅能在slave模式和bridge下开启。此状态可通过wiot api或者wiot-cli进行开启或关闭。低功耗状态由esp8266睡眠功能实现。此状态下可由干电池供电工作数年<a href="https://makecademy.com/esp8266-battery" target="_blank" rel="noopener">[1]</a>。</p><h4 id="组网"><a href="#组网" class="headerlink" title="组网"></a><strong>组网</strong></h4><p>wiot节点使用分布式组网。在路由器信号较强的地方,master节点将接入路由器WiFi网络,并桥接。在路由器信号不强的地方,每一个节点都会找到信号最强的另一个上游的master或bridge节点,并桥接(slave除外)。</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_a42f5a4_1224x561_8_null_normal.jpeg" alt="wiot节点分布式组网"></p><p>如上图,两个距离路由器近的master节点自动接入到路由器wifi。下游的其它节点分别连接至信号最强的上游节点。</p><h4 id="认证"><a href="#认证" class="headerlink" title="认证"></a><strong>认证</strong></h4><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_d184ff2_1442x502_8_null_normal.jpeg" alt="射频指纹识别[2]"><br>wiot节点支持使用<strong>射频指纹识别</strong><a href="https://ieeexplore.ieee.org/document/9149584" target="_blank" rel="noopener">[2]</a>来实现下游通信认证。此方法使用esp8266的RSSI函数以及scan返回参数。在下游设备试图接入网络时,上游设备将搜集指纹信息并向服务器汇报。服务器将指纹与数据库存储的先前版本进行比对,并作出是否允许入网的决策。</p><h3 id="云模块"><a href="#云模块" class="headerlink" title="云模块"></a>云模块</h3><p>云模块充当wiot的云部分,提供云的功能。云模块能够守护运行run-time状态下的wiot程序。此外,云模块还能够提供测试,部署等功能。云模块使用Docker进行虚拟化。</p><h3 id="命令行程序"><a href="#命令行程序" class="headerlink" title="命令行程序"></a>命令行程序</h3><p>即wiot-cli。是wiot在开发者终端上提供的操作工具集。通过wiot-cli,开发者可以实现对wiot程序的测试,部署,恢复等功能。此外,wiot-cli也支持一系列debug等常用功能。详见下方<code>wiot-cli命令</code>。</p><h2 id="用户操作步骤"><a href="#用户操作步骤" class="headerlink" title="用户操作步骤"></a>用户操作步骤</h2><ol><li>用户下载安装并配置好NodeJS环境。</li><li>用户通过命令行运行<code>npm i -g wiot-cli</code>指令安装wiot命令行工具</li><li>用户运行命令<code>wiot init my-wiot-proj</code>在当前目录新建并配置一个wiot项目文件夹,项目名称为my-wiot-proj。此时,会提示用户填写此项目的一些信息,比如项目描述,作者信息,路由器WiFi账户密码,wiot云模块地址,项目主脚本等。</li><li>用户进入到项目目录,将nodeMCU通过数据线连接到电脑,运行<code>wiot node init my-first-node [--type=&lt;master|slave|bridge|debug&gt;]</code>。这将自动配置并将wiot固件烧录到nodeMCU开发板,并将其命名为my-first-node。type为可选参数,可设置为<code>master</code>或<code>slave</code>或<code>bridge</code>或<code>debug</code>,默认为<code>master</code>。</li><li>依次按照此方法烧录好所有的开发板,将其部署在生产环境。</li><li>在项目文件夹运行指令<code>wiot status</code>查看是否所有节点均已在线。如果没有,使用指令<code>wiot log</code>配合<code>grep</code>工具查找日志定位问题。</li><li>从项目主脚本(默认是<code>index.js</code>)开始编写你的wiot程序。</li><li>使用指令<code>wiot check</code>检查你wiot程序的逻辑问题。</li><li>使用指令<code>wiot test</code>将挂起云模块中正在运行的程序,并运行当前项目文件夹中的程序。此时,所有控制台输出将显示在你的命令行窗口。使用<code>Ctrl+C</code>终止当前测试并恢复云模块先前的程序。</li><li>使用指令<code>wiot push</code>将本地的wiot程序部署到云端。</li></ol><h2 id="其它操作"><a href="#其它操作" class="headerlink" title="其它操作"></a>其它操作</h2><h3 id="部署自己的wiot云模块"><a href="#部署自己的wiot云模块" class="headerlink" title="部署自己的wiot云模块"></a>部署自己的wiot云模块</h3><p>默认使用wiot官方wiot云模块。你也可以部署自己的wiot云服务,方法如下:</p><p>安装docker并运行指令<code>docker run -d --name=wiot-cloud -p 3594:3594 -v /var/wiot/data/:/var/wiot/data/ iotcat/wiot</code>。</p><h3 id="wiot-cli命令"><a href="#wiot-cli命令" class="headerlink" title="wiot-cli命令"></a>wiot-cli命令</h3><ul><li><code>wiot help [command]</code>查看帮助</li><li><code>wiot clone &lt;host:user/project&gt;</code>将项目从云模块克隆到本地</li><li><code>wiot pull</code>使用远程代码覆盖本地代码</li><li><code>wiot push</code>将当前文件夹wiot程序部署到云模块</li><li><code>wiot node ls</code>显示当前所有节点</li><li><code>wiot map [nodeID]</code>显示某节点的连接路径</li><li><code>wiot log [nodeID] [--head=&lt;number&gt;|--tail=&lt;number&gt;]</code>查看某节点的日志</li><li><code>wiot stop</code>停止wiot服务</li><li><code>wiot start</code>开启wiot服务</li><li><code>wiot restart</code>重启wiot服务</li><li><code>wiot reload</code>在不重置flash变量情况下重启wiot服务</li><li><code>wiot init &lt;name&gt;</code>新建并初始化wiot项目文件夹</li><li><code>wiot node init &lt;node-name&gt; [--type=&lt;master|slave|bridge|debug&gt;]</code>配置并烧录nodeMCU开发板</li><li><code>wiot check</code>检查当前文件夹项目逻辑问题。</li><li><code>wiot test</code>将挂起云模块中正在运行的程序,并运行当前项目文件夹中的程序。此时,所有控制台输出将显示在你的命令行窗口。使用<code>Ctrl+C</code>终止当前测试并恢复云模块先前的程序。</li><li><code>wiot status [nodeID]</code>显示当前项目或节点状态信息</li><li><code>wiot debug start</code>终止当前云端程序并进入debug模式</li><li><code>wiot debug set &lt;nodeID&gt; &lt;pinID&gt; &lt;0-255&gt;</code>debug模式下设置某个节点pin的PWM输出值</li><li><code>wiot debug reset &lt;nodeID&gt;</code>debug模式下重置某个节点的数据存储,并重连</li><li><code>wiot debug get &lt;nodeID&gt; &lt;pinID&gt;</code>debug模式下获取某个节点pin的PWM值</li><li><code>wiot debug sleep &lt;nodeID&gt; &lt;pinID&gt; &lt;HIGH|LOW&gt;</code>debug模式下设置某节点轻度休眠,直到被某pin的高或低电平唤醒</li><li><code>wiot debug dsleep &lt;nodeID&gt; &lt;millisecond&gt;</code>debug模式下设置某节点深度休眠多少毫秒</li><li><code>wiot debug reconnect [nodeID]</code>debug模式下重新组网或断开重连某个节点</li><li><code>wiot debug setphymode &lt;nodeID&gt; &lt;b|g|n&gt;</code>debug模式下配置节点WiFi协议为802.11b|g|n</li><li><code>wiot module search [keyword]</code>本地和联网搜索可用module类型</li><li><code>wiot module install &lt;moduleName|path&gt;</code>安装并配置某个模块</li><li><code>wiot module remove &lt;moduleId&gt;</code>卸载模块</li><li><code>wiot module ls</code>显示所有已安装模块</li><li><code>wiot search [keyword]</code>本地和联网搜索可用程序</li><li><code>wiot install &lt;programName|path&gt;</code>安装并配置某个程序</li><li><code>wiot remove &lt;programID&gt;</code>卸载某个程序</li><li><code>wiot ls</code>显示所有程序<br> ···</li></ul><h3 id="目录结构"><a href="#目录结构" class="headerlink" title="目录结构"></a>目录结构</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">|</span><br><span class="line">|---.wiot&#x2F; wiot系统目录</span><br><span class="line">|---wiot.yaml wiot系统配置文件</span><br><span class="line">|---nodes&#x2F; 节点配置文件</span><br><span class="line">|---modules&#x2F; 模组配置文件</span><br><span class="line">|---programs&#x2F; 程序配置文件</span><br><span class="line">|---local&#x2F; 本地代码文件</span><br></pre></td></tr></table></figure><h3 id="常用API"><a href="#常用API" class="headerlink" title="常用API"></a>常用API</h3><blockquote><p>待设计,请参考<a href="https://wiot.yimian.xyz/#/home" target="_blank" rel="noopener">一轮开发wiot文档</a></p></blockquote><ul><li>事件</li><li>cron定时任务</li></ul><h3 id="挑战"><a href="#挑战" class="headerlink" title="挑战"></a>挑战</h3><ul><li>错误(设备离线)处理</li></ul></span><span class=".en"><h3 id="wIoT-1"><a href="#wIoT-1" class="headerlink" title="wIoT"></a>wIoT</h3><p>Wiot, a distributed IoT operating system based on NodeJS.</p><h1 id="Project-Description"><a href="#Project-Description" class="headerlink" title="Project Description"></a>Project Description</h1><h2 id="The-original-intention-of-the-project"><a href="#The-original-intention-of-the-project" class="headerlink" title="The original intention of the project"></a>The original intention of the project</h2><p>This project aims to help web developers who are not familiar with firmware programming to implement their own IoT applications.</p><p>When developing traditional Internet of Things programs, we need to write, burn, and debug each development board again and again, and connect them in a certain way to provide a certain service. This method is very cumbersome, and the development cost and threshold are relatively high. In addition, the ancient C and C++ languages lack mature dependency management tools, so that it is difficult for us to write development boards as easy and convenient as developing python or nodeJS programs.</p><p>This project is trying to provide a method to automate the process of burning and debugging the development board, and move the steps of logic writing to the NodeJS interface of the remote computer. In this way, we are able to centrally manage the functions of distributed IoT nodes. In addition, with NodeJS’s mature dependency manager npm, the development of IoT applications is more convenient and efficient.</p><p>So far, down to every IoT node, up to various types of databases and user terminals, all can be configured and operated on the same nodeJS interface. Developers will be able to focus on the development of IoT logic and realize more colorful IoT applications.</p><h1 id="First-round-of-development"><a href="#First-round-of-development" class="headerlink" title="First round of development"></a>First round of development</h1><blockquote><p>The first round of development was completed in May 2019, please refer to <a href="https://www.eee.dog/tech/wiot.html">this blog</a></p></blockquote><p> Realize the pin port mapping of D1 MINI development board to nodeJS, and support a series of functions such as ota.</p><h1 id="Second-round-of-development"><a href="#Second-round-of-development" class="headerlink" title="Second round of development"></a>Second round of development</h1><blockquote><p>To be carried out, plan as FYP project</p></blockquote><h2 id="Supported-development-version"><a href="#Supported-development-version" class="headerlink" title="Supported development version"></a>Supported development version</h2><ul><li><a href="https://www.nodemcu.com/index_en.html" target="_blank" rel="noopener">NodeMCU</a></li></ul><h2 id="Implementation"><a href="#Implementation" class="headerlink" title="Implementation"></a>Implementation</h2><p>By providing standardized microcontroller firmware and automated burning tools, wiot abstracts, organizes, and maps the pin port functions of each development board into a callable NodeJS interface.</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_b0a1fe7_1395x662_8_null_normal.jpeg" alt="wiot Architecture"></p><p>As shown in the figure above, the wiot architecture mainly consists of three parts: Node node, wiot Cloud Module, and wiot cli command line program. Among them, the Node node is the NodeMCU microcontroller with the wiot firmware burned. They use IEEE 802.11 WiFi for distributed communication, and connect to a router at a node to connect to the wiot cloud module. Users use NodeJS to call Wiot on their own PCs and rely on writing IoT programs. After completion, the user uses wiot cli to check, test and deploy the developed program. The deployed IoT program will run on the wiot cloud module, and can use the nodeJS interface to interact with other cloud services or databases.</p><h3 id="Node-node"><a href="#Node-node" class="headerlink" title="Node node"></a>Node node</h3><p>Node node uses NodeMCU development board (expansion board based on ESP8266). After using wiot-cli to burn the wiot firmware, NodeMCU will become a wiot node.</p><h4 id="Mode"><a href="#Mode" class="headerlink" title="Mode"></a><strong>Mode</strong></h4><p>Wiot nodes have four modes: master mode, slave mode, bridge mode and debug mode. This mode can only be configured when burning firmware. In master mode and bridge mode, nodeMCU will enable STA and AP mode at the same time. In slave mode, only STA mode is enabled. The master needs to have a stable and unlimited power supply, which has a large power and is not suitable for low power consumption scenarios. Bridge and slave can flexibly adjust power, which can be used in low power consumption scenarios.</p><p>In debug mode, the node works in STA and AP mode. Users can use mobile phones and other devices to connect to this node and open the root directory webpage. The web page will display various information about the current location of this node in real time, such as the signal strength received from other nodes, which is suitable for deployment scenarios.</p><h4 id="Low-power"><a href="#Low-power" class="headerlink" title="Low power"></a><strong>Low power</strong></h4><p>Wiot nodes support Low Power state. But this state can only be opened in slave mode and bridge. This state can be turned on or off through wiot api or wiot-cli. The low power consumption state is realized by the sleep function of esp8266. In this state, it can be powered by dry batteries for several years <a href="https://makecademy.com/esp8266-battery" target="_blank" rel="noopener">[1]</a>.</p><h4 id="Networking"><a href="#Networking" class="headerlink" title="Networking"></a><strong>Networking</strong></h4><p>Wiot nodes use distributed networking. Where the router signal is strong, the master node will access the router WiFi network and bridge it. Where the router signal is not strong, each node will find another upstream master or bridge node with the strongest signal and bridge it (except slave).</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_a42f5a4_1224x561_8_null_normal.jpeg" alt="wiot node distributed networking"></p><p>As shown in the figure above, the two master nodes close to the router are automatically connected to the router wifi. The other downstream nodes are respectively connected to the upstream node with the strongest signal.</p><h4 id="Certification"><a href="#Certification" class="headerlink" title="Certification"></a><strong>Certification</strong></h4><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_d184ff2_1442x502_8_null_normal.jpeg" alt="Radio frequency fingerprint identification[2]"></p><p>Wiot nodes support the use of <strong>RF Fingerprint Recognition</strong><a href="https://ieeexplore.ieee.org/document/9149584" target="_blank" rel="noopener">[2]</a> to achieve downstream communication authentication. This method uses the RSSI function of esp8266 and scan return parameters. When the downstream device attempts to access the network, the upstream device will collect fingerprint information and report to the server. The server compares the fingerprint with the previous version stored in the database and makes a decision whether to allow access to the network.</p><h3 id="Cloud-Module"><a href="#Cloud-Module" class="headerlink" title="Cloud Module"></a>Cloud Module</h3><p>The cloud module acts as the cloud part of Wiot and provides cloud functions. The cloud module can guard the wiot program running in the run-time state. In addition, the cloud module can also provide functions such as testing and deployment. The cloud module uses Docker for virtualization.</p><h3 id="Command-Line-Program"><a href="#Command-Line-Program" class="headerlink" title="Command Line Program"></a>Command Line Program</h3><p>That is wiot-cli. It is a set of operation tools provided by Wiot on the developer terminal. Through wiot-cli, developers can implement functions such as testing, deploying, and restoring wiot programs. In addition, wiot-cli also supports a series of common functions such as debug. See the <code>wiot-cli command</code> below for details.</p><h2 id="User-operation-steps"><a href="#User-operation-steps" class="headerlink" title="User operation steps"></a>User operation steps</h2><ol><li>The user downloads, installs and configures the NodeJS environment.</li><li>The user runs the command <code>npm i -g wiot-cli</code> through the command line to install the wiot command line tool</li><li>The user runs the command <code>wiot init my-wiot-proj</code> to create and configure a wiot project folder in the current directory, the project name is my-wiot-proj. At this point, the user will be prompted to fill in some information about this project, such as project description, author information, WiFi account password, wiot cloud module address, project main script, etc.</li><li>The user enters the project directory, connects the nodeMCU to the computer through the data cable, and runs <code>wiot node init my-first-node [--type=&lt;master|slave|bridge|debug&gt;]</code>. This will automatically configure and burn the Wiot firmware to the nodeMCU development board and name it my-first-node. type is an optional parameter, which can be set to <code>master</code> or <code>slave</code> or <code>bridge</code> or <code>debug</code>, and the default is <code>master</code>.</li><li>Follow this method to burn all the development boards and deploy them in the production environment.</li><li>Run the command <code>wiot status</code> in the project folder to see if all nodes are online. If not, use the command <code>wiot log</code> with the <code>grep</code> tool to find the log location problem.</li><li>Start writing your wiot program from the main project script (default is <code>index.js</code>).</li><li>Use the command <code>wiot check</code> to check the logic of your wiot program.</li><li>Use the command <code>wiot test</code> to suspend the running program in the cloud module and run the program in the current project folder. At this point, all console output will be displayed in your command line window. Use <code>Ctrl+C</code> to terminate the current test and restore the previous program of the cloud module.</li><li>Use the command <code>wiot push</code> to deploy the local wiot program to the cloud.</li></ol><h2 id="Other-operations"><a href="#Other-operations" class="headerlink" title="Other operations"></a>Other operations</h2><h3 id="Deploy-your-own-wiot-cloud-module"><a href="#Deploy-your-own-wiot-cloud-module" class="headerlink" title="Deploy your own wiot cloud module"></a>Deploy your own wiot cloud module</h3><p>Install docker and run the command <code>docker run -d --name=wiot-cloud -p 3594:3594 -v /var/wiot/data/:/var/wiot/data/ iotcat/wiot</code>.</p><h3 id="wiot-cli-command"><a href="#wiot-cli-command" class="headerlink" title="wiot-cli command"></a>wiot-cli command</h3><ul><li><code>wiot help [command]</code> view help</li><li><code>wiot clone &lt;host:user/project&gt;</code> to clone the project from the cloud module to the local</li><li><code>wiot pull</code> uses remote code to overwrite local code</li><li><code>wiot push</code> deploys the current folder wiot program to the cloud module</li><li><code>wiot ls</code> shows all current nodes</li><li><code>wiot map [nodeID]</code> shows the connection path of a node</li><li><code>wiot log [nodeID] [--head=&lt;number&gt;|--tail=&lt;number&gt;]</code> view the log of a node</li><li><code>wiot stop</code> stop wiot service</li><li><code>wiot start</code> to start wiot service</li><li><code>wiot restart</code> restart wiot service</li><li><code>wiot reload</code> restarts the wiot service without resetting the flash variable</li><li><code>wiot init &lt;name&gt;</code> creates and initializes the wiot project folder</li><li><code>wiot node init &lt;node-name&gt; [--type=&lt;master|slave|bridge|debug&gt;]</code> configure and burn nodeMCU development board</li><li><code>wiot check</code> checks the current folder project logic problem.</li><li><code>wiot test</code> will suspend the running program in the cloud module and run the program in the current project folder. At this point, all console output will be displayed in your command line window. Use <code>Ctrl+C</code> to terminate the current test and restore the previous program of the cloud module.</li><li><code>wiot status [nodeID]</code> displays current project or node status information</li><li><code>wiot debug start</code> terminates the current cloud program and enters debug mode</li><li><code>wiot debug set &lt;nodeID&gt; &lt;pinID&gt; &lt;0-255&gt;</code>Set the PWM output value of a node pin in debug mode</li><li>In <code>wiot debug reset &lt;nodeID&gt;</code>debug mode, reset the data storage of a node and reconnect</li><li><code>wiot debug get &lt;nodeID&gt; &lt;pinID&gt;</code> get the PWM value of a node pin in debug mode</li><li><code>wiot debug sleep &lt;nodeID&gt; &lt;pinID&gt; &lt;HIGH|LOW&gt;</code>debug mode to set a node to lightly sleep until it is awakened by a pin’s high or low level</li><li><code>wiot debug dsleep &lt;nodeID&gt; &lt;millisecond&gt;</code> set how many milliseconds a node deeply sleeps in debug mode</li><li>In <code>wiot debug reconnect [nodeID]</code>debug mode, reconnect to the network or disconnect and reconnect to a node</li></ul><h3 id="Common-API"><a href="#Common-API" class="headerlink" title="Common API"></a>Common API</h3><blockquote><p>To be designed, please refer to <a href="https://wiot.yimian.xyz/#/home" target="_blank" rel="noopener">One-round development wiot document</a></p></blockquote></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> iot </tag>
<tag> nodeJS </tag>
<tag> WiFi </tag>
</tags>
</entry>
<entry>
<title>GRE备考核心矛盾分析</title>
<link href="/life/gre.html"/>
<url>/life/gre.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>我的GRE备考从8.21正式开始,8.28首考(成绩未提交),预计于9月底完成,目标155+170W3.5,总过程历时一个月半。本文阐述了在我的GRE备考过程中,提炼出的矛盾与方法论的汇总。</p></span><span class=".en"><p>My GRE preparation started from 8.21, and the first test was 8.28 (scores not submitted). It is expected to be completed by the end of September. The goal is 155+170W3.5. The total process lasts one and a half months. This article explains the contradictions and methodologies that were extracted during my GRE preparation process.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="备考定位"><a href="#备考定位" class="headerlink" title="备考定位"></a>备考定位</h2><p>我备考GRE的主要目的是,借助GRE的备考过程,有效提升英语词汇量与论文阅读水平(速度)。于此同时,此次备考过程也将成为Tomato Proj的有效试验,为今后实现有序和谐的生活节奏提供经验参考。此外,申请一些美国学校则也需要提供GRE成绩。</p><h2 id="备考矛盾分析"><a href="#备考矛盾分析" class="headerlink" title="备考矛盾分析"></a>备考矛盾分析</h2><h3 id="时间不足"><a href="#时间不足" class="headerlink" title="时间不足"></a>时间不足</h3><p>由于暑假投入大量时间,准备申研材料,学习积累专业知识,准备FYP,我只留下了1个月左右的时间准备GRE。因此,时间不足的问题需要由方法论的精进来弥补。</p><h2 id="数学矛盾分析"><a href="#数学矛盾分析" class="headerlink" title="数学矛盾分析"></a>数学矛盾分析</h2><h3 id="跳过机制"><a href="#跳过机制" class="headerlink" title="跳过机制"></a>跳过机制</h3><p>GRE数学的关键对于我们经理过理科高考的人来说,通过一定量的练习回顾,将期望调节到170左右,是比较轻松的。但是这并不意味着就可以对GRE数学掉以轻心。在备考GRE数学时,除了提高期望外,更加重要的是如何缩小方差。考虑到GRE数学在设计上时间较为紧张,只有35分钟,而且有可能会遇到一些很难的题,或者看不懂的题,这时就要果断跳过,及时止损。因此,在数学的备考过程中,需要<strong>形成一套判断是否跳过的判断机制,且判断耗时越少越好</strong>。</p><h3 id="题型解析机制"><a href="#题型解析机制" class="headerlink" title="题型解析机制"></a>题型解析机制</h3><p>在数学的备考过程中,除了减小方差,也要有效提高期望。与高考不同的是,GRE数学的语言是英语,且还有一系列的逻辑陷阱。因此,要提高GRE数学的期望,需要对以下三点进行”程序化”处理,提炼出相应方法论。</p><ul><li>数学常用英语</li><li>各种题型解题方法套路</li><li>选择方法的方法</li></ul><h3 id="查错机制"><a href="#查错机制" class="headerlink" title="查错机制"></a>查错机制</h3><p>尽管GRE数学的考试时间是否有限,但并不排除有时间会剩下的可能性。因此,可以注意锻炼一套有利于利用剩余时间差错的机制。比如,合理规划使用演草纸等。</p><h2 id="阅读矛盾分析"><a href="#阅读矛盾分析" class="headerlink" title="阅读矛盾分析"></a>阅读矛盾分析</h2><h3 id="一遍读懂"><a href="#一遍读懂" class="headerlink" title="一遍读懂"></a>一遍读懂</h3><p>通过这几天的训练,我发现了一个现象,及如果最开始看文章没有看懂,那么后面做题基本靠蒙。因此,GRE阅读一定要先将文章看懂。要实现这一点,可以通过提炼句子的s3版本,通过居间关系连接词对下一句内容进行预判,以此递归。</p><h3 id="提高速度"><a href="#提高速度" class="headerlink" title="提高速度"></a>提高速度</h3><p>在有限的时间内把文章看懂。。</p><h2 id="填空矛盾分析"><a href="#填空矛盾分析" class="headerlink" title="填空矛盾分析"></a>填空矛盾分析</h2><h3 id="词汇量"><a href="#词汇量" class="headerlink" title="词汇量"></a>词汇量</h3><p>先把3000刷熟,再把托福词汇刷过。。然后再看看。刷单词时一定要批量(比如以500词为一组),多变。一天过好几遍,闪现就行,几天后就会见效。</p><h3 id="公式化处理"><a href="#公式化处理" class="headerlink" title="公式化处理"></a>公式化处理</h3><p>把题目抽象成公式处理。。</p></span><span class=".en"><h2 id="Test-preparation-positioning"><a href="#Test-preparation-positioning" class="headerlink" title="Test preparation positioning"></a>Test preparation positioning</h2><p>My main purpose of preparing for the GRE is to effectively improve my English vocabulary and paper reading level (speed) with the help of the GRE preparation process. At the same time, this test preparation process will also become an effective test of Tomato Proj, providing an experience reference for the realization of an orderly and harmonious life rhythm in the future. In addition, GRE scores are also required to apply to some American schools.</p><h2 id="Test-preparation-contradiction-analysis"><a href="#Test-preparation-contradiction-analysis" class="headerlink" title="Test preparation contradiction analysis"></a>Test preparation contradiction analysis</h2><h3 id="deficiency-of-time"><a href="#deficiency-of-time" class="headerlink" title="deficiency of time"></a>deficiency of time</h3><p>Since I invested a lot of time during the summer vacation, preparing application materials, learning and accumulating professional knowledge, and preparing for FYP, I only left about 1 month to prepare for GRE. Therefore, the problem of insufficient time needs to be compensated by methodological refinement.</p><h2 id="Mathematical-contradiction-analysis"><a href="#Mathematical-contradiction-analysis" class="headerlink" title="Mathematical contradiction analysis"></a>Mathematical contradiction analysis</h2><h3 id="Skip-mechanism"><a href="#Skip-mechanism" class="headerlink" title="Skip mechanism"></a>Skip mechanism</h3><p>The key to GRE mathematics is relatively easy for our managers who have passed the science college entrance examination to adjust their expectations to about 170 through a certain amount of exercise review. But this does not mean that GRE math can be taken lightly. When preparing for the GRE math test, in addition to raising expectations, it is more important to reduce variance. Considering that GRE mathematics is relatively tight in design time, only 35 minutes, and there may be some difficult or unintelligible questions, then you must skip it decisively and stop the loss in time. Therefore, in the preparation process of mathematics, it is necessary to form a judging mechanism for judging whether to skip, and the less time-consuming judgment, the better.</p><h3 id="Question-type-analysis-mechanism"><a href="#Question-type-analysis-mechanism" class="headerlink" title="Question type analysis mechanism"></a>Question type analysis mechanism</h3><p>In the preparation process of mathematics, in addition to reducing variance, we must also effectively raise expectations. Unlike the college entrance examination, the language of GRE math is English, and there are a series of logical traps. Therefore, in order to increase the expectation of GRE mathematics, the following three points need to be “programmed” to refine the corresponding methodology.</p><ul><li>Common English for Mathematics</li><li>Various problem solving methods</li><li>Method of choosing method</li></ul><h3 id="Error-checking-mechanism"><a href="#Error-checking-mechanism" class="headerlink" title="Error checking mechanism"></a>Error checking mechanism</h3><p>Although the time for the GRE math test is limited, it does not rule out the possibility that time will be left. Therefore, you can pay attention to exercise a set of mechanisms that are conducive to using the remaining time error. For example, rationally plan the use of cursive paper.</p><h2 id="Reading-contradiction-analysis"><a href="#Reading-contradiction-analysis" class="headerlink" title="Reading contradiction analysis"></a>Reading contradiction analysis</h2><h3 id="Read-it-again"><a href="#Read-it-again" class="headerlink" title="Read it again"></a>Read it again</h3><p>Through the training of the past few days, I have discovered a phenomenon, and if I did not understand the article at the beginning, then I basically rely on misunderstanding to do the questions later. Therefore, GRE reading must first understand the article. To achieve this, the s3 version of the sentence can be refined, and the content of the next sentence can be pre-judged through the intermediate relational connectives, so as to recurse.</p><h3 id="accelerate"><a href="#accelerate" class="headerlink" title="accelerate"></a>accelerate</h3><p>Read the article in a limited time. .</p><h2 id="Fill-in-the-blank-contradiction-analysis"><a href="#Fill-in-the-blank-contradiction-analysis" class="headerlink" title="Fill in the blank contradiction analysis"></a>Fill in the blank contradiction analysis</h2><h3 id="Vocabulary"><a href="#Vocabulary" class="headerlink" title="Vocabulary"></a>Vocabulary</h3><p>First brush 3000, and then brush the TOEFL vocabulary. . Then look again. When scanning words, be sure to batch (for example, 500 words as a group), changeable. Pass it several times a day, just flash, and it will be effective in a few days.</p><h3 id="Formula-processing"><a href="#Formula-processing" class="headerlink" title="Formula processing"></a>Formula processing</h3><p>Abstract the topic into formula processing. .</p></span>]]></content>
<categories>
<category> life </category>
</categories>
<tags>
<tag> gre </tag>
</tags>
</entry>
<entry>
<title>CS, ECE硕士项目调研</title>
<link href="/life/cs-ece-master-programs.html"/>
<url>/life/cs-ece-master-programs.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>为了准备2021硕士申请,我对一些喜欢的项目做了一些调查,并汇总在这里。</p></span><span class=".en"><p>To prepare for my master’s application in 2021, I did some research on some of my favorite projects and summarized them here.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><blockquote><p>排名来源:<a href="https://www.topuniversities.com/university-rankings/world-university-rankings/2020" target="_blank" rel="noopener">QS2020</a>, <a href="https://www.usnews.com/education/best-global-universities/rankings?page=1" target="_blank" rel="noopener">USNews2020</a>, <a href="http://www.shanghairanking.com/ARWU2019.html" target="_blank" rel="noopener">上海交大2019</a>,<a href="http://csrankings.org/#/index?all&world" target="_blank" rel="noopener">csrank.global.2010-2020</a><br>四个排名代表四种视角(QS-&gt;英国,USNews-&gt;美国,上海交大-&gt;中国,csrank-&gt;cs专业贡献)</p></blockquote><blockquote><p>以下信息部分摘自互联网,可能有<strong>错误</strong>!!</p></blockquote><h1 id="英国-选2-3所"><a href="#英国-选2-3所" class="headerlink" title="英国 (选2-3所)"></a><strong>英国 (选2-3所)</strong></h1><h2 id="帝国理工"><a href="#帝国理工" class="headerlink" title="帝国理工"></a><strong>帝国理工</strong></h2><blockquote><p><code>QS</code>: 9<br><code>USNews</code>: 20<br><code>上海交大</code>: 23<br><code>csrank</code>: 73</p></blockquote><p><strong>申请模式</strong>: </p><p>两个志愿,录取时可以看到你的第二志愿。一年只能提交一次申请。</p><h3 id="MSc-Computing-Science"><a href="#MSc-Computing-Science" class="headerlink" title="MSc Computing Science"></a><a href="https://www.imperial.ac.uk/study/pg/computing/computing-science/" target="_blank" rel="noopener">MSc Computing Science</a></h3><ul><li>学费<code>£33,250</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>任何专业一等学位</li><li>雅思6.5小分6/托福92小分20</li></ul><p> <strong>案例</strong></p><ul><li>均分85, con 85 (校友利)</li><li>gre330 (优留)</li></ul><h3 id="MSc-Applied-Machine-Learning"><a href="#MSc-Applied-Machine-Learning" class="headerlink" title="MSc Applied Machine Learning"></a><a href="https://www.imperial.ac.uk/study/pg/electrical-engineering/applied-machine-learning/" target="_blank" rel="noopener">MSc Applied Machine Learning</a></h3><ul><li>学费<code>£32,500</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>EEE专业一等学位</li><li>雅思6.5小分6/托福92小分20</li></ul><h2 id="UCL"><a href="#UCL" class="headerlink" title="UCL"></a><strong>UCL</strong></h2><blockquote><p><code>QS</code>: 8<br><code>USNews</code>: 21<br><code>上海交大</code>: 15<br><code>csrank</code>: 50</p></blockquote><p><strong>申请模式</strong>: </p><p>可以申请多次。申请由授课老师处理,不同院系不互通。</p><h3 id="MSc-Integrated-Machine-Learning-Systems"><a href="#MSc-Integrated-Machine-Learning-Systems" class="headerlink" title="MSc Integrated Machine Learning Systems"></a><a href="https://www.ucl.ac.uk/prospective-students/graduate/taught-degrees/integrated-machine-learning-systems-msc" target="_blank" rel="noopener">MSc Integrated Machine Learning Systems</a></h3><ul><li>学费<code>£28,530</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>EE/CS专业二等一学位</li><li>雅思6.5小分6/托福92小分读写24-30听说20-30</li></ul><p> <strong>案例</strong></p><ul><li>88均分 (校友利)</li><li>85通信(优留)</li></ul><h3 id="MSc-Computer-Science"><a href="#MSc-Computer-Science" class="headerlink" title="MSc Computer Science"></a><a href="https://www.ucl.ac.uk/prospective-students/graduate/taught-degrees/computer-science-msc" target="_blank" rel="noopener">MSc Computer Science</a></h3><ul><li>学费<code>£30,400</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>非CS专业二等一学位</li><li>雅思7.0小分6.5/托福100小分读写24-30听说20-30</li></ul><h2 id="爱丁堡大学"><a href="#爱丁堡大学" class="headerlink" title="爱丁堡大学"></a><strong>爱丁堡大学</strong></h2><blockquote><p><code>QS</code>: 20<br><code>USNews</code>: 28<br><code>上海交大</code>: 31<br><code>csrank</code>: 33</p></blockquote><h3 id="MSc-Computer-Science-1"><a href="#MSc-Computer-Science-1" class="headerlink" title="MSc Computer Science"></a><a href="https://www.ed.ac.uk/studying/postgraduate/degrees/index.php?r=site/view&edition=2020&id=110" target="_blank" rel="noopener">MSc Computer Science</a></h3><ul><li>学费<code>-</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>大部分工程理学专业二等一学位</li><li>雅思6.5小分6.0/托福92小分20</li></ul><p> <strong>案例</strong></p><ul><li>无录取案例,据说因为与军工有关不收亚裔</li></ul><h3 id="MSc-Signal-Processing-and-Communications"><a href="#MSc-Signal-Processing-and-Communications" class="headerlink" title="MSc Signal Processing and Communications"></a><a href="https://www.ed.ac.uk/studying/postgraduate/degrees/index.php?r=site/view&edition=2020&id=20" target="_blank" rel="noopener">MSc Signal Processing and Communications</a></h3><ul><li>学费<code>-</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>EE与信号相关专业二等一学位</li><li>雅思6.5小分6.0/托福92小分20</li></ul><hr><h1 id="美国-选1-2所"><a href="#美国-选1-2所" class="headerlink" title="美国 (选1-2所)"></a><strong>美国 (选1-2所)</strong></h1><h2 id="康奈尔大学"><a href="#康奈尔大学" class="headerlink" title="康奈尔大学"></a><strong>康奈尔大学</strong></h2><blockquote><p><code>QS</code>: 14<br><code>USNews</code>: 23<br><code>上海交大</code>: 13<br><code>csrank</code>: 7 (参考清华8)</p></blockquote><h3 id="M-Eng-Electrical-and-Computer-Engineering-Ithaca"><a href="#M-Eng-Electrical-and-Computer-Engineering-Ithaca" class="headerlink" title="M.Eng. Electrical and Computer Engineering (Ithaca)"></a><a href="https://gradschool.cornell.edu/academics/fields-of-study/subject/electrical-and-computer-engineering/electrical-and-computer-engineering-meng-ithaca/" target="_blank" rel="noopener">M.Eng. Electrical and Computer Engineering (Ithaca)</a></h3><ul><li>学费<code>$56,550</code></li><li>时长一年(大部分延期一年半)</li></ul><p> <strong>条件</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+</li><li>雅思7.0/托福小分说22读20听15写20</li><li>两封推荐信</li></ul><p> <strong>案例</strong></p><ul><li>gre320,强科研</li></ul><h3 id="M-Eng-Electrical-and-Computer-Engineering-NewYork"><a href="#M-Eng-Electrical-and-Computer-Engineering-NewYork" class="headerlink" title="M.Eng. Electrical and Computer Engineering (NewYork)"></a><a href="https://tech.cornell.edu/programs/masters-programs/master-in-electrical-and-computer-engineering/" target="_blank" rel="noopener">M.Eng. Electrical and Computer Engineering (NewYork)</a></h3><ul><li>学费<code>$58,586</code></li><li>时长一年</li></ul><p> <strong>条件</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+</li><li>雅思7.0/托福小分说22读20听15写20</li><li>两封推荐信</li></ul><h2 id="卡耐基梅隆大学"><a href="#卡耐基梅隆大学" class="headerlink" title="卡耐基梅隆大学"></a><strong>卡耐基梅隆大学</strong></h2><blockquote><p><code>QS</code>: 48<br><code>USNews</code>: 82<br><code>上海交大</code>: 95<br><code>csrank</code>: 1</p></blockquote><h3 id="Master-of-Science-in-Information-Networking"><a href="#Master-of-Science-in-Information-Networking" class="headerlink" title="Master of Science in Information Networking"></a><a href="https://www.cmu.edu/ini/academics/msin/index.html" target="_blank" rel="noopener">Master of Science in Information Networking</a></h3><ul><li>学费<code>$50,100</code></li><li>时长两年</li></ul><p> <strong>条件</strong></p><ul><li>GPA 3.9+</li><li>GRE 330+</li><li>托福102</li><li>三封推荐信</li></ul><p> <strong>案例</strong></p><ul><li>宁诺85+gre326美国暑研(优留)</li></ul><h2 id="哥伦比亚大学"><a href="#哥伦比亚大学" class="headerlink" title="哥伦比亚大学"></a><strong>哥伦比亚大学</strong></h2><blockquote><p><code>QS</code>: 18<br><code>USNews</code>: 7<br><code>上海交大</code>: 8<br><code>csrank</code>: 15</p></blockquote><h3 id="Master-of-Science-in-Electrical-Engineering"><a href="#Master-of-Science-in-Electrical-Engineering" class="headerlink" title="Master of Science in Electrical Engineering"></a><a href="http://www.ee.columbia.edu/ms-program-ee" target="_blank" rel="noopener">Master of Science in Electrical Engineering</a></h3><p> <strong>条件</strong></p><ul><li>GPA 3.7+</li><li>GRE 320+</li><li>托福102</li><li>三封推荐信</li><li>可能有面试</li></ul><hr><h1 id="新加坡-选1-2所"><a href="#新加坡-选1-2所" class="headerlink" title="新加坡 (选1-2所)"></a><strong>新加坡 (选1-2所)</strong></h1><h2 id="新加坡国立大学"><a href="#新加坡国立大学" class="headerlink" title="新加坡国立大学"></a><strong>新加坡国立大学</strong></h2><blockquote><p><code>QS</code>: 11<br><code>USNews</code>: 34<br><code>上海交大</code>: 67<br><code>csrank</code>: 16 </p></blockquote><ul><li>不同学院可申请多个专业</li></ul><h3 id="Master-of-Technology-in-Software-Engineering"><a href="#Master-of-Technology-in-Software-Engineering" class="headerlink" title="Master of Technology in Software Engineering"></a><a href="https://www.iss.nus.edu.sg/graduate-programmes/programme/detail/master-of-technology-in-software-engineering" target="_blank" rel="noopener">Master of Technology in Software Engineering</a></h3><ul><li>学费<code>S$5,350.00</code></li><li>时长一年</li><li>偏向有工作经验者</li></ul><p> <strong>条件</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+</li><li>雅思6.0/托福85</li><li>面试</li></ul><h3 id="Msc-Electrical-Engineering-CE方向"><a href="#Msc-Electrical-Engineering-CE方向" class="headerlink" title="Msc. Electrical Engineering - CE方向"></a><a href="https://www.eng.nus.edu.sg/ece/graduate/coursework-based-programmes/master-of-science-by-course-work/application-details/" target="_blank" rel="noopener">Msc. Electrical Engineering - CE方向</a></h3><ul><li>偏向有工作经验者</li></ul><p> <strong>条件</strong></p><ul><li>GPA</li><li>雅思6.0/托福90 (可免)</li></ul><h3 id="Msc-Computer-Science"><a href="#Msc-Computer-Science" class="headerlink" title="Msc. Computer Science"></a><a href="https://www.comp.nus.edu.sg/programmes/pg/mcs/admissions/" target="_blank" rel="noopener">Msc. Computer Science</a></h3><ul><li>偏向有工作经验者</li><li>转专业可能有限制</li></ul><p> <strong>条件</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+</li><li>雅思6.0/托福90 (可免)</li></ul><h2 id="南洋理工大学"><a href="#南洋理工大学" class="headerlink" title="南洋理工大学"></a><strong>南洋理工大学</strong></h2><blockquote><p><code>QS</code>: 11<br><code>USNews</code>: 43<br><code>上海交大</code>: 73<br><code>csrank</code>: 53</p></blockquote><ul><li>不同学院可申请多个专业</li></ul><h3 id="Msc-Artificial-Intelligence"><a href="#Msc-Artificial-Intelligence" class="headerlink" title="Msc Artificial Intelligence"></a><a href="http://scse.ntu.edu.sg/Programmes/ProspectiveStudents/Graduate/msc-AI/Pages/AdmissionRequirements.aspx" target="_blank" rel="noopener">Msc Artificial Intelligence</a></h3><ul><li>学费<code>S$58,000.00</code></li><li>时长一年</li></ul><p><strong>条件</strong></p><ul><li>GPA 3.8+</li><li>雅思6.5/托福100 (可免)</li></ul><h3 id="MSc-Computer-Control-amp-Automation"><a href="#MSc-Computer-Control-amp-Automation" class="headerlink" title="MSc Computer Control &amp; Automation"></a><a href="http://www.eee.ntu.edu.sg/Programmes/ProspectiveStudents/Graduate/MOE_sub_MSc/MSc_CCA/Pages/Curriculum.aspx" target="_blank" rel="noopener">MSc Computer Control &amp; Automation</a></h3><ul><li>学费<code>S$3,350.00</code></li><li>时长一年</li></ul><p><strong>条件</strong></p><ul><li>GPA 3.6+</li><li>雅思6.5/托福100</li></ul><hr><h1 id="加拿大-选0-1所"><a href="#加拿大-选0-1所" class="headerlink" title="加拿大 (选0-1所)"></a><strong>加拿大 (选0-1所)</strong></h1><h2 id="多伦多大学"><a href="#多伦多大学" class="headerlink" title="多伦多大学"></a><strong>多伦多大学</strong></h2><blockquote><p><code>QS</code>: 29<br><code>USNews</code>: 18<br><code>上海交大</code>: 24<br><code>csrank</code>: 18</p></blockquote><h3 id="MEng-Electrical-and-Computer-Engineering"><a href="#MEng-Electrical-and-Computer-Engineering" class="headerlink" title="MEng. Electrical and Computer Engineering"></a><a href="https://www.sgs.utoronto.ca/programs/electrical-and-computer-engineering/" target="_blank" rel="noopener">MEng. Electrical and Computer Engineering</a></h3><ul><li>时长<code>12-24</code>月</li><li>学费+生活费<code>40</code>万/年</li></ul><p> <strong>条件</strong></p><ul><li>GPA 3.6+</li><li>雅思6.5小分6.0/托福100写作22</li><li>gre</li><li>三封推荐信</li></ul><hr><h1 id="瑞士-选0-2所"><a href="#瑞士-选0-2所" class="headerlink" title="瑞士 (选0-2所)"></a><strong>瑞士 (选0-2所)</strong></h1><h2 id="苏黎世联邦理工"><a href="#苏黎世联邦理工" class="headerlink" title="苏黎世联邦理工"></a><strong>苏黎世联邦理工</strong></h2><blockquote><p><code>QS</code>: 6<br><code>USNews</code>: 25<br><code>上海交大</code>: 19<br><code>csrank</code>: 10 </p></blockquote><ul><li>转专业不友好</li><li>本科学校很重要</li><li>每个地区人数有配额</li></ul><h3 id="Master-Electrical-Engineering-and-Information-Technology"><a href="#Master-Electrical-Engineering-and-Information-Technology" class="headerlink" title="Master Electrical Engineering and Information Technology"></a><a href="https://ethz.ch/en/studies/prospective-masters-degree-students/masters-degree-programmes/engineering-sciences/master-electrical-engineering-and-information-technology.html" target="_blank" rel="noopener">Master Electrical Engineering and Information Technology</a></h3><ul><li>时长1.5年</li></ul><p><strong>条件</strong></p><ul><li>GPA 3.8+ (top 5-10%)</li><li>雅思7.0/托福100</li><li>gre 320+ (不强制)</li><li>三封学术推荐信</li><li>学费生活费一共<code>20-30</code>万</li><li>有奖学金</li></ul><h2 id="洛桑联邦理工"><a href="#洛桑联邦理工" class="headerlink" title="洛桑联邦理工"></a><strong>洛桑联邦理工</strong></h2><blockquote><p><code>QS</code>: 18<br><code>USNews</code>: 45<br><code>上海交大</code>: 78<br><code>csrank</code>: 28 </p></blockquote><ul><li>只能申一个专业</li><li>没有地区配额,全球申请者竞争</li></ul><h3 id="Electrical-and-electronic-Engineering"><a href="#Electrical-and-electronic-Engineering" class="headerlink" title="Electrical and electronic Engineering"></a><a href="https://www.epfl.ch/education/master/programs/electrical-and-electronic-engineering/" target="_blank" rel="noopener">Electrical and electronic Engineering</a></h3><ul><li>时长1.5年</li><li>转专业不友好</li><li>学费生活费一共<code>20-30</code>万</li><li>有奖学金</li></ul><p><strong>条件</strong></p><ul><li>GPA 3.8+</li><li>雅思7.0/托福100</li><li>三封推荐信</li><li>gre 320+ (不强制)</li></ul></span><span class=".en"><blockquote><p>Ranking Source:<a href="https://www.topuniversities.com/university-rankings/world-university-rankings/2020" target="_blank" rel="noopener">QS2020</a>, <a href="https://www.usnews.com/education/best-global-universities/rankings?page=1" target="_blank" rel="noopener">USNews2020</a>, <a href="http://www.shanghairanking.com/ARWU2019.html" target="_blank" rel="noopener">ARWU2019</a>,<a href="http://csrankings.org/#/index?all&world" target="_blank" rel="noopener">csrank.global.2010-2020</a><br>The four rankings represent four perspectives (QS-&gt;UK,USNews-&gt;US,ARWU-&gt;China,csrank-&gt;cs Industry)</p></blockquote><blockquote><p>The following information section is taken from the Internet and may contain <strong>errors</strong>!!</p></blockquote><h1 id="UK"><a href="#UK" class="headerlink" title="UK"></a><strong>UK</strong></h1><h2 id="Imperial-College-London"><a href="#Imperial-College-London" class="headerlink" title="Imperial College London"></a><strong>Imperial College London</strong></h2><blockquote><p><code>QS</code>: 9<br><code>USNews</code>: 20<br><code>ARWU</code>: 23<br><code>csrank</code>: 73</p></blockquote><p><strong>Application mode</strong>: </p><p>Two choices. You can see your second choice when you are admitted.Applications can only be submitted once a year.</p><h3 id="MSc-Computing-Science-1"><a href="#MSc-Computing-Science-1" class="headerlink" title="MSc Computing Science"></a><a href="https://www.imperial.ac.uk/study/pg/computing/computing-science/" target="_blank" rel="noopener">MSc Computing Science</a></h3><ul><li>Fee<code>£33,250</code></li><li>1 year</li></ul><p><strong>Condition</strong></p><ul><li>A first class degree in any major</li><li>Ielts 6.5 score 6/ TOEFL 92 score 20</li></ul><p> <strong>Case</strong></p><ul><li>con 85 (校友利)</li><li>gre330 (优留)</li></ul><h3 id="MSc-Applied-Machine-Learning-1"><a href="#MSc-Applied-Machine-Learning-1" class="headerlink" title="MSc Applied Machine Learning"></a><a href="https://www.imperial.ac.uk/study/pg/electrical-engineering/applied-machine-learning/" target="_blank" rel="noopener">MSc Applied Machine Learning</a></h3><ul><li>Fee<code>£32,500</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>EEE first class</li><li>Ielts 6.5 score 6/ TOEFL 92 score 20</li></ul><h2 id="UCL-1"><a href="#UCL-1" class="headerlink" title="UCL"></a><strong>UCL</strong></h2><blockquote><p><code>QS</code>: 8<br><code>USNews</code>: 21<br><code>ARWU</code>: 15<br><code>csrank</code>: 50</p></blockquote><p><strong>Apply Method</strong>: </p><p>You can apply multiple times.The application is handled by the instructor and is not interchangeable between different departments.</p><h3 id="MSc-Integrated-Machine-Learning-Systems-1"><a href="#MSc-Integrated-Machine-Learning-Systems-1" class="headerlink" title="MSc Integrated Machine Learning Systems"></a><a href="https://www.ucl.ac.uk/prospective-students/graduate/taught-degrees/integrated-machine-learning-systems-msc" target="_blank" rel="noopener">MSc Integrated Machine Learning Systems</a></h3><ul><li>Fee<code>£28,530</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>First class degree in EE/CS</li><li>Ielts 6.5 score 6/ TOEFL 92 score reading and writing 24-30 listening and speaking 20-30</li></ul><p> <strong>Case</strong></p><ul><li>con 88 (校友利)</li><li>85 Telecom(优留)</li></ul><h3 id="MSc-Computer-Science-2"><a href="#MSc-Computer-Science-2" class="headerlink" title="MSc Computer Science"></a><a href="https://www.ucl.ac.uk/prospective-students/graduate/taught-degrees/computer-science-msc" target="_blank" rel="noopener">MSc Computer Science</a></h3><ul><li>Fee<code>£30,400</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>One second class degree in a non-CS major</li><li>Ielts 7.0 score 6.5/ TOEFL 100 score reading and writing 24-30 listening and speaking 20-30</li></ul><h2 id="University-of-Edinburgh"><a href="#University-of-Edinburgh" class="headerlink" title="University of Edinburgh"></a><strong>University of Edinburgh</strong></h2><blockquote><p><code>QS</code>: 20<br><code>USNews</code>: 28<br><code>ARWU</code>: 31<br><code>csrank</code>: 33</p></blockquote><h3 id="MSc-Computer-Science-3"><a href="#MSc-Computer-Science-3" class="headerlink" title="MSc Computer Science"></a><a href="https://www.ed.ac.uk/studying/postgraduate/degrees/index.php?r=site/view&edition=2020&id=110" target="_blank" rel="noopener">MSc Computer Science</a></h3><ul><li>Fee<code>-</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>First class degree in most engineering majors</li><li>Ielts 6.5 score 6.0/ TOEFL 92 score 20</li></ul><p> <strong>Case</strong></p><ul><li>No case of admission, it is said that because of military industry related not to accept Asians</li></ul><h3 id="MSc-Signal-Processing-and-Communications-1"><a href="#MSc-Signal-Processing-and-Communications-1" class="headerlink" title="MSc Signal Processing and Communications"></a><a href="https://www.ed.ac.uk/studying/postgraduate/degrees/index.php?r=site/view&edition=2020&id=20" target="_blank" rel="noopener">MSc Signal Processing and Communications</a></h3><ul><li>Fee<code>-</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>EE and signal related major first class degree</li><li>Ielts 6.5 score 6.0/ TOEFL 92 score 20</li></ul><hr><h1 id="USA"><a href="#USA" class="headerlink" title="USA"></a><strong>USA</strong></h1><h2 id="Cornell-University"><a href="#Cornell-University" class="headerlink" title="Cornell University"></a><strong>Cornell University</strong></h2><blockquote><p><code>QS</code>: 14<br><code>USNews</code>: 23<br><code>ARWU</code>: 13<br><code>csrank</code>: 7 </p></blockquote><h3 id="M-Eng-Electrical-and-Computer-Engineering-Ithaca-1"><a href="#M-Eng-Electrical-and-Computer-Engineering-Ithaca-1" class="headerlink" title="M.Eng. Electrical and Computer Engineering (Ithaca)"></a><a href="https://gradschool.cornell.edu/academics/fields-of-study/subject/electrical-and-computer-engineering/electrical-and-computer-engineering-meng-ithaca/" target="_blank" rel="noopener">M.Eng. Electrical and Computer Engineering (Ithaca)</a></h3><ul><li>Fee<code>$56,550</code></li><li>Duration: one year (most extensions: one and a half years)</li></ul><h2 id="Condition"><a href="#Condition" class="headerlink" title="Condition"></a><strong>Condition</strong></h2><ul><li>3.8 GPA</li><li>the GRE 320 +</li><li>IELTS 7.0/ TOEFL small say 22 Read 20 listen 15 write 20</li><li>Two letters of recommendation</li></ul><p> <strong>Case</strong></p><ul><li>gre320,Strong scientific research</li></ul><h3 id="M-Eng-Electrical-and-Computer-Engineering-NewYork-1"><a href="#M-Eng-Electrical-and-Computer-Engineering-NewYork-1" class="headerlink" title="M.Eng. Electrical and Computer Engineering (NewYork)"></a><a href="https://tech.cornell.edu/programs/masters-programs/master-in-electrical-and-computer-engineering/" target="_blank" rel="noopener">M.Eng. Electrical and Computer Engineering (NewYork)</a></h3><ul><li>Fee<code>$58,586</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+</li><li>IELTS 7.0/ TOEFL small say 22 Read 20 listen 15 write 20</li><li>Two letters of recommendation</li></ul><h2 id="Carnegie-Mellon-University"><a href="#Carnegie-Mellon-University" class="headerlink" title="Carnegie Mellon University"></a><strong>Carnegie Mellon University</strong></h2><blockquote><p><code>QS</code>: 48<br><code>USNews</code>: 82<br><code>ARWU</code>: 95<br><code>csrank</code>: 1</p></blockquote><h3 id="Master-of-Science-in-Information-Networking-1"><a href="#Master-of-Science-in-Information-Networking-1" class="headerlink" title="Master of Science in Information Networking"></a><a href="https://www.cmu.edu/ini/academics/msin/index.html" target="_blank" rel="noopener">Master of Science in Information Networking</a></h3><ul><li>Fee<code>$50,100</code></li><li>2 Years</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.9+</li><li>GRE 330+</li><li>Toefl 102</li><li>Three letters of recommendation</li></ul><p> <strong>Case</strong></p><ul><li>宁诺85+gre326(优留)</li></ul><h2 id="Columbia-University"><a href="#Columbia-University" class="headerlink" title="Columbia University"></a><strong>Columbia University</strong></h2><blockquote><p><code>QS</code>: 18<br><code>USNews</code>: 7<br><code>ARWU</code>: 8<br><code>csrank</code>: 15</p></blockquote><h3 id="Master-of-Science-in-Electrical-Engineering-1"><a href="#Master-of-Science-in-Electrical-Engineering-1" class="headerlink" title="Master of Science in Electrical Engineering"></a><a href="http://www.ee.columbia.edu/ms-program-ee" target="_blank" rel="noopener">Master of Science in Electrical Engineering</a></h3><p> <strong>Condition</strong></p><ul><li>GPA 3.7+</li><li>GRE 320+</li><li>the toefl 102</li><li>Three letters of recommendation</li><li>There might be an interview</li></ul><hr><h1 id="Singapore"><a href="#Singapore" class="headerlink" title="Singapore"></a><strong>Singapore</strong></h1><h2 id="National-University-of-Singapore"><a href="#National-University-of-Singapore" class="headerlink" title="National University of Singapore"></a><strong>National University of Singapore</strong></h2><blockquote><p><code>QS</code>: 11<br><code>USNews</code>: 34<br><code>ARWU</code>: 67<br><code>csrank</code>: 16 </p></blockquote><ul><li>Different colleges can apply for multiple majors</li></ul><h3 id="Master-of-Technology-in-Software-Engineering-1"><a href="#Master-of-Technology-in-Software-Engineering-1" class="headerlink" title="Master of Technology in Software Engineering"></a><a href="https://www.iss.nus.edu.sg/graduate-programmes/programme/detail/master-of-technology-in-software-engineering" target="_blank" rel="noopener">Master of Technology in Software Engineering</a></h3><ul><li>Fee<code>S$5,350.00</code></li><li>1 year</li><li>Prefer people with work experience</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+</li><li>IELTS 6.0/ TOEFL 85</li><li>the interview</li></ul><h3 id="Msc-Electrical-Engineering-CE"><a href="#Msc-Electrical-Engineering-CE" class="headerlink" title="Msc. Electrical Engineering - CE"></a><a href="https://www.eng.nus.edu.sg/ece/graduate/coursework-based-programmes/master-of-science-by-course-work/application-details/" target="_blank" rel="noopener">Msc. Electrical Engineering - CE</a></h3><ul><li>Prefer people with work experience</li></ul><p> <strong>Condition</strong></p><ul><li>GPA</li><li>Ielts 6.0/ TOEFL 90</li></ul><h3 id="Msc-Computer-Science-1"><a href="#Msc-Computer-Science-1" class="headerlink" title="Msc. Computer Science"></a><a href="https://www.comp.nus.edu.sg/programmes/pg/mcs/admissions/" target="_blank" rel="noopener">Msc. Computer Science</a></h3><ul><li>Prefer those with work experience</li><li>There may be restrictions on changing majors</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.8+</li><li>GRE 320+<ul><li>IELTS 6.0/ TOEFL 90 (optional)</li></ul></li></ul><h2 id="Nanyang-Technological-University"><a href="#Nanyang-Technological-University" class="headerlink" title="Nanyang Technological University"></a><strong>Nanyang Technological University</strong></h2><blockquote><p><code>QS</code>: 11<br><code>USNews</code>: 43<br><code>ARWU</code>: 73<br><code>csrank</code>: 53</p></blockquote><ul><li>Different colleges may apply for multiple majors</li></ul><h3 id="Msc-Artificial-Intelligence-1"><a href="#Msc-Artificial-Intelligence-1" class="headerlink" title="Msc Artificial Intelligence"></a><a href="http://scse.ntu.edu.sg/Programmes/ProspectiveStudents/Graduate/msc-AI/Pages/AdmissionRequirements.aspx" target="_blank" rel="noopener">Msc Artificial Intelligence</a></h3><ul><li>Fee<code>S$58,000.00</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.8+<ul><li>IELTS 6.5/ TOEFL 100 (optional)</li></ul></li></ul><h3 id="MSc-Computer-Control-amp-Automation-1"><a href="#MSc-Computer-Control-amp-Automation-1" class="headerlink" title="MSc Computer Control &amp; Automation"></a><a href="http://www.eee.ntu.edu.sg/Programmes/ProspectiveStudents/Graduate/MOE_sub_MSc/MSc_CCA/Pages/Curriculum.aspx" target="_blank" rel="noopener">MSc Computer Control &amp; Automation</a></h3><ul><li>Fee<code>S$3,350.00</code></li><li>1 year</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.6+<ul><li>IELTS 6.5/ TOEFL 100</li></ul></li></ul><hr><h1 id="Canada"><a href="#Canada" class="headerlink" title="Canada"></a><strong>Canada</strong></h1><h2 id="University-of-Toronto"><a href="#University-of-Toronto" class="headerlink" title="University of Toronto"></a><strong>University of Toronto</strong></h2><blockquote><p><code>QS</code>: 29<br><code>USNews</code>: 18<br><code>ARWU</code>: 24<br><code>csrank</code>: 18</p></blockquote><h3 id="MEng-Electrical-and-Computer-Engineering-1"><a href="#MEng-Electrical-and-Computer-Engineering-1" class="headerlink" title="MEng. Electrical and Computer Engineering"></a><a href="https://www.sgs.utoronto.ca/programs/electrical-and-computer-engineering/" target="_blank" rel="noopener">MEng. Electrical and Computer Engineering</a></h3><ul><li>Length<code>12-24</code>months</li><li>All Fee<code>400,000 RMB</code>/year</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.6+<ul><li>IELTS 6.5 score 6.0/ TOEFL 100 writing 22</li></ul></li><li>gre<ul><li>Three letters of recommendation</li></ul></li></ul><hr><h1 id="Switzerland"><a href="#Switzerland" class="headerlink" title="Switzerland"></a><strong>Switzerland</strong></h1><h2 id="Eth-Zurich"><a href="#Eth-Zurich" class="headerlink" title="Eth Zurich"></a><strong>Eth Zurich</strong></h2><blockquote><p><code>QS</code>: 6<br><code>USNews</code>: 25<br><code>ARWU</code>: 19<br><code>csrank</code>: 10 </p></blockquote><ul><li>Switching majors is not friendly</li><li>Undergraduate school is important</li><li>There is a quota for each region</li></ul><h3 id="Master-Electrical-Engineering-and-Information-Technology-1"><a href="#Master-Electrical-Engineering-and-Information-Technology-1" class="headerlink" title="Master Electrical Engineering and Information Technology"></a><a href="https://ethz.ch/en/studies/prospective-masters-degree-students/masters-degree-programmes/engineering-sciences/master-electrical-engineering-and-information-technology.html" target="_blank" rel="noopener">Master Electrical Engineering and Information Technology</a></h3><ul><li>1.5 year</li></ul><p> <strong>Condition</strong></p><ul><li>GPA 3.8+ (top 5-10%)<ul><li>IELTS 7.0/ TOEFL 100</li><li>GRE 320+ (not mandatory)</li><li>Three academic letters of recommendation</li><li>Total tuition and living expenses are 200,000 to 300,000 YUAN</li><li>With a scholarship.</li></ul></li></ul><h2 id="Federal-Institute-of-Technology-in-Lausanne"><a href="#Federal-Institute-of-Technology-in-Lausanne" class="headerlink" title="Federal Institute of Technology in Lausanne"></a><strong>Federal Institute of Technology in Lausanne</strong></h2><blockquote><p><code>QS</code>: 18<br><code>USNews</code>: 45<br><code>ARWU</code>: 78<br><code>csrank</code>: 28 </p></blockquote><ul><li>Only one major</li><li>No regional quotas, global competition for applicants</li></ul><h3 id="Electrical-and-electronic-Engineering-1"><a href="#Electrical-and-electronic-Engineering-1" class="headerlink" title="Electrical and electronic Engineering"></a><a href="https://www.epfl.ch/education/master/programs/electrical-and-electronic-engineering/" target="_blank" rel="noopener">Electrical and electronic Engineering</a></h3><ul><li>1.5 year<ul><li>Switching majors is not friendly</li><li>Total tuition and living expenses are 200,000 to 300,000 YUAN</li><li>With a scholarship.</li></ul></li></ul><p> <strong>Condition</strong></p><ul><li>3.8 GPA</li><li>IELTS 7.0/ TOEFL 100</li><li>Three letters of recommendation</li><li>GRE 320+ (not mandatory)</li></ul></span>]]></content>
<categories>
<category> life </category>
</categories>
<tags>
<tag> master </tag>
<tag> investigation </tag>
</tags>
</entry>
<entry>
<title>Hello Hexo</title>
<link href="/tech/hello-hexo.html"/>
<url>/tech/hello-hexo.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>将blog从Typecho迁移到了Hexo。</p></span><span class=".en"><p>Migrated blog from Typecho to Hexo.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"></span><span class=".en"></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> hexo </tag>
</tags>
</entry>
<entry>
<title>认知派生论</title>
<link href="/thoughts/cognitive-derived-theory.html"/>
<url>/thoughts/cognitive-derived-theory.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>拜读了毛主席的实践论和矛盾论,第一次系统地接触了辩证唯物论这一方法论,深感其强大与自然。综合我自己先前的所经所悟,提炼出认知派生这一观点。</p></span><span class=".en"><p>After reading Chairman Mao’s theory of practice and contradiction, it was the first time to systematically come into contact with the methodology of dialectical materialism, and I deeply felt its power and nature. Combining my own previous experience and understanding, I refined the view of cognitive derivation.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="序"><a href="#序" class="headerlink" title="序"></a>序</h2><p>从巴甫洛夫的狗铃实验[1],到上世纪50年代费斯汀格的认知失调理论[2],再到1971年津巴多教授主导的斯坦福监狱实验[3],这一系列打破预期的心理学生理学实验,一步一步揭示出,人们心理的作用形式,似乎并非大多数人所认为的那样。实际上,这看似重大的心理学发现,其实早在两个世纪前,便已被马克思,恩格斯等人从社会学角度提出,并完善成为理论。后经列宁,斯大林等人通过实践进行完善。传入国内后,被毛泽东所集大成,结合了中国传统文化的底蕴,发展成为唯物辩证法的毛泽东思想。这一论理的形成,源自于这些人对自己所观察到的社会现象以及自己基于论理所实践的社会运动的归纳总结。而这一论理,又指导了中国共产党建国,扎实地完成国内资本原始积累地奇迹。</p><p>辩证唯物论是一套自洽的方法论,它能够有效地指导我们生活实践,从实践中总结论理,再将论理运用于实践的过程。而这一循环的高效运转,正是人类进化出认知的终极意义。</p><h2 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h2><p>方法论是一种十分有效而重要的工具,它为人们提供了一套范式(习惯),帮助人们更有效地践行“社会实践-&gt;认识-&gt;论理-&gt;社会实践”这一模式。</p><h2 id="参考文献"><a href="#参考文献" class="headerlink" title="参考文献"></a>参考文献</h2><p>[1] <a href="https://zh.wikipedia.org/wiki/%E5%B7%B4%E7%94%AB%E6%B4%9B%E5%A4%AB" target="_blank" rel="noopener">巴甫洛夫 - 维基百科</a><br>[2] <a href="https://zh.wikipedia.org/zh/%E8%AA%8D%E7%9F%A5%E5%A4%B1%E8%AA%BF" target="_blank" rel="noopener">認知失調 - 维基百科</a><br>[3] <a href="https://zh.wikipedia.org/zh-hans/%E6%96%AF%E5%9D%A6%E7%A6%8F%E7%9B%91%E7%8B%B1%E5%AE%9E%E9%AA%8C" target="_blank" rel="noopener">斯坦福监狱实验 - 维基百科</a> </p></span><span class=".en"><h2 id="Preface"><a href="#Preface" class="headerlink" title="Preface"></a>Preface</h2><p>From Pavlov’s dog bell experiment[1] to Festinger’s cognitive dissonance theory in the 1950s[2], to the Stanford prison experiment led by Professor Zimbardo in 1971[3], this A series of psychology students’ physical experiments that broke expectations reveals step by step that the role of people’s psychology does not seem to be what most people think. In fact, this seemingly important psychological discovery was actually put forward by Marx, Engels and others from a sociological point of view two centuries ago and perfected it into a theory. Later, Lenin, Stalin and others improved it through practice. After being introduced to China, it was collected by Mao Zedong, combined with the heritage of Chinese traditional culture, and developed into Mao Zedong’s thought of materialist dialectics. The formation of this theory stems from these people’s summary of the social phenomena they observe and the social movements they practice based on the theory. And this reasoning guided the founding of the Communist Party of China and solidly completed the miracle of domestic capital accumulation.</p><p>Dialectical materialism is a set of self-consistent methodology, which can effectively guide our life practice, conclude the theory from practice, and then apply the theory to the process of practice. The efficient operation of this cycle is precisely the ultimate meaning of human cognition.</p><h2 id="in-conclusion"><a href="#in-conclusion" class="headerlink" title="in conclusion"></a>in conclusion</h2><p>Methodology is a very effective and important tool. It provides people with a set of paradigms (habits) to help people practice the model of “social practice -&gt; knowledge -&gt; theory -&gt; social practice” more effectively.</p><h2 id="references"><a href="#references" class="headerlink" title="references"></a>references</h2><p>[1] <a href="https://zh.wikipedia.org/wiki/%E5%B7%B4%E7%94%AB%E6%B4%9B%E5%A4%AB" target="_blank" rel="noopener">巴甫洛夫 - 维基百科</a><br>[2] <a href="https://zh.wikipedia.org/zh/%E8%AA%8D%E7%9F%A5%E5%A4%B1%E8%AA%BF" target="_blank" rel="noopener">認知失調 - 维基百科</a><br>[3] <a href="https://zh.wikipedia.org/zh-hans/%E6%96%AF%E5%9D%A6%E7%A6%8F%E7%9B%91%E7%8B%B1%E5%AE%9E%E9%AA%8C" target="_blank" rel="noopener">斯坦福监狱实验 - 维基百科</a> </p></span>]]></content>
<categories>
<category> thoughts </category>
</categories>
</entry>
<entry>
<title>左宗棠鸡块</title>
<link href="/cook/zuozongtang-chiken.html"/>
<url>/cook/zuozongtang-chiken.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>分享一下改进版炸鸡块做法哦~</p></span><span class=".en"><p>Share the improved version of fried chicken nuggets~</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="材料准备"><a href="#材料准备" class="headerlink" title="材料准备"></a>材料准备</h2><ul><li>鸡胸肉</li><li>一个鸡蛋</li><li>葱末蒜末</li></ul><h2 id="预备步骤"><a href="#预备步骤" class="headerlink" title="预备步骤"></a>预备步骤</h2><ul><li>鸡肉切小块,加料酒,生抽,淀粉,鸡蛋清,搅匀腌10分钟</li><li>鸡块在面粉中打滚</li></ul><h2 id="核心步骤"><a href="#核心步骤" class="headerlink" title="核心步骤"></a>核心步骤</h2><ul><li>热油炸鸡块至焦黄</li><li>植物油蒜末炝锅</li><li>加入一勺生抽,一勺多白醋,一把白糖,番茄酱翻一下</li><li>加入鸡块,让鸡块上沾上酱汁</li><li>撒上葱末</li></ul><h2 id="成品图"><a href="#成品图" class="headerlink" title="成品图"></a>成品图</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_a3b687be_5120x3840_8_null_normal.jpeg" alt="左宗棠鸡块 2020-02-17"></p></span><span class=".en"><h2 id="Material-preparation"><a href="#Material-preparation" class="headerlink" title="Material preparation"></a>Material preparation</h2><ul><li>Chicken breast</li><li>An egg</li><li>Chopped green onion and garlic</li></ul><h2 id="Preliminary-steps"><a href="#Preliminary-steps" class="headerlink" title="Preliminary steps"></a>Preliminary steps</h2><ul><li>Cut chicken into small pieces, add cooking wine, light soy sauce, starch, egg white, stir well and marinate for 10 minutes</li><li>Chicken nuggets rolled in flour</li></ul><h2 id="Core-steps"><a href="#Core-steps" class="headerlink" title="Core steps"></a>Core steps</h2><ul><li>Hot fried chicken nuggets until browned</li><li>Vegetable oil minced garlic pot</li><li>Add a spoonful of light soy sauce, a spoonful of white vinegar, a handful of sugar and ketchup</li><li>Add chicken nuggets, so that the chicken nuggets are covered with sauce</li><li>Sprinkle with chopped green onions</li></ul><h2 id="Finished-picture"><a href="#Finished-picture" class="headerlink" title="Finished picture"></a>Finished picture</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_a3b687be_5120x3840_8_null_normal.jpeg" alt="Zuo Zongtang Chicken Nuggets 2020-02-17"></p></span>]]></content>
<categories>
<category> cook </category>
</categories>
<tags>
<tag> chiken </tag>
</tags>
</entry>
<entry>
<title>欧洲旅行支票兑换攻略</title>
<link href="/travel/traveler-cheque.html"/>
<url>/travel/traveler-cheque.html</url>
<content type="html"><![CDATA[<!--![](https://api.yimian.xyz/img/?path=imgbed/img_6ae04a26_721x412_8_null_normal.png)--><span class=".zh"><p>之前去欧洲旅游办签证,由于没有三个月的银行流水,不得已购买了旅行支票作为资金证明。可是到了欧洲才发现旅行支票很难使用,如果不了解行情会被骗收15%-20%的手续费。这篇Blog记录了我们发现的兑换旅行支票的坑和Tips!</p></span><span class=".en"><p>Before I went to Europe for a tourist visa, I had to buy a traveler’s cheque as a proof of funds because I did not have a three-month bank flow. However, when I arrived in Europe, I found that traveler’s cheques were difficult to use. If I didn’t understand the market, I would be defrauded of 15%-20% handling fees. This blog records the pits and Tips we found in redeeming traveler’s checks!</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>[scode type=”info”]<strong>经验一</strong>: 尽可能<strong>不使用</strong>旅行支票[/scode]<br>[scode type=”info”]<strong>经验二</strong>: 旅支兑换<strong>最低手续费</strong>在4%左右[/scode]</p><blockquote><p>若不想看经历,可直接调至文末兑换旅行支票的Tips处哦!</p></blockquote><h2 id="我的经历"><a href="#我的经历" class="headerlink" title="我的经历"></a>我的经历</h2><p>圣诞假和室友一行四人一起DIY游欧洲,去了意大利和奥地利两个国家,共5个城市。由于英国的银行卡还没有使用到三个月,无法通过打印流水来办签证,我们选择了另一种方法—购买American Express的欧元的旅行支票。殊不知啊,兑换和使用旅行支票真真是一个大坑。</p><p>最开始据旅行支票的官网上所说,欧洲很多城市的店铺里都能直接使用旅行支票,照这样来说,旅游时花掉它肯定比回英国后把它换回英镑划算的多(换回英镑的过程需要损失8%)。然鹅,出发前我们通过看他人的游记发现,欧洲现在很多店都无法直接花旅行支票(按我们后来实际旅行情况来看,只在威尼斯的好几家店看到了旅行支票的标识),于是我们决定去了就在机场红色标识的Change那里将它们全数换成欧元。</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6ae04a26_721x412_8_null_normal.png" alt="Change"></p><p>可到了第一站罗马找到了红色的Change后(如图),却发现700欧元只能给我们590多欧元。这可真的亏的不是一丁半点儿。我对象现场查到了American Express的电话,打过去发现人家现在在意大利没有设点,不过对方建议去银行换,说是可以毫无亏损(注意这也是个坑,,,)。由于有两人已经换了,为了止损,我们决定先不换剩下两人的700欧旅行支票,留着去银行换。</p><p>到了第三天,我们去了梵蒂冈那块儿玩,顺便去了附近American Express工作人员推荐的银行,还给中国银行打电话,结果均被告知不接受旅支。这可咋整?</p><p>这时刚好发现梵蒂冈周围有一堆change,于是又去问了问报价。其中有一家本来只报590多的,听见我们说另一家给了610多的价,说他们能给我们一个student discount,然后还算了算,报了个640。这下可好,我们开始发现这里面的门道了:其实哪有什么折扣,不过想找个借口吸引你罢了。这些change都是盈利性质的,你把旅支给了他们,他们再通过自己的途径卖给别的地方的American Express,中间可能有一点税收,但只要他们以比扣掉税收低的价格从你这里买下,他就一定能赚(一般还赚不少),不过是多赚点少赚点的区别罢了。而且当地有好几家change,我们主要发现了红色change标识的一家和蓝色的一家。若这家嫌你要求高不接受,那钱就让别家赚了呗。</p><p>所以这种时候,我们要想拿到高点的报价,就要掐准人家能接受的度(真的逼太狠了断了人家财路那就没辙了呀),然后通过让他们产生危机意识而提高报价。可以先问个几家,看他们一般会给多少,然后跟他说,别家给我了一个多少的价格。接下来这人可能就会开始打电话给上面的看能给个什么更高的价,叭叭一堆后给你一个略高一点的价格哈哈,你如果不太满意,可以再去找一家问问(不过要注意,如果是同一家的不同店面,要稍微注意点,毕竟他们上面的人可能是一个,说不定就记住你了)。一般来说,大致估估,如果说税可能是百分之二或三,那你起码还是得让人赚个20或30磅(当然你想试试再砍砍也可以,但可能难度会更大)。</p><p>于是我们最后两笔分别换的是640欧和645欧(645欧换了一家用类似方法换到的)。</p><h2 id="Tips"><a href="#Tips" class="headerlink" title="Tips"></a>Tips</h2><ul><li>现在意大利可用旅支消费的地方真不太多,我们去的罗马,佛罗伦萨,威尼斯中,只有威尼斯有几家;</li><li>去意大利想兑换欧元旅支,只能在标有change牌子的地方换(当然有的change是不接受旅支的,但很少)。American Express的直接兑换点,至少在意大利应该是没有了,所以没法无损失地换。但意大利的change的确不少,梵蒂冈附近就尤其多;</li><li>不要遇见一家,他报个很低的价你就接受了,也不要太信他的话,要知道这很可能是在坑你不清楚内情;</li><li>可以先问个两家,了解一下情况。大致估估如果说税可能是百分之二或三,那你起码还是得让人赚个20或30磅,先问问他们的报价,你可以把这个价格说成别家给你的价,去问他们能不能给你高点的价格。当然如果你脸皮薄不好意思胡扯,也可以就只是在这家价格比别家低的情况下把别家价格拿出来激激他们。</li></ul><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>以上就是所有关于旅支兑换的一些个人经历和小tips啦,当然这只是结合我们的个人体会总结的一些东西,还是要结合具体情况分析了。出去游玩肯定主要还是想多走走看看感受下,所以在经济条件允许的状况下也不建议大家在这件事上浪费太多时间,只要你自己觉得差不多能接受就行了。最后,还是想说,去意大利玩能不用旅行支票就还是别用了,毕竟真的挺麻烦还处处是坑!</p></span><span class=".en"><p>[scode type=”info”]<strong>Experience One</strong>: <strong>Do not use</strong> traveler’s checks if possible[/scode]<br>[scode type=”info”]<strong>Experience Two</strong>: The <strong>minimum handling fee</strong> for travel exchange is around 4%[/scode]</p><blockquote><p>If you don’t want to see the experience, you can directly transfer to the Tips where you can redeem traveler’s cheques at the end of the article!</p></blockquote><h2 id="My-experience"><a href="#My-experience" class="headerlink" title="My experience"></a>My experience</h2><p>During the Christmas holiday, I went to Europe with my roommates and a group of four on a DIY trip to 5 cities in Italy and Austria. Since the UK bank card has not been used for three months, it is not possible to apply for a visa by printing the record, so we chose another method-buying American Express’s Euro traveler’s cheque. As everyone knows, exchanging and using traveler’s checks is really a big pit.</p><p>According to the official website of traveler’s cheques, traveler’s cheques can be used directly in shops in many European cities. In this way, it’s definitely more cost-effective to spend it when traveling than to exchange it back in British pounds after returning to the UK. The British pound process requires a loss of 8%). Ran goose, we found through reading other people’s travel notes before departure that many stores in Europe cannot directly spend traveler’s checks (according to our actual travel situation later, we only saw the traveler’s check logo in several stores in Venice), so we When I decided to go, I changed all of them to Euros at the Red Marked Change at the airport.</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6ae04a26_721x412_8_null_normal.png" alt="Change"></p><p>But after I found the red Change at the first stop in Rome (pictured), I found that 700 euros could only give us more than 590 euros. This is really not the slightest loss. My subject checked the phone number of American Express on the spot. I called it and found that there is no location in Italy, but the other party suggested to change to the bank, saying that there is no loss (note that this is also a pit,,,). Since two people have already exchanged them, in order to stop the loss, we decided not to exchange the 700 Euro traveler’s cheques of the remaining two people, and kept them to the bank for exchange.</p><p>On the third day, we went to the Vatican to play. By the way, we went to the bank recommended by the staff of American Express nearby. We also called the Bank of China, but we were all told not to accept travel. How can this be neat?</p><p>At this time, I just found a bunch of changes around the Vatican, so I asked for a quote again. One of them originally only reported more than 590, but we heard that the other offered us a student discount of more than 610, and then it was a good deal and reported a 640. This is great, we are beginning to discover the doorway inside: there are actually no discounts, but I want to find an excuse to attract you. These changes are all profitable. You give them your travel, and they sell them to American Express elsewhere. There may be a little tax in the middle, but as long as they charge you at a lower price than the tax deducted If you buy it here, he will definitely make a profit (generally, he will make a lot of money), but it’s just the difference between earning more and less. And there are several changes in the local area. We mainly found the one with red change and the one with blue. If this family thinks that you are demanding and unacceptable, then the money will be made by others.</p><p>Therefore, at this time, if we want to get a higher offer, we have to pinpoint what is acceptable to others (it’s really too cruel to cut off people’s wealth, then it’s okay), and then let them have a sense of crisis. Increase the offer. You can ask a few companies first to see how much they generally give, and then tell him how much other companies give me a price. Next, this person may start to call the above to see what a higher price can be offered, and after a bunch of them, they will give you a slightly higher price. Haha, if you are not satisfied, you can ask another one. Ask (but be careful, if it is a different store in the same store, be careful, after all, there may be one person above them, maybe I will remember you). Generally speaking, if you say that the tax may be two or three percent, then you still have to earn a 20 or 30 pounds. (Of course, you can try to chop and chop again, but it may be more difficult. Big).</p><p>So our last two transactions were 640 Euros and 645 Euros respectively (645 Euros were replaced by a similar method).</p><h2 id="Tips-1"><a href="#Tips-1" class="headerlink" title="Tips"></a>Tips</h2><ul><li>There are not too many places in Italy for travel and consumption. Among the Rome, Florence, and Venice we go to, there are only a few in Venice;</li><li>If you want to exchange for Euro travel in Italy, you can only change it at the place marked with the change sign (Of course, some changes do not accept travel, but very few). There should be no direct exchange points for American Express, at least in Italy, so there is no way to exchange them without loss. But there are indeed many changes in Italy, especially near the Vatican;</li><li>Don’t meet a family, if he quotes a very low price, you will accept it, and don’t believe him too much. You must know that this is probably because you don’t know the inside story;</li><li>You can ask two families first to find out the situation. A rough estimate. If the tax may be two or three percent, then you still have to make people earn 20 or 30 pounds. First ask them for their quotation. You can say that the price is given to you by another family. Ask if they can give you a higher price. Of course, if you have a thin skin and are embarrassed to talk nonsense, you can just give them the price of this one when the price is lower than that of others.</li></ul><h2 id="to-sum-up"><a href="#to-sum-up" class="headerlink" title="to sum up"></a>to sum up</h2><p>The above is all the personal experiences and small tips about the exchange of travel expenses. Of course, these are just some things summarized based on our personal experience, we still need to analyze the specific situation. If you want to go out and play, you still want to walk around more to see how you feel. Therefore, it is not recommended that you waste too much time on this matter when economic conditions permit, as long as you feel that it is almost acceptable. Finally, I still want to say that if you don’t need traveler’s checks to play in Italy, you should not use it. After all, it is really troublesome and there are pits everywhere!</p></span>]]></content>
<categories>
<category> travel </category>
</categories>
<tags>
<tag> traveler&#39;s cheque </tag>
<tag> Europe </tag>
</tags>
</entry>
<entry>
<title>一键激活win10</title>
<link href="/tech/kms.html"/>
<url>/tech/kms.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>一键激活win10家庭版,专业版,企业版,教育版 φ( ̄∇ ̄o)</p></span><span class=".en"><p>Activate win10 Home Edition, Professional Edition, Enterprise Edition, Education Edition with one click φ( ̄∇ ̄o)</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><!--![](https://api.yimian.xyz/img/?path=wallpaper/img_2020-02-05_1920x1080_96_background_normal.jpg)--><h2 id="方法一-自动安装"><a href="#方法一-自动安装" class="headerlink" title="方法一(自动安装)"></a>方法一(自动安装)</h2><ul><li>使用此方法请先<strong>关闭所有杀毒软件</strong></li><li>使用此方法请先<strong>关闭所有杀毒软件</strong></li><li>使用此方法请先<strong>关闭所有杀毒软件</strong> </li></ul><blockquote><p>p.s. 如果不放心,请使用 方法二-源码安装</p></blockquote><hr><ul><li>点击<a href="https://github.com/IoTcat/kms/releases/download/v1.0/kms.exe" target="_blank" rel="noopener">这里</a>下载<code>exe</code>程序</li></ul><hr><ul><li>运行刚下载的程序。(<strong>请不要修改解压路径</strong>)</li><li>运行刚下载的程序。(<strong>请不要修改解压路径</strong>)</li></ul><hr><ul><li>点击 更多信息<code>-&gt;</code>仍然运行</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_f8f91201_532x498_8_null_normal.png" alt=""><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_5e6b7101_532x498_8_null_normal.png" alt=""></p><ul><li>输入数字进行选择。(可输入数字<code>4</code>获取汉语翻译!!)</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6f4f0165_609x226_8_null_normal.png" alt=""></p><hr><ul><li>耐心等待激活完成~ ::aru:proud:: </li></ul><blockquote><p>脚本已发送到桌面<code>kms.bat</code>,如果不需要您可以删除它~</p></blockquote><h2 id="方法二-源码安装"><a href="#方法二-源码安装" class="headerlink" title="方法二(源码安装)"></a>方法二(源码安装)</h2><ul><li>点击<a href="https://github.com/IoTcat/kms/archive/master.zip" target="_blank" rel="noopener">这里</a>下载压缩文件。</li></ul><hr><ul><li><strong>解压压缩文件</strong>(请<strong>务必解压</strong>,否则无法运行)</li><li><strong>解压压缩文件</strong>(请<strong>务必解压</strong>,否则无法运行)</li><li><strong>解压压缩文件</strong>(请<strong>务必解压</strong>,否则无法运行)</li></ul><hr><ul><li>双击运行文件夹中的<code>kms</code>或<code>kms.bat</code>。</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_c8d641e0_908x257_8_null_normal.png" alt="压缩文件示例"></p><ul><li>点击 更多信息<code>-&gt;</code>仍然运行</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_f8f91201_532x498_8_null_normal.png" alt=""><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_5e6b7101_532x498_8_null_normal.png" alt=""></p><ul><li>输入数字进行选择。(可输入数字<code>4</code>获取汉语翻译!!)</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6f4f0165_609x226_8_null_normal.png" alt=""></p><hr><ul><li>耐心等待激活完成~ ::aru:proud:: </li></ul><h2 id="进阶"><a href="#进阶" class="headerlink" title="进阶"></a>进阶</h2><h3 id="激活码"><a href="#激活码" class="headerlink" title="激活码"></a>激活码</h3><p>您的激活码将保存在<code>C:\Windows\kms.key</code></p><h3 id="运行日志"><a href="#运行日志" class="headerlink" title="运行日志"></a>运行日志</h3><ul><li>激活日志 <code>%temp%\kms.log</code></li><li>在本机尝试过的激活码 <code>%temp%\kms.tried_keys</code></li><li>kms服务器配置 <code>%temp%\kms.skms</code></li><li>ato输出信息 <code>%temp%\kms.ato</code></li></ul><h3 id="恢复未激活状态"><a href="#恢复未激活状态" class="headerlink" title="恢复未激活状态"></a>恢复未激活状态</h3><ul><li>进入<code>kms.bat</code>选择<code>3</code></li><li>等待完成卸载!!!</li></ul><h2 id="源码"><a href="#源码" class="headerlink" title="源码"></a>源码</h2><ul><li>项目地址:<a href="https://github.com/iotcat/kms" target="_blank" rel="noopener">iotcat/kms</a> </li></ul></span><span class=".en"><h2 id="Method-one-automatic-installation"><a href="#Method-one-automatic-installation" class="headerlink" title="Method one (automatic installation)"></a>Method one (automatic installation)</h2><ul><li>To use this method, please <strong>close all antivirus software</strong></li><li>To use this method, please <strong>close all antivirus software</strong></li><li>To use this method, please <strong>close all antivirus software</strong></li></ul><blockquote><p>p.s. If you are not assured, please use Method Two-Source Installation</p></blockquote><hr><ul><li>Click <a href="https://github.com/IoTcat/kms/releases/download/v1.0/kms.exe" target="_blank" rel="noopener">here</a> to download the <code>exe</code> program</li></ul><hr><ul><li>Run the program you just downloaded. (<strong>Please do not modify the decompression path</strong>)</li><li>Run the program you just downloaded. (<strong>Please do not modify the decompression path</strong>)</li></ul><hr><ul><li>Click More info <code>-&gt;</code> still running</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_f8f91201_532x498_8_null_normal.png" alt=""><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_5e6b7101_532x498_8_null_normal.png" alt=""></p><ul><li>Enter numbers to select. (You can enter the number <code>4</code> to get a Chinese translation!!)</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6f4f0165_609x226_8_null_normal.png" alt=""></p><hr><ul><li>Wait patiently for the activation to complete~ ::aru:proud::</li></ul><blockquote><p>The script has been sent to the desktop <code>kms.bat</code>, you can delete it if you don’t need it~</p></blockquote><h2 id="Method-two-source-installation"><a href="#Method-two-source-installation" class="headerlink" title="Method two (source installation)"></a>Method two (source installation)</h2><ul><li>Click <a href="https://github.com/IoTcat/kms/archive/master.zip" target="_blank" rel="noopener">here</a> to download the compressed file.</li></ul><hr><ul><li><strong>Unzip the compressed file</strong> (please <strong>unzip</strong>, otherwise it will not run)</li><li><strong>Unzip the compressed file</strong> (please <strong>unzip</strong>, otherwise it will not run)</li><li><strong>Unzip the compressed file</strong> (please <strong>unzip</strong>, otherwise it will not run)</li></ul><hr><ul><li>Double-click <code>kms</code> or <code>kms.bat</code> in the run folder.</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_c8d641e0_908x257_8_null_normal.png" alt="Compressed file example"></p><ul><li>Click More info <code>-&gt;</code> still running</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_f8f91201_532x498_8_null_normal.png" alt=""><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_5e6b7101_532x498_8_null_normal.png" alt=""></p><ul><li>Enter numbers to select. (You can enter the number <code>4</code> to get a Chinese translation!!)</li></ul><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6f4f0165_609x226_8_null_normal.png" alt=""></p><hr><ul><li>Wait patiently for the activation to complete~ ::aru:proud::</li></ul><h2 id="Advanced"><a href="#Advanced" class="headerlink" title="Advanced"></a>Advanced</h2><h3 id="Activation-code"><a href="#Activation-code" class="headerlink" title="Activation code"></a>Activation code</h3><p>Your activation code will be saved in <code>C:\Windows\kms.key</code></p><h3 id="Run-log"><a href="#Run-log" class="headerlink" title="Run log"></a>Run log</h3><ul><li>Activation log <code>%temp%\kms.log</code></li><li>Tried activation code <code>%temp%\kms.tried_keys</code> on this machine</li><li>kms server configuration <code>%temp%\kms.skms</code></li><li>ato output information <code>%temp%\kms.ato</code></li></ul><h3 id="Restore-inactive-state"><a href="#Restore-inactive-state" class="headerlink" title="Restore inactive state"></a>Restore inactive state</h3><ul><li>Enter <code>kms.bat</code> and select <code>3</code></li><li>Wait for the uninstallation to complete! ! !</li></ul><h2 id="Source-code"><a href="#Source-code" class="headerlink" title="Source code"></a>Source code</h2><ul><li>Project address: <a href="https://github.com/iotcat/kms" target="_blank" rel="noopener">iotcat/kms</a></span></li></ul>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> kms </tag>
<tag> win10 </tag>
</tags>
</entry>
<entry>
<title>部署新型冠状病毒API</title>
<link href="/tech/coro.html"/>
<url>/tech/coro.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>一分钟快速部署你自己的新型冠状病毒API ୧(๑•̀⌄•́๑)૭</p></span><span class=".en"><p>Deploy your own new coronavirus API in one minute ୧(๑•̀⌄•́๑)૭</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h1 id="coro-api"><a href="#coro-api" class="headerlink" title="coro-api"></a>coro-api</h1><p>新型冠状病毒 实时数据 api<br>项目Git地址: <a href="https://github.com/iotcat/coro-api" target="_blank" rel="noopener">iotcat/coro-api</a><br>项目npm地址: <a href="https://www.npmjs.com/package/coro-api" target="_blank" rel="noopener">iotcat/coro-api</a> </p><h2 id="API示例"><a href="#API示例" class="headerlink" title="API示例"></a>API示例</h2><h3 id="获取全部"><a href="#获取全部" class="headerlink" title="获取全部"></a>获取全部</h3><p><a href="https://api.yimian.xyz/coro" target="_blank" rel="noopener">https://api.yimian.xyz/coro</a></p><h3 id="根据省份"><a href="#根据省份" class="headerlink" title="根据省份"></a>根据省份</h3><p><a href="https://api.yimian.xyz/coro?province=%E5%B1%B1%E4%B8%9C" target="_blank" rel="noopener">https://api.yimian.xyz/coro?province=山东</a> </p><h3 id="根据城市"><a href="#根据城市" class="headerlink" title="根据城市"></a>根据城市</h3><p><a href="https://api.yimian.xyz/coro?city=%E6%B3%B0%E5%AE%89" target="_blank" rel="noopener">https://api.yimian.xyz/coro?city=泰安</a></p><h3 id="根据省和城-推荐"><a href="#根据省和城-推荐" class="headerlink" title="根据省和城(推荐)"></a>根据省和城(推荐)</h3><p><a href="https://api.yimian.xyz/coro?province=%E5%B1%B1%E4%B8%9C&city=%E6%B3%B0%E5%AE%89" target="_blank" rel="noopener">https://api.yimian.xyz/coro?province=山东&amp;city=泰安</a> </p><h2 id="快速部署"><a href="#快速部署" class="headerlink" title="快速部署"></a>快速部署</h2><h3 id="环境要求"><a href="#环境要求" class="headerlink" title="环境要求"></a>环境要求</h3><ul><li><code>nodeJS</code>支持<code>express</code>任意版本</li><li><code>git</code>任意版本</li></ul><h3 id="下载文件"><a href="#下载文件" class="headerlink" title="下载文件"></a>下载文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git clone https:&#x2F;&#x2F;github.com&#x2F;iotcat&#x2F;coro-api.git &amp; cd coro-api</span><br></pre></td></tr></table></figure><h3 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm install</span></span><br></pre></td></tr></table></figure><h3 id="启动"><a href="#启动" class="headerlink" title="启动"></a>启动</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> node index.js</span></span><br></pre></td></tr></table></figure><h3 id="访问"><a href="#访问" class="headerlink" title="访问"></a>访问</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http:&#x2F;&#x2F;localhost:17676</span><br></pre></td></tr></table></figure><h2 id="进阶"><a href="#进阶" class="headerlink" title="进阶"></a>进阶</h2><h3 id="GET参数"><a href="#GET参数" class="headerlink" title="GET参数"></a>GET参数</h3><table><thead><tr><th align="center">参数</th><th align="center">描述</th><th align="center">示例</th></tr></thead><tbody><tr><td align="center">province</td><td align="center">省份(国家)</td><td align="center">山东</td></tr><tr><td align="center">city</td><td align="center">城市</td><td align="center">泰安</td></tr></tbody></table><h3 id="修改端口"><a href="#修改端口" class="headerlink" title="修改端口"></a>修改端口</h3><p>从<code>index.js</code>第9行修改默认端口。</p><h3 id="禁止跨域"><a href="#禁止跨域" class="headerlink" title="禁止跨域"></a>禁止跨域</h3><p>注释掉<code>index.js</code>第13行。</p><h3 id="使用pm2守护进程"><a href="#使用pm2守护进程" class="headerlink" title="使用pm2守护进程"></a>使用pm2守护进程</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm i -g pm2</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> pm2 start index.js --name coro-api -o /var/<span class="built_in">log</span>/coro/api.out -e /var/<span class="built_in">log</span>/coro/api.err --watch</span></span><br></pre></td></tr></table></figure><h3 id="Nginx配置"><a href="#Nginx配置" class="headerlink" title="Nginx配置"></a>Nginx配置</h3><p>将以下内容加入<code>server{}</code>中 </p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> / &#123;</span><br><span class="line"> <span class="attribute">proxy_pass</span> http://127.0.0.1:17676;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如果你不是从根目录映射,记得去<code>index.js</code>中第11行<code>app.get(&#39;/&#39;, f)</code>修改成你的路径。</p><h3 id="爬虫配置"><a href="#爬虫配置" class="headerlink" title="爬虫配置"></a>爬虫配置</h3><p>爬虫使用<a href="https://github.com/iotcat/coro-py" target="_blank" rel="noopener">coro-py</a>, 请参考其文档。</p><h2 id="开源协议"><a href="#开源协议" class="headerlink" title="开源协议"></a>开源协议</h2><p>本项目使用MIT协议,允许非署名商业非商业使用。武汉加油!中国加油!!❤</p></span><span class=".en"><h1 id="coro-api-1"><a href="#coro-api-1" class="headerlink" title="coro-api"></a>coro-api</h1><p>Novel coronavirus real-time data api<br>Project Git address: <a href="https://github.com/iotcat/coro-api" target="_blank" rel="noopener">iotcat/coro-api</a><br>Project npm address: <a href="https://www.npmjs.com/package/coro-api" target="_blank" rel="noopener">iotcat/coro-api</a></p><h2 id="API-example"><a href="#API-example" class="headerlink" title="API example"></a>API example</h2><h3 id="Get-all"><a href="#Get-all" class="headerlink" title="Get all"></a>Get all</h3><p><a href="https://api.yimian.xyz/coro" target="_blank" rel="noopener">https://api.yimian.xyz/coro</a></p><h3 id="According-to-province"><a href="#According-to-province" class="headerlink" title="According to province"></a>According to province</h3><p><a href="https://api.yimian.xyz/coro?province=%E5%B1%B1%E4%B8%9C" target="_blank" rel="noopener">https://api.yimian.xyz/coro?province=Shandong</a></p><h3 id="According-to-the-city"><a href="#According-to-the-city" class="headerlink" title="According to the city"></a>According to the city</h3><p><a href="https://api.yimian.xyz/coro?city=%E6%B3%B0%E5%AE%89" target="_blank" rel="noopener">https://api.yimian.xyz/coro?city=泰安</a></p><h3 id="According-to-the-province-and-city-recommended"><a href="#According-to-the-province-and-city-recommended" class="headerlink" title="According to the province and city (recommended)"></a>According to the province and city (recommended)</h3><p><a href="https://api.yimian.xyz/coro?province=%E5%B1%B1%E4%B8%9C&city=%E6%B3%B0%E5%AE%89" target="_blank" rel="noopener">https://api.yimian.xyz/coro?province=Shandong&amp;city=Taian</a></p><h2 id="Quick-deployment"><a href="#Quick-deployment" class="headerlink" title="Quick deployment"></a>Quick deployment</h2><h3 id="Environmental-requirements"><a href="#Environmental-requirements" class="headerlink" title="Environmental requirements"></a>Environmental requirements</h3><ul><li><code>nodeJS</code> supports any version of <code>express</code></li><li>Any version of <code>git</code></li></ul><h3 id="download-file"><a href="#download-file" class="headerlink" title="download file"></a>download file</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ git clone https:&#x2F;&#x2F;github.com&#x2F;iotcat&#x2F;coro-api.git &amp; cd coro-api</span><br></pre></td></tr></table></figure><h3 id="Installation-dependencies"><a href="#Installation-dependencies" class="headerlink" title="Installation dependencies"></a>Installation dependencies</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm install</span></span><br></pre></td></tr></table></figure><h3 id="start-up"><a href="#start-up" class="headerlink" title="start up"></a>start up</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> node index.js</span></span><br></pre></td></tr></table></figure><h3 id="Access"><a href="#Access" class="headerlink" title="Access"></a>Access</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http:&#x2F;&#x2F;localhost:17676</span><br></pre></td></tr></table></figure><h2 id="Advanced"><a href="#Advanced" class="headerlink" title="Advanced"></a>Advanced</h2><h3 id="GET-parameters"><a href="#GET-parameters" class="headerlink" title="GET parameters"></a>GET parameters</h3><table><thead><tr><th align="center">Parameters</th><th align="center">Description</th><th align="center">Example</th></tr></thead><tbody><tr><td align="center">province</td><td align="center">Province (Country)</td><td align="center">Shandong</td></tr><tr><td align="center">city </td><td align="center">city</td><td align="center">Tai’an</td></tr></tbody></table><h3 id="Modify-port"><a href="#Modify-port" class="headerlink" title="Modify port"></a>Modify port</h3><p>Modify the default port from line 9 of <code>index.js</code>.</p><h3 id="Cross-domain-prohibited"><a href="#Cross-domain-prohibited" class="headerlink" title="Cross-domain prohibited"></a>Cross-domain prohibited</h3><p>Comment out line 13 of <code>index.js</code>.</p><h3 id="Use-pm2-daemon"><a href="#Use-pm2-daemon" class="headerlink" title="Use pm2 daemon"></a>Use pm2 daemon</h3><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm i -g pm2</span></span><br><span class="line"><span class="meta">$</span><span class="bash"> pm2 start index.js --name coro-api -o /var/<span class="built_in">log</span>/coro/api.out -e /var/<span class="built_in">log</span>/coro/api.err --watch</span></span><br></pre></td></tr></table></figure><h3 id="Nginx-configuration"><a href="#Nginx-configuration" class="headerlink" title="Nginx configuration"></a>Nginx configuration</h3><p>Add the following content to <code>server{}</code></p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">location</span> / &#123;</span><br><span class="line"> <span class="attribute">proxy_pass</span> http://127.0.0.1:17676;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>If you are not mapping from the root directory, remember to go to the 11th line of <code>index.js</code> and change <code>app.get(&#39;/&#39;, f)</code> to your path.</p><h3 id="Crawler-configuration"><a href="#Crawler-configuration" class="headerlink" title="Crawler configuration"></a>Crawler configuration</h3><p>The crawler uses <a href="https://github.com/iotcat/coro-py" target="_blank" rel="noopener">coro-py</a>, please refer to its documentation.</p><h2 id="Open-Source-Agreement"><a href="#Open-Source-Agreement" class="headerlink" title="Open Source Agreement"></a>Open Source Agreement</h2><p>This project uses the MIT protocol, allowing non-signed commercial and non-commercial use. Go Wuhan! Go China! ! ❤</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> Covid-19 </tag>
<tag> API </tag>
</tags>
</entry>
<entry>
<title>香辣牛肉面</title>
<link href="/cook/awesome-beef-noodle.html"/>
<url>/cook/awesome-beef-noodle.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>自研香辣牛肉面做法~</p></span><span class=".en"><p>Self-developed spicy beef noodle practice~</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="材料准备-两人份"><a href="#材料准备-两人份" class="headerlink" title="材料准备(两人份)"></a>材料准备(两人份)</h2><ul><li>面条</li><li>两个鸡蛋</li><li>两根英国大葱切末</li><li>两片姜切末</li><li>适量牛肉切丁</li><li>准备小碗放一个八角,桂皮,白扣,少许白胡椒粒</li></ul><h2 id="预备步骤"><a href="#预备步骤" class="headerlink" title="预备步骤"></a>预备步骤</h2><ul><li>热锅植物油香油煎鸡蛋</li><li>热水焯一下牛肉</li></ul><h2 id="核心步骤"><a href="#核心步骤" class="headerlink" title="核心步骤"></a>核心步骤</h2><ul><li>热锅植物油香油,放入葱白部分炝锅</li><li>加入开水和牛肉粒,加入碗中的调料,焖3分钟</li><li>加入一勺生抽,半勺老抽,一勺蚝油</li><li>加入适量鸡精和盐调鲜</li><li>加适量红油藤椒油调辣</li><li>放入面条,煮到熟</li></ul><h2 id="后续"><a href="#后续" class="headerlink" title="后续"></a>后续</h2><ul><li>面条添至碗中,盖上鸡蛋</li><li>加剩下的葱绿末</li></ul><h2 id="配图"><a href="#配图" class="headerlink" title="配图"></a>配图</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6dff3385_3648x2736_8_null_normal.jpeg" alt="香辣牛肉面-2020-01-19"></p></span><span class=".en"><h2 id="Material-preparation-for-two-persons"><a href="#Material-preparation-for-two-persons" class="headerlink" title="Material preparation (for two persons)"></a>Material preparation (for two persons)</h2><ul><li>Noodles</li><li>Two eggs</li><li>Two British scallions, minced</li><li>Two slices of ginger minced</li><li>Dice beef</li><li>Prepare a small bowl with anise, cinnamon, white button, and a little white pepper</li></ul><h2 id="Preliminary-steps"><a href="#Preliminary-steps" class="headerlink" title="Preliminary steps"></a>Preliminary steps</h2><ul><li>Hot pot vegetable oil fragrant fried eggs</li><li>Blanch the beef in hot water</li></ul><h2 id="Core-steps"><a href="#Core-steps" class="headerlink" title="Core steps"></a>Core steps</h2><ul><li>Hot pot vegetable oil sesame oil, put the scallion part into the pot</li><li>Add boiling water and beef cubes, add the seasoning in the bowl, and simmer for 3 minutes</li><li>Add a spoonful of light soy sauce, half a spoonful of dark soy sauce, and a spoonful of oyster sauce</li><li>Add appropriate amount of chicken essence and salt to adjust fresh</li><li>Add appropriate amount of red vine pepper oil to adjust spicy</li><li>Add the noodles and cook until cooked</li></ul><h2 id="Follow-up"><a href="#Follow-up" class="headerlink" title="Follow up"></a>Follow up</h2><ul><li>Add the noodles to the bowl and cover with eggs</li><li>Add the remaining green onion</li></ul><h2 id="With-pictures"><a href="#With-pictures" class="headerlink" title="With pictures"></a>With pictures</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_6dff3385_3648x2736_8_null_normal.jpeg" alt="Spicy Beef Noodle-2020-01-19"></p></span>]]></content>
<categories>
<category> cook </category>
</categories>
<tags>
<tag> beef </tag>
<tag> noodle </tag>
</tags>
</entry>
<entry>
<title>英国意大利申根签攻略</title>
<link href="/travel/ivisa-checklist.html"/>
<url>/travel/ivisa-checklist.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>在英国留学,圣诞去欧洲旅游,DIY了意大利申根签证。现在游完归来,总结一份申根签攻略。</p></span><span class=".en"><p>I studied in the UK, traveled to Europe on Christmas, and DIYed an Italian Schengen visa. Now come back from the tour, summarize a Schengen sign strategy.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="大致流程"><a href="#大致流程" class="headerlink" title="大致流程"></a>大致流程</h2><ul><li>仔细阅读<a href="https://www.vfsglobal.com/Italy/UK/London/tourist.html" target="_blank" rel="noopener">官网</a>条件,查看自己是否满足所有要求</li><li>尽早在线<a href="https://www.vfsglobal.com/Italy/UK/London/Schedule_an_Appointment1.html" target="_blank" rel="noopener">面签预约</a>(之后可以修改时间)</li><li>认真研究<a href="https://www.vfsglobal.com/Italy/UK/London/tourist.html" target="_blank" rel="noopener">需要的材料</a>(务必以官网为准)</li><li>生成visa申请表(<a href="https://www.vfsvisaonline.com/OnlineVaf-Italy?Country=QcpCgYPkPBcUOc3/C92SWQ==" target="_blank" rel="noopener">在线生成</a>)</li><li>准备其它材料</li></ul><h2 id="材料类别"><a href="#材料类别" class="headerlink" title="材料类别"></a>材料类别</h2><h3 id="常规签证材料"><a href="#常规签证材料" class="headerlink" title="常规签证材料"></a>常规签证材料</h3><ul><li>Visa申请表</li><li>身份证明</li><li>居住证明</li><li>照片</li></ul><h3 id="附加签证材料"><a href="#附加签证材料" class="headerlink" title="附加签证材料"></a>附加签证材料</h3><ul><li>工作证明</li><li>财产证明</li><li>旅行证明</li><li>住宿证明</li><li>保险证明</li></ul><h2 id="材料CheckList"><a href="#材料CheckList" class="headerlink" title="材料CheckList"></a>材料CheckList</h2><ul><li>visa申请表原件(在线生成后打印)</li><li>护照原件+复印件(黑白)</li><li>BRP原件+复印件(黑白)</li><li>一张证件照-与英国签证一致(<a href="https://www.vfsglobal.com/Italy/UK/London/tourist.html#tourist_photoSpecs" target="_blank" rel="noopener">要求</a>)</li><li>student letter</li><li>旅行支票原件+复印件或三个月银行流水</li><li>往返机票(姓名,日期,to&amp;from)</li><li>火车票(姓名,日期,to&amp;from)</li><li>住宿证明(姓名,日期,地址)</li><li>同行者名单</li><li>旅行保险证明(姓名,地理范围,保额)</li><li>面签预约证明复印件</li></ul><hr><ul><li>旅行行程单(方便跟签证官解释)</li><li>joint travel confirmation letter(如果某个车票或住宿证明上没有你的名字)</li><li>买票者的护照签名页复印件(如果某个车票或住宿证明上没有你的名字)</li></ul><h2 id="材料说明"><a href="#材料说明" class="headerlink" title="材料说明"></a>材料说明</h2><h3 id="visa申请表"><a href="#visa申请表" class="headerlink" title="visa申请表"></a>visa申请表</h3><ul><li>在线填写完第一页记得点SAVE, 记下页面右上角的Reference Number ::aru:shy::</li><li>下一次登录后点击上方<a href="https://www.vfsvisaonline.com/OnlineVAF-Italy/Applicant/Search" target="_blank" rel="noopener">RETRIEVE INCOMPLETE FILLED VAF</a>即可继续填写</li><li>填写参考<a href="https://travel.uk2hand.com/ukvisa/italy-schengen-visa/" target="_blank" rel="noopener">这篇攻略</a></li><li>单面黑白A4打印</li><li>打印好不要填写,不要签字,不要贴照片,到现场签证官会告诉你怎么办</li><li>不要装订,建议用环形针</li></ul><h3 id="Student-Letter"><a href="#Student-Letter" class="headerlink" title="Student Letter"></a>Student Letter</h3><ul><li>去学校FB开</li><li>需要有人签名,电子打印的签名不行</li><li>抬头需要写<code>Italy Consulate</code></li></ul><h3 id="旅行证明"><a href="#旅行证明" class="headerlink" title="旅行证明"></a>旅行证明</h3><ul><li>需要提供付过款的机票和跨城市的火车票</li><li>票的底部需要有网站链接</li><li>所有票上需要有你的名字</li><li>如果某张票没有你的名字,需要票上有名字的人提供签过字的<code>joint travel confirmation letter</code>和<code>护照复印件</code></li><li>可参考我们的<code>joint travel confirmation letter</code><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_65e72a51_634x740_8_null_normal.png" alt="joint letter"></li></ul><h3 id="住宿证明"><a href="#住宿证明" class="headerlink" title="住宿证明"></a>住宿证明</h3><ul><li><code>Booking Confirmation</code>上需要有<code>paid</code>字样</li><li>底部需要有网站链接</li><li>所有材料上需要有你的名字</li><li>如果没有你的名字,需要有名字的人提供签过字的<code>joint travel confirmation letter</code>和<code>护照复印件</code></li><li>建议从<code>Booking</code>等知名网站订购</li></ul><h3 id="保险证明"><a href="#保险证明" class="headerlink" title="保险证明"></a>保险证明</h3><ul><li>一定要覆盖旅程</li><li>保期越长,签证时间越长。。</li><li>我们选择的太平保险申根应急签证,供参考</li></ul><h3 id="预约证明"><a href="#预约证明" class="headerlink" title="预约证明"></a>预约证明</h3><ul><li>到楼下前台拿着预约信挂号</li><li>之后预约信就没用了</li></ul><hr><h2 id="成果"><a href="#成果" class="headerlink" title="成果"></a>成果</h2><p>最后展示一下我拿到的签证 ::aru:cheer::<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_f5690b2c_3968x2976_8_null_normal.jpeg" alt="visa"></p></span><span class=".en"><h2 id="General-process"><a href="#General-process" class="headerlink" title="General process"></a>General process</h2><ul><li>Read <a href="https://www.vfsglobal.com/Italy/UK/London/tourist.html" target="_blank" rel="noopener">Official Website</a> conditions carefully to check whether you meet all the requirements</li><li>Online <a href="https://www.vfsglobal.com/Italy/UK/London/Schedule_an_Appointment1.html" target="_blank" rel="noopener">Interview Appointment</a> online as early as possible (the time can be modified later)</li><li>Carefully study the <a href="https://www.vfsglobal.com/Italy/UK/London/tourist.html" target="_blank" rel="noopener">required materials</a> (must follow the official website)</li><li>Generate visa application form (<a href="https://www.vfsvisaonline.com/OnlineVaf-Italy?Country=QcpCgYPkPBcUOc3/C92SWQ==" target="_blank" rel="noopener">Online generation</a>)</li><li>Prepare other materials</li></ul><h2 id="Material-category"><a href="#Material-category" class="headerlink" title="Material category"></a>Material category</h2><h3 id="Regular-visa-materials"><a href="#Regular-visa-materials" class="headerlink" title="Regular visa materials"></a>Regular visa materials</h3><ul><li>Visa application form</li><li>personal I.D</li><li>Proof of residence</li><li>Photos</li></ul><h3 id="Additional-visa-materials"><a href="#Additional-visa-materials" class="headerlink" title="Additional visa materials"></a>Additional visa materials</h3><ul><li>Proof of employment</li><li>Proof of property</li><li>Travel certificate</li><li>Proof of accommodation</li><li>Insurance certificate</li></ul><h2 id="Material-CheckList"><a href="#Material-CheckList" class="headerlink" title="Material CheckList"></a>Material CheckList</h2><ul><li>Original visa application form (print after online generation)</li><li>Original passport + photocopy (black and white)</li><li>BRP original + copy (black and white)</li><li>A passport photo-consistent with the UK visa (<a href="https://www.vfsglobal.com/Italy/UK/London/tourist.html#tourist_photoSpecs" target="_blank" rel="noopener">Requirements</a>)</li><li>student letter</li><li>Original traveler’s check + copy or three-month bank account</li><li>Round-trip air ticket (name, date, to&amp;from)</li><li>Train ticket (name, date, to&amp;from)</li><li>Proof of accommodation (name, date, address)</li><li>Companion list</li><li>Travel insurance certificate (name, geographic area, insurance amount)</li><li>Copy of appointment certificate</li></ul><hr><ul><li>Travel itinerary (for easy explanation with visa officer)</li><li>joint travel confirmation letter (if your name is not on a certain ticket or accommodation certificate)</li><li>Copy of the passport signature page of the ticket purchaser (if your name is not on the ticket or accommodation certificate)</li></ul><h2 id="Material-Description"><a href="#Material-Description" class="headerlink" title="Material Description"></a>Material Description</h2><h3 id="visa-application-form"><a href="#visa-application-form" class="headerlink" title="visa application form"></a>visa application form</h3><ul><li>After filling out the first page online, remember to click SAVE, and write down the Reference Number ::aru:shy::</li><li>Click <a href="https://www.vfsvisaonline.com/OnlineVAF-Italy/Applicant/Search" target="_blank" rel="noopener">RETRIEVE INCOMPLETE FILLED VAF</a> above to continue to fill in after logging in next time</li><li>Fill in the reference <a href="https://travel.uk2hand.com/ukvisa/italy-schengen-visa/" target="_blank" rel="noopener">this guide</a></li><li>Single-sided black and white A4 printing</li><li>After printing, do not fill in, do not sign, do not post photos, the visa officer will tell you what to do</li><li>Do not staple, it is recommended to use a loop pin</li></ul><h3 id="Student-Letter-1"><a href="#Student-Letter-1" class="headerlink" title="Student Letter"></a>Student Letter</h3><ul><li>Go to school FB to open</li><li>A signature is required, and an electronically printed signature will not work</li><li>Head up to write <code>Italy Consulate</code></li></ul><h3 id="Travel-Proof"><a href="#Travel-Proof" class="headerlink" title="Travel Proof"></a>Travel Proof</h3><ul><li>Need to provide paid air tickets and inter-city train tickets<ul><li>A website link is required at the bottom of the ticket</li></ul></li><li>All tickets need to have your name</li><li>If a ticket does not have your name, the person named on the ticket is required to provide a signed <code>joint travel confirmation letter</code> and a copy of <code>passport</code></li><li>Please refer to our <code>joint travel confirmation letter</code><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_65e72a51_634x740_8_null_normal.png" alt="joint letter"></li></ul><h3 id="Proof-of-Accommodation"><a href="#Proof-of-Accommodation" class="headerlink" title="Proof of Accommodation"></a>Proof of Accommodation</h3><ul><li><code>paid</code> is required on <code>Booking Confirmation</code></li><li>A website link is required at the bottom</li><li>All materials need to have your name</li><li>If you do not have your name, the person who has the name needs to provide a signed <code>joint travel confirmation letter</code> and a copy of <code>passport</code></li><li>It is recommended to order from well-known websites such as <code>Booking</code></li></ul><h3 id="Insurance-Certificate"><a href="#Insurance-Certificate" class="headerlink" title="Insurance Certificate"></a>Insurance Certificate</h3><ul><li>Be sure to cover the journey</li><li>The longer the guarantee period, the longer the visa period. .</li><li>We chose Taiping Insurance Schengen emergency visa for reference</li></ul><h3 id="Appointment-Proof"><a href="#Appointment-Proof" class="headerlink" title="Appointment Proof"></a>Appointment Proof</h3><ul><li>Go to the front desk downstairs to register with the appointment letter</li><li>After that, the appointment letter is useless</li></ul><hr><h2 id="Results"><a href="#Results" class="headerlink" title="Results"></a>Results</h2><p>Finally, let me show the visa I got~<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_f5690b2c_3968x2976_8_null_normal.jpeg" alt="visa"></p></span>]]></content>
<categories>
<category> travel </category>
</categories>
<tags>
<tag> uk </tag>
<tag> italy </tag>
<tag> visa </tag>
</tags>
</entry>
<entry>
<title>今天很开心,在这里留个空</title>
<link href="/life/happy.html"/>
<url>/life/happy.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>先在这里留个空,以后慢慢填~</p></span><span class=".en"><p>Leave a blank here first, then fill it in slowly~</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>φ( ̄∇ ̄o)</p></span><span class=".en"><p>φ( ̄∇ ̄o)</p></span>]]></content>
<categories>
<category> life </category>
</categories>
<tags>
<tag> love </tag>
</tags>
</entry>
<entry>
<title>Liverpool 学生公寓条件调研</title>
<link href="/life/liverpool-accom-inves.html"/>
<url>/life/liverpool-accom-inves.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>为了更清晰更直观的选择出明年居住的公寓,本文汇总了网络上对各公寓的评价信息,供决策参考。</p></span><span class=".en"><p>In order to more clearly and intuitively choose the apartment to live in next year, this article summarizes the evaluation information of each apartment on the Internet for decision-making reference.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>[scode type=”green”]大家积极在评论区补充哦,评论推荐使用qq邮箱[/scode]<br>[scode type=”yellow”]持续更新中…[/scode]<br>[scode type=”blue”]望大家能够<strong>补充</strong>更多房源,以便调查[/scode]</p><p><strong>所有步行距离以Guild为中心!!</strong> </p><h2 id="Dover-Court-我们的最终选择"><a href="#Dover-Court-我们的最终选择" class="headerlink" title="Dover Court (我们的最终选择)"></a>Dover Court (我们的最终选择)</h2><ul><li><code>步行距离</code>: 8 min (西北)</li><li><code>google地图</code>: <a href="https://www.google.com/maps/dir/53.4060943,-2.9635088/dover+court/@53.4073115,-2.9710734,16z/data=!3m1!4b1!4m9!4m8!1m1!4e1!1m5!1m1!1s0x487b2117f02af11d:0xa8248cb9d60eb03d!2m2!1d-2.9700754!2d53.408129" target="_blank" rel="noopener">Dover Court</a></li><li><code>Official Guide</code>: <a href="https://www.youtube.com/watch?v=lMyNP1edztE" target="_blank" rel="noopener">Dover Court</a></li><li><code>优点</code>: 距Lidl近,安静,管理好,安全,定期有人清洁,social place好,楼下自习室很安静</li><li><code>缺点</code>: 房间隔音一般,部分房间小,有的地方天花板低</li><li><code>价格</code>: £155.54 pw (Last Year)</li></ul><h2 id="Horizon-Heights"><a href="#Horizon-Heights" class="headerlink" title="Horizon Heights"></a>Horizon Heights</h2><ul><li><code>步行距离</code>: 14 min (西)</li><li><code>google地图</code>: <a href="https://www.google.com/maps/place/Unite+Students+-+Horizon+Heights/@53.4063639,-2.9762904,14.73z/data=!4m5!3m4!1s0x0:0xeb3661ed145a9ca6!8m2!3d53.4068673!4d-2.9785214" target="_blank" rel="noopener">Horizon Heights</a></li></ul><h2 id="St-Luke’s-View"><a href="#St-Luke’s-View" class="headerlink" title="St Luke’s View"></a>St Luke’s View</h2><ul><li><code>步行距离</code>: 13 min (西南)</li><li><code>google地图</code>: <a href="https://www.google.com/maps/place/Unite+Students+-+St+Luke' target="_blank" rel="noopener"s+View,+Liverpool/@53.4032851,-2.9832055,15.1z/data=!4m5!3m4!1s0x487b2123d300f157:0x7aa4464b82196264!8m2!3d53.4026763!4d-2.975033">St Luke’s View</a></li></ul><h2 id="Apollo-Court"><a href="#Apollo-Court" class="headerlink" title="Apollo Court"></a>Apollo Court</h2><ul><li><code>步行距离</code>: 11 min (西北)</li><li><code>同学反映</code>: 不安静(老雷)</li></ul><h2 id="Capital-Gate"><a href="#Capital-Gate" class="headerlink" title="Capital Gate"></a>Capital Gate</h2><ul><li><code>步行距离</code>: 7 min (西北)</li></ul><h2 id="Grand-Central"><a href="#Grand-Central" class="headerlink" title="Grand Central"></a>Grand Central</h2><ul><li><code>步行距离</code>: 12 min (西)</li></ul><h2 id="Philharmonic-Court"><a href="#Philharmonic-Court" class="headerlink" title="Philharmonic Court"></a>Philharmonic Court</h2><ul><li><code>步行距离</code>: 12 min (南)</li></ul><h2 id="The-Railyard"><a href="#The-Railyard" class="headerlink" title="The Railyard"></a>The Railyard</h2><ul><li><code>步行距离</code>: 9 min (东)</li></ul><h2 id="Myrtle-Court"><a href="#Myrtle-Court" class="headerlink" title="Myrtle Court"></a>Myrtle Court</h2><ul><li><code>步行距离</code>: 9 min (东)</li></ul><h2 id="Larch-House"><a href="#Larch-House" class="headerlink" title="Larch House"></a>Larch House</h2><ul><li><code>步行距离</code>: 7 min (西)</li></ul><h2 id="IQ"><a href="#IQ" class="headerlink" title="IQ"></a>IQ</h2><ul><li><code>步行距离</code>: 9 min (西北) </li><li>人脉: 老叶,灯泡</li></ul><h2 id="The-Arch"><a href="#The-Arch" class="headerlink" title="The Arch"></a>The Arch</h2><ul><li><code>步行距离</code>: 18 min (西南)</li></ul><h2 id="Albert-Court"><a href="#Albert-Court" class="headerlink" title="Albert Court"></a>Albert Court</h2><ul><li><code>步行距离</code>: 10 min (北)</li></ul><h2 id="St-Andrews-Place"><a href="#St-Andrews-Place" class="headerlink" title="St Andrews Place"></a>St Andrews Place</h2><ul><li><code>步行距离</code>: 10 min (西南)</li></ul><h2 id="The-Ascent"><a href="#The-Ascent" class="headerlink" title="The Ascent"></a>The Ascent</h2><ul><li><code>步行距离</code>: 13 min (西)</li></ul><h2 id="Lee-Court"><a href="#Lee-Court" class="headerlink" title="Lee Court"></a>Lee Court</h2><ul><li><code>步行距离</code>: 10 min (北)</li></ul><h2 id="X1-Liverpool-One"><a href="#X1-Liverpool-One" class="headerlink" title="X1 Liverpool One"></a>X1 Liverpool One</h2><ul><li><code>步行距离</code>: 18 min (西)</li></ul><h2 id="X1-The-Edge"><a href="#X1-The-Edge" class="headerlink" title="X1 The Edge"></a>X1 The Edge</h2><ul><li><code>步行距离</code>: 12 min (西北)</li><li><code>其它</code>: 快递可以寄到Cambridge Court (梁斌)</li></ul><h2 id="Cambridge-Court"><a href="#Cambridge-Court" class="headerlink" title="Cambridge Court"></a>Cambridge Court</h2><ul><li><code>步行距离</code>: 8 min (南)</li><li><code>google地图</code>: <a href="https://www.google.com/maps/dir/53.4060907,-2.963637/Cambridge+Ct,+Liverpool/@53.4043312,-2.9678762,17z/data=!3m1!4b1!4m9!4m8!1m1!4e1!1m5!1m1!1s0x487b2118d373aed7:0x8824353bb8192424!2m2!1d-2.967738!2d53.4026346" target="_blank" rel="noopener">Cambridge Court</a></li><li><code>缺点</code>: 隔音不好,地毯潮湿,条件差</li></ul><h2 id="Vita-Student-Liverpool"><a href="#Vita-Student-Liverpool" class="headerlink" title="Vita Student Liverpool"></a>Vita Student Liverpool</h2><ul><li><code>步行距离</code>: 21 min (西)</li></ul><h2 id="Liberty-Park"><a href="#Liberty-Park" class="headerlink" title="Liberty Park"></a>Liberty Park</h2><ul><li><code>缺点</code>: 一楼二楼隔音不好</li><li><code>优点</code>: 回字形楼中间有一个小花园(娇娇,欣怡)</li></ul></span><span class=".en"><p>[scode type=”green”] Everyone is actively adding in the comment area, comments recommend using qq mailbox[/scode]<br>[scode type=”yellow”]Continuously updating…[/scode]<br>[scode type=”blue”]I hope you can <strong>add</strong> more listings for investigation[/scode]</p><p><strong>All walking distances are centered on Guild! !</strong></p><h2 id="Dover-Court-Our-final-choice"><a href="#Dover-Court-Our-final-choice" class="headerlink" title="Dover Court (Our final choice)"></a>Dover Court (Our final choice)</h2><ul><li><code>walking distance</code>: 8 min (Northwest)</li><li><code>google map</code>: <a href="https://www.google.com/maps/dir/53.4060943,-2.9635088/dover+court/@53.4073115,-2.9710734,16z/data=!3m1!4b1!4m9!4m8!1m1!4e1!1m5!1m1!1s0x487b2117f02af11d:0xa8248cb9d60eb03d!2m2!1d-2.9700754!2d53.408129" target="_blank" rel="noopener">Dover Court</a></li><li><code>Official Guide</code>: <a href="https://www.youtube.com/watch?v=lMyNP1edztE" target="_blank" rel="noopener">Dover Court</a></li><li><code>Pros</code>: Close to Lidl, quiet, well managed, safe, cleaned regularly, good social place, quiet study room downstairs</li><li><code>Disadvantages</code>: Room soundproofing is average, some rooms are small, and some places have low ceilings</li><li><code>Price</code>: £155.54 pw (Last Year)</li></ul><h2 id="Horizon-Heights-1"><a href="#Horizon-Heights-1" class="headerlink" title="Horizon Heights"></a>Horizon Heights</h2><ul><li><code>walking distance</code>: 14 min (West)</li><li><code>google map</code>: <a href="https://www.google.com/maps/place/Unite+Students+-+Horizon+Heights/@53.4063639,-2.9762904,14.73z/data=!4m5!3m4!1s0x0:0xeb3661ed145a9ca6!8m2!3d53.4068673!4d-2.9785214" target="_blank" rel="noopener">Horizon Heights</a></li></ul><h2 id="St-Luke’s-View-1"><a href="#St-Luke’s-View-1" class="headerlink" title="St Luke’s View"></a>St Luke’s View</h2><ul><li><code>walking distance</code>: 13 min (southwest)</li><li><code>google map</code>: <a href="https://www.google.com/maps/place/Unite+Students+-+St+Luke' target="_blank" rel="noopener"s+View,+Liverpool/@53.4032851,-2.9832055,15.1z/data=!4m5!3m4!1s0x487b2123d300f157:0x7aa4464b82196264!8m2!3d53.4026763!4d-2.975033">St Luke’s View</a></li></ul><h2 id="Apollo-Court-1"><a href="#Apollo-Court-1" class="headerlink" title="Apollo Court"></a>Apollo Court</h2><ul><li><code>Walking distance</code>: 11 min (Northwest)</li><li><code>Classmates&#39; reflections</code>: Not quiet (Lao Lei)</li></ul><h2 id="Capital-Gate-1"><a href="#Capital-Gate-1" class="headerlink" title="Capital Gate"></a>Capital Gate</h2><ul><li><code>walking distance</code>: 7 min (Northwest)</li></ul><h2 id="Grand-Central-1"><a href="#Grand-Central-1" class="headerlink" title="Grand Central"></a>Grand Central</h2><ul><li><code>walking distance</code>: 12 min (West)</li></ul><h2 id="Philharmonic-Court-1"><a href="#Philharmonic-Court-1" class="headerlink" title="Philharmonic Court"></a>Philharmonic Court</h2><ul><li><code>Walking distance</code>: 12 min (South)</li></ul><h2 id="The-Railyard-1"><a href="#The-Railyard-1" class="headerlink" title="The Railyard"></a>The Railyard</h2><ul><li><code>walking distance</code>: 9 min (East)</li></ul><h2 id="Myrtle-Court-1"><a href="#Myrtle-Court-1" class="headerlink" title="Myrtle Court"></a>Myrtle Court</h2><ul><li><code>walking distance</code>: 9 min (East)</li></ul><h2 id="Larch-House-1"><a href="#Larch-House-1" class="headerlink" title="Larch House"></a>Larch House</h2><ul><li><code>walking distance</code>: 7 min (West)</li></ul><h2 id="IQ-1"><a href="#IQ-1" class="headerlink" title="IQ"></a>IQ</h2><ul><li><code>walking distance</code>: 9 min (Northwest)</li><li>Connection: Lao Ye, Bulb</li></ul><h2 id="The-Arch-1"><a href="#The-Arch-1" class="headerlink" title="The Arch"></a>The Arch</h2><ul><li><code>walking distance</code>: 18 min (southwest)</li></ul><h2 id="Albert-Court-1"><a href="#Albert-Court-1" class="headerlink" title="Albert Court"></a>Albert Court</h2><ul><li><code>walking distance</code>: 10 min (north)</li></ul><h2 id="St-Andrews-Place-1"><a href="#St-Andrews-Place-1" class="headerlink" title="St Andrews Place"></a>St Andrews Place</h2><ul><li><code>Walking distance</code>: 10 min (Southwest)</li></ul><h2 id="The-Ascent-1"><a href="#The-Ascent-1" class="headerlink" title="The Ascent"></a>The Ascent</h2><ul><li><code>walking distance</code>: 13 min (West)</li></ul><h2 id="Lee-Court-1"><a href="#Lee-Court-1" class="headerlink" title="Lee Court"></a>Lee Court</h2><ul><li><code>walking distance</code>: 10 min (north)</li></ul><h2 id="X1-Liverpool-One-1"><a href="#X1-Liverpool-One-1" class="headerlink" title="X1 Liverpool One"></a>X1 Liverpool One</h2><ul><li><code>walking distance</code>: 18 min (West)</li></ul><h2 id="X1-The-Edge-1"><a href="#X1-The-Edge-1" class="headerlink" title="X1 The Edge"></a>X1 The Edge</h2><ul><li><code>Walking distance</code>: 12 min (Northwest)</li><li><code>Others</code>: Express can be sent to Cambridge Court (Liang Bin)</li></ul><h2 id="Cambridge-Court-1"><a href="#Cambridge-Court-1" class="headerlink" title="Cambridge Court"></a>Cambridge Court</h2><ul><li><code>walking distance</code>: 8 min (south)</li><li><code>google map</code>: <a href="https://www.google.com/maps/dir/53.4060907,-2.963637/Cambridge+Ct,+Liverpool/@53.4043312,-2.9678762,17z/data=!3m1!4b1!4m9!4m8!1m1!4e1!1m5!1m1!1s0x487b2118d373aed7:0x8824353bb8192424!2m2!1d-2.967738!2d53.4026346" target="_blank" rel="noopener">Cambridge Court</a></li><li><code>Disadvantages</code>: Poor sound insulation, damp carpets, poor conditions</li></ul><h2 id="Vita-Student-Liverpool-1"><a href="#Vita-Student-Liverpool-1" class="headerlink" title="Vita Student Liverpool"></a>Vita Student Liverpool</h2><ul><li><code>walking distance</code>: 21 min (West)</li></ul><h2 id="Liberty-Park-1"><a href="#Liberty-Park-1" class="headerlink" title="Liberty Park"></a>Liberty Park</h2><ul><li><code>Disadvantages</code>: Sound insulation is not good on the first and second floors</li><li><code>Advantages</code>: There is a small garden in the middle of Huizi Building (Jiaojiao, Xinyi)</li></ul></span>]]></content>
<categories>
<category> life </category>
</categories>
<tags>
<tag> uk </tag>
<tag> liverpool </tag>
<tag> investigation </tag>
<tag> accomodation </tag>
</tags>
</entry>
<entry>
<title>公共开支结算系统</title>
<link href="/tech/crown-place-erp.html"/>
<url>/tech/crown-place-erp.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>在英国留学与4个室友合租,为了更好的控制和监管公共支出,以及维持彼此之间的公共支出平衡,我利用迎新周三天时间设计并开发除了此ERP公共开支计划系统。希望此系统能够便捷接下来一年的生活,减少大家之间的矛盾,促使充满幸福感的公共支出项目持久化OωO</p></span><span class=".en"><p>I studied in the UK and shared with 4 roommates. In order to better control and monitor public expenditures and maintain the balance of public expenditures between each other, I designed and developed this ERP public expenditure planning system during the welcome Wednesday. I hope that this system will make life easier for the next year, reduce conflicts between everyone, and promote the sustainability of public expenditure projects full of happiness OωO</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="1-功能介绍"><a href="#1-功能介绍" class="headerlink" title="1.功能介绍"></a>1.功能介绍</h2><ul><li>统计日均周均流水,让公共支出可视化</li><li>用户申报一次公共支出,并提交发票照片留证</li><li>监视各成员间支出不均衡程度,计算方差,并可视化显示</li><li>对比本周与上周的开支,给出增减比例</li><li>当存在一人支出超出均值阈值,并且存在至少一人支出少于均值阈值,则会邮件这两个人产生一次内部交易</li><li>邮件通知内部交易的双方</li><li>当上例中收款人收到款项后,需要到平台确认收到</li><li>平台所有历史公共开支及发票可查</li></ul><h2 id="2-系统架构"><a href="#2-系统架构" class="headerlink" title="2.系统架构"></a>2.系统架构</h2><h3 id="2-1-前端"><a href="#2-1-前端" class="headerlink" title="2.1 前端"></a>2.1 前端</h3><p>前端基于一个网上找到的比特币网站平台模板,深度改造实现。值得一提的是,前端使用<a href="https://github.com/iotcat/ushio-js" target="_blank" rel="noopener">Ushio-js项目</a>作为安全及日志插件,并得到了<a href="https://ushio.yimian.xyz" target="_blank" rel="noopener">Ushio</a>系统做背后支持。</p><h3 id="2-2-后端"><a href="#2-2-后端" class="headerlink" title="2.2 后端"></a>2.2 后端</h3><p>后端使用php语言编写。提供5个接口,分别提供获取账户事件,获取内部流通信息,获取公共支出信息,获取周报表,操作的功能。</p><p>mail系统使用<a href="https://www.eee.dog/tech/mail-api.html">Yimian Mail API</a>快速构建。</p><h3 id="2-3-数据库"><a href="#2-3-数据库" class="headerlink" title="2.3 数据库"></a>2.3 数据库</h3><p>数据库使用yimian-db/mysql。构建了三个表,分别用于存储流水,公共支出详情,内部流通。</p><h3 id="2-4-图片上传"><a href="#2-4-图片上传" class="headerlink" title="2.4 图片上传"></a>2.4 图片上传</h3><p>直接引用<a href="https://imgbed.yimian.xyz" target="_blank" rel="noopener">呓喵酱の图床</a>代码,少量改写。</p><h3 id="2-5-用户系统"><a href="#2-5-用户系统" class="headerlink" title="2.5 用户系统"></a>2.5 用户系统</h3><p>目前用额外网页简单实现,等待<a href="https://github.com/iotcat/ushio-auth" target="_blank" rel="noopener">ushio-auth项目</a>完成后统一整合。</p><h2 id="3-外观"><a href="#3-外观" class="headerlink" title="3. 外观"></a>3. 外观</h2><p>没啥可说的,摆图,自己看<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_ed08c497_1080x6654_8_null_normal.jpeg" alt="imgbed_ed08c497"></p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_ea04ad82_1080x5082_8_null_normal.jpeg" alt="imgbed_ea04ad82"></p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_a8b3adb0_1080x2160_8_null_normal.jpeg" alt="imgbed_a8b3adb0"></p><hr><p><strong>2020-03-22 更新</strong> </p><p>由于疫情原因,考虑到大家都已撤回中国。为节约服务器费用,停止提供服务。</p><p>结合过去半年运行状况,我做了一些分析总结:</p><h2 id="主要收获"><a href="#主要收获" class="headerlink" title="主要收获"></a>主要收获</h2><ol><li>分析客户真需求的经验</li><li>快速搭建生产环境网站工具的能力</li><li>室友对我能力的认可</li></ol><h2 id="开发方法论"><a href="#开发方法论" class="headerlink" title="开发方法论"></a>开发方法论</h2><ol><li>基于一系列自己过去的项目,3天时间快速立项并投入使用</li><li>仔细研究需求,判断哪些是真需求,哪些是伪需求。</li></ol><h2 id="遇到的挑战"><a href="#遇到的挑战" class="headerlink" title="遇到的挑战"></a>遇到的挑战</h2><ol><li>快速开发,因为大家在抵达英国后已经开始大量花钱买公共用品,因此,急需使用这个系统</li><li>算法一定要稳定可靠,因为是牵扯到大家钱的东西</li><li>本系统的目的是为了更加方便,把会计的工作交给系统来自动化处理。以此一定要在保证公平的前提下,使得大家之间的内部交易的次数尽可能少,且指示明确。</li><li>如何让大家对系统产生信任。</li></ol><h2 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h2><ol><li>基于大量自己先前的项目。用1天开发成型,1天测试debug,1天优化前端,加入方差,百分比等功能。</li><li>参考记账表,使用了表格模式。每次有新的上传,就会实时计算出新的状态。多次测试,充分验证后才投入使用。</li><li>使用“平衡”的构想,关注差异,当差异过大时使支出最多者和支出最少者产生内部交易。且内部交易值为整数。比如我们生产场景应用的是20磅。</li><li>在系统算法稳定的情况下,参考支付宝的设计。内部交易有两个步骤。首选支出者和收入者都收到邮件,告知给谁(从谁收),多少钱。然后在支出者把钱给收入者后,收入者需要登录网页或从邮件链接进行确认。截至此时,系统才认为一笔内部交易完成。</li></ol><hr><p><strong>2020-9-8 更新</strong></p><p>基于Ushio用户系统,结合过去半年的运行情况和大家的需求变化,我重构并开发出了新一版的公共支出系统。</p><h2 id="新功能"><a href="#新功能" class="headerlink" title="新功能"></a>新功能</h2><ul><li>实现了Ushio用户系统的接入</li><li>用户能够随时注册并新建公共账单</li><li>同一个用户能够同时在多个账单</li><li>用户能够随时加入公共账单</li><li>用户能够随时结算并退出某个公共账单</li><li>更加智能的结算算法</li><li>使用LocalStorage优化了二次访问的速度</li></ul><h2 id="体验"><a href="#体验" class="headerlink" title="体验"></a>体验</h2><p>cp-acc现在已经对公众开放,您可以进入其<a href="https://cp-acc.yimian.xyz" target="_blank" rel="noopener">网站</a>进行体验。不过在体验前,您需要先通过ushio用户系统使用您的邮箱登录,以便接收账单消息。</p></span><span class=".en"><h2 id="1-Function-introduction"><a href="#1-Function-introduction" class="headerlink" title="1. Function introduction"></a>1. Function introduction</h2><ul><li>Calculate the daily average weekly flow rate to visualize public expenditure</li><li>The user declares a public expenditure and submits the invoice photo certificate</li><li>Monitor the disequilibrium of expenditure among members, calculate the variance, and display it visually</li><li>Compare spending this week and last week, and give the percentage increase or decrease</li><li>When there is one person whose expenditure exceeds the average threshold, and there is at least one person whose expenditure is less than the average threshold, the two people will be emailed to generate an internal transaction</li><li>When the recipient receives the money in the above example, he needs to go to the platform to confirm receipt</li><li>All historical public expenditures and invoices on the platform can be checked</li></ul><h2 id="2-System-Architecture"><a href="#2-System-Architecture" class="headerlink" title="2. System Architecture"></a>2. System Architecture</h2><h3 id="2-1-Frontend"><a href="#2-1-Frontend" class="headerlink" title="2.1 Frontend"></a>2.1 Frontend</h3><p>The front end is based on a Bitcoin website platform template found on the Internet, and a deep transformation is realized. It is worth mentioning that the front end uses <a href="https://github.com/iotcat/ushio-js" target="_blank" rel="noopener">Ushio-js project</a> as a security and logging plug-in, and got <a href="https://ushio.yimian.xyz" target="_blank" rel="noopener">Ushio</a> The system does behind the scenes.</p><h3 id="2-2-Backend"><a href="#2-2-Backend" class="headerlink" title="2.2 Backend"></a>2.2 Backend</h3><p>The backend is written in php language. Provides 5 interfaces, which respectively provide the functions of obtaining account events, obtaining internal circulation information, obtaining public expenditure information, obtaining weekly statements, and operating.</p><p>The mail system is quickly constructed using <a href="https://www.eee.dog/tech/mail-api.html">Yimian Mail API</a>.</p><h3 id="2-3-Database"><a href="#2-3-Database" class="headerlink" title="2.3 Database"></a>2.3 Database</h3><p>The database uses yimian-db/mysql. Three tables are constructed, which are used to store flow, public expenditure details, and internal circulation.</p><h3 id="2-4-Image-upload"><a href="#2-4-Image-upload" class="headerlink" title="2.4 Image upload"></a>2.4 Image upload</h3><p>Directly quote the code of <a href="https://imgbed.yimian.xyz" target="_blank" rel="noopener">呓喵酱の图床</a> with a small amount of rewriting.</p><h3 id="2-5-User-System"><a href="#2-5-User-System" class="headerlink" title="2.5 User System"></a>2.5 User System</h3><p>At present, it is simple to implement with additional web pages, waiting for the <a href="https://github.com/iotcat/ushio-auth" target="_blank" rel="noopener">ushio-auth project</a> to complete the unified integration.</p><h2 id="3-Appearance"><a href="#3-Appearance" class="headerlink" title="3. Appearance"></a>3. Appearance</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_ed08c497_1080x6654_8_null_normal.jpeg" alt="imgbed_ed08c497"></p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_ea04ad82_1080x5082_8_null_normal.jpeg" alt="imgbed_ea04ad82"></p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_a8b3adb0_1080x2160_8_null_normal.jpeg" alt="imgbed_a8b3adb0"></p><hr><p><strong>2020-03-22 update</strong></p><p>Due to the epidemic, considering that everyone has withdrawn to China. To save server costs, stop providing services.</p><p>Combining the operation status of the past six months, I have made some analysis and summary:</p><h2 id="Main-gains"><a href="#Main-gains" class="headerlink" title="Main gains"></a>Main gains</h2><ol><li>Experience in analyzing the real needs of customers</li><li>Ability to quickly build production environment website tools</li><li>My roommate’s recognition of my ability</li></ol><h2 id="Development-Methodology"><a href="#Development-Methodology" class="headerlink" title="Development Methodology"></a>Development Methodology</h2><ol><li>Based on a series of past projects, quickly set up and put into use in 3 days</li><li>Carefully study the requirements and determine which are true and which are false.</li></ol><h2 id="Challenges-encountered"><a href="#Challenges-encountered" class="headerlink" title="Challenges encountered"></a>Challenges encountered</h2><ol><li>Rapid development, because everyone has started to spend a lot of money on public goods after arriving in the UK, so there is an urgent need to use this system</li><li>The algorithm must be stable and reliable, because it involves everyone’s money</li><li>The purpose of this system is to make it more convenient to delegate the accounting work to the system for automated processing. In this way, the number of internal transactions between everyone must be as few as possible and the instructions must be clear under the premise of ensuring fairness.</li><li>How to make everyone trust the system.</li></ol><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><ol><li>Based on a large number of own previous projects. It takes 1 day to develop and form, 1 day to test debug, 1 day to optimize the front-end, add variance, percentage and other functions.</li><li>Refer to the accounting table and use the table mode. Every time there is a new upload, the new status will be calculated in real time. Tested many times and put into use after full verification.</li><li>Use the concept of “balance” and pay attention to differences. When the differences are too large, make internal transactions between those who spend the most and those who spend the least. And the internal transaction value is an integer. For example, our production scenario uses 20 pounds.</li><li>When the system algorithm is stable, refer to the design of Alipay. There are two steps to internal transactions. Both the first-choice payer and the earner receive emails telling to whom (from whom) and how much money. Then after the payer gives the money to the earner, the earner needs to log in to the web page or confirm it from the email link. As of this time, the system considers that an internal transaction is complete.</li></ol><hr><p><strong>2020-9-8 update</strong></p><p>Based on the Ushio user system, combined with the operation of the past six months and the changes in everyone’s needs, I reconstructed and developed a new version of the public expenditure system.</p><h2 id="New-features"><a href="#New-features" class="headerlink" title="New features"></a>New features</h2><ul><li>Achieved access to Ushio user system</li><li>Users can register and create new public bills at any time</li><li>The same user can be in multiple bills at the same time</li><li>Users can join the public bill at any time</li><li>Users can settle and exit a public bill at any time</li><li>Smarter settlement algorithm</li><li>Use LocalStorage to optimize the speed of secondary access</li></ul><h2 id="Experience"><a href="#Experience" class="headerlink" title="Experience"></a>Experience</h2><p>cp-acc is now open to the public, you can go to its <a href="https://cp-acc.yimian.xyz" target="_blank" rel="noopener">website</a> to experience it. But before the experience, you need to log in with your email address through the ushio user system in order to receive bill messages.</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> crown-place </tag>
<tag> uk </tag>
<tag> liverpool </tag>
<tag> erp </tag>
<tag> system </tag>
</tags>
</entry>
<entry>
<title>呓喵酱的一言API</title>
<link href="/tech/words-api.html"/>
<url>/tech/words-api.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>这里是呓喵酱的语录API哦~</p></span><span class=".en"><p>Hi~ This is the API of IoTcat’s Motto..</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h2><ul><li><code>lang</code>: (可选)语言 e.g. <code>lang</code>=<code>en</code>(英语)/<code>zh</code>(中文)</li></ul><h2 id="请求地址"><a href="#请求地址" class="headerlink" title="请求地址"></a>请求地址</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET https:&#x2F;&#x2F;api.yimian.xyz&#x2F;words&#x2F;</span><br></pre></td></tr></table></figure><h2 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F;随机获取一句中文语录</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;words&#x2F;</span><br><span class="line">&#x2F;&#x2F;随机获取一句英文语录</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;words&#x2F;?lang&#x3D;en</span><br></pre></td></tr></table></figure><h2 id="返回值-plaintext"><a href="#返回值-plaintext" class="headerlink" title="返回值(plaintext)"></a>返回值(plaintext)</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">随机一句话</span><br></pre></td></tr></table></figure></span><span class=".en"><h2 id="Parameters"><a href="#Parameters" class="headerlink" title="Parameters"></a>Parameters</h2><ul><li><code>lang</code>: (optional) Language setting. e.g. <code>lang</code>=<code>en</code>(English)/<code>zh</code>(Chinese)</li></ul><h2 id="Request-address"><a href="#Request-address" class="headerlink" title="Request address"></a>Request address</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET https:&#x2F;&#x2F;api.yimian.xyz&#x2F;words&#x2F;</span><br></pre></td></tr></table></figure><h2 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F;Get a random Chinese quotation</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;words&#x2F;</span><br><span class="line">&#x2F;&#x2F;Get a random English quotation</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;words&#x2F;?lang&#x3D;en</span><br></pre></td></tr></table></figure><h2 id="Return-value-plaintext"><a href="#Return-value-plaintext" class="headerlink" title="Return value (plaintext)"></a>Return value (plaintext)</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Random sentence..</span><br></pre></td></tr></table></figure></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> api </tag>
<tag> motto </tag>
</tags>
</entry>
<entry>
<title>网易云音乐获取API</title>
<link href="/tech/music-api.html"/>
<url>/tech/music-api.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>封装好的网易云音乐API,欢迎大家调用━(<em>`∀´</em>)ノ亻!</p></span><span class=".en"><p>The packaged NetEase Cloud Music API, welcome everyone to use ━(<em>`∀´</em>)ノ亻!</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h2><ul><li><code>type</code>: (必填)模式类型 <code>type</code>=<code>single</code>单曲信息/<code>playlist</code>歌单歌曲信息/<code>url</code>获取歌曲/<code>cover</code>获取封面/<code>lrc</code>获取歌词</li><li><code>id</code>: (必填,搭配type使用)歌单或歌曲id e.g. <code>id</code>=<code>198401123</code></li><li><code>random</code>: 仅对playlist有效,返回的歌曲是否打乱顺序,默认<code>false</code>. e.g. <code>random</code>=<code>true</code> </li><li><code>limit</code>: 返回歌单最大长度 e.g. <code>limit</code>=<code>10</code> </li></ul><blockquote><p>歌单和歌曲的id可以从<a href="https://music.163.com/#/my/" target="_blank" rel="noopener">云音乐网页版</a>获取。点开歌单或歌曲,查看浏览器地址栏,如下图:<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_dfeddac_552x34_8_null_normal.jpeg" alt="Playlist Id"><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_527a5ea_491x37_8_null_normal.jpeg" alt="Single Song Id"></p></blockquote><blockquote><p>2021-6-23起”我喜欢的音乐”歌单不再受支持。如有需求,请创建一个公开的歌单,并将“我喜欢的音乐”中的歌曲移入。</p></blockquote><h2 id="请求地址"><a href="#请求地址" class="headerlink" title="请求地址"></a>请求地址</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;</span><br></pre></td></tr></table></figure><h2 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h2><h3 id="获取id为36308263的歌曲信息"><a href="#获取id为36308263的歌曲信息" class="headerlink" title="获取id为36308263的歌曲信息"></a>获取id为36308263的歌曲信息</h3><p><a href="https://api.yimian.xyz/msc/?type=single&amp;id=36308263" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=single&amp;id=36308263</a></p><h3 id="获取id为2675649523的歌单所有歌曲信息"><a href="#获取id为2675649523的歌单所有歌曲信息" class="headerlink" title="获取id为2675649523的歌单所有歌曲信息"></a>获取id为2675649523的歌单所有歌曲信息</h3><p><a href="https://api.yimian.xyz/msc/?type=playlist&amp;id=2675649523" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=playlist&amp;id=2675649523</a></p><h3 id="获取2675649523歌单前14首歌曲信息"><a href="#获取2675649523歌单前14首歌曲信息" class="headerlink" title="获取2675649523歌单前14首歌曲信息"></a>获取2675649523歌单前14首歌曲信息</h3><p><a href="https://api.yimian.xyz/msc/?type=playlist&amp;id=2675649523&amp;limit=14" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=playlist&amp;id=2675649523&amp;limit=14</a></p><h3 id="随机从2675649523歌单获取14首歌曲信息"><a href="#随机从2675649523歌单获取14首歌曲信息" class="headerlink" title="随机从2675649523歌单获取14首歌曲信息"></a>随机从2675649523歌单获取14首歌曲信息</h3><p><a href="https://api.yimian.xyz/msc/?type=playlist&amp;id=2675649523&amp;limit=14&amp;random=true" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=playlist&amp;id=2675649523&amp;limit=14&amp;random=true</a></p><h3 id="获取36308263的mp3音乐文件"><a href="#获取36308263的mp3音乐文件" class="headerlink" title="获取36308263的mp3音乐文件"></a>获取36308263的mp3音乐文件</h3><p><a href="https://api.yimian.xyz/msc/?type=url&amp;id=36308263" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=url&amp;id=36308263</a></p><h3 id="获取id为3384296792803059的封面图片"><a href="#获取id为3384296792803059的封面图片" class="headerlink" title="获取id为3384296792803059的封面图片"></a>获取id为3384296792803059的封面图片</h3><p><a href="https://api.yimian.xyz/msc/?type=cover&amp;id=3384296792803059" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=cover&amp;id=3384296792803059</a></p><h3 id="获取36308263歌曲的lrc歌词文件"><a href="#获取36308263歌曲的lrc歌词文件" class="headerlink" title="获取36308263歌曲的lrc歌词文件"></a>获取36308263歌曲的lrc歌词文件</h3><p><a href="https://api.yimian.xyz/msc/?type=lrc&amp;id=36308263" target="_blank" rel="noopener">https://api.yimian.xyz/msc/?type=lrc&amp;id=36308263</a></p><h2 id="返回值-json格式"><a href="#返回值-json格式" class="headerlink" title="返回值(json格式)"></a>返回值(json格式)</h2><ul><li><p>single单曲模式: </p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">id: <span class="string">"歌曲id"</span>, </span><br><span class="line">name: <span class="string">"歌曲名称"</span>, </span><br><span class="line">artist: <span class="string">"第一作者"</span>, </span><br><span class="line">album: <span class="string">"专辑名称"</span>, </span><br><span class="line">url: <span class="string">"单曲地址"</span>, </span><br><span class="line">cover: <span class="string">"封面地址"</span>, </span><br><span class="line">lrc: <span class="string">"歌词地址"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>playlist歌单模式: </p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line">&#123;</span><br><span class="line">id: <span class="string">"歌曲id"</span>,</span><br><span class="line">name: <span class="string">"歌曲名称"</span>, </span><br><span class="line">artist: <span class="string">"第一作者"</span>, </span><br><span class="line">album: <span class="string">"专辑名称"</span>, </span><br><span class="line">url: <span class="string">"单曲地址"</span>, </span><br><span class="line">cover: <span class="string">"封面地址"</span>, </span><br><span class="line">lrc: <span class="string">"歌词地址"</span></span><br><span class="line">&#125;, </span><br><span class="line">&#123;歌曲<span class="number">2.</span>.&#125;, </span><br><span class="line">&#123;歌曲<span class="number">3.</span>.&#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure></li><li><p>错误: </p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;<span class="attr">code</span>: <span class="number">500</span>, <span class="attr">err</span>: <span class="string">"错误信息"</span>&#125;</span><br></pre></td></tr></table></figure></li></ul></span><span class=".en"><h2 id="Parameters"><a href="#Parameters" class="headerlink" title="Parameters"></a>Parameters</h2><ul><li><code>type</code>: (Required) Mode type <code>type</code>=<code>single</code> single information/<code>playlist</code> song information/<code>url</code> get song/<code>cover</code> get cover/<code>lrc</code> get lyrics</li><li><code>id</code>: (Required, used with type) Playlist or song id e.g. <code>id</code>=<code>198401123</code></li><li><code>random</code>: Only valid for playlist, whether the returned songs are out of order, the default is <code>false</code>. e.g. <code>random</code>=<code>true</code></li><li><code>limit</code>: return the maximum length of the playlist e.g. <code>limit</code>=<code>10</code></li></ul><blockquote><p>Playlist and song id can be obtained from <a href="https://music.163.com/#/my/" target="_blank" rel="noopener">Cloud Music Web Version</a>. Click to open a playlist or song, and check the browser address bar, as shown below:<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_dfeddac_552x34_8_null_normal.jpeg" alt="Playlist Id"><br><img src="https://api.yimian.xyz/img/?path=imgbed/img_527a5ea_491x37_8_null_normal.jpeg" alt="Single Song Id"></p></blockquote><h2 id="Request-address"><a href="#Request-address" class="headerlink" title="Request address"></a>Request address</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;</span><br></pre></td></tr></table></figure><h2 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">&#x2F;&#x2F;Get song information with id 36308263</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;single&amp;id&#x3D;36308263</span><br><span class="line">&#x2F;&#x2F;Get all song information of the playlist with id 2675649523</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;playlist&amp;id&#x3D;2675649523</span><br><span class="line">&#x2F;&#x2F;Get information about the first 14 songs of the 2675649523 playlist</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;playlist&amp;id&#x3D;2675649523&amp;limit&#x3D;14</span><br><span class="line">&#x2F;&#x2F;Get 14 song information randomly from 2675649523 playlist</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;playlist&amp;id&#x3D;2675649523&amp;limit&#x3D;14&amp;random&#x3D;true</span><br><span class="line">&#x2F;&#x2F;Get 36308263 mp3 music file</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;url&amp;id&#x3D;36308263</span><br><span class="line">&#x2F;&#x2F;Get the cover image with id 3384296792803059</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;cover&amp;id&#x3D;3384296792803059</span><br><span class="line">&#x2F;&#x2F;Get the lrc lyrics file of 36308263 song</span><br><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;msc&#x2F;?type&#x3D;lrc&amp;id&#x3D;36308263</span><br></pre></td></tr></table></figure><h2 id="Return-value-json-format"><a href="#Return-value-json-format" class="headerlink" title="Return value (json format)"></a>Return value (json format)</h2><ul><li><p>single mode:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">id: <span class="string">"Song id"</span>,</span><br><span class="line">name: <span class="string">"Song name"</span>,</span><br><span class="line">artist: <span class="string">"First Author"</span>,</span><br><span class="line">album: <span class="string">"Album Name"</span>,</span><br><span class="line">url: <span class="string">"Single address"</span>,</span><br><span class="line">cover: <span class="string">"Cover Address"</span>,</span><br><span class="line">lrc: <span class="string">"Lyrics address"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></li><li><p>Playlist playlist mode:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">[</span><br><span class="line"> &#123;</span><br><span class="line"> id: <span class="string">"Song id"</span>,</span><br><span class="line"> name: <span class="string">"Song name"</span>,</span><br><span class="line"> artist: <span class="string">"First Author"</span>,</span><br><span class="line"> album: <span class="string">"Album Name"</span>,</span><br><span class="line"> url: <span class="string">"Single address"</span>,</span><br><span class="line"> cover: <span class="string">"Cover Address"</span>,</span><br><span class="line"> lrc: <span class="string">"Lyrics address"</span></span><br><span class="line"> &#125;,</span><br><span class="line"> &#123;Song <span class="number">2.</span>.&#125;,</span><br><span class="line"> &#123;Song <span class="number">3.</span>.&#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure></li><li><p>Error:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">&#123;<span class="attr">code</span>: <span class="number">500</span>, <span class="attr">err</span>: <span class="string">"error message"</span>&#125;</span><br></pre></td></tr></table></figure></li></ul></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> api </tag>
<tag> music </tag>
</tags>
</entry>
<entry>
<title>在家中部署智慧家庭系统</title>
<link href="/tech/smart-home.html"/>
<url>/tech/smart-home.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>基于Home Assisstant搭建综合家庭照明系统,多媒体系统,水流系统的智慧家庭。技术点:天猫精灵交互,LoRa通信,MQTT协议,frp内网穿透,NAS存储,拨动开关电路改造。</p></span><span class=".en"><p>Based on Home Assisstant, build a smart home with integrated home lighting system, multimedia system and water flow system. Technical points: Tmall Genie interaction, LoRa communication, MQTT protocol, FRP intranet penetration, NAS storage, and toggle switch circuit transformation.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>结合所学知识,运用前沿技术,造福生活,是我长期以来的不懈追求。为了让家人体验到更加稳定、舒适智能的生活方式,同时也为了巩固憨实先前在学校smartfarm项目和我自己的ushio系统中所积累的技术基础以及架构经验,我决定在出国前,使用20到23整天时间,重构家中老旧的物联网系统。采用分层架构和面向接口、面向测试、<strong>面向文档</strong>开发原则,以<strong>稳定性(Available)</strong>,<strong>可靠性(Reliable)</strong>为最优先指标,搭建一个运行目标3年以上的高度模块化的,易于远程操控的,开源的家庭软件硬件智能传感控制系统。</p><h2 id="背景:"><a href="#背景:" class="headerlink" title="背景:"></a>背景:</h2><p>大一上学期,初接触单片机,使用Arduino Uno搭建了一个宿舍中的智慧窗帘系统(细节可以参考<a href="https://www.eee.dog/tech/build-236-iot-platform-on-wifiduino.html">这篇blog</a>),积累了一定的经验。</p><h2 id="方法:"><a href="#方法:" class="headerlink" title="方法:"></a>方法:</h2><ol><li>向专家请教(水管问题向五金店老板请教,LoRa向欧朗研发部请教)</li><li>做轮子,不断迭代,在重构中优化系统,获取经验</li><li>认真调研客户(家人)的需求,在设计时重视客户需求,多于客户沟通</li><li>在设计某一系统时,一定要假设与其交互的其它系统不稳定。让系统之间的交互就像君子相交一样,像水一样。从而提高整个系统的裕度。</li><li>持续运维。比如三轮开发前曾经发生过,我妈在打扫卫生时碰掉了一个人体传感器,导致整个灯控系统紊乱。当时在苏州的我通过远程ssh连接到家里的服务器,将坏掉的传感器踢出控制系统进而解决了问题。因此,一定要让自己在任何时候都可以接入到系统进行运维。一定要在设计时充分考虑之后的运维。</li></ol><h2 id="过程综述:"><a href="#过程综述:" class="headerlink" title="过程综述:"></a>过程综述:</h2><h3 id="一轮开发"><a href="#一轮开发" class="headerlink" title="一轮开发"></a>一轮开发</h3><p>大一暑假,开始尝试使用WiFiduino在家中控制一些物体,实现了对(坏了的)太阳能加水(通过电磁阀)的控制(修改了原先家里的管道,加入了电磁阀。跑了好多趟五金店,收获了不少关于水管的知识和实践经验。之后做surf的水泵也有用到。)以及对走廊灯(通过光电耦合器)的控制。找到一台废弃的10年前的我爸的IBM笔记本,装上了win server 2008, 并配置好了mysql数据库,并定期使用http从单片机采集数据。我用php写了一个简单的web界面,来展示相关信息,并实现网页控制。由于家里被分配的是中国移动分配的大NAT内网IP,因此使用frp来实现内网穿透,使外界可以访问家里服务器上的web网页。</p><h3 id="二轮开发"><a href="#二轮开发" class="headerlink" title="二轮开发"></a>二轮开发</h3><p>大二寒假,改进先前的固件,使用wifiduino陆续实现了对厨房,客厅,餐厅的灯体的控制,并部署了一系列传感器,并接入网络。由于先前太阳能管道的单片机WiFi信号弱,于是在附近使用路由器做了桥接。值得一提的是,年三十晚上春晚开始前2分钟我还在家里停电施工,,不知道爸妈是什么感受⊙0⊙。。</p><h3 id="三轮开发"><a href="#三轮开发" class="headerlink" title="三轮开发"></a>三轮开发</h3><p>大二暑假,基于本学期经验,重构系统。在服务器上,重装系统为Centos7使用home assistant 开源项目提供UI等服务,使用mqtt作为通信协议。使用nodeJS编写了灯控自动化和太阳能加水的控制逻辑。在单片机,更新了固件,支持ota远程更新固件(参考了部分wiot经验,但更加因地制宜)。此外,新增了两个流量计,以实现太阳能加水完全自动化(之前是通过网页设置加水时长)。由于流量计WiFi信号弱,我们使用了Arduino uno + LoRa作为通信手段。本次设计,结合爸妈的意见,充分考虑了整体系统的稳定性。比如,如何handle各种类型的错误和失联,如何在断电后丝滑得重启,如何在服务器无响应情况下保证单片机不紊乱,如何在系统失控后物理切回到手动(比如灯,和太阳能加水)。</p><h3 id="四轮开发"><a href="#四轮开发" class="headerlink" title="四轮开发"></a>四轮开发</h3><p>大三暑假,基于过去积累的传感器数据,使用LSTM模型,通过keras+tensorflow训练神经网络,实现对灯控状态的预测。目前仍在持续优化中,预计9月前完成。此外,有计划接入天猫精灵的打算(仍在队列中,需等待ushio oauth系统的研发,ushio oauth系统需要等待ushio user系统研发,ushio user系统需要稳定的js-session作为支撑,js-session需要使用fp来精确识别用户设备。。目前fp仍处于第三测试阶段。所以,一步一步来吧,,)。</p><h2 id="硬件设计"><a href="#硬件设计" class="headerlink" title="硬件设计"></a>硬件设计</h2><h3 id="单片机选材"><a href="#单片机选材" class="headerlink" title="单片机选材"></a>单片机选材</h3><p>使用Arduino UNO作为计算单元。一方面,Arduino Uno拥有高可靠性,我之前的智慧窗帘系统使用Arduino Uno作为主控板,平稳运行1年半未出现硬件问题。另一方面,Arduino Uno拥有较大的RAM,无需为了争夺RAM而在单片机编程上煞费苦心。</p><p>Arduino UNO的缺陷主要是价格高,但是为保障长期稳定运行,这个成本是必要的。</p><h3 id="WiFi通信模块选材"><a href="#WiFi通信模块选材" class="headerlink" title="WiFi通信模块选材"></a>WiFi通信模块选材</h3><p>使用ESP-01作为WiFi的通信模块。主要原因是之前学校课程使用过ESP-01搭建遥控小车,对其工作方式和性能比较了解,降低开发成本。</p><h3 id="LoRa通信模块选材"><a href="#LoRa通信模块选材" class="headerlink" title="LoRa通信模块选材"></a>LoRa通信模块选材</h3><p>使用<strong>安信可 LORA RA-02 LORA</strong>作为LoRa节点和LoRa网关通信模块。原因是surf项目使用的就是这个模块,比较了解它。</p><h3 id="智能音箱选材"><a href="#智能音箱选材" class="headerlink" title="智能音箱选材"></a>智能音箱选材</h3><p>智能音箱作为此物联网系统人机交互的最主要界面,发挥着举足轻重的作用。经研究,我使用天猫精灵方糖R作为家用智能音箱。一方面,天猫精灵的性价比摆在那里,非常便宜。第二,与小米开发小爱同学不同,阿里开发天猫精灵的目的是提供平台,它允许开发者以各种形式接入其网络,这一点对我至关重要。</p><h3 id="灯拨动开关"><a href="#灯拨动开关" class="headerlink" title="灯拨动开关"></a>灯拨动开关</h3><p>初期设想: 单向控制+复位器。<br>实际实现:将原有单开改造为双开,一路与继电器串联,另一路与两个pin口相连。</p><h2 id="通信设计"><a href="#通信设计" class="headerlink" title="通信设计"></a>通信设计</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_43b85bd4_1096x660_8_null_normal.png" alt="网络拓扑图"></p><p>采用WiFi+LoRa两种通信模式。在需要高速高质量通信的场景,如天猫精灵,手机,笔记本,使用WiFi作为通信手段。在WiFi信号不稳定的地方,使用LoRa进行通信。使用MQTT为应用层协议。</p><h2 id="主控系统设计"><a href="#主控系统设计" class="headerlink" title="主控系统设计"></a>主控系统设计</h2><p>使用python3开源项目Home Assistant 为基础搭建本项目的主控系统。效果如下图:</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_c1a1b81_1895x859_8_null_normal.jpeg" alt="Sola Website"></p><h2 id="多媒体系统设计"><a href="#多媒体系统设计" class="headerlink" title="多媒体系统设计"></a>多媒体系统设计</h2><p>多媒体主要由天猫精灵提供。此外,通过小米盒子,家庭网盘中的视频,图片,音乐实现了电视与音响上的播放。</p><h2 id="云端支持系统设计"><a href="#云端支持系统设计" class="headerlink" title="云端支持系统设计"></a>云端支持系统设计</h2><p>dns.yimian.xyz提供dns解析服务。</p><h2 id="NAS存储系统设计"><a href="#NAS存储系统设计" class="headerlink" title="NAS存储系统设计"></a>NAS存储系统设计</h2><p>通过挂载从老电脑上拆卸的闲置500G机械硬盘到老IBM服务器,实现存储系统的搭建。<br>对局域网内,由于家里都是win系统,使用smb作为共享协议实现文件传输,支持局域网内挂载。速度稳定,全网读写10MB/s左右。对外网访问,通过http,frp反代实现,但速度较慢。</p><p>以下是对网页界面的一个截屏:</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_352da66_1866x814_8_null_normal.jpeg" alt="NAS Web Page"></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><h3 id="主要收获"><a href="#主要收获" class="headerlink" title="主要收获"></a>主要收获</h3><ol><li>全栈物联网(云+管+端)系统搭建运维经验</li><li>LoRa,WiFi通信系统搭建经验</li><li>机器学习开发运维经验</li><li>客户需求分析经验</li><li>家用电路线路改装经验</li><li>家用水管管道改造经验</li></ol><h3 id="遇到的挑战"><a href="#遇到的挑战" class="headerlink" title="遇到的挑战"></a>遇到的挑战</h3><ol><li>如何保证所有的单片机处拥有优质的网络连接</li><li>家人希望预留方法,在系统崩溃时一键回到最古老的手动开关状态。</li><li>准确的控制灯的开关</li><li>如何降低各模块间的耦合</li></ol><h3 id="解决方法"><a href="#解决方法" class="headerlink" title="解决方法"></a>解决方法</h3><ol><li>使用WiFi,LoRa双协议。WiFi用于连接距离路由器较近的单片机,LoRa 连接距离较远WiFi信号弱的原处的单片机。</li><li>我在每一个开关都配置了双保险,让每一个开关都可以经过轻易的操作即可回到手动状态。如果要回到手动状态,只需要扫描开关上的二维码,根据指示操作。详见<a href="https://sola.yimian.xyz/#/home?id=%E5%BA%94%E6%80%A5%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97" target="_blank" rel="noopener">应急操作指南</a></li><li>在第一轮开发,灯控是由单片机决定的。与楼道里的声控灯并无本质差别,都是传感器-&gt;单片机-&gt;灯。第二轮开发时,将这个判断逻辑转移到了服务器。第三轮开发,我们引入了夜间模式,白天模式,午夜模式等,并在决策时使用了数学模型,通过各传感器的数据测算有人的概率,来决定对灯的控制。但是,这一方法并不总是及时,家里人在天刚黑时总是需要去按一下拨动开关。因此,第四轮开发中,我希望能够借助机器学习,让其自己学习家人的开关习惯。目前,正在持续采集数据并训练中,夜间准确度在0.75左右。</li><li>各个模块和单片机都是用mqtt进行交互。每个单片机都有在线模式和离线模式。灯控决策模块和太阳能控制模块是单独的两个nodeJS模块,由pm2守护。为了保证其服务不间断性,他们是用redis(已配置持久化)作为实时数据存储。</li></ol><hr><p><strong>2020.6 更新</strong></p><h2 id="RNN实现对灯控制"><a href="#RNN实现对灯控制" class="headerlink" title="RNN实现对灯控制"></a>RNN实现对灯控制</h2><p>基于先前积累的人体传感器数据,通过LSTM模型,使用keras训练神经网络,实现对开灯状态的预测。</p><hr><p><strong>2020.8 更新</strong></p><h2 id="天猫精灵接入"><a href="#天猫精灵接入" class="headerlink" title="天猫精灵接入"></a>天猫精灵接入</h2><p>自建了OAuth服务器,实现了天猫精灵的接入。</p></span><span class=".en"><p>Combining the knowledge I have learned and using cutting-edge technology to benefit life has been my unremitting pursuit for a long time. In order to let my family experience a more stable, comfortable and intelligent lifestyle, and to consolidate the technical foundation and architecture experience accumulated in the school smartfarm project and my own ushio system, I decided to use 20 to 23 before going abroad. All day long, reconstruct the old IoT system at home. Adopt a layered architecture and interface-oriented, test-oriented, and <strong>document-oriented</strong> development principles, with <strong>Available</strong> and <strong>Reliable</strong> as the highest priority indicators to build an operational target 3. A highly modular, easy-to-remote control, open source home software and hardware intelligent sensor control system for more than years.</p><h2 id="Background"><a href="#Background" class="headerlink" title="Background:"></a>Background:</h2><p>In the first semester of the freshman year, I was new to MCU and used Arduino Uno to build a smart curtain system in the dormitory (for details, please refer to <a href="https://www.eee.dog/tech/build-236-iot-platform">this blog</a> -on-wifiduino.html)), has accumulated a certain amount of experience.</p><h2 id="Method"><a href="#Method" class="headerlink" title="Method:"></a>Method:</h2><ol><li>Ask experts (for water pipe problems, ask the owner of the hardware store, and LoRa for advice from Oulang R&amp;D department)</li><li>Be a wheel, keep iterating, optimize the system in refactoring, and gain experience</li><li>Investigate the needs of customers (family) carefully, pay more attention to customer needs in design, rather than communicate with customers</li><li>When designing a system, it must be assumed that other systems that interact with it are unstable. Let the interaction between systems be like gentlemen intersect, like water. Thereby improving the margin of the whole system.</li><li>Continuous operation and maintenance. For example, it happened before the three rounds of development. My mother touched a human sensor while cleaning, causing the entire light control system to be disordered. At that time, I was in Suzhou connected to the server at home via remote ssh, kicked the broken sensor out of the control system and solved the problem. Therefore, you must allow yourself to be connected to the system for operation and maintenance at any time. The future operation and maintenance must be fully considered in the design.</li></ol><h2 id="Process-overview"><a href="#Process-overview" class="headerlink" title="Process overview:"></a>Process overview:</h2><h3 id="First-round-of-development"><a href="#First-round-of-development" class="headerlink" title="First round of development"></a>First round of development</h3><p>Freshman summer vacation, I began to try to use WiFiduino to control some objects at home, and realized the control of (broken) solar water (through solenoid valve) (modified the original home pipes and added solenoid valves. I went to the hardware store many times. , I have gained a lot of knowledge and practical experience on water pipes. Later, I will also be useful to do surf pumps.) and control the corridor lights (through photocouplers). I found an abandoned IBM laptop of my dad 10 years ago, installed it with win server 2008, and configured the mysql database, and regularly used http to collect data from the microcontroller. I wrote a simple web interface in php to display relevant information and implement web control. Since the home is assigned a large NAT intranet IP allocated by China Mobile, frp is used to achieve intranet penetration, so that the outside world can access the web pages on the home server.</p><h3 id="Second-round-of-development"><a href="#Second-round-of-development" class="headerlink" title="Second round of development"></a>Second round of development</h3><p>During the sophomore winter vacation, the previous firmware was improved, wifiduino was used to control the lights in the kitchen, living room, and dining room one after another, and a series of sensors were deployed and connected to the network. Because the WiFi signal of the single-chip microcomputer of the solar energy pipeline was weak, a router was used nearby to bridge. It is worth mentioning that on the night of New Year’s Eve, I was still at home with a power outage 2 minutes before the start of the Spring Festival Gala. I don’t know how my parents feel. .</p><h3 id="Third-round-of-development"><a href="#Third-round-of-development" class="headerlink" title="Third round of development"></a>Third round of development</h3><p>Sophomore summer vacation, based on the experience of this semester, reconstruct the system. On the server, the reinstallation system provides UI and other services for Centos7 to use the home assistant open source project, using mqtt as the communication protocol. Use nodeJS to write the control logic of light control automation and solar water adding. In the single chip microcomputer, the firmware is updated, and the ota remote firmware update is supported (referring to some Wiot experience, but more tailored to local conditions). In addition, two new flow meters have been added to fully automate the solar water addition (previously, the water addition time was set through the web page). Due to the weak WiFi signal of the flowmeter, we used Arduino uno + LoRa as the communication means. This design, combined with the opinions of parents, fully considered the stability of the overall system. For example, how to handle various types of errors and loss of connection, how to restart after a power failure, how to ensure that the MCU is not disordered when the server is unresponsive, and how to physically switch back to manual after the system is out of control (such as lights, and Solar energy plus water).</p><h3 id="Fourth-round-of-development"><a href="#Fourth-round-of-development" class="headerlink" title="Fourth round of development"></a>Fourth round of development</h3><p>In the summer vacation of the junior year, based on the sensor data accumulated in the past, the LSTM model is used to train the neural network through keras+tensorflow to realize the prediction of the light control state. The optimization is still ongoing and is expected to be completed before September. In addition, there are plans to connect to the Tmall Wizard (still in the queue, waiting for the development of the ushio oauth system, the ushio oauth system needs to wait for the development of the ushio user system, and the ushio user system needs stable js-session as support, js-session Need to use fp to accurately identify user equipment.. Currently fp is still in the third test stage. So, let’s do it step by step,,).</p><h2 id="Hardware-design"><a href="#Hardware-design" class="headerlink" title="Hardware design"></a>Hardware design</h2><h3 id="Single-Chip-Microcomputer-Material-Selection"><a href="#Single-Chip-Microcomputer-Material-Selection" class="headerlink" title="Single Chip Microcomputer Material Selection"></a>Single Chip Microcomputer Material Selection</h3><p>Use Arduino UNO as the calculation unit. On the one hand, Arduino Uno has high reliability. My previous smart curtain system used Arduino Uno as the main control board, and it ran smoothly for one and a half years without hardware problems. On the other hand, Arduino Uno has a larger RAM, so there is no need to bother to program the microcontroller in order to compete for RAM.</p><p>The main disadvantage of Arduino UNO is its high price, but this cost is necessary to ensure long-term stable operation.</p><h3 id="WiFi-communication-module-selection"><a href="#WiFi-communication-module-selection" class="headerlink" title="WiFi communication module selection"></a>WiFi communication module selection</h3><p>Use ESP-01 as the WiFi communication module. The main reason is that the ESP-01 has been used to build a remote control car in the previous school courses, and I have a better understanding of its working methods and performance to reduce development costs.</p><h3 id="LoRa-communication-module-selection"><a href="#LoRa-communication-module-selection" class="headerlink" title="LoRa communication module selection"></a>LoRa communication module selection</h3><p>Use <strong>Anxinke LORA RA-02 LORA</strong> as the communication module between LoRa node and LoRa gateway. The reason is that this module is used in the surf project, so I understand it better.</p><h3 id="Smart-speaker-selection"><a href="#Smart-speaker-selection" class="headerlink" title="Smart speaker selection"></a>Smart speaker selection</h3><p>As the most important interface for human-computer interaction in this IoT system, smart speakers play a pivotal role. After research, I use Tmall Elf Sugar R as a home smart speaker. On the one hand, the price/performance ratio of Tmall Genie is very cheap. Second, unlike Xiaomi’s development of Xiao Ai, the purpose of Ali’s development of Tmall Genie is to provide a platform that allows developers to access its network in various forms, which is very important to me.</p><h3 id="Light-toggle-switch"><a href="#Light-toggle-switch" class="headerlink" title="Light toggle switch"></a>Light toggle switch</h3><p>Initial idea: one-way control + reset device.<br>Actual realization: The original single-opening is transformed into double-opening, one is connected in series with the relay, and the other is connected with two pin ports.</p><h2 id="Communication-Design"><a href="#Communication-Design" class="headerlink" title="Communication Design"></a>Communication Design</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_43b85bd4_1096x660_8_null_normal.png" alt="Network Topology Diagram"></p><p>Two communication modes of WiFi+LoRa are adopted. In scenarios that require high-speed and high-quality communication, such as Tmall Genie, mobile phones, and notebooks, use WiFi as a means of communication. In places where the WiFi signal is unstable, use LoRa for communication. Use MQTT as the application layer protocol.</p><h2 id="Main-control-system-design"><a href="#Main-control-system-design" class="headerlink" title="Main control system design"></a>Main control system design</h2><p>Use the python3 open source project Home Assistant as the basis to build the main control system of this project. The effect is as follows:</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_c1a1b81_1895x859_8_null_normal.jpeg" alt="Sola Website"></p><h2 id="Multimedia-system-design"><a href="#Multimedia-system-design" class="headerlink" title="Multimedia system design"></a>Multimedia system design</h2><p>Multimedia is mainly provided by Tmall Genie. In addition, through the Xiaomi box, the video, pictures, and music in the home network disk can be played on the TV and stereo.</p><h2 id="Cloud-support-system-design"><a href="#Cloud-support-system-design" class="headerlink" title="Cloud support system design"></a>Cloud support system design</h2><p>dns.yimian.xyz provides dns resolution service.</p><h2 id="NAS-storage-system-design"><a href="#NAS-storage-system-design" class="headerlink" title="NAS storage system design"></a>NAS storage system design</h2><p>By mounting the idle 500G mechanical hard disk removed from the old computer to the old IBM server, the storage system is built.<br>In the local area network, since the home is a win system, smb is used as a sharing protocol to realize file transfer and supports mounting in the local area network. The speed is stable, and the whole network reads and writes about 10MB/s. Access to the external network is realized through http and frp reverse generation, but the speed is slow.</p><p>The following is a screenshot of the web interface:</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_352da66_1866x814_8_null_normal.jpeg" alt="NAS Web Page"></p><h2 id="Conclusion"><a href="#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><h3 id="Main-gains"><a href="#Main-gains" class="headerlink" title="Main gains"></a>Main gains</h3><ol><li>Full-stack IoT (cloud + pipe + terminal) system construction operation and maintenance experience</li><li>LoRa, WiFi communication system construction experience</li><li>Machine learning development operation and maintenance experience</li><li>Customer needs analysis experience</li><li>Experience in home circuit modification</li><li>Experience in renovation of household water pipes</li></ol><h3 id="Challenges-encountered"><a href="#Challenges-encountered" class="headerlink" title="Challenges encountered"></a>Challenges encountered</h3><ol><li>How to ensure that all MCUs have high-quality network connections</li><li>The family hopes to reserve a way to return to the oldest manual switch state with one click when the system crashes.</li><li>Control the light switch accurately</li><li>How to reduce the coupling between modules</li></ol><h3 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h3><ol><li>Use WiFi, LoRa dual protocol. WiFi is used to connect the single-chip microcomputer closer to the router, and LoRa connects to the single-chip microcomputer in the original place where the WiFi signal is weaker.</li><li>I have equipped each switch with double insurance, so that each switch can be returned to manual state after easy operation. If you want to return to manual mode, just scan the QR code on the switch and follow the instructions. For details, see <a href="https://sola.yimian.xyz/#/home?id=%E5%BA%94%E6%80%A5%E6%93%8D%E4%BD%9C%E6%8C%87%E5%8D%97" target="_blank" rel="noopener">Emergency Operation Guide</a></li><li>In the first round of development, the light control is determined by the microcontroller. There is no essential difference with the sound-controlled lights in the corridor, they are all sensors -&gt; single chip microcomputer -&gt; lights. In the second round of development, this judgment logic was transferred to the server. In the third round of development, we introduced night mode, day mode, midnight mode, etc., and used mathematical models in the decision-making process to determine the probability of people using the data of each sensor to determine the control of the lights. However, this method is not always timely. Family members always need to press the toggle switch when it is just dark. Therefore, in the fourth round of development, I hope to use machine learning to let myself learn the switching habits of my family. Currently, data is being continuously collected and trained, and the night accuracy is around 0.75.</li><li>Each module and the single-chip microcomputer use mqtt to interact. Each microcontroller has an online mode and an offline mode. The light control decision module and the solar control module are two separate nodeJS modules, guarded by pm2. In order to ensure uninterrupted services, they use redis (configured persistence) as real-time data storage.</li></ol><hr><p><strong>2020.6 update</strong></p><h2 id="RNN-realizes-light-control"><a href="#RNN-realizes-light-control" class="headerlink" title="RNN realizes light control"></a>RNN realizes light control</h2><p>Based on the previously accumulated human sensor data, the LSTM model is used to train the neural network using keras to realize the prediction of the light state.</p><hr><p><strong>2020.8 update</strong></p><h2 id="Tmall-Elf-Access"><a href="#Tmall-Elf-Access" class="headerlink" title="Tmall Elf Access"></a>Tmall Elf Access</h2><p>Self-built OAuth server has realized the access of Tmall Wizard.</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> Arduino </tag>
<tag> iot </tag>
<tag> smart-home </tag>
<tag> LoRa </tag>
<tag> WiFi </tag>
<tag> ESP8266 </tag>
<tag> MQTT </tag>
</tags>
</entry>
<entry>
<title>2019 SURF SmartFarming Proj 架构说明</title>
<link href="/tech/smartfarming-surf.html"/>
<url>/tech/smartfarming-surf.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>本文详细介绍了XJTLU大学2019暑期科研SmartFarming Proj物联网架构的设计思路,实施情况以及缺陷反思。</p></span><span class=".en"><p>This article introduces in detail the design ideas, implementation status and defect reflections of the SmartFarming Proj IoT architecture of XJTLU University’s 2019 summer scientific research.</p></span><a id="more"></a><script> session.onload(function(){ if(page.tran.getLang() == 'en'){ tips.warning({ title: 'Caution', position: 'topRight', message: 'This page was translated by Machine!!', buttons: [['<button>Show Original Page</button>', function (instance, toast) { page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]] }); } });</script><span class=".zh"><h2 id="1-背景"><a href="#1-背景" class="headerlink" title="1 背景"></a>1 背景</h2><h3 id="1-1-需求"><a href="#1-1-需求" class="headerlink" title="1.1 需求"></a>1.1 需求</h3><p>为了探究农业物联网技术的可行性,Alam Mohammed导师希望我们能够提供一个<strong>稳定(Available)</strong>并<strong>可靠(Reliable)</strong>的物联网系统,以实现对农田的智能监控和管理。这个系统将能够适时地探测土壤以及空气中与植物健康相关的参数,处理并存储这些数据(由Alam提出)。同时,自动化控制的灌溉功能(由Caleb提出)以及一些数据展示方法(由Alam提出的可选需求)也被期待由本系统提供。</p><h3 id="1-2-定位"><a href="#1-2-定位" class="headerlink" title="1.2 定位"></a>1.2 定位</h3><p>由于是针对农业物联网设计的小型科研项目,项目的目标是对农业物联网的可行性进行探究,愿景是模拟最普遍的小型农业物联网应用场景。因此本架构的定位是<strong>适用于大部分具备感知,控制和展示功能的小型农业物联网工程</strong>。</p><h2 id="2-名词解释"><a href="#2-名词解释" class="headerlink" title="2 名词解释"></a>2 名词解释</h2><blockquote><ul><li><code>MQTT</code>: MQTT消息队列遥测传输(Message Queuing Telemetry Transport)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议[1]。</li></ul></blockquote><blockquote><ul><li><code>LoRa</code>: LoRa是当前市场上的一种新兴技术,其在1 GHz以下的公共频段中运行,用于远距离低功耗通信[2]。</li></ul></blockquote><h2 id="3-设计目标"><a href="#3-设计目标" class="headerlink" title="3 设计目标"></a>3 设计目标</h2><h3 id="3-1-实现功能"><a href="#3-1-实现功能" class="headerlink" title="3.1 实现功能"></a>3.1 实现功能</h3><p>本架构功能性需求主要包括土地数据采集,气象数据采集,灌溉系统控制,与无人机小组系统进行交互,网页控制台(可查看实时和历史传感数据,指标数据;能够控制系统)。</p><h3 id="3-2-性能指标"><a href="#3-2-性能指标" class="headerlink" title="3.2 性能指标"></a>3.2 性能指标</h3><ul><li><code>通信范围(测试)</code>:半径不低于1km</li><li><code>通信范围(生产)</code>:半径不低于3km</li><li><code>延时</code>:平均小于1s</li><li><code>超时率</code>:不超过5%</li><li><code>资源占用</code>:节点RAM不超过2k</li><li><code>运行周期</code>:1分 (测试) | 15分 (生产)</li></ul><h2 id="4-系统环境"><a href="#4-系统环境" class="headerlink" title="4 系统环境"></a>4 系统环境</h2><h3 id="4-1-相关软件及硬件"><a href="#4-1-相关软件及硬件" class="headerlink" title="4.1 相关软件及硬件"></a>4.1 相关软件及硬件</h3><div style="overflow:scroll;"><table ><tr> <td style="vertical-align: middle;text-align: center;"><strong>节点名称</strong></td> <td style="vertical-align: middle;text-align: center;"><strong>硬件设施</strong></td> <td style="vertical-align: middle;text-align: center;"><strong>软件集群</strong></td></tr><tr> <td rowspan="6" style="vertical-align: middle;text-align: center;">土地节点<br/>Ground Nodes</td> <td>Arduino Nano</td> <td>Arduino.h</td></tr><tr> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.11.58a54915TdUHKS&id=556174103413&ns=1&abbucket=14#detail" target="_blank" rel="noopener">SX1278 LORA模块</a></td> <td>SPI.h</td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a230r.1.14.20.161f53ed47xg5U&id=41414863412&ns=1&abbucket=10" target="_blank" rel="noopener">LM35DZ 温度传感</a></td> <td><a href="https://github.com/sandeepmistry/arduino-LoRa" target="_blank" rel="noopener">LoRa.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-21581912015.41.6c425535FUUqU7&id=37365775741&rn=b1c1a8a7f17260619669f001aa3241bf&abbucket=14&skuId=4138700612305" target="_blank" rel="noopener">土壤湿度传感</a></td> <td><a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">LoRa-Socket.h</a></td></tr><tr> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.16.21461532U3rUws&id=541730394024&ns=1&abbucket=14#detail" target="_blank" rel="noopener">四分电磁阀</a></td> <td><a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">LoRa-mqtt.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">vector.h</a></td></tr><tr> <td rowspan="7" style="vertical-align: middle;text-align: center;">气象站节点<br/>Air Station</td> <td>Arduino Nano</td> <td>Arduino.h</td></tr><tr> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.11.58a54915TdUHKS&id=556174103413&ns=1&abbucket=14#detail" target="_blank" rel="noopener">SX1278 LORA模块</a></td> <td>SPI.h</td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.1.1b456f1dTRXYJd&id=576191025158&areaId=320500&user_id=738263294&cat_id=2&is_b=1&rn=14dcb16f28668aa5ca15c5be0f88d092" target="_blank" rel="noopener">BME280 温度,湿度,大气压强传感</a></td> <td><a href="https://github.com/sandeepmistry/arduino-LoRa" target="_blank" rel="noopener">LoRa.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-21581912015.32.2fe555358wswJr&id=521238059334&rn=233756c78897999fd97ca2dd4f649071&abbucket=14" target="_blank" rel="noopener">GY-30 光强传感</a></td> <td><a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">LoRa-Socket.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-21581912015.52.23e05535hDDYEB&id=13302081252&rn=ced14f01f4a9179e7b090c544cf5836a&abbucket=14" target="_blank" rel="noopener">MQ-135 空气质量传感</a></td> <td><a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">LoRa-mqtt.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-21581912015.52.270b5535itNYUg&id=13673403530&rn=418dfd01fe7ae4ce8b775fc271d9886a&abbucket=14" target="_blank" rel="noopener">MQ-7 一氧化碳传感</a></td> <td><a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">vector.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.5-b-s.w4011-21581825912.37.16ca535042HtRT&id=41536690942&rn=a0912ce05addd045044d65bc796797e8&abbucket=14" target="_blank" rel="noopener">雨量传感</a></td> <td></td></tr><tr> <td rowspan="8" style="vertical-align: middle;text-align: center;">LoRa 网关<br/>LoRa Gateway</td> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.58.6c20435c9AhMz2&id=555750159003&ns=1&abbucket=14#detail" target="_blank" rel="noopener">SX1278</a></td> <td>Arduino.h</td></tr><tr> <td></td> <td>SPI.h</td></tr><tr> <td></td> <td>WiFi.h</td></tr><tr> <td></td> <td><a href="https://github.com/sandeepmistry/arduino-LoRa" target="_blank" rel="noopener">LoRa.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">LoRa-Socket.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">LoRa-mqtt.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">vector.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/knolleary/pubsubclient" target="_blank" rel="noopener">PubSubClient.h</a></td></tr><tr> <td rowspan="5" style="vertical-align: middle;text-align: center;">内网控制器/MQTT代理<br/>Controler/MQTT Proxy</td> <td>树莓派3B - RASPBIAN</td> <td>Python3.7</td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a230r.1.14.9.791b1000Beu0tp&id=555610012670&cm_id=140105335569ed55e27b&abbucket=14" target="_blank" rel="noopener">直流变频水泵</a></td> <td>NodeJS</td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-mqtt-proxy" target="_blank" rel="noopener">sf-mqtt-proxy@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-pump" target="_blank" rel="noopener">sf-pump@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/forever" target="_blank" rel="noopener">forever@npm</a></td></tr><tr> <td rowspan="6" style="vertical-align: middle;text-align: center;">云服务器<br/>Cloud Server</td> <td>华为云主机 - Centos7.4</td> <td>Nginx/1.12.2</td></tr><tr> <td></td> <td>NodeJS/12.4.0</td></tr><tr> <td></td> <td>Redis/3.2.12</td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-mqtt-broker" target="_blank" rel="noopener">sf-mqtt-broker@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-web-api" target="_blank" rel="noopener">sf-web-api@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/forever" target="_blank" rel="noopener">forever@npm</a></td></tr><tr> <td rowspan="1" style="vertical-align: middle;text-align: center;">数据库<br/>Database</td> <td>华为云数据库</td> <td>MySQL 5.7.23</td></tr></table></div><h3 id="4-2-数据规模预估"><a href="#4-2-数据规模预估" class="headerlink" title="4.2 数据规模预估"></a>4.2 数据规模预估</h3><p>按照生产场景预估,每15分钟产生一组数据集合,一组数据集合约占用253-291字节。按照291计算,每天将新增27.93KB数据。</p><h2 id="5-设计思路"><a href="#5-设计思路" class="headerlink" title="5 设计思路"></a>5 设计思路</h2><h3 id="5-1-理念"><a href="#5-1-理念" class="headerlink" title="5.1 理念"></a>5.1 理念</h3><ul><li>面向文档</li><li>面向接口</li><li>面向测试</li></ul><h3 id="5-2-关键问题"><a href="#5-2-关键问题" class="headerlink" title="5.2 关键问题"></a>5.2 关键问题</h3><ul><li>土地节点RAM资源稀缺,只有2K</li><li>LoRa通信采用433MHz,单信道收发,干扰多</li><li>服务器需要采集聚合来自多节点的散列数据</li><li>预留与无人机AI小组的交互方法</li><li>实时消息向前端浏览器推送</li></ul><h3 id="5-3-方案选择"><a href="#5-3-方案选择" class="headerlink" title="5.3 方案选择"></a>5.3 方案选择</h3><p>为了<strong>优先</strong>确保通信以及服务的<strong>稳定性</strong>和<strong>可拓展性</strong>,我们选取<strong>分层模型</strong>作为架构的设计模式。整个系统分成多个层级,层级之间具备必要的交互行为。每个层级都独立运行,崩溃时会迅速重启,具备高度的可靠性。</p><p>安全上,采取<strong>内外网隔离</strong>的方法。内网中考虑到部分设备计算资源稀缺,与内网服务器的交互采用不加密的通信模式。内网服务器通过SSL加密的方式与云服务器进行交互。为了确保客户端的资料安全,云服务器API只接受具备SSL加密的HTTP和WebSocket请求。</p><h2 id="6-架构设计"><a href="#6-架构设计" class="headerlink" title="6 架构设计"></a>6 架构设计</h2><h3 id="6-1-基础介绍"><a href="#6-1-基础介绍" class="headerlink" title="6.1 基础介绍"></a>6.1 基础介绍</h3><p>本架构的主要目的是提供一个<strong>稳定(Available)</strong>并<strong>可靠(Reliable)</strong>的物联网系统,通过采集农田中的实时数据,结合通过无人机采集的图片以及CNN判断的植物健康情况,实现对灌溉系统以及植物健康状况的智能管理。本架构理论上适用于大部分农场环境。测试环境半径2~5km(取决于天线)以内,风力3级以下。本系统通过传感器获取农田数据,通过晶体管电路,继电器等控制灌溉系统,通过网页与API与管理者进行交互。</p><h3 id="6-2-系统层级图"><a href="#6-2-系统层级图" class="headerlink" title="6.2 系统层级图"></a>6.2 系统层级图</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_c46f5639_577x906_8_null_normal.jpeg" alt="Smart Farm 系统分层结构图"></p><p>此图展示了此架构的抽象层级结构。正如其所指出的,此分层架构可明确为<strong>感知层</strong>,<strong>网络层</strong>,<strong>应用层</strong>三个横向操作层以及一个纵向<strong>错误处理层</strong>。</p><p>其中,<strong>感知层</strong>又可细化为<strong>环境层</strong>以及<strong>硬件层</strong>。环境层中包含植物,土壤,空气,水流等我们要检测和控制的自然物体,硬件层通过传感器、控制器等人造电气设备为系统对自然要素的交互行为(检测,控制)提供了底层技术可行性。当感知层实现对自然信息的交互后,相应的数字信息被传往网络层进行通信。相应的,感知层也会从网络层接受相应的控制信息,并根据这些指令做出相应的控制行为。</p><p><strong>网络层</strong>分为三层。其中最低一层为<strong>预处理层</strong>,它的主要任务是对感知层采集的数据进行打包处理,转变成网络流通所适合的形式,如套接字。因此,预处理层需要少量的计算存储资源,比如单片机,EEPROM等。经过预处理层的封装后,数据被传往<strong>物理层</strong>。基于物理层中的网关、路由器等设备,这些数据包得以被有秩序的分发和传递。<strong>通信层</strong>中的MQTT协议的应用,使得这些数据包分发的管理更加高效与便利。此外,通信层中QoS服务质量检测体系的实施也使得网络层的性能更加的容错和可靠。</p><p><strong>应用层</strong>主要负责一些应用层面的服务于业务逻辑,比如数据分析,事件处理等。在应用层的最底端,<strong>服务层</strong>在长期的运转着。服务层是应用层中最近接网络层的部分,它的主要目的是实时处理从网络层传入的数据,并对相应的请求及错误事件进行快速响应。同时,服务层也负责将传感器采集的数据进行整理分析并传递到<strong>数据库</strong>层进行存储。为了保证服务的可靠性,服务层的实现程序被注册为系统服务并由专门的守护进程进行守护。与服务层的长期运行不同,<strong>业务层</strong>则是按需唤起。当界面层有新的请求传入或服务层发生特定的事件时,业务层将会被调用并处理它们。除了一些基础的数据分析外,业务层也有权限向AI层进行分析请求。<strong>AI层</strong>通过分析从无人机传回的图像数据后,会传回一个判断结果给业务层。根据请求的具体内容,业务层会将图像识别结果,历史传感器数据等进行整理,并传递到界面层。<strong>界面层</strong>则主要用来提供不同形式的接口,比如HTTP接口和WebSocket接口,以方便客户端调用。</p><h3 id="6-3-系统拓扑图"><a href="#6-3-系统拓扑图" class="headerlink" title="6.3 系统拓扑图"></a>6.3 系统拓扑图</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_27df1756_1426x710_8_null_normal.png" alt="Smart Farm 系统拓扑图"></p><p>从拓扑结构来看,如上图所示,整个系统物理上可划分为土地节点,气象节点,LoRa网关,内网服务器,云服务器,数据库和用户终端。</p><p>从功能机制上看,整个系统包含:传感器模块,LoRa通信模块,LoRa网关模块,MQTT-Proxy代理模块,水泵控制模块,MQTT+数据处理模块,web接口模块,守护进程模块和数据库模块。</p><p><strong><em>土地节点</em></strong><br>土地节点部署于不同区域的农田中,用于探测土壤温度,湿度参数,并能够提供对相应位置水流电磁阀的控制。土地节点使用Arduino Nano作为计算单元,使用LoRa作为通信方式连接LoRa网关(和其它节点),使用电池供电。其数量较多,工作环境恶劣,无线通信不稳定,是系统中最大的不确定性来源。</p><p><strong><em>气象节点</em></strong><br>气象节点部署于农田特定位置,用于探测空气温度,湿度,大气压,降雨量,光照,NH3浓度,CO浓度等气象参数。气象节点使用Arduino Nano作为计算单元,使用LoRa作为通信方式连接LoRa网关(和土地节点),使用电池或有线供电。其工作环境较为恶劣,无线通信质量一般。</p><p><strong><em>LoRa网关</em></strong><br>LoRa网关部署于室内,为扩大有效通信半径,其天线可延伸至室外。LoRa网关通过LoRa连接各土地节点和气象节点,通过WiFi连接内网服务器。LoRa网关能够将通过LoRa传入的socket包转换为mqtt消息并传递给内网服务器,以及将内网服务器传来的mqtt消息转换为socket包通过LoRa发送至指定节点。</p><p><strong><em>内网服务器</em></strong><br>内网服务器是一个树莓派3B,它包含三个功能模块:MQTT-Proxy代理模块,水泵控制模块以及守护进程模块。</p><p><em>MQTT-Proxy代理模块</em>能够接收由LoRa网关通过WiFi发送的mqtt消息,对其进行SSL加密并转发至云服务器。同时,MQTT-Proxy代理模块也将接受指定的来自云服务器的mqtt消息,将其解密并转发至LoRa网关。</p><p><em>水泵控制模块</em>通过树莓派的GPIO通过继电器控制水泵的状态。与水泵控制模块直接与云服务器进行mqtt通信,不经过MQTT-Proxy代理。</p><p><em>守护进程模块</em>运行在Linux上,用于监视MQTT-Proxy代理模块和水泵控制模块。当探测到模块停止运行时,守护进程模块会及时重启这些模块,以确保服务的稳定性和连续性。</p><p><strong><em>云服务器</em></strong><br>云服务器运行在位于北京的华为云上,包含MQTT+数据处理模块,web接口模块和守护进程模块。</p><p><em>MQTT+数据处理模块</em>包含了层级结构中的Service层和Business层。这个模块通过mqtt与内网进行通信,通过mqtt, redis与web接口模块(和AI模块)进行交互。当收到来自内网的各种散列的数据后,本模块会自动对它们进行聚合,整理成一条一条的数据,存入数据库,并通过redis推送给web接口模块。此外,本模块会定时向各节点发送请求以获取它们的数据,这些请求将被追踪以计算延时。</p><p><em>web接口模块</em>提供一系列的HTTP和WebSocket接口。这些接口可用于获取数据,发送指令,刷新数据以及获取推送消息。</p><p><em>守护进程模块</em>运行在Linux上,用于监视MQTT+数据处理模块和web接口模块。当探测到模块停止运行时,守护进程模块会及时重启这些模块,以确保服务的稳定性和连续性。</p><h2 id="7-模块说明"><a href="#7-模块说明" class="headerlink" title="7 模块说明"></a>7 模块说明</h2><h3 id="7-1-LoRa通信模块"><a href="#7-1-LoRa通信模块" class="headerlink" title="7.1 LoRa通信模块"></a>7.1 LoRa通信模块</h3><p>LoRa通信模块用于在单信道情况下实现稳定可靠的socket通信。本模块包含LoRa-socket和LoRa-mqtt。</p><p>LoRa-socket是在LoRa-Arduino的基础上进行了数据包的封装,实现了简单的udp和tcp通信,让传统的LoRa通信更加可靠。通过在数据包的head添加收发ip地址,以及在数据包的最后添加hash校验值,LoRa-socket支持点对点通信和广播通信,并且具有强大的噪音处理能力和数据防篡改能力。<br><strong><em>项目地址</em></strong>:<a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">iotcat/LoRa-socket</a></p><p>LoRa-mqtt是在LoRa-socket基础上对mqtt协议进行的一个简单再现。基于udp和tcp,LoRa-mqtt支持qos为0和1的mqtt通信。<br><strong><em>项目地址</em></strong>:<a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">iotcat/LoRa-mqtt</a></p><h3 id="7-2-MQTT-Proxy代理模块"><a href="#7-2-MQTT-Proxy代理模块" class="headerlink" title="7.2 MQTT-Proxy代理模块"></a>7.2 MQTT-Proxy代理模块</h3><p>本模块运行在内网服务器,实现了对内网mqtt的加密转发。<br><strong><em>项目地址</em></strong>:<a href="https://www.npmjs.com/package/sf-mqtt-broker" target="_blank" rel="noopener">iotcat/sf-mqtt-proxy</a></p><h3 id="7-3-水泵控制模块"><a href="#7-3-水泵控制模块" class="headerlink" title="7.3 水泵控制模块"></a>7.3 水泵控制模块</h3><p>本模块运行在内网服务器,实现了通过GPIO对继电器水泵的控制。<br><strong><em>项目地址</em></strong>:<a href="https://www.npmjs.com/package/sf-pump" target="_blank" rel="noopener">iotcat/sf-pump</a></p><h3 id="7-4-mqtt-数据处理模块"><a href="#7-4-mqtt-数据处理模块" class="headerlink" title="7.4 mqtt+数据处理模块"></a>7.4 mqtt+数据处理模块</h3><p>本模块运行在云服务器,实现了对来自底层mqtt消息的数据聚合,处理和存储。<br><strong><em>项目地址</em></strong>:<a href="https://www.npmjs.com/package/sf-mqtt-broker" target="_blank" rel="noopener">iotcat/sf-mqtt-broker</a></p><h3 id="7-5-web接口模块"><a href="#7-5-web接口模块" class="headerlink" title="7.5 web接口模块"></a>7.5 web接口模块</h3><p>本模块运行在云服务器,实现了功能性接口的提供。<br><strong><em>项目地址</em></strong>:<a href="https://www.npmjs.com/package/sf-web-api" target="_blank" rel="noopener">iotcat/sf-web-api</a></p><h2 id="8-开发文档"><a href="#8-开发文档" class="headerlink" title="8 开发文档"></a>8 开发文档</h2><h3 id="8-1-mqtt主题"><a href="#8-1-mqtt主题" class="headerlink" title="8.1 mqtt主题"></a>8.1 mqtt主题</h3><ul><li><a href="https://doc.smartfarm.yimian.xyz/#/home?id=mqtt" target="_blank" rel="noopener">mqtt主题列表</a></li></ul><h3 id="8-2-http接口"><a href="#8-2-http接口" class="headerlink" title="8.2 http接口"></a>8.2 http接口</h3><ul><li><a href="https://doc.smartfarm.yimian.xyz/#/home?id=api-http" target="_blank" rel="noopener">http接口文档</a></li></ul><h3 id="8-3-websocket接口"><a href="#8-3-websocket接口" class="headerlink" title="8.3 websocket接口"></a>8.3 websocket接口</h3><ul><li><a href="https://doc.smartfarm.yimian.xyz/#/home?id=api-websocket" target="_blank" rel="noopener">websocket接口文档</a></li></ul><h2 id="9-运行状态"><a href="#9-运行状态" class="headerlink" title="9 运行状态"></a>9 运行状态</h2><h3 id="9-1-系统延时"><a href="#9-1-系统延时" class="headerlink" title="9.1 系统延时"></a>9.1 系统延时</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_b36d5030_1806x546_8_null_normal.png" alt="qos"></p><p>上图展示了土地节点(左),气象节点(右),水泵(下)的延时统计折线图。由图可以看出,土地节点的平均延时在730ms左右,气象节点延时在900ms左右,水泵的延时较低,在45ms左右。</p><h3 id="9-2-传感器数据"><a href="#9-2-传感器数据" class="headerlink" title="9.2 传感器数据"></a>9.2 传感器数据</h3><p><a href="https://smartfarm.yimian.xyz/chart-station.html?f=1564484461&t=1564570861" target="_blank" rel="noopener">点击这里查看2019-7-31的气象传感器数据</a></p><hr><p><strong>Reference List:</strong></p><p>[1] OASIS, (2015,12.10). MQTT Version 3.1.1 Plus Errata 01 [Online]. Available: <a href="https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html" target="_blank" rel="noopener">https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt-v3.1.1-errata01-os-complete.html</a></p><p>[2] Sinha, R.S., Wei, Y. and Hwang, S.H., “A survey on LPWA technology: LoRa and NB-IoT”, in Ict Express, 3(1), pp.14-21, 2017.</p></span><span class=".en"><h2 id="1-Background"><a href="#1-Background" class="headerlink" title="1 Background"></a>1 Background</h2><h3 id="1-1-Requirements"><a href="#1-1-Requirements" class="headerlink" title="1.1 Requirements"></a>1.1 Requirements</h3><p>In order to explore the feasibility of agricultural Internet of Things technology, instructor Alam Mohammed hopes that we can provide a <strong>Available</strong> and <strong>Reliable</strong> Internet of Things system to realize intelligent monitoring and management of farmland. This system will be able to timely detect the parameters related to plant health in the soil and the air, process and store these data (proposed by Alam). At the same time, the automatic control irrigation function (proposed by Caleb) and some data display methods (optional requirements proposed by Alam) are also expected to be provided by this system.</p><h3 id="1-2-Positioning"><a href="#1-2-Positioning" class="headerlink" title="1.2 Positioning"></a>1.2 Positioning</h3><p>As it is a small scientific research project designed for the agricultural Internet of Things, the goal of the project is to explore the feasibility of the agricultural Internet of Things, and the vision is to simulate the most common small-scale agricultural Internet of Things application scenarios. Therefore, the positioning of this architecture is <strong>applicable to most small agricultural IoT projects with sensing, control and display functions</strong>.</p><h2 id="2-Glossary"><a href="#2-Glossary" class="headerlink" title="2 Glossary"></a>2 Glossary</h2><blockquote><ul><li><code>MQTT</code>: MQTT Message Queuing Telemetry Transport is a message protocol based on the publish/subscribe paradigm under the ISO standard (ISO/IEC PRF 20922). It works on the TCP/IP protocol suite and is a publish/subscribe message protocol designed for remote devices with low hardware performance and poor network conditions [1].</li></ul></blockquote><blockquote><ul><li><code>LoRa</code>: LoRa is an emerging technology in the current market, which operates in the public frequency band below 1 GHz for long-distance low-power communication [2].</li></ul></blockquote><h2 id="3-Design-goals"><a href="#3-Design-goals" class="headerlink" title="3 Design goals"></a>3 Design goals</h2><h3 id="3-1-Implementing-functions"><a href="#3-1-Implementing-functions" class="headerlink" title="3.1 Implementing functions"></a>3.1 Implementing functions</h3><p>The functional requirements of this architecture mainly include land data collection, weather data collection, irrigation system control, interaction with the drone group system, web console (can view real-time and historical sensor data, index data; be able to control the system).</p><h3 id="3-2-Performance-indicators"><a href="#3-2-Performance-indicators" class="headerlink" title="3.2 Performance indicators"></a>3.2 Performance indicators</h3><ul><li><code>Communication range (test)</code>: the radius is not less than 1km</li><li><code>Communication range (production)</code>: the radius is not less than 3km</li><li><code>Delay</code>: average less than 1s</li><li><code>Timeout rate</code>: no more than 5%</li><li><code>Resource occupation</code>: Node RAM does not exceed 2k</li><li><code>Run cycle</code>: 1 minute (test) | 15 minutes (production)</li></ul><h2 id="4-System-Environment"><a href="#4-System-Environment" class="headerlink" title="4 System Environment"></a>4 System Environment</h2><h3 id="4-1-Related-software-and-hardware"><a href="#4-1-Related-software-and-hardware" class="headerlink" title="4.1 Related software and hardware"></a>4.1 Related software and hardware</h3><div style="overflow:scroll;"><table><tr> <td style="vertical-align: middle;text-align: center;"><strong>Node name</strong></td> <td style="vertical-align: middle;text-align: center;"><strong>Hardware facilities</strong></td> <td style="vertical-align: middle;text-align: center;"><strong>Software cluster</strong></td></tr><tr> <td rowspan="6" style="vertical-align: middle;text-align: center;">Ground Nodes<br/>Ground Nodes</td> <td>Arduino Nano</td> <td>Arduino.h</td></tr><tr> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.11.58a54915TdUHKS&id=556174103413&ns=1&abbucket=14#detail" target="_blank" rel="noopener">SX1278 LORA module</a></td > <td>SPI.h</td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a230r.1.14.20.161f53ed47xg5U&id=41414863412&ns=1&abbucket=10" target="_blank" rel="noopener">LM35DZ temperature sensor</a></td> <td><a href="https://github.com/sandeepmistry/arduino-LoRa" target="_blank" rel="noopener">LoRa.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-21581912015.41.6c425535FUUqU7&id=37365775741&rn=b1c1a8a7f17260619669f001aa3241bf&abbucket=14&skuId=4138700612305" target="_blank" rel="noopener">土壤湿度传感</a></td> <td><a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">LoRa-Socket.h</a></td></tr><tr> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.16.21461532U3rUws&id=541730394024&ns=1&abbucket=14#detail" target="_blank" rel="noopener">Four-point solenoid valve</a></a></a> td> <td><a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">LoRa-mqtt.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">vector.h</a></td></tr><tr> <td rowspan="7" style="vertical-align: middle;text-align: center;">weather station node<br/>Air Station</td> <td>Arduino Nano</td> <td>Arduino.h</td></tr><tr> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.11.58a54915TdUHKS&id=556174103413&ns=1&abbucket=14#detail" target="_blank" rel="noopener">SX1278 LORA module</a></td > <td>SPI.h</td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a220m.1000858.1000725.1.1b456f1dTRXYJd&id=576191025158&areaId=320500&user_id=738263294&cat_id=2&is_b=1&rn=14dcb16f28668aa5ca15c5be0f88d092" target="_blank" rel="noopener">BME280 温度,湿度,大气压强传感</a></td> <td><a href="https://github.com/sandeepmistry/arduino-LoRa" target="_blank" rel="noopener">LoRa.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-bs.w4011-21581912015.32.2fe555358wswJr&id=521238059334&rn=233756c78897999fd97ca2dd4f649071&abbucket=14" target="_blank" rel="noopener">GY-30 light intensity sensor </a></td> <td><a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">LoRa-Socket.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-bs.w4011-21581912015.52.23e05535hDDYEB&id=13302081252&rn=ced14f01f4a9179e7b090c544cf5836a&abbucket=14" target="_blank" rel="noopener">MQ-135 air quality sensor </a></td> <td><a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">LoRa-mqtt.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.3-bs.w4011-21581912015.52.270b5535itNYUg&id=13673403530&rn=418dfd01fe7ae4ce8b775fc271d9886a&abbucket=14" target="_blank" rel="noopener">MQ-7 carbon monoxide sensor< /a></td> <td><a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">vector.h</a></td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a1z10.5-bs.w4011-21581825912.37.16ca535042HtRT&id=41536690942&rn=a0912ce05addd045044d65bc796797e8&abbucket=14" target="_blank" rel="noopener">rainfall sensor</a> </td> <td></td></tr><tr> <td rowspan="8" style="vertical-align: middle;text-align: center;">LoRa Gateway<br/>LoRa Gateway</td> <td><a href="https://item.taobao.com/item.htm?spm=a230r.1.14.58.6c20435c9AhMz2&id=555750159003&ns=1&abbucket=14#detail" target="_blank" rel="noopener">SX1278</a></td> <td>Arduino.h</td></tr><tr> <td></td> <td>SPI.h</td></tr><tr> <td></td> <td>WiFi.h</td></tr><tr> <td></td> <td><a href="https://github.com/sandeepmistry/arduino-LoRa" target="_blank" rel="noopener">LoRa.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">LoRa-Socket.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">LoRa-mqtt.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">vector.h</a></td></tr><tr> <td></td> <td><a href="https://github.com/knolleary/pubsubclient" target="_blank" rel="noopener">PubSubClient.h</a></td></tr><tr> <td rowspan="5" style="vertical-align: middle;text-align: center;">Intranet Controller/MQTT Proxy<br/>Controler/MQTT Proxy</td> <td>Raspberry Pi 3B-RASPBIAN</td> <td>Python3.7</td></tr><tr> <td><a href="https://detail.tmall.com/item.htm?spm=a230r.1.14.9.791b1000Beu0tp&id=555610012670&cm_id=140105335569ed55e27b&abbucket=14" target="_blank" rel="noopener">DC frequency conversion water pump</a></td> <td>NodeJS</td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-mqtt-proxy" target="_blank" rel="noopener">sf-mqtt-proxy@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-pump" target="_blank" rel="noopener">sf-pump@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/forever" target="_blank" rel="noopener">forever@npm</a></td></tr><tr> <td rowspan="6" style="vertical-align: middle;text-align: center;">Cloud Server<br/>Cloud Server</td> <td>Huawei Cloud Host-Centos7.4</td> <td>Nginx/1.12.2</td></tr><tr> <td></td> <td>NodeJS/12.4.0</td></tr><tr> <td></td> <td>Redis/3.2.12</td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-mqtt-broker" target="_blank" rel="noopener">sf-mqtt-broker@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/sf-web-api" target="_blank" rel="noopener">sf-web-api@npm</a></td></tr><tr> <td></td> <td><a href="https://www.npmjs.com/package/forever" target="_blank" rel="noopener">forever@npm</a></td></tr><tr> <td rowspan="1" style="vertical-align: middle;text-align: center;">Database<br/>Database</td> <td>Huawei Cloud Database</td> <td>MySQL 5.7.23</td></tr></table></div><h3 id="4-2-Data-size-estimation"><a href="#4-2-Data-size-estimation" class="headerlink" title="4.2 Data size estimation"></a>4.2 Data size estimation</h3><p>According to the production scenario, a data set is generated every 15 minutes, and a data set occupies about 253-291 bytes. According to 291 calculation, 27.93KB of data will be added every day.</p><h2 id="5-Design-Ideas"><a href="#5-Design-Ideas" class="headerlink" title="5 Design Ideas"></a>5 Design Ideas</h2><h3 id="5-1-Idea"><a href="#5-1-Idea" class="headerlink" title="5.1 Idea"></a>5.1 Idea</h3><ul><li>Document-oriented</li><li>Interface-oriented</li><li>Test-oriented</li></ul><h3 id="5-2-Key-Issues"><a href="#5-2-Key-Issues" class="headerlink" title="5.2 Key Issues"></a>5.2 Key Issues</h3><ul><li>Land node RAM resources are scarce, only 2K</li><li>LoRa communication adopts 433MHz, single-channel transceiving, much interference</li><li>The server needs to collect and aggregate hash data from multiple nodes</li><li>Reserve a method of interaction with the drone AI team</li><li>Push real-time messages to the front-end browser</li></ul><h3 id="5-3-Scheme-selection"><a href="#5-3-Scheme-selection" class="headerlink" title="5.3 Scheme selection"></a>5.3 Scheme selection</h3><p>In order to <strong>prioritize</strong> to ensure the <strong>stability</strong> and <strong>scalability</strong> of communication and services, we select <strong>layered model</strong> as the design mode of the architecture. The entire system is divided into multiple levels, with necessary interactions between levels. Each level runs independently, restarts quickly when it crashes, and has a high degree of reliability.</p><p>In terms of safety, the method of <strong>internal and external network isolation</strong> is adopted. Taking into account the scarcity of computing resources of some devices in the intranet, the interaction with the intranet server adopts an unencrypted communication mode. The intranet server interacts with the cloud server through SSL encryption. To ensure the security of the client’s data, the cloud server API only accepts HTTP and WebSocket requests with SSL encryption.</p><h2 id="6-Architecture-Design"><a href="#6-Architecture-Design" class="headerlink" title="6 Architecture Design"></a>6 Architecture Design</h2><h3 id="6-1-Basic-introduction"><a href="#6-1-Basic-introduction" class="headerlink" title="6.1 Basic introduction"></a>6.1 Basic introduction</h3><p>The main purpose of this architecture is to provide a <strong>stable (Available)</strong> and <strong>reliable</strong> Internet of Things system, which collects real-time data in farmland, combines pictures collected by drones and judged by CNN Plant health, realize intelligent management of irrigation system and plant health. This framework is theoretically suitable for most farm environments. The test environment is within a radius of 2~5km (depending on the antenna), and the wind is below level 3. This system acquires farmland data through sensors, controls the irrigation system through transistor circuits, relays, etc., and interacts with managers through web pages and APIs.</p><h3 id="6-2-System-hierarchy-diagram"><a href="#6-2-System-hierarchy-diagram" class="headerlink" title="6.2 System hierarchy diagram"></a>6.2 System hierarchy diagram</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_c46f5639_577x906_8_null_normal.jpeg" alt="Smart Farm system hierarchical structure diagram"></p><p>This figure shows the abstract hierarchy of this architecture. As pointed out, this layered architecture can be clearly defined as the <strong>perception layer</strong>, <strong>network layer</strong>, <strong>application layer</strong>, three horizontal operation layers, and a vertical <strong>error handling layer</strong>.</p><p>Among them, the <strong>perception layer</strong> can be further refined into <strong>environment layer</strong> and <strong>hardware layer</strong>. The environment layer contains plants, soil, air, water and other natural objects that we want to detect and control. The hardware layer provides the underlying technology for the system’s interactive behavior (detection, control) of natural elements through artificial electrical devices such as sensors and controllers. Sex. When the perception layer realizes the interaction of natural information, the corresponding digital information is transmitted to the network layer for communication. Correspondingly, the perception layer will also receive corresponding control information from the network layer, and make corresponding control actions according to these instructions.</p><p><strong>Network layer</strong> is divided into three layers. The lowest layer is the <strong>preprocessing layer</strong>. Its main task is to package the data collected by the perception layer and transform it into a form suitable for network circulation, such as sockets. Therefore, the pre-processing layer requires a small amount of computing storage resources, such as a single-chip microcomputer, EEPROM, etc. After encapsulation by the preprocessing layer, the data is transmitted to the <strong>physical layer</strong>. Based on devices such as gateways and routers in the physical layer, these data packets can be distributed and transmitted in an orderly manner. The application of the MQTT protocol in the <strong>communication layer</strong> makes the management of these data packet distribution more efficient and convenient. In addition, the implementation of the QoS service quality detection system in the communication layer also makes the performance of the network layer more fault-tolerant and reliable.</p><p><strong>Application layer</strong> is mainly responsible for some application-level services for business logic, such as data analysis, event processing, etc. At the bottom of the application layer, the <strong>service layer</strong> is running for a long time. The service layer is the closest part of the application layer to the network layer. Its main purpose is to process the incoming data from the network layer in real time and respond quickly to corresponding requests and error events. At the same time, the service layer is also responsible for sorting and analyzing the data collected by the sensors and passing it to the <strong>database</strong> layer for storage. In order to ensure the reliability of the service, the implementation program of the service layer is registered as a system service and guarded by a special daemon. Unlike the long-term operation of the service layer, the <strong>business layer</strong> is invoked on demand. When a new request comes in from the interface layer or a specific event occurs in the service layer, the business layer will be called and processed. In addition to some basic data analysis, the business layer also has the authority to make analysis requests to the AI layer. <strong>AI layer</strong> After analyzing the image data returned from the drone, it will send back a judgment result to the business layer. According to the specific content of the request, the business layer will organize the image recognition results, historical sensor data, etc., and pass them to the interface layer. <strong>Interface layer</strong> is mainly used to provide different forms of interfaces, such as HTTP interface and WebSocket interface, to facilitate client calls.</p><h3 id="6-3-System-Topology-Diagram"><a href="#6-3-System-Topology-Diagram" class="headerlink" title="6.3 System Topology Diagram"></a>6.3 System Topology Diagram</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_27df1756_1426x710_8_null_normal.png" alt="Smart Farm system topology diagram"></p><p>From the topological structure, as shown in the figure above, the entire system can be physically divided into land nodes, weather nodes, LoRa gateways, intranet servers, cloud servers, databases and user terminals.</p><p>From the perspective of functional mechanism, the entire system includes: sensor module, LoRa communication module, LoRa gateway module, MQTT-Proxy proxy module, water pump control module, MQTT+ data processing module, web interface module, daemon module and database module.</p><p><strong><em>Land Node</em></strong><br>Land nodes are deployed in farmland in different regions to detect soil temperature and humidity parameters, and can provide control of water flow solenoid valves at corresponding locations. The land node uses Arduino Nano as the computing unit, uses LoRa as the communication method to connect to the LoRa gateway (and other nodes), and uses battery power. Its large number, harsh working environment and unstable wireless communication are the biggest source of uncertainty in the system.</p><p><strong><em>Weather Node</em></strong><br>Meteorological nodes are deployed at specific locations in farmland to detect meteorological parameters such as air temperature, humidity, atmospheric pressure, rainfall, light, NH3 concentration, and CO concentration. The weather node uses Arduino Nano as the computing unit, uses LoRa as the communication method to connect to the LoRa gateway (and the land node), and uses battery or wired power. The working environment is harsh and the wireless communication quality is average.</p><p><strong><em>LoRa Gateway</em></strong><br>The LoRa gateway is deployed indoors. In order to expand the effective communication radius, its antenna can be extended outdoors. The LoRa gateway connects to various land nodes and weather nodes through LoRa, and connects to the intranet server through WiFi. The LoRa gateway can convert the socket packet incoming through LoRa into an mqtt message and pass it to the intranet server, and convert the mqtt message from the intranet server into a socket packet and send it to the designated node through LoRa.</p><p><strong><em>Intranet server</em></strong><br>The intranet server is a Raspberry Pi 3B, which contains three functional modules: MQTT-Proxy proxy module, water pump control module and daemon process module.</p><p><em>MQTT-Proxy proxy module</em> can receive the mqtt message sent by the LoRa gateway via WiFi, encrypt it with SSL and forward it to the cloud server. At the same time, the MQTT-Proxy proxy module will also accept the specified mqtt message from the cloud server, decrypt it and forward it to the LoRa gateway.</p><p><em>Water pump control module</em> The state of the water pump is controlled through a relay through the GPIO of the Raspberry Pi. The mqtt communication with the water pump control module directly communicates with the cloud server without passing through the MQTT-Proxy proxy.</p><p><em>Daemon module</em> runs on Linux and is used to monitor the MQTT-Proxy proxy module and the water pump control module. When modules are detected to stop running, the daemon module will restart these modules in time to ensure the stability and continuity of services.</p><p><strong><em>Cloud Server</em></strong><br>The cloud server runs on Huawei Cloud located in Beijing and includes MQTT+ data processing module, web interface module and daemon module.</p><p><em>MQTT+data processing module</em> includes the Service layer and the Business layer in the hierarchical structure. This module communicates with the intranet through mqtt, and interacts with the web interface module (and AI module) through mqtt and redis. After receiving various hashed data from the intranet, this module will automatically aggregate them, organize them into one piece of data, store it in the database, and push it to the web interface module through redis. In addition, this module will periodically send requests to each node to obtain their data, and these requests will be tracked to calculate the delay.</p><p><em>web interface module</em> provides a series of HTTP and WebSocket interfaces. These interfaces can be used to get data, send instructions, refresh data, and get push messages.</p><p><em>Daemon module</em> runs on Linux and is used to monitor MQTT+ data processing module and web interface module. When modules are detected to stop running, the daemon module will restart these modules in time to ensure the stability and continuity of services.</p><h2 id="7-Module-description"><a href="#7-Module-description" class="headerlink" title="7 Module description"></a>7 Module description</h2><h3 id="7-1-LoRa-communication-module"><a href="#7-1-LoRa-communication-module" class="headerlink" title="7.1 LoRa communication module"></a>7.1 LoRa communication module</h3><p>The LoRa communication module is used to realize stable and reliable socket communication in a single channel. This module includes LoRa-socket and LoRa-mqtt.</p><p>LoRa-socket encapsulates data packets on the basis of LoRa-Arduino, realizes simple udp and tcp communication, and makes traditional LoRa communication more reliable. By adding the sending and receiving ip address to the head of the data packet, and adding the hash check value at the end of the data packet, LoRa-socket supports point-to-point communication and broadcast communication, and has powerful noise processing capabilities and data tamper resistance.<br><strong><em>Project address</em></strong>: <a href="https://github.com/IoTcat/LoRa-socket" target="_blank" rel="noopener">iotcat/LoRa-socket</a></p><p>LoRa-mqtt is a simple reproduction of the mqtt protocol based on LoRa-socket. Based on udp and tcp, LoRa-mqtt supports mqtt communication with qos 0 and 1.<br><strong><em>Project address</em></strong>: <a href="https://github.com/IoTcat/LoRa-mqtt" target="_blank" rel="noopener">iotcat/LoRa-mqtt</a></p><h3 id="7-2-MQTT-Proxy-proxy-module"><a href="#7-2-MQTT-Proxy-proxy-module" class="headerlink" title="7.2 MQTT-Proxy proxy module"></a>7.2 MQTT-Proxy proxy module</h3><p>This module runs on the intranet server and realizes the encrypted forwarding of the intranet mqtt.<br><strong><em>Project address</em></strong>: <a href="https://www.npmjs.com/package/sf-mqtt-broker" target="_blank" rel="noopener">iotcat/sf-mqtt-proxy</a></p><h3 id="7-3-Water-pump-control-module"><a href="#7-3-Water-pump-control-module" class="headerlink" title="7.3 Water pump control module"></a>7.3 Water pump control module</h3><p>This module runs on the intranet server and realizes the control of the relay water pump through GPIO.<br><strong><em>Project address</em></strong>: <a href="https://www.npmjs.com/package/sf-pump" target="_blank" rel="noopener">iotcat/sf-pump</a></p><h3 id="7-4-mqtt-data-processing-module"><a href="#7-4-mqtt-data-processing-module" class="headerlink" title="7.4 mqtt+data processing module"></a>7.4 mqtt+data processing module</h3><p>This module runs on the cloud server and realizes the data aggregation, processing and storage of the underlying mqtt messages.<br><strong><em>Project address</em></strong>: <a href="https://www.npmjs.com/package/sf-mqtt-broker" target="_blank" rel="noopener">iotcat/sf-mqtt-broker</a></p><h3 id="7-5-web-interface-module"><a href="#7-5-web-interface-module" class="headerlink" title="7.5 web interface module"></a>7.5 web interface module</h3><p>This module runs on the cloud server and realizes the provision of functional interfaces.<br><strong><em>Project address</em></strong>: <a href="https://www.npmjs.com/package/sf-web-api" target="_blank" rel="noopener">iotcat/sf-web-api</a></p><h2 id="8-Development-Document"><a href="#8-Development-Document" class="headerlink" title="8 Development Document"></a>8 Development Document</h2><h3 id="8-1-mqtt-theme"><a href="#8-1-mqtt-theme" class="headerlink" title="8.1 mqtt theme"></a>8.1 mqtt theme</h3><ul><li><a href="https://doc.smartfarm.yimian.xyz/#/home?id=mqtt" target="_blank" rel="noopener">mqtt topic list</a></li></ul><h3 id="8-2-http-interface"><a href="#8-2-http-interface" class="headerlink" title="8.2 http interface"></a>8.2 http interface</h3><ul><li><a href="https://doc.smartfarm.yimian.xyz/#/home?id=api-http" target="_blank" rel="noopener">httpinterface document</a></li></ul><h3 id="8-3-websocket-interface"><a href="#8-3-websocket-interface" class="headerlink" title="8.3 websocket interface"></a>8.3 websocket interface</h3><ul><li><a href="https://doc.smartfarm.yimian.xyz/#/home?id=api-websocket" target="_blank" rel="noopener">websocket interface document</a></li></ul><h2 id="9-Running-status"><a href="#9-Running-status" class="headerlink" title="9 Running status"></a>9 Running status</h2><h3 id="9-1-System-delay"><a href="#9-1-System-delay" class="headerlink" title="9.1 System delay"></a>9.1 System delay</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_b36d5030_1806x546_8_null_normal.png" alt="qos"></p><p>The figure above shows the line graphs of the delay statistics of the land node (left), the weather node (right), and the water pump (bottom). It can be seen from the figure that the average delay of the land node is about 730ms, the delay of the weather node is about 900ms, and the delay of the water pump is relatively low, about 45ms.</p><h3 id="9-2-Sensor-data"><a href="#9-2-Sensor-data" class="headerlink" title="9.2 Sensor data"></a>9.2 Sensor data</h3><p><a href="https://smartfarm.yimian.xyz/chart-station.html?f=1564484461&t=1564570861" target="_blank" rel="noopener">Click here to view the weather sensor data of 2019-7-31</a></p><hr><p><strong>Reference List:</strong></p><p>[1] OASIS, (2015,12.10). MQTT Version 3.1.1 Plus Errata 01 [Online]. Available: <a href="https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt" target="_blank" rel="noopener">https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/errata01/os/mqtt</a> -v3.1.1-errata01-os-complete.html</p><p>[2] Sinha, R.S., Wei, Y. and Hwang, S.H., “A survey on LPWA technology: LoRa and NB-IoT”, in Ict Express, 3(1), pp.14-21, 2017.</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> Arduino </tag>
<tag> iot </tag>
<tag> LoRa </tag>
<tag> MQTT </tag>
<tag> smart-farming </tag>
</tags>
</entry>
<entry>
<title>Arduino中[]=重载导致的String调用问题</title>
<link href="/tech/arduino-operator-string-issue.html"/>
<url>/tech/arduino-operator-string-issue.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>最近在物联网开发中使用Arduino搭建LoRa网关和节点,发现在调用String时总遇到一些奇奇怪怪的现象。经过排查,发现是由于其它地方[]=运算符的重载所导致。</p></span><span class=".en"><p>Recently, I have used Arduino to build LoRa gateways and nodes in the development of the Internet of Things, and I found that some strange phenomena are always encountered when calling String. After investigation, it was found that it was caused by overloading of the []= operator elsewhere.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>为了方便,在开发节点时,我们使用了<a href="https://github.com/iotcat/lora-socket" target="_blank" rel="noopener">LoRa-Socket</a>和<a href="https://arduinojson.org/" target="_blank" rel="noopener">ArduinoJSON</a>作为依赖。我们发现这两个依赖分别使用时表现良好,但如果在同一个项目文件中使用,则会导致一些怪异的问题。</p><h2 id="情况一"><a href="#情况一" class="headerlink" title="情况一"></a>情况一</h2><p>通过指针调用函数时String参数传递异常。代码如下:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">inline</span> <span class="keyword">static</span> <span class="keyword">void</span> _onReceived(<span class="keyword">const</span> <span class="keyword">String</span>&amp; msg, <span class="keyword">const</span> <span class="keyword">String</span>&amp; from, <span class="keyword">const</span> <span class="keyword">String</span>&amp; to, <span class="keyword">const</span> <span class="keyword">String</span>&amp; type)&#123;</span><br><span class="line"> (*_f)(msg, from, to, type);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>在这个案例中,我们发现msg等String在此函数中的数值是一切正常的,可是却没有能够成功传递到_f中。经过一系列骚操作,我们得出如下结论:</p><ul><li>发现如果将String换成int或其它类型,则参数传递至_f一切正常。有问题的只有String和char类型。</li><li>我们尝试过将String转换为其它类型,再转回,但是没有效果。</li><li>String或char类型全局变量的声明会使单片机崩溃。</li><li>当我们将ArduinoJSON依赖删去,String参数的传递则一切正常。</li></ul><p>我们从而可以得出,这种怪异现象是由于与ArduinoJSON包的冲突所致。</p><h2 id="情况二"><a href="#情况二" class="headerlink" title="情况二"></a>情况二</h2><p>在使用<a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">ArduinoVector</a>制作String类型Vector时,我们也发现了String类型的不稳定现象。神奇的是,这种现象只出现在String的使用中,其它如int类型运作良好。</p><p>这些不稳定现象可以总结如下:</p><ul><li>赋值时被截断</li><li>String值局部乱序</li><li>String值部分乱码</li><li>作为参数传给函数时会失败,读取出来是空(与案例一类似)</li></ul><h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2><p>通过上述两个案例,我们可以初步总结出,这是由于[]=赋值运算符的重载与String有冲突。只要使用[]=重新定义String,即有可能出现String怪异的问题。</p></span><span class=".en"><p>For convenience, we used <a href="https://github.com/iotcat/lora-socket" target="_blank" rel="noopener">LoRa-Socket</a> and <a href="https://arduinojson.org/" target="_blank" rel="noopener">ArduinoJSON</a> as dependencies when developing nodes. We found that these two dependencies perform well when used separately, but if used in the same project file, it will cause some weird problems.</p><h2 id="Situation-One"><a href="#Situation-One" class="headerlink" title="Situation One"></a>Situation One</h2><p>When calling a function through a pointer, the String parameter passing is abnormal. code show as below:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">inline</span> <span class="keyword">static</span> <span class="keyword">void</span> _onReceived(<span class="keyword">const</span> <span class="keyword">String</span>&amp; msg, <span class="keyword">const</span> <span class="keyword">String</span>&amp; from, <span class="keyword">const</span> <span class="keyword">String</span>&amp; to, <span class="keyword">const</span> <span class="keyword">String</span>&amp; type)&#123;</span><br><span class="line"> (*_f)(msg, from, to, type);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure><p>In this case, we found that the value of msg and other String in this function is all normal, but it was not successfully passed to _f. After a series of Sao operations, we come to the following conclusions:</p><ul><li>Found that if you change String to int or other types, the parameters passed to _f are all normal. Only the String and char types are problematic.</li><li>We tried to convert String to other types, and then back, but to no avail.</li><li>The declaration of global variables of type String or char will crash the microcontroller.</li><li>When we delete the ArduinoJSON dependency, the passing of String parameters is normal.</li></ul><p>We can conclude that this strange phenomenon is caused by the conflict with the ArduinoJSON package.</p><h2 id="Situation-Two"><a href="#Situation-Two" class="headerlink" title="Situation Two"></a>Situation Two</h2><p>When using <a href="https://github.com/tomstewart89/Vector" target="_blank" rel="noopener">ArduinoVector</a> to make a String type Vector, we also discovered the instability of the String type. The magic is that this phenomenon only occurs in the use of String, other types such as int work well.</p><p>These instabilities can be summarized as follows:</p><ul><li>Truncated during assignment</li><li>String values are locally out of order</li><li>Part of the String value is garbled</li><li>It will fail when passed as a parameter to the function, and it will be empty (similar to case 1)</li></ul><h2 id="Summary"><a href="#Summary" class="headerlink" title="Summary"></a>Summary</h2><p>Through the above two cases, we can preliminarily conclude that this is due to the conflict between the overload of the []= assignment operator and String. As long as you use []= to redefine String, string weird problems may occur.</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> Arduino </tag>
<tag> cpp </tag>
</tags>
</entry>
<entry>
<title>随机图片API</title>
<link href="/tech/rand-pic-api.html"/>
<url>/tech/rand-pic-api.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>本API基于华为云对象存储,使用华为CDN云加速,全球平均下载速度达10MB/s。API中已收录1100+张二次元图片,20+张Bing壁纸(每日自动抓取),150+张二次元头像,10+张图床上传图片。</p></span><span class=".en"><p>This API is based on Huawei Cloud Object Storage and uses Huawei CDN Cloud acceleration. The global average download speed is 10MB/s. The API has included 1100+ two-dimensional pictures, 20+ Bing wallpapers (automatically captured daily), 150+ two-dimensional avatars, and 10+ pictures uploaded on the bed.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><blockquote><p>本API不承诺<strong>永久</strong>维护,使用前请务必斟酌<strong>使用风险</strong>!!</p></blockquote><h2 id="1-API地址"><a href="#1-API地址" class="headerlink" title="1 API地址"></a>1 API地址</h2><ul><li><code>https://api.yimian.xyz/img</code></li></ul><h2 id="2-快速入门"><a href="#2-快速入门" class="headerlink" title="2 快速入门"></a>2 快速入门</h2><p><strong><em>随机二次元图片</em></strong></p><ul><li><code>GET/POST /img?type=moe</code></li><li>示例:<a href="https://api.yimian.xyz/img?type=moe" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe</a></li></ul><p><strong><em>随机Bing壁纸</em></strong></p><ul><li><code>GET/POST /img?type=wallpaper</code></li><li>示例:<a href="https://api.yimian.xyz/img?type=wallpaper" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=wallpaper</a></li></ul><p><strong><em>随机二次元头像</em></strong></p><ul><li><code>GET/POST /img?type=head</code></li><li>示例:<a href="https://api.yimian.xyz/img?type=head" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=head</a></li></ul><p><strong><em>随机图床图片</em></strong></p><ul><li><code>GET/POST /img?type=imgbed</code></li><li>示例:<a href="https://api.yimian.xyz/img?type=imgbed" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=imgbed</a></li></ul><p><strong><em>随机1920x1080尺寸二次元图片</em></strong></p><ul><li><code>GET/POST /img?type=moe&amp;size=1920x1080</code></li><li>示例:<a href="https://api.yimian.xyz/img?type=moe&size=1920x1080" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe&amp;size=1920x1080</a></li></ul><h2 id="3-参数列表"><a href="#3-参数列表" class="headerlink" title="3 参数列表"></a>3 参数列表</h2><div style="overflow:scroll;"><table><thead><tr><th align="center">名称</th><th align="center">描述</th><th align="center">格式</th><th align="center">示例</th></tr></thead><tbody><tr><td align="center"><strong>type</strong></td><td align="center">图片种类</td><td align="center"><code>moe</code>/<code>wallpaper</code>/<code>head</code>/<code>imgbed</code></td><td align="center"><code>type=moe</code></td></tr><tr><td align="center"><strong>size</strong></td><td align="center">根据图片大小筛选</td><td align="center"><code>??x??</code>;<br><code>*x??</code>;<br><code>*x*</code>;<br><code>??-??x??</code>;<br><code>??-??x??-??</code>;<br><code>??-??x*</code></td><td align="center"><code>display=1920x1080</code>;<br><code>display=1920x*</code>;<br><code>display=1920-1950x230-500</code>;<br><code>display=1920-1950x*</code>;</td></tr><tr><td align="center"><strong>range</strong></td><td align="center">尺寸误差范围</td><td align="center">number</td><td align="center"><code>range=100</code></td></tr><tr><td align="center"><strong>id</strong></td><td align="center">根据图片id筛选</td><td align="center">number</td><td align="center"><code>id=15</code></td></tr><tr><td align="center"><strong>path</strong></td><td align="center">根据路径提取图片</td><td align="center">abs path</td><td align="center"><code>path=wallpaper/img_··mal.jpg</code></td></tr><tr><td align="center"><strong>display</strong></td><td align="center">是否以网页格式展示</td><td align="center"><code>true</code>/<code>false</code>(default)</td><td align="center"><code>display=true</code></td></tr><tr><td align="center"><strong>R18</strong></td><td align="center">是否显示18禁图片</td><td align="center"><code>true</code>/<code>false</code>(default)</td><td align="center"><code>R18=true</code></td></tr></tbody></table></div><h2 id="4-参数详解"><a href="#4-参数详解" class="headerlink" title="4 参数详解"></a>4 参数详解</h2><h3 id="4-1-type"><a href="#4-1-type" class="headerlink" title="4.1 type"></a>4.1 type</h3><p><strong><em>二次元(默认)</em></strong></p><ul><li><code>GET/POST /img?type=moe</code></li><li>图片来源: 呓喵酱的日常收藏(Pivix, Twitter)</li><li>示例:<a href="https://api.yimian.xyz/img?type=moe" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe</a></li></ul><p><strong><em>bing每日壁纸</em></strong></p><ul><li><code>GET/POST /img?type=wallpaper</code></li><li>图片来源: Bing每日壁纸</li><li>示例:<a href="https://api.yimian.xyz/img?type=wallpaper" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=wallpaper</a><blockquote><p>每日自动更新中</p></blockquote></li></ul><p><strong><em>二次元头像</em></strong></p><ul><li><code>GET/POST /img?type=head</code></li><li>图片来源: 从二次元图片中选择性截取</li><li>示例:<a href="https://api.yimian.xyz/img?type=head" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=head</a></li></ul><p><strong><em>呓喵酱图床</em></strong></p><ul><li><code>GET/POST /img?type=imgbed</code></li><li>图片来源: <a href="https://imgbed.yimian.xyz" target="_blank" rel="noopener">呓喵酱图床</a></li><li>示例:<a href="https://api.yimian.xyz/img?type=imgbed" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=imgbed</a></li></ul><p><strong><em>こいぬちゃん</em></strong></p><ul><li><code>GET/POST /img?type=koino</code></li><li>图片来源: @九条だんぼ(Twitter, Pivix, Google)</li><li>示例:<a href="https://api.yimian.xyz/img?type=koino" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=koino</a></li></ul><p><strong><em>EasyVer人机验证</em></strong></p><ul><li><code>GET/POST /img?type=easyver</code></li><li>图片来源: 呓喵酱优化整理</li><li>示例:<a href="https://api.yimian.xyz/img?type=easyver" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=easyver</a></li></ul><h3 id="4-2-display"><a href="#4-2-display" class="headerlink" title="4.2 display"></a>4.2 display</h3><p>如果本参数置为true,则会禁用302跳转,直接返回完整图片编码。本方法<strong>效率极低</strong>,速度很慢,请慎用。</p><p><strong>false(默认)</strong></p><ul><li><code>GET/POST /img?display=false</code></li><li>描述: 302跳转返回图片,建议使用</li><li>示例:<a href="https://api.yimian.xyz/img?display=false" target="_blank" rel="noopener">https://api.yimian.xyz/img?display=false</a></li></ul><p><strong>true</strong></p><ul><li><code>GET/POST /img?display=true</code></li><li>描述: 直接返回图片,速度慢</li><li>示例:<a href="https://api.yimian.xyz/img?display=true" target="_blank" rel="noopener">https://api.yimian.xyz/img?display=true</a></li></ul><h3 id="4-3-size"><a href="#4-3-size" class="headerlink" title="4.3 size"></a>4.3 size</h3><p>使用本参数限制图片尺寸。本参数支持以下格式:</p><p><strong><em>??x??</em></strong></p><ul><li><code>GET/POST /img?size=??x??</code></li><li>描述: 宽度x高度</li><li>示例:<a href="https://api.yimian.xyz/img?size=1920x1080" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1920x1080</a></li></ul><p><strong><em>??x*</em></strong></p><ul><li><code>GET/POST /img?size=??x*</code></li><li>描述: 宽度x任意高度<li>示例:<a href="https://api.yimian.xyz/img?size=1920x*" target="_blank">https://api.yimian.xyz/img?size=1920x*</a></li></li></ul><p><strong><em>\</em>x??*</strong></p><ul><li><code>GET/POST /img?size=*x??</code></li><li>描述: 任意宽度x高度<li>示例:<a href="https://api.yimian.xyz/img?size=*x1080" target="_blank">https://api.yimian.xyz/img?size=*x1080</a></li></li></ul><p><strong><em>\</em>x**</strong></p><ul><li><code>GET/POST /img?size=*x*</code></li><li>描述: 任意宽度x任意高度(默认)<li>示例:<a href="https://api.yimian.xyz/img?size=*x*" target="_blank">https://api.yimian.xyz/img?size=*x*</a></li></li></ul><p><strong><em>??-??x??</em></strong></p><ul><li><code>GET/POST /img?size=??-??x??</code></li><li>描述: 宽度范围x高度</li><li>示例:<a href="https://api.yimian.xyz/img?size=1910-1930x1080" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1910-1930x1080</a></li></ul><p><strong><em>??x??-??</em></strong></p><ul><li><code>GET/POST /img?size=??x??-??</code></li><li>描述: 宽度x高度范围</li><li>示例:<a href="https://api.yimian.xyz/img?size=1920x1070-1090" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1920x1070-1090</a></li></ul><p><strong><em>??-??x??-??</em></strong></p><ul><li><code>GET/POST /img?size=??-??x??-??</code></li><li>描述: 宽度范围x高度范围</li><li>示例:<a href="https://api.yimian.xyz/img?size=1910-1930x1070-1090" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1910-1930x1070-1090</a></li></ul><p><strong><em>??-??x*</em></strong></p><ul><li><code>GET/POST /img?size=??-??x*</code></li><li>描述: 宽度范围x任意高度<li>示例:<a href="https://api.yimian.xyz/img?size=1910-1930x*" target="_blank">https://api.yimian.xyz/img?size=1910-1930x*</a></li></li></ul><p><strong><em>\</em>x??-??*</strong></p><ul><li><code>GET/POST /img?size=*x??-??</code></li><li>描述: 任意宽度x高度范围<li>示例:<a href="https://api.yimian.xyz/img?size=*x1070-1090" target="_blank">https://api.yimian.xyz/img?size=*x1070-1090</a></li></li></ul><h3 id="4-4-range"><a href="#4-4-range" class="headerlink" title="4.4 range"></a>4.4 range</h3><p>本参数规定允许的size的误差,需搭配size使用,默认为0。</p><p><strong><em>对于??型size参数</em></strong></p><ul><li><code>GET/POST /img?size=??x??&amp;range=100</code></li><li>描述: 宽度±100 x 高度±100</li><li>示例:<a href="https://api.yimian.xyz/img?size=1920x1080&range=100" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1920x1080&amp;range=100</a></li></ul><p><strong><em>对于??-??型size参数</em></strong></p><ul><li><code>GET/POST /img?size=??-??x??-??&amp;range=100</code></li><li>描述: 最小宽度-100|最大宽度+100 x 最小高度-100|最大高度+100</li><li>示例:<a href="https://api.yimian.xyz/img?size=1910-1930x1070-1090&range=100" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1910-1930x1070-1090&amp;range=100</a></li></ul><p><strong><em>对于*型size参数</em></strong></p><ul><li><code>GET/POST /img?size=*x*&amp;range=100</code></li><li>描述: range无效</li></ul><h3 id="4-5-id"><a href="#4-5-id" class="headerlink" title="4.5 id"></a>4.5 id</h3><p>每一个种类都有自己的id系统,同一种类下不同图片id唯一。</p><p><strong><em>二次元</em></strong></p><ul><li><code>GET/POST /img?type=moe&amp;id=15</code></li><li>描述:提取id为15的二次元图片</li><li>示例:<a href="https://api.yimian.xyz/img?type=moe&id=15" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe&amp;id=15</a></li></ul><p><strong><em>bing每日壁纸</em></strong></p><ul><li><code>GET/POST /img?type=wallpaper&amp;id=2019-07-28</code></li><li>描述:提取2019-07-28的壁纸图片</li><li>示例:<a href="https://api.yimian.xyz/img?type=wallpaper&id=2019-07-28" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=wallpaper&amp;id=2019-07-28</a></li></ul><p><strong><em>二次元头像</em></strong></p><ul><li><code>GET/POST /img?type=head&amp;id=15</code></li><li>描述:提取id为15的头像</li><li>示例:<a href="https://api.yimian.xyz/img?type=head&id=15" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=head&amp;id=15</a></li></ul><p><strong><em>呓喵酱图床</em></strong></p><ul><li><code>GET/POST /img?type=imgbed&amp;id=529745e0</code></li><li>描述:提取id为529745e0的图床图片</li><li>示例:<a href="https://api.yimian.xyz/img?type=imgbed&id=529745e0" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=imgbed&amp;id=529745e0</a></li></ul><h3 id="4-6-path"><a href="#4-6-path" class="headerlink" title="4.6 path"></a>4.6 path</h3><p>使用绝对路径直接提取图片,优先级高于type,<strong>效率最高</strong>。</p><blockquote><p>请前往<a href="https://img.yimian.xyz/" target="_blank" rel="noopener">呓喵酱の图库</a>获取图片的path!</p></blockquote><ul><li><code>GET/POST /img?path=xx/xx.xx</code></li><li>路径格式:<code>种类/图片文件名</code></li><li>路径格式示例:<code>imgbed/img_529745e0_900x900_8_null_normal.jpeg</code></li><li>描述:提取在xx/xx.xx的图片</li><li>示例:<a href="https://api.yimian.xyz/img/?path=imgbed/img_529745e0_900x900_8_null_normal.jpeg" target="_blank" rel="noopener">https://api.yimian.xyz/img/?path=imgbed/img_529745e0_900x900_8_null_normal.jpeg</a></li></ul><h3 id="4-7-R18"><a href="#4-7-R18" class="headerlink" title="4.7 R18"></a>4.7 R18</h3><p>是否显示18禁图片,默认为false。</p><ul><li><code>GET/POST /img?type=xx&amp;R18=true</code><ul><li>描述:是否解除对R18的限制,随机提取xx类别中包含R18图片在内的所有图片</li><li>示例:<a href="https://api.yimian.xyz/img/?type=koino&R18=true" target="_blank" rel="noopener">https://api.yimian.xyz/img/?type=koino&amp;R18=true</a></li></ul></li></ul><h2 id="5-报错格式"><a href="#5-报错格式" class="headerlink" title="5 报错格式"></a>5 报错格式</h2><h3 id="5-1-找不到指定type类型"><a href="#5-1-找不到指定type类型" class="headerlink" title="5.1 找不到指定type类型"></a>5.1 找不到指定type类型</h3><p>若找不到指定的type类型,将会自动返回一个moe类型的图片。</p><h3 id="5-2-找不到符合条件的图片"><a href="#5-2-找不到符合条件的图片" class="headerlink" title="5.2 找不到符合条件的图片"></a>5.2 找不到符合条件的图片</h3><p>返回JSON</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line"> <span class="string">"err"</span>: <span class="string">"错误信息"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>每台设备每天<strong>全局</strong>调用上限500次!!</p></blockquote><hr><p><strong>CHANGELOG:</strong></p><ul><li><code>2021-1-23</code>: 修改R18参数说明,在path方法中添加图库链接 </li></ul></span><span class=".en"><blockquote><p>This API does not promise <strong>permanent</strong> maintenance, please be sure to consider <strong>use risks</strong> before use! ! </p></blockquote><h2 id="1-API-address"><a href="#1-API-address" class="headerlink" title="1 API address"></a>1 API address</h2><ul><li><code>https://api.yimian.xyz/img</code></li></ul><h2 id="2-Quick-start"><a href="#2-Quick-start" class="headerlink" title="2 Quick start"></a>2 Quick start</h2><p><strong><em>Random two-dimensional picture</em></strong></p><ul><li><code>GET/POST /img?type=moe</code></li><li>Example: <a href="https://api.yimian.xyz/img?type=moe" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe</a></li></ul><p><strong><em>Random Bing Wallpaper</em></strong></p><ul><li><code>GET/POST /img?type=wallpaper</code></li><li>Example: <a href="https://api.yimian.xyz/img?type=wallpaper" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=wallpaper</a></li></ul><p><strong><em>Random two-dimensional avatar</em></strong></p><ul><li><code>GET/POST /img?type=head</code></li><li>Example: <a href="https://api.yimian.xyz/img?type=head" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=head</a></li></ul><p><strong><em>Random bed pictures</em></strong></p><ul><li><code>GET/POST /img?type=imgbed</code></li><li>Example: <a href="https://api.yimian.xyz/img?type=imgbed" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=imgbed</a></li></ul><p><strong><em>Random 1920x1080 size two-dimensional picture</em></strong></p><ul><li><code>GET/POST /img?type=moe&amp;size=1920x1080</code></li><li>Example: <a href="https://api.yimian.xyz/img?type=moe&size=1920x1080" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe&amp;size=1920x1080</a></li></ul><h2 id="3-Parameter-list"><a href="#3-Parameter-list" class="headerlink" title="3 Parameter list"></a>3 Parameter list</h2><div style="overflow:scroll;"><table><thead><tr><th align="center">Name</th><th align="center">Description</th><th align="center">Format</th><th align="center">Example</th></tr></thead><tbody><tr><td align="center"><strong>type</strong></td><td align="center">Image type</td><td align="center"><code>moe</code>/<code>wallpaper</code>/<code>head</code>/<code>imgbed</code></td><td align="center"><code>type=moe</code></td></tr><tr><td align="center"><strong>size</strong></td><td align="center">Filter by image size</td><td align="center"><code>??x??</code>;<br><code>*x??</code>;<br><code>*x*</code>;<br><code>??-??x??</code>;<br><code>??-??x??-??</code>;<br> <code>??-??x*</code></td><td align="center"><code>display=1920x1080</code>;<br><code>display=1920x*</code>;<br ><code>display=1920-1950x230-500</code>;<br><code>display=1920-1950x*</code>;</td></tr><tr><td align="center"><strong>range</strong></td><td align="center">Size error range</td><td align="center">number</td><td align="center"><code>range=100</code></td></tr><tr><td align="center"><strong>id</strong></td><td align="center">Filter by image id</td><td align="center">number</td><td align="center"><code>id=15</code></td></tr><tr><td align="center"><strong>path</strong></td><td align="center">Extract pictures based on path</td><td align="center">abs path</td><td align="center"><code>path=wallpaper/img_··mal.jpg</code></td></tr><tr><td align="center"><strong>display</strong></td><td align="center">Whether to display in web page format</td><td align="center"><code>true</code>/<code>false</code>(default)</td><td align="center"><code>display=true</code></td></tr><tr><td align="center"><strong>R18</strong></td><td align="center">Whether to display 18 prohibited pictures</td><td align="center"><code>true</code>/<code>false</code>(default)</td><td align="center"><code>R18=true</code></td></tr></tbody></table></div><h2 id="4-Detailed-parameters"><a href="#4-Detailed-parameters" class="headerlink" title="4 Detailed parameters"></a>4 Detailed parameters</h2><h3 id="4-1-type-1"><a href="#4-1-type-1" class="headerlink" title="4.1 type"></a>4.1 type</h3><p><strong><em>Two-dimensional (default)</em></strong></p><ul><li><code>GET/POST /img?type=moe</code></li><li>Image source: Daily Collection of Miao Miao Jiang (Pivix, Twitter)</li><li>Example: <a href="https://api.yimian.xyz/img?type=moe" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe</a></li></ul><p><strong><em>bing daily wallpaper</em></strong></p><ul><li><code>GET/POST /img?type=wallpaper</code></li><li>Image source: Bing Daily Wallpaper</li><li>Example: <a href="https://api.yimian.xyz/img?type=wallpaper" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe</a><blockquote><p>Automatically updated daily</p></blockquote></li></ul><p><strong><em>Two-dimensional avatar</em></strong></p><ul><li><code>GET/POST /img?type=head</code></li><li>Image source: Selectively intercepted from two-dimensional images</li><li>Example: <a href="https://api.yimian.xyz/img?type=head" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=head</a></li></ul><p><strong><em>Miao meow sauce picture bed</em></strong></p><ul><li><code>GET/POST /img?type=imgbed</code></li><li>Image source: <a href="https://imgbed.yimian.xyz" target="_blank" rel="noopener">呓喵酱图床</a></li><li>Example: <a href="https://api.yimian.xyz/img?type=imgbed" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=imgbed</a></li></ul><p><strong><em>こいぬちゃん</em></strong></p><ul><li><code>GET/POST /img?type=koino</code></li><li>Image source: @九条だんぼ (Twitter, Pivix, Google)</li><li>Example: <a href="https://api.yimian.xyz/img?type=koino" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=koino</a></li></ul><p><strong><em>EasyVer man-machine verification</em></strong></p><ul><li><code>GET/POST /img?type=easyver</code></li><li>Image source: Optimized finishing</li><li>Example: <a href="https://api.yimian.xyz/img?type=easyver" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=easyver</a></li></ul><h3 id="4-2-display-1"><a href="#4-2-display-1" class="headerlink" title="4.2 display"></a>4.2 display</h3><p>If this parameter is set to true, 302 jump will be disabled and the complete picture encoding will be returned directly. This method is <strong>very low</strong> and slow. Please use it carefully.</p><p><strong>false (default)</strong></p><ul><li><code>GET/POST /img?display=false</code></li><li>Description: 302 Jump to return to the picture, recommended</li><li>Example: <a href="https://api.yimian.xyz/img?display=false" target="_blank" rel="noopener">https://api.yimian.xyz/img?display=false</a></li></ul><p><strong>true</strong></p><ul><li><code>GET/POST /img?display=true</code></li><li>Description: Return to the picture directly, slow</li><li>Example: <a href="https://api.yimian.xyz/img?display=true" target="_blank" rel="noopener">https://api.yimian.xyz/img?display=true</a></li></ul><h3 id="4-3-size-1"><a href="#4-3-size-1" class="headerlink" title="4.3 size"></a>4.3 size</h3><p>Use this parameter to limit the image size. This parameter supports the following formats:</p><p><strong><em>??x??</em></strong></p><ul><li><code>GET/POST /img?size=??x??</code></li><li>Description: width x height</li><li>Example: <a href="https://api.yimian.xyz/img?size=1920x1080" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1920x1080</a></li></ul><p><strong><em>??x*</em></strong></p><ul><li><code>GET/POST /img?size=??x*</code></li><li>Description: width x any height<li>Example: <a href="https://api.yimian.xyz/img?size=1920x*" target="_blank">https://api.yimian.xyz/img?size=1920x*</a></li></li></ul><p><strong><em>\</em>x??*</strong></p><ul><li><code>GET/POST /img?size=*x??</code></li><li>Description: Any width x height<li>Example: <a href="https://api.yimian.xyz/img?size=*x1080" target="_blank">https://api.yimian.xyz/img?size=*x1080</a></li></li></ul><p><strong><em>\</em>x**</strong></p><ul><li><code>GET/POST /img?size=*x*</code></li><li>Description: any width x any height (default)<li>Example: <a href="https://api.yimian.xyz/img?size=*x*" target="_blank">https://api.yimian.xyz/img?size=*x *</a></li></li></ul><p><strong><em>??-??x??</em></strong></p><ul><li><code>GET/POST /img?size=??-??x??</code></li><li>Description: width range x height</li><li>Example: <a href="https://api.yimian.xyz/img?size=1910-1930x1080" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1910-1930x1080</a></li></ul><p><strong><em>??x??-??</em></strong></p><ul><li><code>GET/POST /img?size=??x??-??</code></li><li>Description: width x height range</li><li>Example: <a href="https://api.yimian.xyz/img?size=1920x1070-1090" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1920x1070-1090</a></li></ul><p><strong><em>??-??x??-??</em></strong></p><ul><li><code>GET/POST /img?size=??-??x??-??</code></li><li>Description: width range x height range</li><li>Example: <a href="https://api.yimian.xyz/img?size=1910-1930x1070-1090" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1910-1930x1070-1090</a></li></ul><p><strong><em>??-??x*</em></strong></p><ul><li><code>GET/POST /img?size=??-??x*</code></li><li>Description: width range x any height<li>Example: <a href="https://api.yimian.xyz/img?size=1910-1930x*" target="_blank">https://api.yimian.xyz/img?size=1910 -1930x*</a></li></li></ul><p><strong><em>\</em>x??-??*</strong></p><ul><li><code>GET/POST /img?size=*x??-??</code></li><li>Description: Any width x height range<li>Example: <a href="https://api.yimian.xyz/img?size=*x1070-1090" target="_blank">https://api.yimian.xyz/img?size=* x1070-1090</a></li></li></ul><h3 id="4-4-range-1"><a href="#4-4-range-1" class="headerlink" title="4.4 range"></a>4.4 range</h3><p>This parameter specifies the allowable size error, which needs to be used with size, and the default is 0.</p><p><strong><em>For the?? type size parameter</em></strong></p><ul><li><code>GET/POST /img?size=??x??&amp;range=100</code></li><li>Description: width ±100 x height ±100</li><li>Example: <a href="https://api.yimian.xyz/img?size=1920x1080&range=100" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1920x1080&amp;range=100</a></li></ul><p><strong><em>For??-?? type size parameter</em></strong></p><ul><li><code>GET/POST /img?size=??-??x??-??&amp;range=100</code></li><li>Description: Min width-100|Max width+100 x Min height-100|Max height+100</li><li>Example: <a href="https://api.yimian.xyz/img?size=1910-1930x1070-1090&range=100" target="_blank" rel="noopener">https://api.yimian.xyz/img?size=1910-1930x1070-1090&amp;range=100</a></li></ul><p><strong><em>For *type size parameter</em></strong></p><ul><li><code>GET/POST /img?size=*x*&amp;range=100</code></li><li>Description: Invalid range</li></ul><h3 id="4-5-id-1"><a href="#4-5-id-1" class="headerlink" title="4.5 id"></a>4.5 id</h3><p>Each category has its own id system, and different image ids under the same category are unique.</p><p><strong>*Two-dimensional *</strong></p><ul><li><code>GET/POST /img?type=moe&amp;id=15</code></li><li>Description: Extract the two-dimensional image with id 15</li><li>Example: <a href="https://api.yimian.xyz/img?type=moe&id=15" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=moe&amp;id=15</a></li></ul><p><strong><em>bing daily wallpaper</em></strong></p><ul><li><code>GET/POST /img?type=wallpaper&amp;id=2019-07-28</code></li><li>Description: Extract wallpaper pictures from 2019-07-28</li><li>Example: <a href="https://api.yimian.xyz/img?type=wallpaper&id=2019-07-28" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=wallpaper&amp;id=2019-07-28</a></li></ul><p><strong><em>Two-dimensional avatar</em></strong></p><ul><li><code>GET/POST /img?type=head&amp;id=15</code></li><li>Description: Extract the avatar with id 15</li><li>Example: <a href="https://api.yimian.xyz/img?type=head&id=15" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=head&amp;id=15</a></li></ul><p><strong><em>Miao meow sauce picture bed</em></strong></p><ul><li><code>GET/POST /img?type=imgbed&amp;id=529745e0</code></li><li>Description: Extract the picture bed with id 529745e0</li><li>Example: <a href="https://api.yimian.xyz/img?type=imgbed&id=529745e0" target="_blank" rel="noopener">https://api.yimian.xyz/img?type=imgbed&amp;id=529745e0</a></li></ul><h3 id="4-6-path-1"><a href="#4-6-path-1" class="headerlink" title="4.6 path"></a>4.6 path</h3><p>Use absolute path to directly extract pictures, priority is higher than type, <strong>highest efficiency</strong>.</p><blockquote><p>Please go to <a href="https://img.yimian.xyz/" target="_blank" rel="noopener">呓喵酱の Gallery</a> to get the path of the picture!</p></blockquote><ul><li><code>GET/POST /img?path=xx/xx.xx</code></li><li>Path format: <code>Type/Picture File Name</code></li><li>Example of path format: <code>imgbed/img_529745e0_900x900_8_null_normal.jpeg</code></li><li>Description: Extract pictures in xx/xx.xx</li><li>Example: <a href="https://api.yimian.xyz/img/?path=imgbed/img_529745e0_900x900_8_null_normal.jpeg" target="_blank" rel="noopener">https://api.yimian.xyz/img/?path=imgbed/img_529745e0_900x900_8_null_normal.jpeg</a></li></ul><h3 id="4-7-R18-1"><a href="#4-7-R18-1" class="headerlink" title="4.7 R18"></a>4.7 R18</h3><p>Whether to display 18 prohibited pictures, the default is false.</p><ul><li><code>GET/POST /img?type=xx&amp;R18=true</code><ul><li>Description: Whether to lift the restriction on R18, randomly extract all pictures including R18 pictures in xx category</li><li>Example: <a href="https://api.yimian.xyz/img/?type=koino&R18=true" target="_blank" rel="noopener">https://api.yimian.xyz/img/?type=koino&amp;R18=true</a></li></ul></li></ul><h2 id="5-Error-format"><a href="#5-Error-format" class="headerlink" title="5 Error format"></a>5 Error format</h2><h3 id="5-1-Cannot-find-the-specified-type"><a href="#5-1-Cannot-find-the-specified-type" class="headerlink" title="5.1 Cannot find the specified type"></a>5.1 Cannot find the specified type</h3><p>If the specified type cannot be found, a moe type picture will be automatically returned.</p><h3 id="5-2-Can’t-find-matching-images"><a href="#5-2-Can’t-find-matching-images" class="headerlink" title="5.2 Can’t find matching images"></a>5.2 Can’t find matching images</h3><p>Return JSON</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line"> <span class="string">"err"</span>: <span class="string">"error message"</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>The maximum number of <strong>global calls</strong> for each device is 500 per day!!</p></blockquote></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> api </tag>
<tag> img </tag>
<tag> random </tag>
<tag> moe </tag>
</tags>
</entry>
<entry>
<title>wIoT - 轻松物联</title>
<link href="/tech/wiot.html"/>
<url>/tech/wiot.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>基于NodeJS搭建的物联网系统,配合D1 MINI单片机,帮助你灰常快速实现物联~</p></span><span class=".en"><p>The Internet of Things system based on NodeJS, combined with D1 MINI microcontroller, helps you quickly realize the Internet of Things~</p></span><a id="more"></a><script> session.onload(function(){ if(page.tran.getLang() == 'en'){ tips.warning({ title: 'Caution', position: 'topRight', message: 'English version may be not up to date!!', buttons: [['<button>Show Chinese Page</button>', function (instance, toast) { page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]] }); } });</script><span class=".zh"><h3 id="wIoT-for-NodeJS"><a href="#wIoT-for-NodeJS" class="headerlink" title="wIoT for NodeJS"></a>wIoT for NodeJS</h3><p>适用于NodeJS的wIoT服务器控制组件,轻松物联</p><h1 id="项目简介"><a href="#项目简介" class="headerlink" title="项目简介"></a>项目简介</h1><h2 id="立项初衷"><a href="#立项初衷" class="headerlink" title="立项初衷"></a>立项初衷</h2><p>本项目旨在帮助不熟悉固件编程的网络开发者实现出自己的物联网应用。您仅需要一台网络内部的服务器(比如树莓派),以及若干个支持可联网(通过串口,WiFi,LoRa,蓝牙,Zigbee等)的单片机,即可轻松创建并管理属于您自己的物联网集群。</p><h2 id="支持功能"><a href="#支持功能" class="headerlink" title="支持功能"></a>支持功能</h2><ul><li>ota (隔空自动更新固件)</li><li>自动扫描网络内单片机</li><li>通过wifi连接设置</li><li>使用socket/HTTP通信</li></ul><h2 id="todo-List"><a href="#todo-List" class="headerlink" title="todo List"></a>todo List</h2><ul><li>支持python界面</li><li>开发web面板,图像化管理</li><li>支持更多单片机,比如esp8266等</li><li>开发nodeJS wiot-cli 命令行程序</li><li>支持nodeJS自动烧写固件,并自动配置(很重要)</li></ul><h1 id="使用方法"><a href="#使用方法" class="headerlink" title="使用方法"></a>使用方法</h1><blockquote><p>正式开发文档见<a href="https://wiot.yimian.xyz/#/home" target="_blank" rel="noopener"><strong>这里</strong></a></p></blockquote><h2 id="先觉条件"><a href="#先觉条件" class="headerlink" title="先觉条件"></a>先觉条件</h2><ul><li>拥有烧录好<a href="https://wiot-ota.yimian.xyz/get.php" target="_blank" rel="noopener">wIoT固件</a>的<strong>D1 MINI</strong>单片机</li><li>一台或多台无线WiFi路由器2.4G/5G</li><li>局域网内拥有一台装有<strong>NodeJS</strong>的服务器或电脑 (NodeJS装法非常简单, 请自行Google或百度)</li><li>配置好<strong>npm</strong></li></ul><h2 id="快速开始"><a href="#快速开始" class="headerlink" title="快速开始"></a>快速开始</h2><h3 id="单片机接入"><a href="#单片机接入" class="headerlink" title="单片机接入"></a>单片机接入</h3><ol><li>使用MicroUSB, 5V, 或3V pin脚给单片机供电</li><li>用一根导线连接D0脚与3V3脚,持续一秒以上拔出,以重置单片机</li><li>用手机或电脑搜索它的WiFi热点,名称格式<code>wiot-xx:xx:xx:xx:xx:xx</code></li><li>连接上此热点,密码为<code>1234567890</code></li><li>用浏览器打开网址<code>http://192.168.0.1</code>,记录网页中的MAC地址,这将用于识别此单片机</li><li>配置你无线路由器的ssid(即wifi名称,注意不能有非ASCII字符,比如汉字)和密码</li><li>配置完成后热点将自动断开,单片机将连接到你的无线路由器</li></ol><h3 id="依赖安装"><a href="#依赖安装" class="headerlink" title="依赖安装"></a>依赖安装</h3><p>在你的项目文件夹下打开命令行,输入以下指令安装wiot:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> npm install wiot</span></span><br></pre></td></tr></table></figure><h3 id="使用方法-1"><a href="#使用方法-1" class="headerlink" title="使用方法"></a>使用方法</h3><p>在你的项目文件夹中新建一个app.js文件,输入以下内容:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> wiot = <span class="built_in">require</span>(<span class="string">'wiot'</span>); <span class="comment">//引入wiot依赖包</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 新建一个单片机对象</span></span><br><span class="line"><span class="comment">// 这里使用了两个参数,MAC是单片机的MAC地址,pin中指定需要OUTPUT输出的端口</span></span><br><span class="line"><span class="comment">// 请自行修改MAC地址的值</span></span><br><span class="line"><span class="keyword">var</span> MyMCU = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 以下代码将实现,板载led亮1秒,灭1秒的循环</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 等待所有单品即准备就绪</span></span><br><span class="line">wiot.begin([MyMCU], ()=&gt;&#123; <span class="comment">// 第一个参数为要等待的单片机对象数组,第二个参数为要执行的函数</span></span><br><span class="line"> <span class="comment">// 设置计时器,每隔2000毫秒, MyMCU的3号pin口将拉高一次电平</span></span><br><span class="line"> setInterval(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> MyMCU.write(wiot.D4, wiot.HIGH);</span><br><span class="line"> &#125;, <span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 设置计时器,延时1000毫秒后开始执行大括号中指令</span></span><br><span class="line"> setTimeout(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> <span class="comment">// 设置计时器,每隔2000毫秒,MyMCU的3号pin口将拉低一次电平</span></span><br><span class="line"> setInterval(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> MyMCU.write(wiot.D4, wiot.LOW);</span><br><span class="line"> &#125;, <span class="number">2000</span>);</span><br><span class="line"> &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="开始执行"><a href="#开始执行" class="headerlink" title="开始执行"></a>开始执行</h3><p>在项目文件夹中打开命令行,输入以下指令:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">node app.js</span><br></pre></td></tr></table></figure><h3 id="预期结果"><a href="#预期结果" class="headerlink" title="预期结果"></a>预期结果</h3><p>如果一切顺利,你现在应该会发现你的板载led在闪烁了</p><h3 id="社区支持"><a href="#社区支持" class="headerlink" title="社区支持"></a>社区支持</h3><p>也许你会觉得上述代码难以理解,这是正常的,由于delay功能在JS中难以实现。但是不用担心,这些问题将会由社区中的其它开发者帮你解决。 </p><p>wIoT在实现基本的单片机控制同时,也提供了丰富的<a href="#传感器扩展模块">扩展功能</a>。更神奇的是,任何人都可以在wIoT中编写自己的扩展并与全世界共享它们。在这里我们可以使用wIoT官方提供的led扩展轻松实现上例功能!</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> wiot = <span class="built_in">require</span>(<span class="string">'wiot'</span>); <span class="comment">//引入wiot依赖包</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 新建一个单片机对象</span></span><br><span class="line"><span class="keyword">var</span> MyMCU = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 新建一个led模块</span></span><br><span class="line"><span class="keyword">var</span> led = <span class="keyword">new</span> wiot.led(MyMCU, wiot.D4);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 以下代码将实现,板载led亮1秒,灭1秒的循环</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 等待所有单品即准备就绪</span></span><br><span class="line">wiot.begin([MyMCU], ()=&gt;&#123;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 调用led模块构建亮1秒灭1秒的动作</span></span><br><span class="line"> led.set([wiot.HIGH, wiot.LOW], [<span class="number">1000</span>, <span class="number">1000</span>]);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="进阶设置"><a href="#进阶设置" class="headerlink" title="进阶设置"></a>进阶设置</h2><h3 id="wiot-client"><a href="#wiot-client" class="headerlink" title="wiot.client"></a>wiot.client</h3><h4 id="参数说明"><a href="#参数说明" class="headerlink" title="参数说明"></a>参数说明</h4><div style="overflow:scroll;"><table><thead><tr><th>名称</th><th>默认值</th><th>描述</th></tr></thead><tbody><tr><td>MAC</td><td>“”</td><td>单片机的MAC地址</td></tr><tr><td>pin</td><td>{D1: 0, D2: 0, D3: 0, D4: 0, D5: 0, D6: 0, D7: 0, D8: 0}</td><td>pin脚的模式, 0为INPUT, 1为OUTPUT, 2为INPUT_PULLUP</td></tr><tr><td>hint</td><td>true</td><td>是否显示状态提示</td></tr><tr><td>debug</td><td>false</td><td>是否开启debug模式</td></tr><tr><td>ip</td><td>“default”</td><td>指定单片机IP, 请在长时间搜索不到IP时尝试此选项</td></tr><tr><td>port</td><td>8848</td><td>Client的TCP Socket通信端口,默认8848</td></tr><tr><td>ip_range</td><td>“192.168.0”</td><td>IP搜索字段,请在长时间搜索不到IP时尝试此选项</td></tr><tr><td>localIP</td><td>“127.0.0.1”</td><td>本机IP</td></tr><tr><td>OnlyHTTP</td><td>false</td><td>是否仅使用HTTP模式连接单片机</td></tr><tr><td>errDelayTime</td><td>2000</td><td>遇到网络错误时重试间隔时间(毫秒)</td></tr><tr><td>okDelayTime</td><td>30</td><td>收到网络请求后延时等待时间(毫秒)</td></tr><tr><td>resetDelayTime</td><td>4500</td><td>向单片机发送重置指令后多久不再发送新消息(毫秒)</td></tr><tr><td>noTryMaxTime</td><td>15000</td><td>经过此时间单片机仍未响应则重新发送消息(毫秒)</td></tr><tr><td>IntervalTime</td><td>2000</td><td>监听行为心跳间隔</td></tr><tr><td>MaxToReScanTime</td><td>180000</td><td>经过此事件单片机无响应则从新扫描IP地址(毫秒)</td></tr><tr><td>MinResearchTime</td><td>5000</td><td>搜索IP经过一此轮询后间隔时间(毫秒)</td></tr><tr><td>IpScanTimeout</td><td>1</td><td>IP扫描时的Ping检测超时时间(秒)</td></tr><tr><td>pingTimeout</td><td>2</td><td>心跳Ping检测的超时时间(秒)</td></tr><tr><td>MaxTraceBackTimes</td><td>8</td><td>判断连接状态所向前追溯的历史心跳个数</td></tr></tbody></table></div><p>例如:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MyMCU = <span class="keyword">new</span> wiot.client(&#123;</span><br><span class="line"> MAC: <span class="string">"xx:xx:xx:xx:xx:xx"</span>,</span><br><span class="line"> pin: &#123;</span><br><span class="line"> D1: <span class="number">0</span>,</span><br><span class="line"> D2: <span class="number">0</span>,</span><br><span class="line"> D3: <span class="number">1</span>,</span><br><span class="line"> D4: <span class="number">1</span>,</span><br><span class="line"> D5: <span class="number">0</span>,</span><br><span class="line"> D6: <span class="number">1</span>,</span><br><span class="line"> D7: <span class="number">0</span>,</span><br><span class="line"> D8: <span class="number">0</span></span><br><span class="line"> &#125;,</span><br><span class="line"> hint: <span class="literal">true</span>,</span><br><span class="line"> debug: <span class="literal">false</span>,</span><br><span class="line"> ip: <span class="string">"192.168.0.55"</span>,</span><br><span class="line"> port: <span class="number">6666</span>,</span><br><span class="line"> ip_range: <span class="string">"192.168.0"</span>,</span><br><span class="line"> localIP: <span class="string">"127.0.0.1"</span>,</span><br><span class="line"> errDelayTime: <span class="number">2000</span>,</span><br><span class="line"> okDelayTime: <span class="number">30</span>,</span><br><span class="line"> resetDelayTime: <span class="number">4500</span>,</span><br><span class="line"> noTryMaxTime: <span class="number">15000</span>,</span><br><span class="line"> IntervalTime: <span class="number">2000</span>,</span><br><span class="line"> MaxToReScanTime: <span class="number">180000</span>,</span><br><span class="line"> MinResearchTime: <span class="number">5000</span>,</span><br><span class="line"> IpScanTimeOut: <span class="number">1</span>,</span><br><span class="line"> pingTimeout: <span class="number">2</span>,</span><br><span class="line"> MaxTraceBackTimes: <span class="number">8</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h4 id="方法列表"><a href="#方法列表" class="headerlink" title="方法列表"></a>方法列表</h4><ul><li><code>.write(pin: wiot.pin/number, state: iot.state/number)</code>: 向指定pin口输出状态指令,状态可以是wiot.HIGH/wiot.LOW或PWM调制(0-255数字)</li><li><code>wiot.read(pin: wiot.pin/number)</code>: 读取指定pin口状态,数字pin返回wiot.HIGH/wiot.LOW,模拟pin返回0-1024数值</li></ul><h4 id="事件绑定"><a href="#事件绑定" class="headerlink" title="事件绑定"></a>事件绑定</h4><p><code>.on(event, handler)</code></p><p><strong>client事件列表</strong></p><ul><li><code>begin</code> 开始于单片机正常交互</li><li><code>disConnected</code> 与单片机断开连接</li><li><code>reConnected</code> 与单片机恢复连接</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MCU = <span class="keyword">new</span> wiot.client(&#123;<span class="string">"MAC"</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line">MCU.on(<span class="string">'disConnected'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="comment">// 当与MCU失联时会执行此处指令</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Disconnected with MCU!!'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p><code>.pinOn(pin, event, handler)</code></p><p><strong>pin事件列表</strong></p><ul><li><code>on</code> pin口电位从低到高</li><li><code>off</code> pin口电位从高到低</li><li><code>change</code> pin口电位变化</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MCU = <span class="keyword">new</span> wiot.client(&#123;<span class="string">"MAC"</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line">MCU.pinOn(wiot.D2, <span class="string">'on'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="comment">// 当MCU的D2电位由低到高时会执行</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'D2 from LOW to HIGH!!'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="API"><a href="#API" class="headerlink" title="API"></a>API</h3><ul><li><code>wiot.begin()</code>: 单片机准备完成后开始执行</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line">MCU1 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:ww"</span>&#125;);</span><br><span class="line"></span><br><span class="line">wiot.begin([MCU0, MCU1], ()=&gt;&#123;</span><br><span class="line"> <span class="comment">//这里放你要执行的指令</span></span><br><span class="line"> <span class="comment">//这些指令将会在MCU0和MCU1准备就绪后开始执行</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><ul><li><code>wiot.loop()</code>: 循环执行的指令,适合于条件控制语句</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line">MCU1 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:ww"</span>&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 以下代码将实现: 当MCU0的D5接收到HIGH,MCU1的D4将会输出HIGH</span></span><br><span class="line"><span class="comment">// 当MCU0的D5接收到LOW, MCU1的D4将会输出LOW</span></span><br><span class="line"><span class="comment">// 本函数接受两个参数: 第一个是MCU对象数组, 第二个是参数为MCU对象数组的函数</span></span><br><span class="line">wiot.loop([MCU0, MCU1], () =&gt; &#123;</span><br><span class="line"> <span class="keyword">if</span>(MCU1.read(wiot.D5) == wiot.HIGH)&#123;</span><br><span class="line"> MCU0.write(wiot.D4, wiot.HIGH);</span><br><span class="line"> &#125;<span class="keyword">else</span>&#123;</span><br><span class="line"> MCU0.write(wiot.D4, wiot.LOW);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="注册表"><a href="#注册表" class="headerlink" title="注册表"></a>注册表</h3><ul><li><code>wiot.register.set(status1, status2, function)</code>: 向注册表中添加一条规则, status可以是值或函数,当status1==status2时会触发function。<br>注册表的设计是为了方便协调各扩展模块的使用,详见下文<a href="#传感器扩展模块">扩展模块</a>。</li><li><code>wiot.register.set(status, function)</code>: 你也可以传入两个函数,其中status的返回值是bool型,变为true时触发function</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myLED = wiot.led(MyMCU, wiot.D4);</span><br><span class="line"><span class="keyword">var</span> pir = wiot.pir(MyMCU, wiot.D2);</span><br><span class="line"></span><br><span class="line"><span class="comment">//注册一条规则,当pir探测到人时,myLED亮</span></span><br><span class="line">wiot.register.set(pir.getStatus, wiot.HIGH, ()=&gt;&#123;</span><br><span class="line"> myLED.set(wiot.HIGH);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//注册一条规则,当人离开时,myLED灭</span></span><br><span class="line">wiot.register.set(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> <span class="keyword">return</span> (wiot.LOW == pir.getStatus);</span><br><span class="line">&#125;, ()=&gt;&#123;</span><br><span class="line"> myLED.clear();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="传感器扩展模块"><a href="#传感器扩展模块" class="headerlink" title="传感器扩展模块"></a>传感器扩展模块</h2><h3 id="LED"><a href="#LED" class="headerlink" title="LED"></a>LED</h3><ul><li><code>wiot.led(MCU, pin)</code>: 声明一个led模块</li><li><code>wiot.led.getStatus()</code>: 获取led状态</li><li><code>wiot.led.set(status, time = 0, isSmooth = false)</code>: 设置led状态,起始状态,中间状态,最终状态,周期</li><li><code>wiot.led.breath(period)</code>: 设置一个呼吸灯</li><li><code>wiot.led.clear()</code>: 重置led</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myLED = wiot.led(MCU0, wiot.D4); <span class="comment">//新建一个led对象,使用MCU0上的D4口</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 如果myLED不亮,则点亮它 */</span></span><br><span class="line"><span class="keyword">if</span>(!myLED.getStatus())&#123;</span><br><span class="line"> myLED.set(wiot.HIGH);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 设置一个周期为2秒的呼吸灯 */</span></span><br><span class="line">myLED.breath(<span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 设置一个亮三秒,灭四秒的led */</span></span><br><span class="line">myLED.set([wiot.HIGH, wiot.LOW], [<span class="number">3000</span>, <span class="number">4000</span>]);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 设置一个呼1秒吸3秒的呼吸渐变灯 */</span></span><br><span class="line">myLED.set([wiot.LOW, wiot.HIGH], [<span class="number">1000</span>, <span class="number">3000</span>], <span class="literal">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 自定义一个先半亮2秒再全亮3秒再熄灭2秒的led灯 */</span></span><br><span class="line">myLED.set([<span class="number">100</span>, wiot.HIGH, wiot.LOW], [<span class="number">2000</span>, <span class="number">3000</span>, <span class="number">2000</span>]);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 熄灭led */</span></span><br><span class="line">myLED.clear();</span><br></pre></td></tr></table></figure><h3 id="PIR-红外人体传感器"><a href="#PIR-红外人体传感器" class="headerlink" title="PIR 红外人体传感器"></a>PIR 红外人体传感器</h3><ul><li><code>wiot.pir(MCU, pin)</code>: 声明一个PIR模块</li><li><code>wiot.pir.getStatus()</code>: 获取PIR状态,返回值wiot.HIGH(有人),wiot.LOW(无人)</li></ul><p><strong>事件触发器</strong></p><ul><li><code>wiot.pir.on(event, handler)</code></li></ul><p><strong>事件列表</strong></p><ul><li><code>detected</code> 探测到人</li><li><code>undetected</code> 人体移动出探测范围</li><li><code>change</code> 状态改变,包括有人到无人和无人到有人</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myPIR = wiot.pir(MCU0, wiot.D2); <span class="comment">//新建一个pir对象,使用MCU0上的D2口</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 输出pir状态到控制台 */</span></span><br><span class="line"><span class="built_in">console</span>.log(myPIR.getStatus());</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 当探测到人,打印 "Detected People!" 到控制台 */</span></span><br><span class="line">myPIR.on(<span class="string">"detected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Detected People!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 人移动出探测范围,打印 "No People!!" 到控制台 */</span></span><br><span class="line">myPIR.on(<span class="string">"undetected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"No People!!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 当状态改变,执行指令 */</span></span><br><span class="line">myPIR.on(<span class="string">"change"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="comment">/* 你的指令 */</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="IR-红外循迹-障碍传感器"><a href="#IR-红外循迹-障碍传感器" class="headerlink" title="IR 红外循迹/障碍传感器"></a>IR 红外循迹/障碍传感器</h3><ul><li><code>wiot.ir(MCU, pin)</code>: 声明一个IR模块,pin可以是模拟或数字端口</li><li><code>wiot.ir.getStatus()</code>: 获取IR状态,返回值wiot.HIGH(有障碍),wiot.LOW(无障碍),或者0-1024数值(限模拟端口)</li></ul><p><strong>事件触发器</strong></p><ul><li><code>wiot.ir.on(event, handler)</code></li></ul><p><strong>事件列表</strong></p><ul><li><code>detected</code> 探测到障碍</li><li><code>undetected</code> 障碍消失</li><li><code>change</code> 状态改变</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myIR = wiot.ir(MCU0, wiot.D2); <span class="comment">//新建一个ir对象,使用MCU0上的D2口</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 输出ir状态到控制台 */</span></span><br><span class="line"><span class="built_in">console</span>.log(myIR.getStatus());</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 当探测到物体,打印 "Detected Object!" 到控制台 */</span></span><br><span class="line">myIR.on(<span class="string">"detected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Detected Object!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 物体移动出探测范围,打印 "No Object!!" 到控制台 */</span></span><br><span class="line">myIR.on(<span class="string">"undetected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"No Object!!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 当状态改变,执行指令 */</span></span><br><span class="line">myIR.on(<span class="string">"change"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="comment">/* 你的指令 */</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="lightSensor-光敏传感器"><a href="#lightSensor-光敏传感器" class="headerlink" title="lightSensor 光敏传感器"></a>lightSensor 光敏传感器</h3><ul><li><code>wiot.lightSensor(MCU, pin)</code>: 声明一个lightSensor模块, pin可以是模拟或数字端口</li><li><code>wiot.lightSensor.getStatus()</code>: 获取lightSensor状态,返回值wiot.HIGH(有光),wiot.LOW(无光),或者0-1024数值(限模拟端口)</li></ul><p><strong>事件触发器</strong></p><ul><li><code>wiot.light.on(event, handler)</code></li></ul><p><strong>事件列表</strong></p><ul><li><code>light</code> 由暗到明</li><li><code>dark</code> 由明到暗</li><li><code>change</code> 状态改变</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myLightSensor = wiot.lightSensor(MCU0, wiot.D1); <span class="comment">//新建一个pir对象,使用MCU0上的D2口</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* 输出LightSensor状态到控制台 */</span></span><br><span class="line"><span class="built_in">console</span>.log(mylightSensor.getStatus());</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 当由暗到明,打印 "Light!!!" 到控制台 */</span></span><br><span class="line">myLightSensor.on(<span class="string">"light"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Light!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 由明到暗,打印 "Dark!!" 到控制台 */</span></span><br><span class="line">myLightSensor.on(<span class="string">"dark"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Dark!!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* 当状态改变,执行指令 */</span></span><br><span class="line">myLightSensor.on(<span class="string">"change"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="comment">/* 你的指令 */</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="网络扩展模块"><a href="#网络扩展模块" class="headerlink" title="网络扩展模块"></a>网络扩展模块</h2><h3 id="mail-邮件模块"><a href="#mail-邮件模块" class="headerlink" title="mail 邮件模块"></a>mail 邮件模块</h3><p>使用本模块向指定邮箱发送邮件。自豪地引用<a href="https://api.yimian.xyz/" target="_blank" rel="noopener">Yimian API</a>构建!</p><ul><li><code>wiot.mail(to, from = &quot;wIoT&quot;)</code>: 声明一个mail模块,参数收件地址,发件人名称</li><li><code>wiot.mail.send(subject, body)</code>: 发送邮件,需传入主题,邮件内容</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> mail = wiot.mail(<span class="string">"i@iotcat.me"</span>, <span class="string">"wIoT Test"</span>);</span><br><span class="line"></span><br><span class="line">mail.send(<span class="string">"Test"</span>, <span class="string">"Test from wiot!!"</span>);</span><br></pre></td></tr></table></figure><h3 id="guguji-咕咕机模块"><a href="#guguji-咕咕机模块" class="headerlink" title="guguji 咕咕机模块"></a>guguji 咕咕机模块</h3><p>使用本模块向指定咕咕机发送消息。咕咕机是一款便携式私人打印机,详见<a href="https://www.memobird.shop/" target="_blank" rel="noopener">官网</a>。使用本模块需要在官网提前申请好自己的开发者ak, 详见<a href="https://api.yimian.xyz/gugu/intro.php" target="_blank" rel="noopener">这里</a>。自豪地引用<a href="https://api.yimian.xyz/" target="_blank" rel="noopener">Yimian API</a>构建!</p><ul><li><code>wiot.guguji(ak, userID, memobirdID)</code>: 声明一个guguji模块,参数: 开发者ak, 用户id, 咕咕机id</li><li><code>wiot.guguji.send(msg)</code>: 发送消息,需传入待发送的消息</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gugu = wiot.guguji(<span class="string">"9e55121803474371bfa25d20e554b31f"</span>, <span class="string">"832598"</span>, <span class="string">"b3ee06a8bd9b49e1"</span>);</span><br><span class="line"></span><br><span class="line">gugu.print(<span class="string">"This is from wIoT!!"</span>);</span><br></pre></td></tr></table></figure></span><span class=".en"><h1 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h1><p>This project aims to help web developers who are not familiar with firmware programming to implement their own IoT applications. You only need a server inside the network (such as Raspberry Pi) and several MCUs (single-chip computers) that support networking (via serial port, WiFi, LoRa, Bluetooth, Zigbee, etc.), you can easily create and manage your own Internet of Things Cluster.</p><h2 id="Current-Support-devices"><a href="#Current-Support-devices" class="headerlink" title="Current Support devices"></a>Current Support devices</h2><ul><li>D1 MINI</li></ul><h2 id="Node-js-Install-Node-js"><a href="#Node-js-Install-Node-js" class="headerlink" title="Node.js Install Node.js"></a>Node.js Install Node.js</h2><p>Node.js is a widely used programming language for web developers. To make use of wIoT, you should first install Node.js to your computer. </p><p>For <strong>windows</strong> user, you can follow the instruction in <a href="https://www.jianshu.com/p/03a76b2e7e00" target="_blank" rel="noopener">this website</a> </p><h2 id="Install-wIoT-package"><a href="#Install-wIoT-package" class="headerlink" title="Install wIoT package"></a>Install wIoT package</h2><p>After install Node.js and configure npm successfully, you should then use npm to download wIoT package by enter following command in your command window.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install wiot</span><br></pre></td></tr></table></figure><p>Windows user can use cmd or powershell.It should be notice that this may report error for some users. The solution is to open your cmd window as administrator. You can right click on cmd and choose <em>run as an administrator</em>. You can also press windows+R and input <em>cmd</em> then press Ctrl+Shift+Enter to open it as administrator. </p><h2 id="Burn-firmware"><a href="#Burn-firmware" class="headerlink" title="Burn firmware"></a>Burn firmware</h2><h2 id="Connect-your-device-to-D1-MINI"><a href="#Connect-your-device-to-D1-MINI" class="headerlink" title="Connect your device to D1 MINI"></a>Connect your device to D1 MINI</h2><ul><li>After burning the firmware, you should try to connect your device to D1 MINI<br>Follow the steps below, I’m sure it would not be a problem for such a smart person like you </li></ul><h3 id="1-Reset-your-D1-MINI"><a href="#1-Reset-your-D1-MINI" class="headerlink" title="1. Reset your D1 MINI"></a>1. Reset your D1 MINI</h3><ul><li>Find pin <strong>D0</strong> on your D1 MINI, it should be in the middle of A0 and D5. </li><li>Use a wire to connect <strong>3V3</strong> to <strong>D0</strong>. If your MINI works normally, you would see its BUILT-IN LED blink. </li><li>You <strong>don’t</strong> have to wait until it stops blink, just stay for <strong>2s</strong>, then you can pull out the wire and your MINI would reset. </li></ul><h3 id="2-Find-your-D1-MINI-on-your-device"><a href="#2-Find-your-D1-MINI-on-your-device" class="headerlink" title="2.Find your D1 MINI on your device"></a>2.Find your D1 MINI on your device</h3><ul><li>After you finish step 1, your MINI would work in AP mode, which means you can search it with your smart phone or personal computer by scanning the Wi-Fi around </li><li>If your MINI was reset successfully, you would find a Wi-Fi with SSID in the form of <strong>wiot-xx:xx:xx:xx:xx:xx</strong>.<br>Example:<br><img src="https://api.yimian.xyz/img/?path=docs/wiot/ssid.png" alt="ssid"><br>“xx:xx:xx:xx:xx:xx” is the MAC address of this MINI, please try to remember the address for you may use it later </li></ul><p>The default password for D1 MINI is <strong>1234567890</strong>, enter the password and you should be able to connect to your MINI.</p><h2 id="Connect-D1-MINI-to-your-Wi-Fi"><a href="#Connect-D1-MINI-to-your-Wi-Fi" class="headerlink" title="Connect D1 MINI to your Wi-Fi"></a>Connect D1 MINI to your Wi-Fi</h2><p>Congratulations, you have successfully connect your device to D1 MINI<br>However, this is not the end, you should now try to connect D1 MINI to your Wi-Fi<br>Use the device which had just been connected to D1 MINI and follow the steps below </p><h3 id="1-Visit-the-control-page-of-D1-MINI"><a href="#1-Visit-the-control-page-of-D1-MINI" class="headerlink" title="1. Visit the control page of D1 MINI"></a>1. Visit the control page of D1 MINI</h3><p>Visit <strong><a href="http://192.168.0.1" target="_blank" rel="noopener">http://192.168.0.1</a></strong> with the browser on your device<br>Normally, you would see a webpage like this:<br><img src="https://api.yimian.xyz/img/?path=docs/wiot/webpage.png" alt="webpage"><br>In this page, you can see the MAC Address and wIoT version of your MINI<br>Again, please <strong>remember</strong> the MAC Address </p><h3 id="2-Submit-SSID-and-password-to-your-MINI"><a href="#2-Submit-SSID-and-password-to-your-MINI" class="headerlink" title="2.Submit SSID and password to your MINI"></a>2.Submit SSID and password to your MINI</h3><p>From the page, you can see two blanks that ask the SSID and password of your Wi-Fi<br>Input information of the Wi-FI which you would like to connect your MINI, click <em>Submit</em><br>If you have input the right SSID and password, you will see a page showing the message: <strong>Set Successfully!! Rebooting!!</strong><br>Then, after a minute, you will see the SSID of D1 MINI has vanished </p><p>If you submitted the wrong message, do not try to directly reconnect to D1 MINI. Restart the whole procedure from the reset part of the last section</p><h2 id="Execute-Example-Code"><a href="#Execute-Example-Code" class="headerlink" title="Execute Example Code"></a>Execute Example Code</h2><p>If you have successfully connect D1 MINI to your Wi-Fi, you can execute the example code below to realize a simple function of wIoT<br>Before executing the code, you should first connect a LED to D1 MINI with positive pole connect to pin D4 and negative pole connect to GND</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> wiot = <span class="built_in">require</span>(<span class="string">'wiot'</span>); <span class="comment">//Import wiot package from npm</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Create an object of single chip</span></span><br><span class="line"><span class="comment">// Here are two parameters, MAC is the MAC adress of single chip, the output port should be defined in pin</span></span><br><span class="line"><span class="comment">// The MAC address should be editted by user</span></span><br><span class="line"><span class="keyword">var</span> MyMCU = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"3C:71:BF:3A:F6:CF"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span> : <span class="number">1</span>&#125;, <span class="attr">hint</span> : <span class="literal">true</span>&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// The following code can let the BUILTIN_LED turn on for one second and off for one second periodically</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Wait for all the chips to get ready</span></span><br><span class="line">wiot.begin([MyMCU], ()=&gt;&#123; </span><br><span class="line"> <span class="comment">// First parameter is the name of chip, second parameter is the function that is going to be executed</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">// Set timer, pin 3 of MyMCU will pull up every 2 seconds</span></span><br><span class="line"> setInterval(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> MyMCU.write(wiot.D4, wiot.HIGH);</span><br><span class="line"> &#125;, <span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Set timer, executer the command in &#123;&#125; after a one-second delay</span></span><br><span class="line"> setTimeout(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Set timer, pin 3 of MyMCU will pull down every 2 seconds</span></span><br><span class="line"> setInterval(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> MyMCU.write(wiot.D4, wiot.LOW);</span><br><span class="line"> &#125;, <span class="number">2000</span>);</span><br><span class="line"> &#125;, <span class="number">1000</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>The LED is expected to blink after you execute the code</p><h1 id="Advanced-development"><a href="#Advanced-development" class="headerlink" title="Advanced development"></a>Advanced development</h1><h2 id="Parameters"><a href="#Parameters" class="headerlink" title="Parameters"></a>Parameters</h2><div style="overflow:scroll;"><table><thead><tr><th>Name</th><th>Default Value</th><th>Declaration</th></tr></thead><tbody><tr><td>MAC</td><td>“”</td><td>MAC Address of MCU</td></tr><tr><td>pin</td><td>{D1: 0, D2: 0, D3: 0, D4: 0, D5: 0, D6: 0, D7: 0, D8: 0}</td><td>Mode of each pin, 0 is INPUT, 1 is OUTPUT, 2is INPUT_PULLUP</td></tr><tr><td>hint</td><td>true</td><td>Whether print the status prompt</td></tr><tr><td>debug</td><td>false</td><td>Whether open the debug mode</td></tr><tr><td>ip</td><td>“default”</td><td>Specify MCU IP, please try this option when you cannot find IP for a long time</td></tr><tr><td>port</td><td>8848</td><td>TCP Socket communication port for Client, default 8848</td></tr><tr><td>ip_range</td><td>“192.168.0”</td><td>IP search field, try this option if you cannot find IP for a long time</td></tr><tr><td>localIP</td><td>“127.0.0.1”</td><td>local IP</td></tr><tr><td>errDelayTime</td><td>2000</td><td>Retry interval when network error is encountered (milliseconds)</td></tr><tr><td>okDelayTime</td><td>30</td><td>Waiting time after receiving the network request (milliseconds)</td></tr><tr><td>resetDelayTime</td><td>4500</td><td>Waiting time for stop sending new messages after sending reset instructions to MCU (milliseconds)</td></tr><tr><td>noTryMaxTime</td><td>15000</td><td>If the MCU fails to respond after this time, the message will be sent again (milliseconds).</td></tr><tr><td>IntervalTime</td><td>2000</td><td>Interval between monitoring (heartbeat)</td></tr><tr><td>MaxToReScanTime</td><td>180000</td><td>After this time, if the MCU has no response, it will scan the IP address again (in milliseconds).</td></tr><tr><td>MinResearchTime</td><td>5000</td><td>Interval between each polling</td></tr><tr><td>IpScanTimeout</td><td>1</td><td>Ping detection timeout for IP scanning (seconds)</td></tr><tr><td>pingTimeout</td><td>2</td><td>Timeout of Heartbeat Ping detection (seconds)</td></tr><tr><td>MaxTraceBackTimes</td><td>8</td><td>Determine the number of historical heartbeats traced back to the connection state</td></tr></tbody></table></div><h2 id="Parameters-Declaration-Example"><a href="#Parameters-Declaration-Example" class="headerlink" title="Parameters Declaration Example"></a>Parameters Declaration Example</h2><h3 id="General-Example"><a href="#General-Example" class="headerlink" title="General Example"></a>General Example</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MyMCU = <span class="keyword">new</span> wiot.client(&#123;</span><br><span class="line"> MAC: <span class="string">"xx:xx:xx:xx:xx:xx"</span>,</span><br><span class="line"> pin: &#123;</span><br><span class="line"> D1: <span class="number">0</span>,</span><br><span class="line"> D2: <span class="number">0</span>,</span><br><span class="line"> D3: <span class="number">1</span>,</span><br><span class="line"> D4: <span class="number">1</span>,</span><br><span class="line"> D5: <span class="number">0</span>,</span><br><span class="line"> D6: <span class="number">1</span>,</span><br><span class="line"> D7: <span class="number">0</span>,</span><br><span class="line"> D8: <span class="number">0</span></span><br><span class="line"> &#125;,</span><br><span class="line"> hint: <span class="literal">true</span>,</span><br><span class="line"> debug: <span class="literal">false</span>,</span><br><span class="line"> ip: <span class="string">"192.168.0.55"</span>,</span><br><span class="line"> port: <span class="number">6666</span>,</span><br><span class="line"> ip_range: <span class="string">"192.168.0"</span>,</span><br><span class="line"> localIP: <span class="string">"127.0.0.1"</span>,</span><br><span class="line"> errDelayTime: <span class="number">2000</span>,</span><br><span class="line"> okDelayTime: <span class="number">30</span>,</span><br><span class="line"> resetDelayTime: <span class="number">4500</span>,</span><br><span class="line"> noTryMaxTime: <span class="number">15000</span>,</span><br><span class="line"> IntervalTime: <span class="number">2000</span>,</span><br><span class="line"> MaxToReScanTime: <span class="number">180000</span>,</span><br><span class="line"> MinResearchTime: <span class="number">5000</span>,</span><br><span class="line"> IpScanTimeOut: <span class="number">1</span>,</span><br><span class="line"> pingTimeout: <span class="number">2</span>,</span><br><span class="line"> MaxTraceBackTimes: <span class="number">8</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="Event-Binding"><a href="#Event-Binding" class="headerlink" title="Event Binding"></a>Event Binding</h2><h3 id="Client"><a href="#Client" class="headerlink" title="Client"></a>Client</h3><p><code>.on(event, handler)</code></p><h4 id="Event-List-of-client"><a href="#Event-List-of-client" class="headerlink" title="Event List of client"></a>Event List of client</h4><ul><li><code>begin</code> It begins when MCU starts to interact normally</li><li><code>disConnected</code> Disconnect from MCU</li><li><code>reConnected</code> Connection with MCU restored</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> MCU = <span class="keyword">new</span> wiot.client(&#123;<span class="string">"MAC"</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line">MCU.on(<span class="string">'disConnected'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Execute the command below when lost connection with MCU</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'Disconnected with MCU!!'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="Pin"><a href="#Pin" class="headerlink" title="Pin"></a>Pin</h3><p><code>.pinOn(pin, event, handler)</code></p><h4 id="Event-List-of-pin"><a href="#Event-List-of-pin" class="headerlink" title="Event List of pin"></a>Event List of pin</h4><ul><li><code>on</code> Change output of pin from LOW to HIGH</li><li><code>off</code> Change output of pin from HIGH to LOW</li><li><code>change</code> Change the output of pin</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> MCU = <span class="keyword">new</span> wiot.client(&#123;<span class="string">"MAC"</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line">MCU.pinOn(wiot.D2, <span class="string">'on'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line"> <span class="comment">// Execute when the output of D2 changes from LOW to HIGH</span></span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">'D2 from LOW to HIGH!!'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="API-1"><a href="#API-1" class="headerlink" title="API"></a>API</h3><ul><li><code>wiot.begin()</code>: Execute when MCU is ready</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line">MCU1 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:ww"</span>&#125;);</span><br><span class="line"></span><br><span class="line">wiot.begin([MCU0, MCU1], ()=&gt;&#123;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//Write the command you want to execute here</span></span><br><span class="line"> <span class="comment">//These command would execute once MCU0 and MCU1 are ready</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><p>+<br> <code>wiot.loop()</code>: A loop command,Suitable for conditional control statements</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line">MCU1 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:ww"</span>&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// Following code would realize: When pin D5 of MCU0 receive HIGH,D4 of MCU1 would output HIGH</span></span><br><span class="line"><span class="comment">// When pin D5 of MCU0 receive LOW,D4 of MCU1 would output LOW</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// This function receives two parameters: first is an array of objects for MCU, second is a function which use MCU array of objects as its parameter</span></span><br><span class="line"></span><br><span class="line">wiot.loop([MCU0, MCU1], () =&gt; &#123;</span><br><span class="line"> <span class="keyword">if</span>(MCU1.read(wiot.D5) == wiot.HIGH)&#123;</span><br><span class="line"> MCU0.write(wiot.D4, wiot.HIGH);</span><br><span class="line"> &#125;<span class="keyword">else</span>&#123;</span><br><span class="line"> MCU0.write(wiot.D4, wiot.LOW);</span><br><span class="line"> &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="Register"><a href="#Register" class="headerlink" title="Register"></a>Register</h3><ul><li><p><code>wiot.register.set(status1, status2, function)</code>: Add a rule to register that status can be either value or function,<br>function would trigger if status1 == status2<br>The registry is designed to facilitate the use of various extension modules, See [extension module] below (# Sensor Extension Module).</p></li><li><p><code>wiot.register.set(status, function)</code>: You can also pass in two functions, where the return value of status is of type bool, it would trigger the function if it changes to true</p></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> myLED = wiot.led(MyMCU, wiot.D4);</span><br><span class="line"><span class="keyword">var</span> pir = wiot.pir(MyMCU, wiot.D2);</span><br><span class="line"></span><br><span class="line"><span class="comment">//Sign up for a rule that says myLED lights up when pir detects a person</span></span><br><span class="line">wiot.register.set(pir.getStatus, wiot.HIGH, ()=&gt;&#123;</span><br><span class="line"> myLED.set(wiot.HIGH);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">//Sign up for a rule that when people leave, myLED goes off</span></span><br><span class="line">wiot.register.set(<span class="function"><span class="params">()</span>=&gt;</span>&#123;</span><br><span class="line"> <span class="keyword">return</span> (wiot.LOW == pir.getStatus);</span><br><span class="line">&#125;, ()=&gt;&#123;</span><br><span class="line"> myLED.clear();</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="Sensor-extension-module"><a href="#Sensor-extension-module" class="headerlink" title="Sensor extension module"></a>Sensor extension module</h2><h3 id="LED-1"><a href="#LED-1" class="headerlink" title="LED"></a>LED</h3><ul><li><p><code>wiot.led(MCU, pin)</code>: Declare a LED module</p></li><li><p><code>wiot.led.getStatus()</code>: Get status of LED</p></li><li><p><code>wiot.led.set(status, time = 0, isSmooth = false)</code>: Set led state, initial state, intermediate state, final state, period</p></li><li><p><code>wiot.led.breath(period)</code>: Set a breathing LED</p></li><li><p><code>wiot.led.clear()</code>: Reset LED</p></li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> wiot = <span class="built_in">require</span>(<span class="string">'wiot'</span>); <span class="comment">//Import wiot package from npm</span></span><br><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"3C:71:BF:3A:F6:CF"</span>, <span class="attr">pin</span>: &#123;<span class="attr">D4</span>: wiot.OUTPUT&#125;&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myLED = wiot.led(MCU0, wiot.D4); <span class="comment">//Create a new led object using the D4 port on MCU0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* If myLED is not shining, light it up*/</span></span><br><span class="line"><span class="keyword">if</span>(!myLED.getStatus())&#123;</span><br><span class="line"> myLED.set(wiot.HIGH);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Set a breathing light with cycle of 2s */</span></span><br><span class="line">myLED.breath(<span class="number">2000</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Set a LED which light 3 seconds and off 4 seconds */</span></span><br><span class="line">myLED.set([wiot.HIGH, wiot.LOW], [<span class="number">3000</span>, <span class="number">4000</span>]);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Set a breathing light which use 1 second to light and 3 second to extinguish */</span></span><br><span class="line">myLED.set([wiot.LOW, wiot.HIGH], [<span class="number">1000</span>, <span class="number">3000</span>], <span class="literal">true</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Set a LED which shine with half brightness for 2 seconds, shine with full brightness for 3 seconds and then dextinguish for 2 seconds */</span></span><br><span class="line">myLED.set([<span class="number">100</span>, wiot.HIGH, wiot.LOW], [<span class="number">2000</span>, <span class="number">3000</span>, <span class="number">2000</span>]);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Turn off LED */</span></span><br><span class="line">myLED.clear();</span><br></pre></td></tr></table></figure><h3 id="PIR-Passive-Infrared-Sensor"><a href="#PIR-Passive-Infrared-Sensor" class="headerlink" title="PIR (Passive Infrared Sensor)"></a>PIR (Passive Infrared Sensor)</h3><ul><li><code>wiot.pir(MCU, pin)</code>: Declare a PIR module</li><li><code>wiot.pir.getStatus()</code>: Gets the PIR state, returns the value wiot.high (have people), wiot.low (no people)</li></ul><h4 id="Event-Trigger"><a href="#Event-Trigger" class="headerlink" title="Event Trigger"></a>Event Trigger</h4><ul><li><code>wiot.pir.on(event, handler)</code></li></ul><p><strong>Events List</strong></p><ul><li><code>detected</code> Person detected</li><li><code>undetected</code> People out of the detective field</li><li><code>change</code> State change, includes from detected to undetected and from undetected to detected</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> wiot = <span class="built_in">require</span>(<span class="string">'wiot'</span>); <span class="comment">//Import wiot package from npm</span></span><br><span class="line"></span><br><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"3C:71:BF:3A:F6:CF"</span>&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myPIR = wiot.pir(MCU0, wiot.D2); <span class="comment">//Create an object of pir, use the D2 port on MCU0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* Output the status of pir to console */</span></span><br><span class="line"><span class="built_in">console</span>.log(myPIR.getStatus());</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When human is detected,print "Detected People!" to console */</span></span><br><span class="line">myPIR.on(<span class="string">"detected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Detected People!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When human is out of the detection zone,print "No People!!" to console */</span></span><br><span class="line">myPIR.on(<span class="string">"undetected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"No People!!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When there is a change to status, execute your command */</span></span><br><span class="line">myPIR.on(<span class="string">"change"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="comment">/* Write command in here */</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="IR-Infrared-Sensor"><a href="#IR-Infrared-Sensor" class="headerlink" title="IR Infrared Sensor"></a>IR Infrared Sensor</h3><ul><li><code>wiot.ir(MCU, pin)</code>: Declare an IR module, pin can be analog or digital port</li><li><code>wiot.ir.getStatus()</code>: Get IR state, return value wiot.high (with a barrier), wiot.low (with no barrier), or a value of 0-1024 (only for analog port)</li></ul><h4 id="Event-Trigger-1"><a href="#Event-Trigger-1" class="headerlink" title="Event Trigger"></a>Event Trigger</h4><ul><li><code>wiot.ir.on(event, handler)</code></li></ul><p><strong>Event List</strong></p><ul><li><code>detected</code> Barrier detected</li><li><code>undetected</code> Barrier vanished</li><li><code>change</code> Change state</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myIR = wiot.ir(MCU0, wiot.D2); <span class="comment">//Create a new ir object using the D2 port on MCU0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* Output ir status to console */</span></span><br><span class="line"><span class="built_in">console</span>.log(myIR.getStatus());</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When an object is detected, print "Detected Object!" to the console */</span></span><br><span class="line">myIR.on(<span class="string">"detected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Detected Object!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When the object move out of the detective area, print "No Object!!" to the console */</span></span><br><span class="line">myIR.on(<span class="string">"undetected"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"No Object!!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Execute the command when state changes */</span></span><br><span class="line">myIR.on(<span class="string">"change"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="comment">/* Your command */</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h3 id="lightSensor"><a href="#lightSensor" class="headerlink" title="lightSensor"></a>lightSensor</h3><ul><li><code>wiot.lightSensor(MCU, pin)</code>: Declare a lightSensor module, pin can be analog or digital port</li><li><code>wiot.lightSensor.getStatus()</code>: Get lightSensor state, return value wiot.HIGH(light), wiot.LOW(dark), or a value of 0-1024 (limited to analog port)</li></ul><h4 id="Event-Trigger-2"><a href="#Event-Trigger-2" class="headerlink" title="Event Trigger"></a>Event Trigger</h4><ul><li><code>wiot.light.on(event, handler)</code></li></ul><p><strong>Event List</strong></p><ul><li><code>light</code> From dark to light</li><li><code>dark</code> From light to dark</li><li><code>change</code> Change state</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">MCU0 = <span class="keyword">new</span> wiot.client(&#123;<span class="attr">MAC</span>: <span class="string">"xx:xx:xx:xx:xx:xx"</span>&#125;);</span><br><span class="line"><span class="keyword">var</span> myLightSensor = wiot.lightSensor(MCU0, wiot.D1); <span class="comment">//Create a new pir object using the D2 port on MCU0</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/* Output the LightSensor state to the console */</span></span><br><span class="line"><span class="built_in">console</span>.log(mylightSensor.getStatus());</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When going from dark to Light, print "Light!!!" to the console */</span></span><br><span class="line">myLightSensor.on(<span class="string">"light"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Light!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When going from light to Dark, print "Dark!!" to the console */</span></span><br><span class="line">myLightSensor.on(<span class="string">"dark"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Dark!!"</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/* When the state changes, execute the command */</span></span><br><span class="line">myLightSensor.on(<span class="string">"change"</span>, ()=&gt;&#123;</span><br><span class="line"> <span class="comment">/* Your command */</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure><h2 id="Internet-Extension-Module"><a href="#Internet-Extension-Module" class="headerlink" title="Internet Extension Module"></a>Internet Extension Module</h2><h3 id="Mail-module"><a href="#Mail-module" class="headerlink" title="Mail module"></a>Mail module</h3><p>Use this module to send messages to the specified mailbox. Proudly built with reference to <a href="https://api.yimian.xyz/" target="_blank" rel="noopener">Yimian API</a>!</p><ul><li><code>wiot.mail(to, from = &quot;wIoT&quot;)</code>: Declare an mail module with sender’s name and reveiver’s address</li><li><code>wiot.mail.send(subject, body)</code>: Send email with a subject and content</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> mail = wiot.mail(<span class="string">"i@iotcat.me"</span>, <span class="string">"wIoT Test"</span>);</span><br><span class="line"></span><br><span class="line">mail.send(<span class="string">"Test"</span>, <span class="string">"Test from wiot!!"</span>);</span><br></pre></td></tr></table></figure><h3 id="guguji"><a href="#guguji" class="headerlink" title="guguji"></a>guguji</h3><p>Use this module to send messages to the specified cooing machine.Goo goo is a portable private printer, see <a href="https://www.memobird.shop/" target="_blank" rel="noopener">official website</a>.<br>To use this module, you need to apply for your own developer ak in advance on the official website. See <a href="https://api.yimian.xyz/gugu/intro.php" target="_blank" rel="noopener">here</a>. Proudly reference <a href="https://api.yimian.xyz/" target="_blank" rel="noopener">Yimian API</a>!</p><ul><li><code>wiot.guguji(ak, userID, memobirdID)</code>: Declare a goo goo chicken module, parameter: developer’s ak, user id, cooing machine id</li><li><code>wiot.guguji.send(msg)</code>: Send message, need to pass in the message to be sent</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> gugu = wiot.guguji(<span class="string">"9e55121803474371bfa25d20e554b31f"</span>, <span class="string">"832598"</span>, <span class="string">"b3ee06a8bd9b49e1"</span>);</span><br><span class="line"></span><br><span class="line">gugu.print(<span class="string">"This is from wIoT!!"</span>);</span><br></pre></td></tr></table></figure></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> iot </tag>
<tag> nodeJS </tag>
<tag> WiFi </tag>
</tags>
</entry>
<entry>
<title>中美贸易战-解</title>
<link href="/thoughts/trade-war.html"/>
<url>/thoughts/trade-war.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>中美贸易战的解不在美国,而是在我们自己身上。</p></span><span class=".en"><p>The solution to the Sino-US trade war is not in the United States, but in ourselves.</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>关于谈判,党内争议比较大,但最终很有可能会拒绝做出让步。<br>当美关税抬升,国内相关产业链将大批转移至台湾及东南亚国家,累计将造成1亿人口的就业问题。与前几次的危机不同,这一次我们不但要提防房市泡沫的激化,也没有那麽多的基建可提供就业。从另一方面看,近几年来,中国的产能过剩问题主要通过出口得以解决,拿着贸易顺差来发展国内经济,以实现不可思议的经济增长。如今特朗普政府征加关税,将使得这一策略不再行得通。</p><p>如果在谈判中妥协,中方将丧失好不容易占来的第四次工业革命先机,并经济将会想日本,韩国一样任人摆布。</p><p>我认为,在不妥协的前提下,中共有三个破局之法。</p><ol><li>武统台湾<br>这个需要看明年台湾大选,是否能找到正当的武统理由。但的确有助于缓解国内社会焦点问题。</li><li>房市改革<br>可能性极大,把泡沫危机转变成创造就业机会的资本。</li><li>游戏<br>将社会上的过剩劳动力转移进游戏产业空转,以缓解社会矛盾的形成。</li></ol><p>为了缓解失业冲击的强度,央行将通过印人民币使人民币贬值来增进出口,吸引他国来补充美资撤离的空缺。</p><p>以上。。</p></span><span class=".en"><p>Regarding negotiations, there are relatively large disputes within the party, but in the end it is very likely that they will refuse to make concessions.<br>When U.S. tariffs rise, related domestic industrial chains will be transferred to Taiwan and Southeast Asian countries in large numbers, which will cause employment problems for 100 million people. Unlike previous crises, this time we not only have to guard against the intensification of the housing market bubble, but also there is not so much infrastructure that can provide employment. On the other hand, in recent years, China’s overcapacity problem has been solved mainly through exports, and the trade surplus is used to develop the domestic economy in order to achieve incredible economic growth. Now that the Trump administration imposes tariffs, this strategy will no longer work.</p><p>If it compromises in the negotiation, China will lose the opportunity of the Fourth Industrial Revolution that it finally took over, and its economy will be at the mercy of Japan and South Korea.</p><p>I think that under the premise of no compromise, there are three ways to break the game.</p><ol><li>Wu Tong Taiwan<br>This depends on whether Taiwan’s general election next year can find a legitimate reason for military reunification. But it does help alleviate domestic social focus issues.</li><li>Housing market reform<br>It is very possible to turn the bubble crisis into capital for job creation.</li><li>Games<br>Transfer the surplus labor force in the society into the game industry to ease the formation of social conflicts.</li></ol><p>In order to alleviate the intensity of the unemployment shock, the central bank will increase imports and exports by printing the renminbi to depreciate the renminbi, attracting other countries to supplement the vacancy of the withdrawal of US capital.</p><p>the above. .</p></span>]]></content>
<categories>
<category> thoughts </category>
</categories>
<tags>
<tag> war </tag>
</tags>
</entry>
<entry>
<title>咕咕机API</title>
<link href="/tech/memobird-printer-api.html"/>
<url>/tech/memobird-printer-api.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>这是一个简易的咕咕机API哦~</p></span><span class=".en"><p>This is a simple Memobird Printer API~</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><blockquote><p>本API仅为官方接口的二次封装,意在降低其使用门槛。本站承诺不会保存任何使用者信息。如果您对本站存有疑惑,请慎重使用本接口!!本接口<a href="https://github.yimian.xyz/iotcat/gugu-api" target="_blank" rel="noopener">源码</a></p></blockquote><h2 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h2><ul><li><code>ak</code>: 咕咕机AccessKey(前往<a href="https://open.memobird.cn/" target="_blank" rel="noopener">咕咕机开放平台</a>申请)</li><li><code>userID</code>: 用户的咕咕号(手机软件&gt;&gt;我的&gt;&gt;头像旁边的咕咕号)</li><li><code>memobirdID</code>: 咕咕机ID(手机软件&gt;&gt;我的&gt;&gt;我的咕咕机&gt;&gt;咕咕机&gt;&gt;设备编号)</li><li><code>body</code>: 内容</li></ul><h2 id="请求地址"><a href="#请求地址" class="headerlink" title="请求地址"></a>请求地址</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET https:&#x2F;&#x2F;api.yimian.xyz&#x2F;gugu&#x2F;</span><br></pre></td></tr></table></figure><h2 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;gugu&#x2F;?ak&#x3D;9e55121803474371bfa25d20e554b31d&amp;userID&#x3D;832598&amp;memobirdID&#x3D;c3ee06a8bd9b49e1&amp;body&#x3D;你好呀世界</span><br></pre></td></tr></table></figure><h2 id="返回值-plaintext"><a href="#返回值-plaintext" class="headerlink" title="返回值(plaintext)"></a>返回值(plaintext)</h2><ul><li>成功: </li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line"><span class="string">"showapi_res_code"</span>: <span class="number">1</span>, <span class="comment">//1为发送成功,0为失败</span></span><br><span class="line"><span class="string">"showapi_res_error"</span>: <span class="string">"ok"</span>, <span class="comment">//"ok"为发送成功,否则显示错误信息</span></span><br><span class="line"><span class="string">"result"</span>: <span class="number">1</span>, <span class="comment">//1为打印成功</span></span><br><span class="line"><span class="string">"smartGuid"</span>: <span class="string">"149e2257412e532e"</span>, <span class="comment">//会话标识符</span></span><br><span class="line"><span class="string">"printcontentid"</span>: <span class="number">234784</span> <span class="comment">//打印内容识别编码</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>失败:</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line"><span class="string">"showapi_res_code"</span>: <span class="number">1</span>, <span class="comment">//1为发送成功,0为失败</span></span><br><span class="line"><span class="string">"showapi_res_error"</span>: <span class="string">"错误信息"</span> <span class="comment">//否则显示错误信息</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>更多用法见<a href="http://open.memobird.cn/upload/webapi.pdf" target="_blank" rel="noopener">官方文件</a></p></blockquote></span><span class=".en"><blockquote><p>This API is only a simplified package of the official interface, intending to lower the threshold for its use. This site promises not to save any user information. If you have any doubts about this site, please use this interface carefully! ! This interface <a href="https://github.yimian.xyz/iotcat/gugu-api" target="_blank" rel="noopener">source code</a>.</p></blockquote><h2 id="Parameters"><a href="#Parameters" class="headerlink" title="Parameters"></a>Parameters</h2><p> -<code>ak</code>: Memobird Printer AccessKey (Go to <a href="https://open.memobird.cn/" target="_blank" rel="noopener">Memobird Printer Open Platform</a> to apply)<br> -<code>userID</code>: the user’s id (the User id is next to the avatar in mobile Memobird software)<br> -<code>memobirdID</code>: Memobird Printer ID (Find it in the mobile Memobird software)<br> -<code>body</code>: content to print</p><h2 id="Request-address"><a href="#Request-address" class="headerlink" title="Request address"></a>Request address</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">GET https:&#x2F;&#x2F;api.yimian.xyz&#x2F;gugu&#x2F;</span><br></pre></td></tr></table></figure><h2 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;gugu&#x2F;?ak&#x3D;9e55121803474371bfa25d20e554b31d&amp;userID&#x3D;832598&amp;memobirdID&#x3D;c3ee06a8bd9b49e1&amp;body&#x3D;Hello world</span><br></pre></td></tr></table></figure><h2 id="Return-value-plaintext"><a href="#Return-value-plaintext" class="headerlink" title="Return value (plaintext)"></a>Return value (plaintext)</h2><ul><li>Success:</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line"><span class="string">"showapi_res_code"</span>: <span class="number">1</span>, <span class="comment">//1 means transmission is successful, 0 means failure</span></span><br><span class="line"><span class="string">"showapi_res_error"</span>: <span class="string">"ok"</span>, <span class="comment">//"ok" means the transmission is successful, otherwise an error message will be displayed</span></span><br><span class="line"><span class="string">"result"</span>: <span class="number">1</span>, <span class="comment">//1 means successful printing</span></span><br><span class="line"><span class="string">"smartGuid"</span>: <span class="string">"149e2257412e532e"</span>, <span class="comment">//session identifier</span></span><br><span class="line"><span class="string">"printcontentid"</span>: <span class="number">234784</span> <span class="comment">//Print content identification code</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><ul><li>Failure:</li></ul><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line"><span class="string">"showapi_res_code"</span>: <span class="number">1</span>, <span class="comment">//1 means sending successfully, 0 means failure</span></span><br><span class="line"><span class="string">"showapi_res_error"</span>: <span class="string">"Error message"</span> <span class="comment">//Otherwise display error message</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><blockquote><p>For more usage, please refer to <a href="http://open.memobird.cn/upload/webapi.pdf" target="_blank" rel="noopener">Official Document</a></p></blockquote></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> api </tag>
<tag> motto </tag>
</tags>
</entry>
<entry>
<title>自动发邮件API</title>
<link href="/tech/mail-api.html"/>
<url>/tech/mail-api.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>重整自己先前的mail模块,顺便封装了一个API出来,欢迎大家调用~</p></span><span class=".en"><p>Reorganized my previous mail module and encapsulated an API by the way. Welcome everyone to call~</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h2><h3 id="参数-接受GET和POST"><a href="#参数-接受GET和POST" class="headerlink" title="参数(接受GET和POST)"></a>参数(接受GET和POST)</h3><ul><li><code>to</code>收信人邮箱地址</li><li><code>subject</code>邮件主题</li><li><code>body</code>邮件内容(建议使用html格式)</li><li><code>from</code>发件人名称</li></ul><h3 id="请求地址"><a href="#请求地址" class="headerlink" title="请求地址"></a>请求地址</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;mail</span><br></pre></td></tr></table></figure><h3 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;mail&#x2F;?to&#x3D;收信邮箱&amp;subject&#x3D;邮件主题&amp;body&#x3D;邮件内容&amp;from&#x3D;发件人名称</span><br></pre></td></tr></table></figure><p>[scode type=”yellow”]如遇到GET传递邮件内容错误,请尝试使用POST[/scode]</p><h3 id="返回值-json格式"><a href="#返回值-json格式" class="headerlink" title="返回值(json格式)"></a>返回值(json格式)</h3><ul><li>参数<code>state</code>::<code>true</code>(成功)或<code>false</code>(失败)</li></ul><p>[scode type=”dangerous”]每个IP每天请求上限50个[/scode]</p></span><span class=".en"><h2 id="Method"><a href="#Method" class="headerlink" title="Method"></a>Method</h2><h3 id="Parameters-accept-GET-and-POST"><a href="#Parameters-accept-GET-and-POST" class="headerlink" title="Parameters (accept GET and POST)"></a>Parameters (accept GET and POST)</h3><ul><li><code>to</code> recipient email address</li><li><code>subject</code> mail subject</li><li><code>body</code> email content (html format is recommended)</li><li><code>from</code> sender name</li></ul><h3 id="Request-address"><a href="#Request-address" class="headerlink" title="Request address"></a>Request address</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;mail</span><br></pre></td></tr></table></figure><h3 id="Example"><a href="#Example" class="headerlink" title="Example"></a>Example</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https:&#x2F;&#x2F;api.yimian.xyz&#x2F;mail&#x2F;?to&#x3D;receiving mailbox&amp;subject&#x3D;mail subject&amp;body&#x3D;mail content&amp;from&#x3D;sender name</span><br></pre></td></tr></table></figure><p>[scode type=”yellow”] If you encounter an error in GET delivery of the mail content, please try using POST[/scode]</p><h3 id="Return-value-json-format"><a href="#Return-value-json-format" class="headerlink" title="Return value (json format)"></a>Return value (json format)</h3><ul><li>Parameter <code>state</code>::<code>true</code> (success) or <code>false</code> (failure)</li></ul><p>[scode type=”dangerous”] There are 50 requests per day per IP[/scode]</p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> api </tag>
<tag> mail </tag>
</tags>
</entry>
<entry>
<title>JS中那些惊艳的操作</title>
<link href="/tech/js-notes.html"/>
<url>/tech/js-notes.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>教你如何一步步迷上JS.. ╮(╯▽╰)╭ </p></span><span class=".en"><p>Teach you how to fall in love with JS step by step.. ╮(╯▽╰)╭</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><p>好嘀,只是一些总结 </p><h2 id="JS中的那些萌点"><a href="#JS中的那些萌点" class="headerlink" title="JS中的那些萌点"></a>JS中的那些萌点</h2><ul><li><code>&lt;script&gt;</code>标签中,合理使用<code>defer=&quot;defer&quot;</code>(延迟执行),<code>async=&quot;async&quot;</code>(异步执行)</li><li>外部JS可以使用其它扩展名(如.php),但必须返回正确MINE类型</li><li>使用<code>var obj = preferredObj || backupObj;</code> 提供后备值 ::aru:surprised:: </li><li>函数中使用<code>arguements[]</code>获取参数</li><li>无函数签名,再见吧重载 ::aru:meditation:: </li><li>函数无引用传参,只要不作死用全局变量,封装就很完美</li><li>神奇的垃圾收集功能,开发时无需考虑手动释放内存</li><li>函数传参使用<code>function hh({})</code>直接传包含参数的对象,更加灵活</li><li>数组每一个位置可以存不同类型的数据 ::aru:blood2:: </li><li>数组支持模拟栈操作,如<code>push()</code>和<code>pop()</code></li><li>数组支持模拟队列操作,如<code>push()</code>和<code>shift()</code></li><li>数组支持从相反方向模拟队列,如<code>unshift()</code>和<code>pop()</code></li><li><code>sort()</code>可自定义比较函数为参数</li><li>数组<code>splice()</code>可太好用了吧</li><li>函数是对象,函数名是指针</li><li>可以像传递参数一样把一个函数传给另一个函数,也可以将一个函数作为另一个函数的结果返回</li><li>函数中可通过<code>arguments.callee</code>获取当前函数名指针</li><li>使用<code>arguments.callee.caller</code>获取调用当前函数的引用</li><li>使用<code>function.apply(this/*作用域*/, arguments)</code>或<code>function.call(this, arg1, arg2...)</code>指定作用域运行函数</li><li>使用函数固有属性<code>function.length</code>获取其期待的参数个数</li><li>通过函数继承属性<code>toLocaleString()``toString()``valueOf()</code>返回代码,方便调试</li><li>使用<code>indexOf()``lastIndexOf()</code>查找元素出现位置</li><li><code>trim()</code>删除字符串开头结尾空格</li><li>支持正则<code>RegExp</code></li><li>神奇但可怕的<code>eval(&quot;&quot;)</code>可将字符串转译成代码并就地执行</li><li><code>encodeURI()/decodeURI()</code>与<code>encodeURIComponent()/decodeURICompoent()</code>处理uri</li><li>立即调用函数<code>function(){}();</code></li><li>内置Math对象</li><li>Math中<code>ceil()``floor()``round()</code>向上,向下,标准舍入</li><li><code>Math.random()</code>大于零小于一随机数</li><li>对象中使用<code>functionName: function(){}</code>直接定义函数</li><li>ES6中<code>(x)=&gt;x+1</code>等价于<code>function(x){return x+1;}</code></li><li>使用<code>;(function(name, context, definition){moudle.exports = definition();})(&#39;funationName&#39;, this, function(){});</code>封装模块</li></ul><h2 id="小心得"><a href="#小心得" class="headerlink" title="小心得"></a>小心得</h2><ul><li>不建议使用<code>with</code>语句</li><li><code>label</code>标签少用</li><li><code>0.1 + 0.2 != 0.3</code> 浮点型天坑,与C类似</li><li><code>~26 == -27</code> 利用按位非提高效率</li><li>标识符查询由内部环境向外部环境进行</li><li>没有块级作用域,与C++不同</li><li><code>var obj2 = obj1;</code>实际是引用</li><li>函数传参时传对象,实际传的是指针</li><li>全局变量用完及时置为null以提性能</li><li>使用变量属性访问对象只能使用<code>obj[var]</code></li><li><code>var sum = function sum(){};</code>在Safari中会报错</li><li>不能为基本类型值添加属性和方法</li><li><code>new Number(&quot;25&quot;)</code>返回对象,而<code>Number(&quot;25&quot;)</code>返回25</li><li>布尔表达式中对象均为true</li></ul></span><span class=".en"><p>Okay, just some summary</p><h2 id="Those-cute-points-in-JS"><a href="#Those-cute-points-in-JS" class="headerlink" title="Those cute points in JS"></a>Those cute points in JS</h2><ul><li>In the <code>&lt;script&gt;</code> tag, reasonably use <code>defer=&quot;defer&quot;</code> (delayed execution) and <code>async=&quot;async&quot;</code> (asynchronous execution)</li><li>External JS can use other extensions (such as .php), but must return the correct MINE type</li><li>Use <code>var obj = preferredObj || backupObj;</code> to provide a backup value ::aru:surprised::</li><li>Use <code>arguements[]</code> to get parameters in the function</li><li>No function signature, goodbye overload ::aru:meditation::</li><li>The function has no reference to pass parameters, as long as the global variable is not used for deadly, the encapsulation is perfect</li><li>Magic garbage collection function, no need to consider manually releasing memory during development</li><li>Use <code>function hh({})</code> to pass parameters directly to functions, which is more flexible</li><li>Each position of the array can store different types of data ::aru:blood2::</li><li>Array supports simulated stack operations, such as <code>push()</code> and <code>pop()</code></li><li>Array supports simulated queue operations, such as <code>push()</code> and <code>shift()</code></li><li>Array supports simulating queues from the opposite direction, such as <code>unshift()</code> and <code>pop()</code></li><li><code>sort()</code> can customize the comparison function as a parameter</li><li>The array <code>splice()</code> is so easy to use, right?</li><li>Functions are objects and function names are pointers</li><li>You can pass a function to another function as parameters, or you can return a function as the result of another function</li><li>In the function, the current function name pointer can be obtained through <code>arguments.callee</code></li><li>Use <code>arguments.callee.caller</code> to get a reference to call the current function</li><li>Use <code>function.apply(this/*scope*/, arguments)</code> or <code>function.call(this, arg1, arg2...)</code> to specify the scope to run the function</li><li>Use the function intrinsic property <code>function.length</code> to get the number of expected parameters</li><li>Inherit the property <code>toLocaleString(), toString(), and valueOf()</code> return code through the function to facilitate debugging</li><li>Use <code>indexOf() and lastIndexOf()</code> to find the element’s appearance</li><li><code>trim()</code> delete spaces at the beginning and end of the string</li><li>Support regular <code>RegExp</code></li><li>The magical but terrible <code>eval(&quot;&quot;)</code> can translate the string into code and execute it in place</li><li><code>encodeURI()/decodeURI()</code> and <code>encodeURIComponent()/decodeURICompoent()</code> handle uri</li><li>Call the function immediately <code>function()()();</code></li><li>Built-in Math object</li><li><code>ceil(), floor(), round()</code> in Math up, down, standard rounding</li><li><code>Math.random()</code> is a random number greater than zero and less than one</li><li>Use <code>functionName: function(){}</code> in the object to directly define the function</li><li>In ES6 <code>(x)=&gt;x+1</code> is equivalent to <code>function(x){return x+1;}</code></li><li>Use <code>;(function(name, context, definition){moudle.exports = definition();})(&#39;funationName&#39;, this, function()());</code> to encapsulate the module</li></ul><h2 id="Be-careful"><a href="#Be-careful" class="headerlink" title="Be careful"></a>Be careful</h2><ul><li>It is not recommended to use <code>with</code> statement</li><li>Less use of <code>label</code></li><li><code>0.1 + 0.2 != 0.3</code> floating point tiankeng, similar to C</li><li><code>~26 == -27</code> Use bitwise not to improve efficiency</li><li>Identifier query is carried out from the internal environment to the external environment</li><li>No block-level scope, different from C++</li><li><code>var obj2 = obj1;</code> is actually a reference</li><li>The object is passed when the function is passed, but the pointer is actually passed</li><li>Set global variables to null when used up to improve performance</li><li>Use variable attributes to access objects can only use <code>obj[var]</code></li><li><code>var sum = function sum(){};</code> will report an error in Safari</li><li>You cannot add attributes and methods to basic type values</li><li><code>new Number(&quot;25&quot;)</code> returns the object, and <code>Number(&quot;25&quot;)</code> returns 25</li><li>All objects in Boolean expressions are true</li></ul></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> nodeJS </tag>
</tags>
</entry>
<entry>
<title>Centos7下 Nginx 配置ssl证书自动续期</title>
<link href="/tech/ssl-auto-apply.html"/>
<url>/tech/ssl-auto-apply.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>断断续续玩web已经一年了,一些之前从腾讯云申的TrustAsia证书已经陆陆续续开始过期,很方..于是开始尝试申请Let’s Encrypt的免费证书,并实现自动续期|´・ω・)ノ</p></span><span class=".en"><p>I’ve been playing on the web intermittently for a year, and some of the TrustAsia certificates from Tencent’s Yunshang have started to expire one after another. It’s very fragrant.. So I started to try to apply for Let’s Encrypt’s free certificate, and realized automatic renewal|´・ω・)ノ</p></span><a id="more"></a><script> session.onload(function(){ if(page.tran.getLang() == 'en'){ tips.warning({ title: 'Caution', position: 'topRight', message: 'This page was translated by Machine!!', buttons: [['<button>Show Original Page</button>', function (instance, toast) { page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]] }); } });</script><span class=".zh"><h2 id="前提条件"><a href="#前提条件" class="headerlink" title="前提条件"></a>前提条件</h2><ul><li>必须是Centos7系统,其它未测试,不保证有效</li><li>有自己的域名</li><li>确认dns已将域名指向服务器</li><li>防火墙放行80与443端口</li><li>已配置好nginx代理,并<code>可以通过http访问域名</code>(一定确定能访问)</li></ul><h2 id="安装certbot"><a href="#安装certbot" class="headerlink" title="安装certbot"></a>安装certbot</h2><p>通过yum安装certbot</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ yum update #更新yum源</span><br><span class="line">$ yum install -y epel-release #安装epel源</span><br><span class="line">$ yum install -y certbot #安装certbot</span><br></pre></td></tr></table></figure><h2 id="初次申领证书"><a href="#初次申领证书" class="headerlink" title="初次申领证书"></a>初次申领证书</h2><h3 id="初次申领某域名证书"><a href="#初次申领某域名证书" class="headerlink" title="初次申领某域名证书"></a>初次申领某域名证书</h3><p>格式为</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ certbot certonly --webroot -w [Web站点目录] -d [站点域名] -m [联系人email地址] --agree-tos</span><br></pre></td></tr></table></figure><p>例如</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ certbot certonly --webroot -w &#x2F;opt&#x2F;www&#x2F;demo.yourdomain.com -d demo.yourdomain.com -m yourname@gmail.com --agree-tos</span><br></pre></td></tr></table></figure><h3 id="证书位置"><a href="#证书位置" class="headerlink" title="证书位置"></a>证书位置</h3><p>证书存放在<code>/etc/letsencrypt/live/demo.yourdomain.com/</code>文件夹中。<br>一共有4个文件,你可能要用到的是<code>fullchain.pem</code>和<code>privkey.pem</code>。</p><h3 id="配置nginx"><a href="#配置nginx" class="headerlink" title="配置nginx"></a>配置nginx</h3><p>在相应的<code>server{}</code>中加入以下内容:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">listen 443 ssl;</span><br><span class="line"></span><br><span class="line">ssl_certificate &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;fullchain.pem; #2</span><br><span class="line">ssl_certificate_key &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;privkey.pem; #3</span><br><span class="line"></span><br><span class="line">ssl_session_cache shared:SSL:1m;</span><br><span class="line">ssl_session_timeout 5m;</span><br><span class="line">ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;</span><br><span class="line">ssl_protocols TLSv1 TLSv1.1 TLSv1.2;</span><br><span class="line">ssl_prefer_server_ciphers on;</span><br><span class="line">error_page 404 &#x3D; &#x2F;404.php;</span><br></pre></td></tr></table></figure><p>例如</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line"> listen 443 ssl;</span><br><span class="line"> listen 80;</span><br><span class="line"></span><br><span class="line"> server_name demo.yourdomain.com; #1</span><br><span class="line"> root &#x2F;opt&#x2F;www&#x2F;demo.yourdomain.com;</span><br><span class="line"> index index.html;</span><br><span class="line"> client_max_body_size 1000M;</span><br><span class="line"></span><br><span class="line"> ssl_certificate &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;fullchain.pem; #2</span><br><span class="line"> ssl_certificate_key &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;privkey.pem; #3</span><br><span class="line"></span><br><span class="line"> ssl_session_cache shared:SSL:1m;</span><br><span class="line"> ssl_session_timeout 5m;</span><br><span class="line"> ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;</span><br><span class="line"> ssl_protocols TLSv1 TLSv1.1 TLSv1.2;</span><br><span class="line"> ssl_prefer_server_ciphers on;</span><br><span class="line"> error_page 404 &#x3D; &#x2F;404.html;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>配置成功后执行如下指令:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ nginx -t #检查nginx conf语法</span><br><span class="line">$ systemctl restart nginx #重启nginx</span><br></pre></td></tr></table></figure><h2 id="配置自动续期"><a href="#配置自动续期" class="headerlink" title="配置自动续期"></a>配置自动续期</h2><p>编辑crontab规则:(<a href="https://www.cnblogs.com/p0st/p/9482167.html" target="_blank" rel="noopener">初次配置crontab</a>)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ crontab -e</span><br></pre></td></tr></table></figure><p>键入以下内容(每月1号5时刷新证书并重启nginx)保存并退出</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00 05 01 * * &#x2F;usr&#x2F;bin&#x2F;certbot renew --quiet &amp;&amp; &#x2F;bin&#x2F;systemctl restart nginx</span><br></pre></td></tr></table></figure><p>重启crontab</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ systemctl restart crond.service</span><br></pre></td></tr></table></figure><hr><p>参考链接:<br><a href="https://blog.csdn.net/sheng119/article/details/72956717" target="_blank" rel="noopener">https://blog.csdn.net/sheng119/article/details/72956717</a></p></span><span class=".en"><h2 id="Prerequisites"><a href="#Prerequisites" class="headerlink" title="Prerequisites"></a>Prerequisites</h2><ul><li>Must be Centos7 system, others have not been tested and are not guaranteed to be valid</li><li>Have your own domain name</li><li>Confirm that dns has pointed the domain name to the server</li><li>The firewall allows port 80 and 443</li><li>The nginx proxy has been configured, and <code>domain name can be accessed via http</code> (be sure to be able to access)</li></ul><h2 id="Install-certbot"><a href="#Install-certbot" class="headerlink" title="Install certbot"></a>Install certbot</h2><p>Install certbot via yum</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ yum update #Update yum source</span><br><span class="line">$ yum install -y epel-release #Install epel source</span><br><span class="line">$ yum install -y certbot #Install certbot</span><br></pre></td></tr></table></figure><h2 id="Initial-application-certificate"><a href="#Initial-application-certificate" class="headerlink" title="Initial application certificate"></a>Initial application certificate</h2><h3 id="Apply-for-a-domain-name-certificate-for-the-first-time"><a href="#Apply-for-a-domain-name-certificate-for-the-first-time" class="headerlink" title="Apply for a domain name certificate for the first time"></a>Apply for a domain name certificate for the first time</h3><p>The format is</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ certbot certonly --webroot -w [Web site directory] -d [domain name] -m [contact email address] --agree-tos</span><br></pre></td></tr></table></figure><p>E.g</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ certbot certonly --webroot -w &#x2F;opt&#x2F;www&#x2F;demo.yourdomain.com -d demo.yourdomain.com -m yourname@gmail.com --agree-tos</span><br></pre></td></tr></table></figure><h3 id="Certificate-location"><a href="#Certificate-location" class="headerlink" title="Certificate location"></a>Certificate location</h3><p>The certificate is stored in the <code>/etc/letsencrypt/live/demo.yourdomain.com/</code> folder.<br>There are 4 files in total, you may need to use <code>fullchain.pem</code> and <code>privkey.pem</code>.</p><h3 id="Configure-nginx"><a href="#Configure-nginx" class="headerlink" title="Configure nginx"></a>Configure nginx</h3><p>Add the following content to the corresponding <code>server{}</code>:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">listen 443 ssl;</span><br><span class="line"></span><br><span class="line">ssl_certificate &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;fullchain.pem; #2</span><br><span class="line">ssl_certificate_key &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;privkey.pem; #3</span><br><span class="line"></span><br><span class="line">ssl_session_cache shared:SSL:1m;</span><br><span class="line">ssl_session_timeout 5m;</span><br><span class="line">ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;</span><br><span class="line">ssl_protocols TLSv1 TLSv1.1 TLSv1.2;</span><br><span class="line">ssl_prefer_server_ciphers on;</span><br><span class="line">error_page 404 &#x3D; &#x2F;404.php;</span><br></pre></td></tr></table></figure><p>E.g</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">server &#123;</span><br><span class="line"> listen 443 ssl;</span><br><span class="line"> listen 80;</span><br><span class="line"></span><br><span class="line"> server_name demo.yourdomain.com; #1</span><br><span class="line"> root &#x2F;opt&#x2F;www&#x2F;demo.yourdomain.com;</span><br><span class="line"> index index.html;</span><br><span class="line"> client_max_body_size 1000M;</span><br><span class="line"></span><br><span class="line"> ssl_certificate &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;fullchain.pem; #2</span><br><span class="line"> ssl_certificate_key &#x2F;etc&#x2F;letsencrypt&#x2F;live&#x2F;demo.yourdomain.com&#x2F;privkey.pem; #3</span><br><span class="line"></span><br><span class="line"> ssl_session_cache shared:SSL:1m;</span><br><span class="line"> ssl_session_timeout 5m;</span><br><span class="line"> ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;</span><br><span class="line"> ssl_protocols TLSv1 TLSv1.1 TLSv1.2;</span><br><span class="line"> ssl_prefer_server_ciphers on;</span><br><span class="line"> error_page 404 &#x3D; &#x2F;404.html;</span><br><span class="line"></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>After the configuration is successful, execute the following instructions:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ nginx -t #Check nginx conf syntax</span><br><span class="line">$ systemctl restart nginx #Restart nginx</span><br></pre></td></tr></table></figure><h2 id="Configure-automatic-renewal"><a href="#Configure-automatic-renewal" class="headerlink" title="Configure automatic renewal"></a>Configure automatic renewal</h2><p>Edit crontab rules: (<a href="https://www.cnblogs.com/p0st/p/9482167.html" target="_blank" rel="noopener">First configuration crontab</a>)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ crontab -e</span><br></pre></td></tr></table></figure><p>Type the following (refresh the certificate and restart nginx on the 1st and 5th of each month) to save and exit</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">00 05 01 * * &#x2F;usr&#x2F;bin&#x2F;certbot renew --quiet &amp;&amp; &#x2F;bin&#x2F;systemctl restart nginx</span><br></pre></td></tr></table></figure><p>Restart crontab</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ systemctl restart crond.service</span><br></pre></td></tr></table></figure><hr><p>Reference link:<br><a href="https://blog.csdn.net/sheng119/article/details/72956717" target="_blank" rel="noopener">https://blog.csdn.net/sheng119/article/details/72956717</a></p></span>]]></content>
<categories>
<category> tech </category>
</categories>
<tags>
<tag> centos7 </tag>
<tag> ssl </tag>
</tags>
</entry>
<entry>
<title>数电期中总结</title>
<link href="/notes/digital-circuit.html"/>
<url>/notes/digital-circuit.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>上学期掉了魔电的坑,这学期来搞点数电小攻略掩饰一下(☆ω☆)</p></span><span class=".en"><p>I lost the pit of magic electricity last semester. This semester, let’s make a small strategy to hide it (☆ω☆)</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h1 id="1-数制与码制"><a href="#1-数制与码制" class="headerlink" title="1. 数制与码制"></a>1. 数制与码制</h1><h2 id="二进制运算"><a href="#二进制运算" class="headerlink" title="二进制运算"></a>二进制运算</h2><h3 id="补码"><a href="#补码" class="headerlink" title="补码"></a>补码</h3><p>常用补码来表示负数,以便于计算。<br>正数和零补码是其自身,负数的补码方法如下:<br>二进制减法可以通过被减数加要减数的补码来实现。<br><strong>&lt;法一&gt;直接法</strong><br>$$(N)_{COMP}=\begin{cases}N&amp;\text{N为正数}\2^{n}-N&amp; \text{N为负数} \end{cases}$$</p><p>符号位为零(正数)时,补码与源码相同,符号位为1(负数)时,补码为$2^{n}-N$.<br><strong>&lt;法二&gt;观察法</strong><br>欲求补码,可以先找其反码。<br>$$(N)_{INV}=\begin{cases}N&amp;\text{N为正数}\(2^{n}-1)-N&amp; \text{N为负数} \end{cases}$$</p><p>即,除符号位外其他值0变1,1变0。<br>随后反码整体加1即可得到补码~</p><h2 id="常用编码"><a href="#常用编码" class="headerlink" title="常用编码"></a>常用编码</h2><h3 id="DCB"><a href="#DCB" class="headerlink" title="DCB"></a>DCB</h3><p>即8421恒权码。DCB作为10进制显示时,须在每一个Invalid位(&gt;9)上加6。</p><h3 id="Signed-Numbers"><a href="#Signed-Numbers" class="headerlink" title="Signed Numbers"></a>Signed Numbers</h3><p>使用8位,最左边一位表示符号,其余7位表示数值。</p><h2 id="期中总结"><a href="#期中总结" class="headerlink" title="期中总结"></a>期中总结</h2><h3 id="第一周-初识数电"><a href="#第一周-初识数电" class="headerlink" title="第一周 - 初识数电"></a>第一周 - 初识数电</h3><ul><li>模拟量太复杂,不符合人类思维</li><li>三极管MOS管等非线性器件为魔转数提供了器件基础</li><li>因为模电太难,所以我们要学数电<br><strong>一些要点</strong></li><li>TTL意思是指晶体管逻辑电路,由各种三极管和电阻组成,特点是速度快</li><li>TTL中0-0.8V为低电平,2-5V为高电平</li><li>二进制与十进制相互转换(整数/小数)</li><li>LSB(Least Significant Bit)/MSB(Most S B)</li></ul><h3 id="第二周-数制"><a href="#第二周-数制" class="headerlink" title="第二周 - 数制"></a>第二周 - 数制</h3><ul><li>反码 1’s Complement</li><li>补码 2’s Complement</li><li>有时候二进制太长不好用,这使16进制很方便</li><li>16进制类似2进制的助记符,如观察<code>1100 0101</code>可直接写出<code>C5</code></li><li>BCD是用一个16进制表示一个10进制数</li><li>BCD很符合人类的思维习惯,但造成极大的资源浪费</li><li>BCD四则运算,我觉得最好转成10进制算完再转回去,反正很方便</li><li>计算机BCD加法采取+6进位法</li><li>数字储存时最左一位是符号位</li><li>负数使用补码来存储(<a href="https://zhidao.baidu.com/question/1692306348989800588.html" target="_blank" rel="noopener">栗子</a>)</li><li>1字节signed数字范围<code>-128-127</code></li><li>合理设计存储位数,小心溢出</li><li><a href="https://zhidao.baidu.com/question/293829485.html" target="_blank" rel="noopener">二进制乘法</a></li><li><a href="https://zhidao.baidu.com/question/304091753926723564.html" target="_blank" rel="noopener">二进制除法</a> 与十进制类似</li></ul><h3 id="第三周-逻辑门与电路封装类型"><a href="#第三周-逻辑门与电路封装类型" class="headerlink" title="第三周 - 逻辑门与电路封装类型"></a>第三周 - 逻辑门与电路封装类型</h3><ul><li>非门 NOT</li><li>与门 AND</li><li>或门 OR</li><li>非与门 NAND</li><li>非或门 NOR</li><li>异或门 XOR</li><li>常见有TTL和CMOS两类</li><li>CMOS按照供压可分为3.3V和5V两类</li><li>fan-out是指有效input个数</li><li>propagation delay time指响应时间</li><li>集成电路命名,如<code>74LS04</code>中74指商品级,LS指种类,04为型号</li><li>按复杂程度分类:SSI(1-12门),MSI(13-99门),LSI(100-9999门),VLSI(10000-99999),ULSI(100000+)</li></ul><h3 id="第四周-布尔运算"><a href="#第四周-布尔运算" class="headerlink" title="第四周 - 布尔运算"></a>第四周 - 布尔运算</h3><ul><li>遵循交换,结合,分配律</li><li>结论<code>A+AB=A</code>与<code>A+~AB=A+B</code></li><li>DeMorgan’s Theorems <code>~(AB)=(~A+~B)</code> 与 <code>~(A+B)=~A~B</code></li><li><code>~A~B</code>为Negative AND, <code>~(AB)</code>为NAND, OR同理</li><li>SOP格式为<code>··+··+··</code></li><li>POS格式为<code>()*()*()</code></li><li>Truth Table即为将全部可能的Input和output列表</li></ul><h3 id="第五周-Karnaugh-Map"><a href="#第五周-Karnaugh-Map" class="headerlink" title="第五周 - Karnaugh Map"></a>第五周 - Karnaugh Map</h3><ul><li>Karnaugh Map来可视化逻辑门化简</li></ul><h3 id="第六周-逻辑门组合"><a href="#第六周-逻辑门组合" class="headerlink" title="第六周 - 逻辑门组合"></a>第六周 - 逻辑门组合</h3><ul><li>NAND和NOR可以组合出其它任意门</li><li>加法器 左位放<code>A AND B</code>右位放<code>A XOR B</code></li><li>比较器 1bit<code>A XOR B</code> 2bit<code>(A0 XOR B0) NOR (A1 XOR B0)</code></li><li>译码器 逻辑二进制转控制电平输出</li></ul><hr><p>课件:<br><a href="https://www.eee.dog/usr/uploads/2019/02/1948813444.pdf">Lecture03.pdf</a><br><a href="https://www.eee.dog/usr/uploads/2019/02/20970449.pdf">Lecture04.pdf</a></p></span><span class=".en"><h1 id="1-Number-system-and-code-system"><a href="#1-Number-system-and-code-system" class="headerlink" title="1. Number system and code system"></a>1. Number system and code system</h1><h2 id="Binary-operation"><a href="#Binary-operation" class="headerlink" title="Binary operation"></a>Binary operation</h2><h3 id="Complement"><a href="#Complement" class="headerlink" title="Complement"></a>Complement</h3><p>The complement is often used to represent negative numbers for easy calculation.<br>Positive numbers and zero complement are themselves, and the complement method of negative numbers is as follows:<br>Binary subtraction can be implemented by adding the complement of the subtracted number to the subtracted number.<br><strong><Method One> Direct Method</strong><br>$$(N)_{COMP}=\begin{cases}N&amp;\text{N is a positive number}\2^{n}-N&amp; \text{N is a negative number} \end{cases}$$</p><p>When the sign bit is zero (positive number), the complement is the same as the source code. When the sign bit is 1 (negative number), the complement is $2^{n}-N$.<br><strong><Method Two> Observation Method</strong><br>If you want the complement, you can find the inverse first.<br>$$(N)_{INV}=\begin{cases}N&amp;\text{N is a positive number}\(2^{n}-1)-N&amp; \text{N is a negative number} \end{cases}$$</p><p>That is, except for the sign bit, 0 changes to 1, and 1 changes to 0.<br>Then add 1 to the whole complement to get the complement~</p><h2 id="Common-coding"><a href="#Common-coding" class="headerlink" title="Common coding"></a>Common coding</h2><h3 id="DCB-1"><a href="#DCB-1" class="headerlink" title="DCB"></a>DCB</h3><p>That is, the 8421 constant weight code. When DCB is displayed as a decimal number, 6 must be added to each Invalid bit (&gt;9).</p><h3 id="Signed-Numbers-1"><a href="#Signed-Numbers-1" class="headerlink" title="Signed Numbers"></a>Signed Numbers</h3><p>8 bits are used, the leftmost bit represents the sign, and the remaining 7 bits represent the value.</p><h2 id="Mid-term-summary"><a href="#Mid-term-summary" class="headerlink" title="Mid-term summary"></a>Mid-term summary</h2><h3 id="First-week-first-acquaintance-with-digital-telephony"><a href="#First-week-first-acquaintance-with-digital-telephony" class="headerlink" title="First week-first acquaintance with digital telephony"></a>First week-first acquaintance with digital telephony</h3><ul><li>The analog quantity is too complicated to conform to human thinking</li><li>Non-linear devices such as triode and MOS tube provide the device basis for the magic speed</li><li>Because analog electricity is too difficult, we have to learn math electricity<br><strong>Some points</strong></li><li>TTL means transistor logic circuit, composed of various transistors and resistors, and is characterized by fast speed</li><li>0-0.8V in TTL is low level, 2-5V is high level</li><li>Conversion between binary and decimal (integer/decimal)</li><li>LSB(Least Significant Bit)/MSB(Most S B)</li></ul><h3 id="Second-week-Number-system"><a href="#Second-week-Number-system" class="headerlink" title="Second week-Number system"></a>Second week-Number system</h3><ul><li>1’s Complement</li><li>2’s Complement</li><li>Sometimes the binary is too long to use, which makes hexadecimal very convenient</li><li>Hexadecimal is similar to binary mnemonic, if you observe <code>1100 0101</code>, you can write <code>C5</code> directly</li><li>BCD uses a hexadecimal number to represent a decimal number</li><li>BCD is in line with human thinking habits, but it causes a great waste of resources</li><li>BCD four arithmetic, I think it’s best to convert to decimal and then convert it back. Anyway, it’s very convenient</li><li>Computer BCD addition adopts +6 carry method</li><li>When storing numbers, the leftmost digit is the sign bit</li><li>Negative numbers are stored using one’s complement (<a href="https://zhidao.baidu.com/question/1692306348989800588.html" target="_blank" rel="noopener">chestnut</a>)</li><li>1 byte signed number range <code>-128-127</code></li><li>Reasonably design the number of storage bits and be careful of overflow</li><li><a href="https://zhidao.baidu.com/question/293829485.html" target="_blank" rel="noopener">Binary Multiplication</a></li><li><a href="https://zhidao.baidu.com/question/304091753926723564.html" target="_blank" rel="noopener">Binary Division</a> Similar to decimal</li></ul><h3 id="Week-3-Logic-Gate-and-Circuit-Package-Type"><a href="#Week-3-Logic-Gate-and-Circuit-Package-Type" class="headerlink" title="Week 3-Logic Gate and Circuit Package Type"></a>Week 3-Logic Gate and Circuit Package Type</h3><ul><li>NOT</li><li>AND gate</li><li>OR gate OR</li><li>NOT AND gate NAND</li><li>NOR gate</li><li>Exclusive OR gate XOR</li><li>Commonly there are TTL and CMOS two types</li><li>CMOS can be divided into 3.3V and 5V according to the supply voltage</li><li>Fan-out refers to the number of valid inputs</li><li>propagation delay time refers to response time</li><li>IC naming, for example, 74 in <code>74LS04</code> means commodity grade, LS means type, 04 is model</li><li>Classification by complexity: SSI (1-12 doors), MSI (13-99 doors), LSI (100-9999 doors), VLSI (10000-99999), ULSI (100000+)</li></ul><h3 id="Week-4-Boolean-operations"><a href="#Week-4-Boolean-operations" class="headerlink" title="Week 4-Boolean operations"></a>Week 4-Boolean operations</h3><ul><li>Follow the exchange, combination, and distribution laws</li><li>Conclusion <code>A+AB=A</code> and <code>A+~AB=A+B</code></li><li>DeMorgan’s Theorems <code>~(AB)=(~A+~B)</code> and <code>~(A+B)=~A~B</code></li><li><code>~A~B</code> is Negative AND, <code>~(AB)</code> is NAND, OR is the same</li><li>SOP format is <code>··+··+··</code></li><li>POS format is <code>()*()*()</code></li><li>Truth Table is a list of all possible Input and Output</li></ul><h3 id="Week-5-Karnaugh-Map"><a href="#Week-5-Karnaugh-Map" class="headerlink" title="Week 5-Karnaugh Map"></a>Week 5-Karnaugh Map</h3><ul><li>Karnaugh Map to visualize logic gate simplification</li></ul><h3 id="Week-6-Logic-Gate-Combination"><a href="#Week-6-Logic-Gate-Combination" class="headerlink" title="Week 6-Logic Gate Combination"></a>Week 6-Logic Gate Combination</h3><ul><li>NAND and NOR can be combined into any other gate</li><li>Adder put <code>A AND B</code> on the left bit and <code>A XOR B</code> on the right bit</li><li>Comparator 1bit<code>A XOR B</code> 2bit<code>(A0 XOR B0) NOR (A1 XOR B0)</code></li><li>Decoder logic binary to control level output</li></ul><hr><p>Courseware:<br><a href="https://www.eee.dog/usr/uploads/2019/02/1948813444.pdf">Lecture03.pdf</a><br><a href="https://www.eee.dog/usr/uploads/2019/02/20970449.pdf">Lecture04.pdf</a></p></span>]]></content>
<categories>
<category> notes </category>
</categories>
<tags>
<tag> circuit </tag>
</tags>
</entry>
<entry>
<title>经济,环境可持续性</title>
<link href="/thoughts/economy-environment-sustainability.html"/>
<url>/thoughts/economy-environment-sustainability.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>经济学是一门研究选择的学问。人们活在世上总是在进行着各种选择。发展落后的国家希望尽快工业化发展经济,来改善自己的生存环境。而工业化后的国家则希望发展同时兼顾环境。于是落后国家需要50年来发展工业,搞基建,破坏环境。之后的50年则拼命治理环境,发展生态。由于地球生态是一个整体,发达国家非常不爽落后的国家搞工业化污染环境,于是各种矛盾。不过在21世纪,有望利用信息数字科技打破50-50年法则,为新一批的国家崛起提供蹊径( ๑´•ω•) “</p></span><span class=".en"><p>Economics is a study of choice. People are always making various choices in the world. Countries that are underdeveloped hope to industrialize and develop their economy as soon as possible to improve their living environment. The post-industrial countries hope to develop while taking the environment into consideration. So backward countries need 50 years to develop industry, engage in infrastructure construction, and destroy the environment. For the next 50 years, he worked hard to control the environment and develop the ecology. Because the earth’s ecology is a whole, developed countries are very upset and backward countries are engaged in industrialization and polluting the environment, so various contradictions arise. However, in the 21st century, it is expected to use information and digital technology to break the 50-50 year rule and provide a path for the rise of a new group of countries (๑´•ω•) “</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="为什么追求发展"><a href="#为什么追求发展" class="headerlink" title="为什么追求发展"></a>为什么追求发展</h2><p>自然环境较为恶劣,不完全适合人类生存。于是具备主观能动性的人类开始由改造环境的冲动。这一心理行为逐步早就了名为“发展”的宏伟故事,大家都对其深信不已。就像故事中所描述的一样,人们为了实现这一目标开始减少内耗(战争),社会趋于高度分工化。</p><p>人类有一种基本心理效应叫蔡格尼克效应,讲的是人如果开始做一件事情便会难以在中途停下来。这一效应在群体行为中则会变本加厉的体现。当人们开始追求发展,并且得到了一定的激励(生活的确更舒适了,至少人们是这样认为的),于是这个势头便不会轻易停下来了,于是人类进入了千年级别的发展时期。</p><p>发展初期,太多的基础设施需要建设,太多的工业需要发展,最重要的是这个时候大家都很穷,都只是在一个信念的支撑下在向着发展的目标努力搞生产。而且一般当这个时候,往往会有其他强国对你虎视眈眈,所以这个时候,大家都会很团结,但不会像祖先以及后辈一样在乎什么环境生态的。只有一个想法便是希望发展起来。</p><p>经过大约50年的发展,生活好了,底气足了,开始关注一些更长久的事情,比如教育和环境。于是接下来的50年,开始拼命治理环境,搞教育。于是渐渐的环境好了,下一代也成长起来了。于是年轻一代们便利用他们头脑中的书本知识,开始批判祖先们破坏环境这不好那不好,开始投科研资金,股市凡是跟环保相关的板块开始居高不下,可持续发展开始成为许多人的口头禅。而这时,当时那些破坏环境的罪魁祸首们正退休在家里乐呵呵的看着这一切的发生。大概就是这么一个过程了。</p><h2 id="Environmental-Kuznet-Curve"><a href="#Environmental-Kuznet-Curve" class="headerlink" title="Environmental Kuznet Curve"></a>Environmental Kuznet Curve</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_d6d943f_299x169_8_null_normal.jpeg" alt="Environmental Kuznet Curve"></p><p>上图的曲线非常科学地向我们展示出了一个国家在发展与环境之间摇摆的必然趋势。在这一图表的背后,反应出了以下几点:</p><ul><li>人们倾向于只考虑自己的假设</li><li>不同于个体的人群特性</li><li>生存资源稀缺</li><li>生产资料流通低效</li></ul><p>这意味着,如果能够改变上述的任何一个条件,Kuznet 诅咒便有希望得以改变,从而减小摆动周期和幅度,控制环境重建与修复成本,真正在宏观上实现人们所希望的高效率可持续发展。而新一代的数字信息技术正是这一可能性得以实践的关键。</p><h2 id="概念图"><a href="#概念图" class="headerlink" title="概念图"></a>概念图</h2><!-- 引入mermaid制图--><div class="mermaid">graph TDA{Environment}B{Economy}C{Society}D[GDB Based]E[NNI** HDI]F[Kuznet Curve]G[Env Kuznet Curve]H((Human Nature))I[Human Behavior]J[Improve Living Environment]K[Request for Dev]A --> JJ --> KK --> BB --> |measured by| DD --> |neglect| CB --> |predicted by| FF --> CD --> |foments| ID --> |spoils| AG --> CH --> IE --> |consider| AB --> EA --> HI --> |caused by| CI --> A</div><hr><p><strong>参考课件:</strong><br><a href="https://yimian-attachment.obs.myhwclouds.com/ppt/lan104/Week%202%20Economic%20Development%20%20The%20Environment.pdf" target="_blank" rel="noopener">Economic Development and The Environment.pdf</a></p></span><span class=".en"><h2 id="Why-pursue-development"><a href="#Why-pursue-development" class="headerlink" title="Why pursue development"></a>Why pursue development</h2><p>The natural environment is relatively harsh and not entirely suitable for human survival. Therefore, human beings with subjective initiative begin to change the environment from the impulse. This psychological behavior gradually resulted in a magnificent story called “development”, and everyone was convinced of it. As described in the story, in order to achieve this goal, people begin to reduce internal friction (war), and society tends to be highly divided.</p><p>Human beings have a basic psychological effect called the Zeignik effect, which means that if a person starts to do something, it will be difficult to stop in the middle. This effect will be intensified in group behavior. When people start to pursue development, and get a certain amount of incentives (life is indeed more comfortable, at least people think so), then this momentum will not easily stop, so mankind has entered a millennium-level development period.</p><p>In the early stages of development, too much infrastructure needs to be built, too much industry needs to be developed, and the most important thing is that everyone is very poor at this time, and they are only working hard towards the goal of development under the support of a belief. And generally at this time, there will often be other powerful countries looking at you, so at this time, everyone will be very united, but they will not care about the environment and ecology like their ancestors and descendants. There is only one idea that I hope to develop.</p><p>After about 50 years of development, my life is better and I am more confident, and I start to pay attention to some longer-term things, such as education and the environment. So in the next 50 years, I began to work hard to improve the environment and engage in education. As a result, the environment gradually improved, and the next generation grew up. So the younger generation made use of the book knowledge in their minds and began to criticize their ancestors for destroying the environment, which is not good or not, and began to invest in scientific research funds. The stock market began to remain high in environmental protection-related sectors, and sustainable development began to become many people. Mantra. At this time, the culprits who were damaging the environment at that time were retiring at home and happily watching this happen. It’s probably such a process.</p><h2 id="Environmental-Kuznet-Curve-1"><a href="#Environmental-Kuznet-Curve-1" class="headerlink" title="Environmental Kuznet Curve"></a>Environmental Kuznet Curve</h2><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_d6d943f_299x169_8_null_normal.jpeg" alt="Environmental Kuznet Curve"></p><p>The curve in the figure above shows us very scientifically the inevitable trend of a country swinging between development and the environment. Behind this chart, the following points are reflected:</p><ul><li>People tend to only consider their own assumptions</li><li>Different from individual characteristics of the population</li><li>Survival resources are scarce</li><li>Inefficient circulation of production materials</li></ul><p>This means that if any of the above conditions can be changed, the Kuznet curse will hopefully be changed, thereby reducing the swing cycle and amplitude, controlling the cost of environmental reconstruction and restoration, and truly achieving the high-efficiency and sustainable development that people hope on the macro level. . The new generation of digital information technology is the key to this possibility.</p><h2 id="Concept-map"><a href="#Concept-map" class="headerlink" title="Concept map"></a>Concept map</h2><!-- Introduce mermaid drawing--><div class="mermaid">graph TDA{Environment}B{Economy}C{Society}D[GDB Based]E[NNI** HDI]F[Kuznet Curve]G[Env Kuznet Curve]H((Human Nature))I[Human Behavior]J[Improve Living Environment]K[Request for Dev]A --> JJ --> KK --> BB --> |measured by| DD --> |neglect| CB --> |predicted by| FF --> CD --> |foments| ID --> |spoils| AG --> CH --> IE --> |consider| AB --> EA --> HI --> |caused by| CI --> A</div><hr><p><strong>Reference Courseware:</strong><br><a href="https://yimian-attachment.obs.myhwclouds.com/ppt/lan104/Week%202%20Economic%20Development%20%20The%20Environment.pdf" target="_blank" rel="noopener">Economic Development and The Environment.pdf</a></p></span>]]></content>
<categories>
<category> thoughts </category>
</categories>
<tags>
<tag> development </tag>
<tag> environment </tag>
</tags>
</entry>
<entry>
<title>气候变化与全球环境</title>
<link href="/thoughts/global-climate-change.html"/>
<url>/thoughts/global-climate-change.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>全球气候变化与人类行为有着显著的相关性,人类行为又会改变气候的自然变化。通过研究Ice core等Archive,发现地球历史中温度与$CO_{2}$浓度有着显著正相关性。如今,人类行为使大气$CO_{2}$含量远超其正常水平,其可能引起全球变暖,冰川融化等,但仅为可能..</p></span><span class=".en"><p>Global climate change has a significant correlation with human behavior, and human behavior will change the natural changes in climate. By studying Archives such as Ice core, it is found that there is a significant positive correlation between the temperature and the concentration of $CO_{2}$ in the history of the earth. Nowadays, human behavior makes the atmospheric content of $CO_{2}$ far exceed its normal level, which may cause global warming, melting of glaciers, etc., but it is only possible…</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h2 id="概念简介"><a href="#概念简介" class="headerlink" title="概念简介"></a>概念简介</h2><h3 id="天气与气候"><a href="#天气与气候" class="headerlink" title="天气与气候"></a>天气与气候</h3><p>天气是指一段较短时间段内的大气状态,而气候研究的主要使更长时间中周期行动大气状态规律。简言之,气候是周期变化的天气。气候具备地域性,随纬度与海陆分布密切相关。在更长的时间维度上,我们发现地球的气候变迁也呈现出显著的周期性。</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_8a6ca9c_720x237_8_null_normal.jpeg" alt="地球历史温度变迁"></p><p>上图描述了地球的历史温度,其具有明显的周期性。值得注意的是,每当全球气候变暖,便会激发物种爆炸。而现在,正处于一次小规模的温度上升期,且温度上升速度与历史数据并无太大异常,因此无法确凿证明其与人类二氧化碳排放有关。</p><h2 id="研究方法"><a href="#研究方法" class="headerlink" title="研究方法"></a>研究方法</h2><h3 id="直接法(研究现代)"><a href="#直接法(研究现代)" class="headerlink" title="直接法(研究现代)"></a>直接法(研究现代)</h3><ol><li>记录温度</li><li>记录降雨量 (Precipitation)</li><li>研究植被 (Vegetation)</li><li>海平面</li><li>冰川 (Glaciers) :: 主要通过研究冰盖融化与生成的Balance</li></ol><h3 id="间接法(研究历史)"><a href="#间接法(研究历史)" class="headerlink" title="间接法(研究历史)"></a>间接法(研究历史)</h3><ol><li>Proxy</li><li>Archive e.g. “Ice Core” ::从冰层(Ice Sheet)中提取的分层的冰棍标本</li></ol><h3 id="Ice-Core分层原因"><a href="#Ice-Core分层原因" class="headerlink" title="Ice Core分层原因"></a>Ice Core分层原因</h3><p>积雪后,随着时间推移,积雪会经历以下几种状态:</p><ol><li>Snow (几小时,主要成分是空气)</li><li>Firn (几天,粒雪)</li><li>Glacial Ice (数年)</li></ol><h3 id="时间追溯方法"><a href="#时间追溯方法" class="headerlink" title="时间追溯方法"></a>时间追溯方法</h3><p>由于积雪时的温度不同,因此冰层中会以年为单位周期变化,通过计数层数即可获得某一冰层的所属年代。<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_c2461c9_600x400_8_null_normal.jpeg" alt="冰层"></p><h3 id="历史温度研究方法"><a href="#历史温度研究方法" class="headerlink" title="历史温度研究方法"></a>历史温度研究方法</h3><p>大气中${}^{18}O/{}^{16}O$比值与温度密切相关,因此通过测量冰层中相应位置的同位素比值即可间接推得当时的温度。<br>此外,还可以通过类似的方法测得各历史时期的$CO_{2}$浓度。</p><h2 id="研究发现"><a href="#研究发现" class="headerlink" title="研究发现"></a>研究发现</h2><h3 id="二氧化碳浓度与温度密切相关"><a href="#二氧化碳浓度与温度密切相关" class="headerlink" title="二氧化碳浓度与温度密切相关"></a>二氧化碳浓度与温度密切相关</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_d2a8246_394x204_8_null_normal.jpeg" alt="历史二氧化碳与温度"></p><p>由上图可看出,地球历史上,二氧化碳浓度与温度具备密切的相关性。直到近150年,这一规律被打破,大气二氧化碳浓度极具上升。人表示慌得一批⌇●﹏●⌇</p><h2 id="与人类"><a href="#与人类" class="headerlink" title="与人类"></a>与人类</h2><h3 id="一个公式"><a href="#一个公式" class="headerlink" title="一个公式"></a>一个公式</h3><div style="overflow:scroll;"><p>$$Increase CO_{2} = Increasing Population + \Delta Emission per Person + Efficiency of CO_{2} Use$$</p></div><p>这个公式也可以转译为:</p><div style="overflow:scroll;"><p>$$碳排量 = 人口 + 经济 - 科技$$</p></div><h3 id="一个组织"><a href="#一个组织" class="headerlink" title="一个组织"></a>一个组织</h3><p>Intergovernmental Panel on Climate Change (IPCC) 制定了一个小目标来限制各国温室气体排放,表示到2050年,全球二氧化碳排放量要卡一半。。这其实等同于将排放量和钱联系起来,给每个国家分一部分排放量,如果多排就要交钱来买。结果已经工业化完的发达国家切走了超过40%的蛋糕,国科大校长老丁表示这不能忍啊,发展中国家的人到底还有没有人权啊ヾ(´・ ・`。)ノ”</p><h2 id="气候变暖影响"><a href="#气候变暖影响" class="headerlink" title="气候变暖影响"></a>气候变暖影响</h2><h3 id="Good"><a href="#Good" class="headerlink" title="Good"></a>Good</h3><ul><li>数据表明温度越高,世界范围战争数量越少</li><li>实验表明,温度高时,粮食等植被产量更高</li></ul><h3 id="Bad"><a href="#Bad" class="headerlink" title="Bad"></a>Bad</h3><ul><li>南方动物(虫子)比植物北迁的快,北方无天敌,植物被虫子吃光</li><li>海平面上升,淹没苏州</li></ul><!-- 引入mermaid制图--><div class="mermaid">graph TDA{Climate Change}B[Economy]C[Politic]D[Tech]E[Agriculture]F[Human Health]A --> |influence| EE --> |change| BE --> |change| CB --> |change| CB --> |determine| DC --> |determine| DB --> |influence| FD --> |affect| FD --> AC --> AD --> EE --> |Green Plant| AE --> FF --> E</div><hr><p>参考课件:<br><a href="https://www.eee.dog/usr/uploads/2019/02/3411175553.pdf">Climate change - From past to Future - Yi Zou-2019.pdf</a></p> </span><span class=".en"><h2 id="Concept-introduction"><a href="#Concept-introduction" class="headerlink" title="Concept introduction"></a>Concept introduction</h2><h3 id="Weather-and-Climate"><a href="#Weather-and-Climate" class="headerlink" title="Weather and Climate"></a>Weather and Climate</h3><p>Weather refers to the state of the atmosphere in a short period of time, and climate research mainly focuses on the law of atmospheric state in a longer period of time. In short, climate is weather that changes periodically. The climate is regional and closely related to the distribution of land and sea with latitude. In a longer time dimension, we find that the Earth’s climate change also shows significant periodicity.</p><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_8a6ca9c_720x237_8_null_normal.jpeg" alt="The temperature changes in the history of the earth"></p><p>The figure above describes the historical temperature of the earth, which has obvious periodicity. It is worth noting that whenever the global climate warms, it will trigger an explosion of species. But now, it is in a small-scale temperature rise period, and the temperature rise rate is not too abnormal with historical data, so it is impossible to conclusively prove that it is related to human carbon dioxide emissions.</p><h2 id="research-method"><a href="#research-method" class="headerlink" title="research method"></a>research method</h2><h3 id="Direct-method-research-modern"><a href="#Direct-method-research-modern" class="headerlink" title="Direct method (research modern)"></a>Direct method (research modern)</h3><ol><li>Record the temperature</li><li>Record rainfall (Precipitation)</li><li>Research vegetation (Vegetation)</li><li>Sea level</li><li>Glaciers :: Balance, mainly through the study of the melting and formation of ice sheets</li></ol><h3 id="Indirect-Method-Research-History"><a href="#Indirect-Method-Research-History" class="headerlink" title="Indirect Method (Research History)"></a>Indirect Method (Research History)</h3><ol><li>Proxy</li><li>Archive e.g. “Ice Core” :: a layered ice lolly specimen extracted from the Ice Sheet</li></ol><h3 id="Ice-Core-layering-reasons"><a href="#Ice-Core-layering-reasons" class="headerlink" title="Ice Core layering reasons"></a>Ice Core layering reasons</h3><p>After snow cover, over time, snow cover will experience the following states:</p><ol><li>Snow (a few hours, the main component is air)</li><li>Firn (a few days, snow)</li><li>Glacial Ice (several years)</li></ol><h3 id="Time-tracking-method"><a href="#Time-tracking-method" class="headerlink" title="Time tracking method"></a>Time tracking method</h3><p>Because the temperature of snow is different, the ice layer will change periodically in units of years, and the age of a certain ice layer can be obtained by counting the number of layers.<br><img src="https://api.yimian.xyz/img/?path=imgbed/img_c2461c9_600x400_8_null_normal.jpeg" alt="冰层"></p><h3 id="Historical-temperature-research-method"><a href="#Historical-temperature-research-method" class="headerlink" title="Historical temperature research method"></a>Historical temperature research method</h3><p>The ratio of ${}^{18}O/{}^{16}O$ in the atmosphere is closely related to temperature. Therefore, the current temperature can be indirectly inferred by measuring the isotope ratio of the corresponding position in the ice layer.<br>In addition, the concentration of $CO_{2}$ in each historical period can also be measured by a similar method.</p><h2 id="The-study-found"><a href="#The-study-found" class="headerlink" title="The study found"></a>The study found</h2><h3 id="Carbon-dioxide-concentration-is-closely-related-to-temperature"><a href="#Carbon-dioxide-concentration-is-closely-related-to-temperature" class="headerlink" title="Carbon dioxide concentration is closely related to temperature"></a>Carbon dioxide concentration is closely related to temperature</h3><p><img src="https://api.yimian.xyz/img/?path=imgbed/img_d2a8246_394x204_8_null_normal.jpeg" alt="History of carbon dioxide and temperature"></p><p>As can be seen from the above figure, in the history of the earth, the concentration of carbon dioxide has a close correlation with temperature. Until the past 150 years, this rule was broken, and the concentration of atmospheric carbon dioxide increased dramatically. People expressed panic ⌇●﹏●⌇</p><h2 id="With-humans"><a href="#With-humans" class="headerlink" title="With humans"></a>With humans</h2><h3 id="A-formula"><a href="#A-formula" class="headerlink" title="A formula"></a>A formula</h3><div style="overflow:scroll;"><p>$$Increase CO_{2} = Increasing Population + \Delta Emission per Person + Efficiency of CO_{2} Use$$</p></div><p>This formula can also be translated as:</p><div style="overflow:scroll;"><p>$$Carbon emissions = population + economy-technology$$</p></div><h3 id="An-organization"><a href="#An-organization" class="headerlink" title="An organization"></a>An organization</h3><p>The Intergovernmental Panel on Climate Change (IPCC) has set a small goal to limit greenhouse gas emissions in various countries, stating that by 2050, global carbon dioxide emissions will have to be half. . In fact, this is equivalent to linking emissions with money, giving each country a portion of the emissions, and paying for more emissions. As a result, the industrialized developed countries cut away more than 40% of the cake. The president of the National University of Science and Technology, Lao Ding, said that this is unbearable. Do people in developing countries have human rights? ヾ(´・ ・`。)ノ”</p><h2 id="Climate-warming-impact"><a href="#Climate-warming-impact" class="headerlink" title="Climate warming impact"></a>Climate warming impact</h2><h3 id="Good-1"><a href="#Good-1" class="headerlink" title="Good"></a>Good</h3><ul><li>Data shows that the higher the temperature, the fewer wars worldwide</li><li>Experiments show that when the temperature is high, the yield of vegetation such as grain is higher</li></ul><h3 id="Bad-1"><a href="#Bad-1" class="headerlink" title="Bad"></a>Bad</h3><ul><li>Southern animals (bugs) move northward faster than plants. There are no natural enemies in the north, and plants are eaten up by bugs.</li><li>Sea level rises, flooding Suzhou</li></ul><!-- Introduce mermaid drawing--><div class="mermaid">graph TDA{Climate Change}B[Economy]C[Politic]D[Tech]E[Agriculture]F[Human Health]A --> |influence| EE --> |change| BE --> |change| CB --> |change| CB --> |determine| DC --> |determine| DB --> |influence| FD --> |affect| FD --> AC --> AD --> EE --> |Green Plant| AE --> FF --> E</div><hr><p>Reference courseware:<br><a href="https://www.eee.dog/usr/uploads/2019/02/3411175553.pdf">Climate change-From past to Future-Yi Zou-2019.pdf</a></p></span>]]></content>
<categories>
<category> thoughts </category>
</categories>
<tags>
<tag> environment </tag>
<tag> climate </tag>
</tags>
</entry>
<entry>
<title>工程电磁学</title>
<link href="/notes/electromagnetism.html"/>
<url>/notes/electromagnetism.html</url>
<content type="html"><![CDATA[<span class=".zh"><p>麦克斯韦大法好!!</p></span><span class=".en"><p>Maxwell Dafa is good! !</p></span><a id="more"></a><script>session.onload(function(){if(page.tran.getLang() == 'en'){tips.warning({title: 'Caution',position: 'topRight',message: 'This page was translated by Machine!!',buttons: [['<button>Show Original Page</button>', function (instance, toast) {page.tran.setLang('zh'); instance.hide({ transitionOut: 'fadeOut' }, toast, 'button'); }, true]]});}});</script><span class=".zh"><h3 id="先供上麦克斯韦方程-膜拜膜拜-o-•ェ•-o"><a href="#先供上麦克斯韦方程-膜拜膜拜-o-•ェ•-o" class="headerlink" title="先供上麦克斯韦方程 膜拜膜拜( o=^•ェ•)o"></a>先供上麦克斯韦方程 膜拜膜拜( o=^•ェ•)o</h3><div style="overflow:scroll;"><p>$$<br>\nabla\cdot\vec{E} = \frac{\rho}{\varepsilon_0}<br>$$</p><p>$$<br>\nabla\cdot\vec{B} = 0<br>$$</p><p>$$<br>\nabla\times\vec{E} = -\frac{\partial B}{\partial t}<br>$$</p><p>$$<br>\nabla\times\vec{B} = \mu_0\left(\vec{J}+\varepsilon_0\frac{\partial E}{\partial t} \right)<br>$$</p></div><hr><h2 id="第一话-高斯生库伦"><a href="#第一话-高斯生库伦" class="headerlink" title="第一话 - 高斯生库伦"></a>第一话 - 高斯生库伦</h2><ul><li>假设空间中两点电荷$Q_{1}$,$Q_{2}$,相距d,欲求其相互作用的电场力。</li><li>现以$Q_{1}$为圆心,$d$为半径做球。根据高斯law可知球面上的电通量只与球内电荷量有关,本例中为$\frac{Q_{1}}{\varepsilon_0}$。</li><li>将上式中电通量除以求表面积可得电场强度$\frac{Q_{1}}{4\pi d^{2}\varepsilon_0}$</li><li>场强乘以$Q_{2}$即可得库仑力$\frac{Q_{1}Q_{2}}{4\pi d^{2}\varepsilon_0}$</li><li>令$k=\frac{1}{4\pi \varepsilon_0}$整理得<br>$$F = \frac{k Q_{1}Q_{2}}{d^{2}}$$<br>证毕</li></ul><h2 id="第二话-高斯金箍棒"><a href="#第二话-高斯金箍棒" class="headerlink" title="第二话 - 高斯金箍棒"></a>第二话 - 高斯金箍棒</h2><ul><li>假设一均匀带电长度正无穷细杆,电荷密度为$\lambda$,求距其$d$处场强。</li><li>绕杆画一个过待求点的圆柱,设高为$x$。</li><li>由于杆长无限,圆柱两底面电场被抵消。</li><li>圆柱侧面积为$2\pi dx$</li><li>圆柱内电荷量为$\lambda x$</li><li>引入高斯,得<br>$$<br>2\pi dxE = \frac{\lambda x}{\varepsilon_{0}}<br>$$<br>整理得<br>$$<br>E = \frac{\lambda}{2\pi d\varepsilon_{0}}<br>$$<br>证毕</li></ul><h2 id="高斯球球球"><a href="#高斯球球球" class="headerlink" title="高斯球球球"></a>高斯球球球</h2><ul><li>首先要有一个带电小球,电量$Q$,想求其外部距其圆心$d$处场强。</li><li>然后可列式<br>$$<br>4\pi d^2 E = \frac{Q}{\varepsilon_0}<br>$$<br>整理得<br>$$<br>E = \frac{Q}{4\pi \varepsilon_0 d^2}<br>$$<br>毕</li></ul><h2 id="高斯大面"><a href="#高斯大面" class="headerlink" title="高斯大面"></a>高斯大面</h2><ul><li>首先有一个均匀带电无穷面,带电面密度$\rho$,欲求距其$d$的点场强。</li><li>以无穷面为中央横截面,做一个底面圆心为待求点的圆柱,半径为$r$。</li><li>由于电场线皆平行,只有两个底面有电场线穿过。</li><li>可列式<br>$$<br>2\pi r^2 E = \frac{\rho \pi r^2}{\varepsilon_0}<br>$$<br>整理得<br>$$<br>E = \frac{\rho}{2\varepsilon_0}<br>$$<br>完事</li></ul><hr><p>To Be Continued…</p></span><span class=".en"><h3 id="First-offer-to-Maxwell’s-equation-worship-o-•ェ•-o"><a href="#First-offer-to-Maxwell’s-equation-worship-o-•ェ•-o" class="headerlink" title="First offer to Maxwell’s equation, worship ( o=^•ェ•)o"></a>First offer to Maxwell’s equation, worship ( o=^•ェ•)o</h3><div style="overflow:scroll;"><p>$$<br>\nabla\cdot\vec{E} = \frac{\rho}{\varepsilon_0}<br>$$</p><p>$$<br>\nabla\cdot\vec{B} = 0<br>$$</p><p>$$<br>\nabla\times\vec{E} = -\frac{\partial B}{\partial t}<br>$$</p><p>$$<br>\nabla\times\vec{B} = \mu_0\left(\vec{J}+\varepsilon_0\frac{\partial E}{\partial t} \right)<br>$$</p></div><hr><h2 id="Chapter-One-Gossian-Cullen"><a href="#Chapter-One-Gossian-Cullen" class="headerlink" title="Chapter One-Gossian Cullen"></a>Chapter One-Gossian Cullen</h2><ul><li>Suppose two electric charges $Q_{1}$ and $Q_{2}$ in space are separated by d, and the electric field force they want to interact with.</li><li>Now take $Q_{1}$ as the center of the circle and $d$ as the radius to make the ball. According to the Gaussian law, the electric flux on the sphere is only related to the amount of charge in the sphere, which is $\frac{Q_{1}}{\varepsilon_0}$