树莓派云浇水--上层搭建自研版 :P

这个是个人的实际需求。如果出差,家中个别宝贝植物如何看护? 

翻文章的话,经常看到的一套是什么检测土壤湿度,判断完数据后浇水的。个人觉得,植物浇水嘛,大部分的普通植物,看到它叶子耷拉了,那就一定要浇水了。鬼个土壤湿度检测模块。我需要的是远程监控模块(让我远程检查植物生存状态),和浇水装置。

当然说白了,就买个家庭监控活动摄像头,再淘个远程浇水是最快解决问题的。

但如果要搞一体化(说白了就是作),应该怎么动手?本文记录一套打法。

BOM表如下,

1. 能联网的树莓派(我后面要用土豆派降低成本,树莓派已经贵的不像话)。240元朝上

2. 网购5vDC输入的usb小水泵,对,就是给鱼缸抽水那玩意儿。15元

👆🏻这玩意儿剪断usb头,把正负极抽出来。

3. 面包板,杜邦线。算10元

4.1路继电器一个。3元

 5.树莓派那个csi摄像头。18元

以上成本逃不开。3-5或者至少3和4,可以一起买,包邮。

实现思路就是内网穿透导致公网可以访问到树莓派,查看美丽的花草,然后浇水。

我看现成用motion的也不少,我觉得不需要,其实有实时图片就够了,不用这么大一套框架。接下来介绍散装手法,以及里面最重要的细节。

首先一套cpolar,让树莓派可以公网访问,可以从公网ssh树莓派开始。hmmm cpolar的穿透谈不上什么难度吧,可能就https那里(至少买了基本套餐保留二级域名),有个坑。我采用了去sslforfree网站生成完证书上传树莓派,再配置cpolar和nginx这种方式。另外如果只是自己用,最好上来就用个http auth。具体nginx方面的写法,展示在后面代码部分。

接下来我用的是nginx+php-fpm+mysql这个后台引擎组合拳,前端搭了个wordpress,选择了blank的专题。

按两个钮,看图和浇水。

这个已经是公网访问的成品了。

这俩钮也许在服务器终端是好控制的,但是做到php脚本里真是苦煞老奴(嗯,主要还是因为很多东西不懂)首先其实libcamera和raspi-gpio的控制权都在root手里,或者是因为/dev/media*的控制权在root手里。个人觉得比较保险的一个做法是给运行nginx的user一个sudo免密码权限,具体就是  sudo visudo,然后给对应用户搞两个sudo免密权限。

接下来是写php、js、html和css的痛苦。尤其是这帮混蛋要都在一个php文件里。专业的看这个估计是看笑话,但是对于本人是千辛万苦的代码搬运啊。主要是在专题的index.php里面改,以及创建一个叫execute-shell-command.php。 直接上关键代码,留以日后嘲笑。

