『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 52912|回复: 185

[新奇玩法] 解決新版 [綠色PCB小愛同學] 無法寫入檔案+開機ssh+mico(3P排....

  [复制链接]

2

主题

171

帖子

1169

积分

金牌会员

Rank: 6Rank: 6

积分
1169
金钱
998
HASS币
10
发表于 2018-11-3 22:40:14 | 显示全部楼层 |阅读模式
本帖最后由 liuje 于 2019-2-28 22:23 编辑

*************** 2/24/2019更新 (綠板PCB, 只能用F大前版的mico.sh, 最新版的匹配度較差) **************
這兩天將小愛同學恢復出廠設置,  再重新做配置.  發現目前直接下載F大的最終版mico.sh攔截程序,
跟綠板PCB的小愛同學相容度很差.     只要連續下命令, 經常只會回應 "找不到設備....." ,  
然後隔個幾十秒, 才突然動作起來..   一整個怪異.  延遲非常嚴重 .
但只要改用底下較早的代碼,  就可以完美匹配.      請各位同鞋留意 ~

** 請修改自己的nodred服務器地址 "nodered_url=......" 此處,
    還有,  如果nodered有設密碼請改這邊   nodered_auth=":"  (這裡預設是無密碼)
    (如有密碼請改成例如 : nodered_auth="admin:admin")

# @author FlashSoft
# == 自定义配置========================================
# 设定拦截词,以竖线分割每个拦截词,被拦截的内容会转发给nodered服务器进行处理
keywords="晚安|传感器"
# 配置nodered的接收地址
nodered_url="http://192.168.1.10:1880/miai"
# 配置从nodered更新拦截词的间隔,单位秒
# 0代表不更新,一直使用本地拦截词
# 大于0则更新,会从上面设定的nodered_url去获取拦截词,并覆盖本地的拦截词
keywords_update_timeout=0
# == /自定义配置========================================
 
asr_file="/tmp/mipns/mibrain/mibrain_asr.log"
res_file="/tmp/mipns/mibrain/mibrain_response.log"
nodered_auth=":"
 
# 解决可能存在第一次文件不存在问题
touch $res_file && touch $asr_file
res_md5=""
last_time=`date +%s`
 
echo "== 拦截词: $keywords"
echo "== NodeRed地址:$nodered_url"
echo "== 更新拦截词时间间隔 $keywords_update_timeout 秒"
 
while true;do
  # 计算md5值 
  new_md5=`md5sum $res_file | awk '{print $1}'`
  # 如果是第一次,就赋值比较用的md5
  [ -z $res_md5 ] && res_md5=$new_md5
  # 如果md5不等则文件变化
  if [[ $new_md5 != $res_md5 ]];then
    # 记录md5变化后结果
    res_md5=$new_md5
 
    
    # 获取asr内容
    asr_content=`cat $asr_file`
    # 获取res内容
    res_content=`cat $res_file`
 
    # echo $asr_content
    # echo ""
    # echo $res_content

    # 如果拦截词不为空,且匹配到了拦截词则试图拦截

    # if [ "`echo "$res_content"|grep '"domain": "smartMiot"'`" ];then
    miai_domain=`echo "$res_content"|awk -F '"domain": ' '{print $2}'|awk -F '"' '{print $2}'`

    echo "== 有内容更新 | type: $miai_domain"

    if ([[ ! -z $keywords ]] && [[  ! -z `echo $res_content|awk 'match($0,/'$keywords'/){print 1}'` ]]) || [ "`echo "$res_content"|grep SM_NO_DEVICE_TO_OPERATE_DEVICE_LIST_NOT_EMPTY`" ];then
      echo "== 试图停止"
      # 若干循环,直到resume成功一次直接跳出
      seq 1 200 | while read line;do
        code=`ubus call mediaplayer player_play_operation {"action":"resume"}|awk -F 'code":' '{print $2}'`
        if [[ "$code" -eq "0" ]];then
          echo "== 停止成功"
          break
        fi
        sleep 0
      done
 
      # 记录播放状态并暂停,方便在HA服务器处理逻辑的时候不会插播音乐,0为未播放,1为播放中,2为暂停
      play_status=`ubus -t 1 call mediaplayer player_get_play_status | awk -F 'status' '{print $2}' | cut -c 5`
      # echo $play_status
      ubus call mediaplayer player_play_operation {"action":"pause"} > /dev/null 2>&1
 
      # @todo:
      # 转发asr和res给服务端接口,远端可以处理控制逻辑完成后返回需要播报的TTS文本
      # 2秒连接超时,4秒传输超时
      tts=`curl -u "$nodered_auth" –connect-timeout 2 -m 4 -s --data-urlencode "asr=$asr_content" --data-urlencode "res=$res_content" $nodered_url`
      echo "== 请求完成"

      # 如果远端返回内容不为空则用TTS播报之
      if [[ -n "$tts" ]];then
        echo "== 播报TTS | TTS内容: $tts"
        ubus call mibrain text_to_speech "{"text":"$tts","save":0}" > /dev/null 2>&1
        # @fixme
        # 这里的4秒有点瞎扯淡,后续需要修改成判断是否TTS播报完毕
        sleep 4
      fi
 
      # 如果之前音乐是播放的则接着播放
      if [[ "$play_status" -eq "1" ]];then
        echo "== 继续播放音乐"
        # 这里延迟一秒是因为前面处理如果太快,可能引起恢复播放不成功
        sleep 1
        ubus call mediaplayer player_play_operation {"action":"play"} > /dev/null 2>&1
      fi
    fi
  fi
 
  # 以某频度去更新拦截词
  if [[ "$keywords_update_timeout" -gt "0" ]];then
    now=`date +%s`
    step=`expr $now - $last_time`
    # 根据设定时间间隔获取更新词
    if [[ "$step" -gt "$keywords_update_timeout" ]];then
        keywords=`curl -u "$nodered_auth" –connect-timeout 2 -m 4 -s $nodered_url`
        echo "== 更新关键词 | 关键词内容: $keywords"
        last_time=`date +%s`
    fi
  fi
  sleep 0
done



********************* 12/15更新 (以 USB-TTL 直接燒錄hex, 免安裝Arduino) ****************************
有同好問起怎麼用USB-TTL直接燒錄hex,  這邊做個簡單教程 :

1.  插上USB-TTL, 從 "設備管理器" 查詢到對應的com口,  例如我的是對應在 com5.
2.  連接好pro mini板, 共連接VCC/GND/Rx/Tx四條線, 其中 USB-TTL標示"Rx" 必須連接到 Pro mini 的"Tx"腳,
     USB-TTL標示"Tx" 必須連接到 Pro mini的 "Rx"腳  (交錯連接).
3.  解壓附檔燒錄工具以及編譯好的hex代碼到某個目錄下.
4.  按住 Pro mini上的唯一一顆小按鍵(reset按鈕)不放.
5.  到剛剛解壓的目錄下, 打開command窗口,  並運行底下命令:
    avrdude -q -c stk500v1 -P com5 -b 57600 -p atmega328p -U flash:w:Xiaomi_AI_SSH_mico(181215).hex
(請自己修改 com5 這個參數, 對應到你自己的狀況)
6.  仔細看USB-TTL上的傳輸指示燈,  當看到第1次閃一下時,  立即放開Pro mini的按鍵(如果超過2秒沒放開, 可能就會失敗)
    失敗的話, 如下畫面跑完後, 只要重覆以上4-5步驟, 試個2~3次肯定會成功.      成功的話, 會看到2個led燈快速交錯閃爍,
    代表正開始燒錄,  整個燒錄時間大概10秒以內就完成了.
7. 燒錄完成, Pro mini會自動重啟, 會看到Pro mini上頭指示燈快速閃爍3-5秒鐘然後熄滅, 就說明能工作了.
8. 再一次提醒, 一定要找 Pro mini 5V/16MHZ的版本來燒錄 (3.3V/8MHZ串口速率無法達到115200的速率要求)

(燒錄成功 : 當USB-TTL上, 任一顆傳輸LED閃動第1下時, 閃爍時間非常短.    要在2秒內放開Pro mini上的reset按鈕,  10秒內就燒錄成功了)
2018-12-15_16-51-04.gif

(燒錄失敗 :  可能原因是沒按上面說明, 在一定時間內放開reset按鈕, 或者是Rx/Tx接錯, 都只會看到這個錯誤畫面)
2018-12-15_16-51-24.gif

(燒錄工具 +  hex燒錄代碼)
avrdude-6.3-mingw32.rar (187.15 KB, 下载次数: 186)

**********************************************************************************


********************* 12/8更新 (Pro mini 另一種代碼, 定時運行) ****************************
我改了一版pro mini程序,  變成跟F大那篇一樣,  定時10秒鐘就去檢查程序是否運行,  如沒有就運行起來..     
這種方法, 可以避免以後固件大幅度升級後,  有可能輸出的文字串會不同,  原來的那種判斷特定字符串的方式有可能失效.   
這種定時運行的,  就能避免此問題.    提供如下給大家參考..
#include <Arduino.h>

void setup()
{
  Serial.begin(115200); 
  pinMode(LED_BUILTIN, OUTPUT);  
  for (int i=0; i<30; i++) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(50);
  }
  digitalWrite(LED_BUILTIN, LOW);   
}


void loop()
{
  // 每10秒檢查 dropbear 以及 mico.sh 是否運行? 如果沒有,則打開ssh以及運行mico.sh
  Serial.println();
  Serial.println("test `ps|grep 'dropbear -r /data/dropbear_rsa_host_key'|grep -v grep|wc -l` -eq 0 && dropbear -r /data/dropbear_rsa_host_key");
  Serial.println();
  Serial.println("test `ps|grep 'sh /data/mico.sh'|grep -v grep|wc -l` -eq 0 && sh /data/mico.sh > /tmp/mico.log 2>&1 &");
  delay(10000); 
}


*****************************************************************************************

********************* 11/11更新 (免拆PCB螺絲, 直接改機) ****************************


更優雅的改機方式, 可以找3pin, 1.0mm間距的排線, 直接裝上就搞定了(如下圖下方的3pin排線).   
就不用拆PCB螺絲尋找背面那3個焊點了.

參考連接如:  (非廣告)
2018-11-11_16-16-15.jpg

*********************************************************************************


************** 11/7補充 (有朋友在問詳細一點的配線方式, 再提供圖片如下) ***********************

2018-11-03_21-30-29.jpg

*********************************************************************************




****** 11/5補充 (有一些人碰到了node-red導入流程文件無法運行, 一直報錯的問題, 這邊給個提醒 *********
可能是少裝了 Node-RED  與 Homeassistant 溝通的插件..     這部份,  幾位大佬的教程文件沒特別提到, 所以我也看一些在問,  為什麼流程文件導入後,  總是有幾個地方一直報錯,  原因就是沒有安裝插件.  (我自己也是第1次用 node-red,   也是花了好幾小時才找到是插件沒裝問題)

當然,  安裝插件以後,  有幾個控制點, 包括Homeassistant佈署地址,  設備的 entity_id 等等,  也要改成你實際有的.    才會動的.
插件有兩種可選 : node-red-contrib-home-assistant-websocket  與  node-red-contrib-home-assistant .
其中 "node-red-contrib-home-assistant"  已停止維護,  只支援HA原來的密碼驗證.
而 "node-red-contrib-home-assistant-websocket"  目前還在維護中, 已支持新版HA的 token驗證.  
建議安裝 node-red-contrib-home-assistant-websocket ,  以免日後HA停止支持單純的密碼驗證.

可以參考這邊的安裝 :  (要到node-red目錄下進行安裝才可以)
1.   cd ~/.node-red
2.   npm install node-red-contrib-home-assistant-websocket
https://www.npmjs.com/package/node-red-contrib-home-assistant-websocket

************************************************************************


~感謝眾多高手的努力, 讓小愛音箱在局網內就可以控制任何自製設備 ~


花了兩天時間, 終於把剛剛買的小愛音箱給改好了.   目前最新的小愛音箱都是綠色PCB,

並且通過串口連接後,  會發現 /etc/init.d 這個目錄被小米設成只讀了.    也等於斷絕了設置自動運行的可能.

"flashsoft" 大, 也有教我們使用單片機來解決這問題.   (https://bbs.hassbian.com/thread-5110-1-1.html)

底下改造步驟,  簡單做個分享...

1.  按下圖把 RX/TX/GND 三個信號點焊線出來. (參考下圖)
      2018-11-03_21-30-29.jpg

2.  連接 USB<-->TTL , 速率設為 115200,N,8,1  .    就能直接以root身份登入 (不用輸入密碼)
    輸入以下命令: (這裡, 我們修改了rsa檔的存放路徑,  因為其它文章提到的目錄,  沒法寫入,
                           我們改放在 /data 目錄, 就沒問題,  命令執行後, SSH就打開了)

   
dropbearkey -t rsa -f /data/dropbear_rsa_host_key
    dropbear -r /data/dropbear_rsa_host_key

    這裡 "dropbearkey -t rsa -f /data/dropbear_rsa_host_key"  是把金鑰產生到指定的目錄下.
    然後 "dropbear -r /data/dropbear_rsa_host_key"  是引用指定位置的金鑰,  執行此命令後才會真正開啟SSH.
    這邊做個提醒, 如果是第1次安裝, 或者小愛同學恢復出廠設置.   需要連接串口, 至少運行一次
    產生金鑰的命令.    因為單片機裡頭, 每10秒運行一次的命令, 僅僅是引用指定位置的金鑰.
    所以, 全新或復歸出廠設置 這兩種狀況下,  都必須手動運行過一次 "dropbearkey -t rsa -f /data/dropbear_rsa_host_key"
    否則可能會發現根本沒打開ssh.     請特別注意 !

3.  使用合適的單片機 (我是使用ATmega328P , 5V, 16MHZ的 Arduino Pro mini板) , 要注意的是,
     我一開始用8MHZ / 3.3V的版本,  發現uart沒辦法跑到115200, 會變亂碼.  如果要跟我用一樣的,
     請特別注意,  一定要選用5V/16MHZ版本
.   由於Pro mini體積很小, 耗電流也小(估計只有10-20mA).
     其實不需用到ESP8266,  相對耗電量大很多.   取電需注意.    底下Arduino代碼供參考 :
   
#include <Arduino.h>
#include <SoftwareSerial.h>

SoftwareSerial swSer(10, 11);

void setup()
{
  Serial.begin(115200); 
  swSer.begin(57600);
  pinMode(LED_BUILTIN, OUTPUT);  
  for (int i=0; i<30; i++) {
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    delay(50);
  }
  digitalWrite(LED_BUILTIN, LOW);   

}

void loop()
{
 while(swSer.available()) 
 {
   String str = swSer.readString(); 
   Serial.println(str);
 }
 delay(1);  
}


void serialEvent()
{
 while(Serial.available()) 
 {
   String str = Serial.readString(); 
   //Serial.println(str); 
   swSer.println(str);
   if ( (str.indexOf("Please press Enter to activate this console") > 0) or (str.indexOf("crond (busybox 1.27.2) started, log level 5") > 0) )
   {
      //Serial.println("Got the command!"); 
      Serial.println();
      Serial.println();
      delay(10000);      //一定要加上至少10秒的延遲,  如果發現, 重起之後, 本來可以, 但只回應 "沒有找到你要的設備呢......" , 可以延長到15000(15秒)
      Serial.println("sh /data/mico.sh > /tmp/mico.log 2>&1 &");
      Serial.println();
      Serial.println("dropbear -r /data/dropbear_rsa_host_key");
      Serial.println();
      for (int i=0; i<30; i++) {
        digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
        delay(50);
      }
      digitalWrite(LED_BUILTIN, LOW);   
   }
 }
 delay(1);
}

  
(我的作法不太一樣,  不是用定時間隔發送, 而是偵測小愛開機時的系統運行資訊, 判斷特定字串再執行,
  因此, 只會在重開機完成後運行一次.  判斷的字串就像底下這樣子.... 我是抓了兩個字串 "lease press Enter to activate this console"
  以及 "crond (busybox 1.27.2) started, log level 5"  做判斷,   並且一定要延遲大約10秒, 再發送命令.
  如果不做延遲馬上發送, 就只能成功打開ssh, 無法成功讓mico.sh 監控程序在背景運行起來)

  (開機時通過TTL輸出的狀態輸出片斷)
-----------(略)--------------
Starting kernel ...
 
uboot time: 1544270 us
domain-0 init dvfs: 4
[    0.273594@2] ff803000.serial: clock gate not found
get key is 0x00 , curr_boot is boot1
Booting from boot1
/dev/mtdblock5 is ready now.
[    1.609729@3] i2c i2c-1: [aml_i2c_xfer] error ret = -5 (-EIO)
[    1.609858@3] i2c i2c-1: token 1, master_no(1) 300K addr 0x3c
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
Please press Enter to activate this console.
[    6.395681@0] cyttsp 0-0008: Failed to request firmware touch.cyacd
[    6.396330@0] cyttsp 0-0008: Failed to update firmware;
[    8.264743@3] name: mac_wifi, size 17
[    8.280245@0] name: mac_bt, size 17
crond[1098]: crond (busybox 1.27.2) started, log level 5

(改好的樣子, 紅框為加裝的小PCB, 使用ATmega328P , Arduino Pro mini,  小巧精幹)
2018-11-03_19-29-00.jpg
    2018-11-03_19-28-44.jpg
    2018-11-03_22-12-35.jpg


4.  flashsoft 大大分享的 "小爱拦截器'安装工具",  下載以後需要做修改 (因為/root , /etc/init.d 這兩個目錄,
    在最新的綠版PCB, 都變成只讀了.    所以, 我們要改成其它目錄 (例如 /data)
.
要修改 /install.sh 此script檔
# @author FlashSoft
# root=`pwd`
root=""
# 脚本存放地址
#mico_path="${root}/root/mico.sh"
mico_path="${root}/data/mico.sh"       ##修改為 /data
# 脚本开机启动
#mico_initpath="${root}/etc/init.d/mico_enable"
mico_initpath="${root}/data/mico_enable"    ## 也修改為 /data (此檔無作用了, 因為無法成功寫入開機啟動)
mico_tmppath="/tmp"
關於 mico.sh  此scipt  ** 建議直接引用最上頭的mico.sh內容,  因為F大有改過mich.sh內容, 目前僅能適配黑版PCB .

此版本系統可能不太一樣,  已經沒有 usleep (延遲us, 微秒) 這個命令 , 如果直接運行 mico.sh 會報錯, 無法運行.  需要把 usleep xx 改成 "sleep 0" 才能保證兼容性與長期運行的可靠性.

(請參考本貼#48樓的說明 ~~~)


** 建議直接引用最上方的mico.sh內容,  因為F大在去年底有修改過mico.sh, 經過我測試, 如果現在才下載的,
       跟綠色PCB相容性很差,  會有一堆延遲問題.    所以,  直接改用我上方的內容, 才能完美匹配.   02/24/2019註. **


5.  其它請參考Node-red安裝/使用,  最近幾天也有視頻操作教程.   基本上看過一遍就能明白操作原理.

(我使用的固件版本為 1.34.33 )
root@mico:/# uci -c /usr/share/mico show
uci: Entry not found
uci: Entry not found
version.version=core
version.version.ROM='1.34.33'
version.version.CHANNEL='release'
version.version.HARDWARE='S12A'
version.version.APPID='xxxxxxxxxxxxxxxxxxxx'
version.version.APPTOKEN='xxxxxxxxxxxxxxx'
version.version.UBOOT='0.0.1'
version.version.LINUX='0.0.1'
version.version.RAMFS='0.0.1'
version.version.SQAFS='0.0.1'
version.version.ROOTFS='0.0.1'
version.version.BUILDTIME='Mon, 22 Oct 2018 14:30:23 +0800'
version.version.BUILDTS='1540189823'
version.version.GTAG='commit b9e9b6640c2491c7a77a22612e47790e6c8c0356'



最後,  祝大家都能改造成功 ~















评分

参与人数 3金钱 +50 HASS币 +10 收起 理由
flashsoft + 20 我来瀚思就为看你!
lidicn + 20 纳尼,还有这种操作?
Roger + 10 + 10 厉害了word楼主!

查看全部评分

回复

使用道具 举报

0

主题

204

帖子

1037

积分

金牌会员

Rank: 6Rank: 6

积分
1037
金钱
833
HASS币
0
发表于 2018-11-3 22:44:03 | 显示全部楼层
谢谢分享
回复

使用道具 举报

7

主题

219

帖子

1298

积分

金牌会员

Rank: 6Rank: 6

积分
1298
金钱
1074
HASS币
0
发表于 2018-11-3 22:56:25 来自手机 | 显示全部楼层
叔叔我来支持你~
回复

使用道具 举报

11

主题

359

帖子

2408

积分

金牌会员

Rank: 6Rank: 6

积分
2408
金钱
2049
HASS币
0
发表于 2018-11-3 23:14:43 | 显示全部楼层
厉害,留个脚印备用
回复

使用道具 举报

4

主题

282

帖子

3653

积分

论坛元老

Rank: 8Rank: 8

积分
3653
金钱
3371
HASS币
0
发表于 2018-11-3 23:24:04 | 显示全部楼层
厉害,mark
回复

使用道具 举报

9

主题

249

帖子

4114

积分

元老级技术达人

积分
4114
金钱
3850
HASS币
100
发表于 2018-11-3 23:25:20 | 显示全部楼层

膜拜大神!
看来近期小爱会涨价
E5-2650L-V2+华南X79+16GB*2
回复

使用道具 举报

7

主题

359

帖子

1294

积分

金牌会员

Rank: 6Rank: 6

积分
1294
金钱
935
HASS币
0
发表于 2018-11-4 10:21:47 | 显示全部楼层
厉害了,大佬们给力
回复

使用道具 举报

2

主题

190

帖子

1733

积分

金牌会员

Rank: 6Rank: 6

积分
1733
金钱
1543
HASS币
0
发表于 2018-11-4 11:40:09 | 显示全部楼层
太強大了,感謝大神們分享! 學習了!
回复

使用道具 举报

16

主题

271

帖子

2221

积分

金牌会员

Rank: 6Rank: 6

积分
2221
金钱
1950
HASS币
10
发表于 2018-11-4 12:12:06 | 显示全部楼层
绿板的小爱的话 每次断电重启都要执行flashsoft大的一键安装包吗??
回复

使用道具 举报

16

主题

271

帖子

2221

积分

金牌会员

Rank: 6Rank: 6

积分
2221
金钱
1950
HASS币
10
发表于 2018-11-4 12:13:12 | 显示全部楼层
还是说 只要接上这个小板就能 每次开启启动破解 然后会自动执行了?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-4-20 18:45 , Processed in 0.065469 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表