index.php

 <?php
 /**
  * The base (and only) template
  *
  * @package WordPress
  * @subpackage intentionally-blank
  */

 ?><!DOCTYPE html>
 <html <?php language_attributes(); ?>>
 <head>
 <meta charset="<?php bloginfo( 'charset' ); ?>">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <?php wp_head(); ?>
 </head>
 <body <?php body_class(); ?>><?php wp_body_open(); ?><div id="page">
 <div class="site-title"><div class="site-title-bg">
 <h1><a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"><?php bloginfo( 'name' ); ?></a></h1>
 <?php
 $blank_description = get_bloginfo( 'description', 'display' );
 if ( $blank_description || is_customize_preview() ) :
         ?>
         <p class="site-description"><?php echo esc_html( $blank_description ); ?></p>
 <?php endif; ?>
 </div></div>
 <?php the_custom_logo(); ?>
         <div class="pic_button">
                 <button id="pic_taking">实时图片</button>
         </div>
         <p></p>
         <div class="water_button">
                 <button id="water_pouring" onclick="alert('点击确定,开始工作。将浇水10秒');" >浇水</button>
         </div>
         <script>
         const pic = document.getElementById("pic_taking");
         const water = document.getElementById("water_pouring");
         pic.addEventListener("click", ()=>{executeCommand('taking')});
         water.addEventListener("click", ()=>{executeCommand('pouring')});
         async function executeCommand(action) {
                 try {
                         const res = await fetch(`https://hahahahhaha.com/interesting_scripts/execute-shell-command.php?action=${action}`);
                         console.log(res.json());
                 } catch (error) {
                         console.error(new Error(error));
                 }
         }
         </script>
 </div>
 <p></p>
 <div style="text-align: center;">
 <?php
         $fileList = glob("wp-content/uploads/plant_pic/*");
         foreach($fileList as $filename){
                 if (is_file($filename)){
                         echo "<img src=".$filename." />";
                         break;
                 }
         }
         if (count($fileList)==0)
                 echo "<img src=wp-content/uploads/Untargeted/FileNotFound.jpg />";
 ?>
 </div>

 <footer id="colophon" class="site-footer">
         <?php if ( get_theme_mod( 'blank_show_copyright', true ) ) : ?>
         <div class="site-info">
                 <?php echo wp_kses_post( get_theme_mod( 'blank_copyright', __( 'Intentionally Blank - Proudly powered by WordPress', 'intentionally-blank' ) )     ); ?>
         </div>
         <?php endif; ?>
 </footer>
 </div><!-- #page -->
 <?php wp_footer(); ?></body></html>

execute-shell-command.php

<?php
// Get the query params
$action = $_GET["action"];
if (isset($action)) {
  if ($action === "taking") {
        shell_exec('rm -rf /your/forlder/*');
        $now = time();
        shell_exec('sudo libcamera-still -o /you/flder/'.$now.'cool.jpg --width 720 --height 640 --mode 720:640 --vflip');
  }
  if ($action === "pouring") {
        shell_exec('sudo raspi-gpio set 17 op'); //设定gpio17为输出
        shell_exec('sudo raspi-gpio set 17 dh'); //我的逻辑是高电平时水泵工作
        shell_exec('sleep 10'); //工作了10秒
        shell_exec('sudo raspi-gpio set 17 dl'); //将gpio17弄回低电平
        shell_exec('sudo raspi-gpio set 17 ip pd'); //将gpio恢复成最初的未选择状态
  }
}
// Anything echo'd will be the response to the request
// and will get console.logged in the browser
echo json_encode(array("requested action"=>$action));

nginx配置文件:

##
# Default server configuration
#
upstream php {
        server unix:/run/php/php7.3-fpm.sock;
        server 127.0.0.1:9000;
}
server {
        listen 80;
        listen [::]:80;
        auth_basic "请输入口令!";
        auth_basic_user_file /your/folder/path/.htpasswd;
        root /your/folder/path;
        index index.html index.htm index.php;
        server_name nameyourserver.com;
        add_header Content-Security-Policy upgrade-insecure-requests;  #加上,不然报https混入http内容的错误
        location = /favicon.ico {
                log_not_found off;
                access_log off;
        }
        location = /robots.txt {
                allow all;
                log_not_found off;
                access_log off;
        }
        location ~ /\. {
                deny all;
        }
        location ~* /(?:uploads|files)/.*\.php$ {
                deny all;
        }
        location / {
                try_files $uri $uri/ /index.php?$args;
        }
        location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                expires max;
                log_not_found off;
        }
        location /wordpress {
                try_files $uri $uri/ /wordpress/index.php?$args;
        }
        location ~ \.php$ {
                include fastcgi.conf;
                fastcgi_split_path_info ^(.+?\.php)(/.*)$;
                if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }
                fastcgi_index index.php;
                fastcgi_pass unix:/run/php/php7.3-fpm.sock;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
}

整体板子布局:

 水泵与继电器的连接方式,抄了个灯泡的图,反正也就电源正负,一个意思啦。

借鉴了很多提问回答,大佬思路。太多了,实在点不了鸣谢。只能说,都是站在高手们肩膀上瞎折腾。感谢! 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

取啥都被占用

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值