2014年12月24日 星期三

Arch 開機自動登錄開啟全屏firefox

系統:Arch Linux
桌面:enlightenment
註:enlightenment 關閉程式熱鍵是ctrl+alt+x 不是alt+f4

需求:
開機自動登錄,然後開啟全屏firefox

開機自動登錄(無須輸入密碼):
https://wiki.archlinux.org/index.php/SLiM_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)
修改 /etc/slim.conf:
# default_user simone => default_user username
取消该行的注释,然后将“simone”改为需要自动登录的用户名。
# auto_login no
取消该行的注释,然后将‘no’改为‘yes’
自动登录功能就被启用了。

登錄後自動開啟firefox:
$ cp /etc/skel/.xinitrc ~
編輯.xinitrc:
firefox -new-window localhost/welcome/exhibition(你要打開的網址) &
exec enlightenment_start
這邊似乎可以用 openbox做 https://wiki.archlinux.org/index.php/openbox ,沒試過
https://wiki.archlinux.org/index.php/Xinitrc
注意:
確保取消註釋只有一行exec,因為這將是.xinitrc script的最後一個運行命令; 以下所有命令只會被忽略。
如果只執行exec firefox ,不登錄桌面。會有解析度問題

Firefox打開全屏:
安裝 Real Kiosk 套件 https://addons.mozilla.org/zh-tw/firefox/addon/r-kiosk/

2014年12月19日 星期五

LINUX 插入USB執行某個script

系統:
Arch linux

需求:
重開機後/dev/ttyUSB[0-9] 的設定會跑掉,我的板子頻率要跑9600 8n1 才能溝通

手動設定指令:
# stty -F /dev/ttyUSB1 raw speed 9600 -crtscts cs8 -parenb -cstopb

重開機自動設定:
原本在這篇 arch 開機執行程式 想要用rc.local做,但是stty在rc.local我一直無法設定,印出來的內容是空的,所以改從udev的rules下手
新增檔案 /etc/udev/rules.d/usb.rules ,內容為:
ACTION=="add", KERNEL=="ttyUSB*", RUN+="/usr/bin/bash /your_script_path/set_stty.sh"
功用為:
在/dev/ttyUSBx插入時,會跑set_stty.sh這個程式。

根據 Arch 官方文件 https://wiki.archlinux.org/index.php/udev ,必須命名 .rules 的檔案,而/etc/udev/rules.d/ 和 /usr/lib/udev/rules.d/ (由其他packages自動產生的rules)有同樣名字的rules時,以 /etc/udev/ 下的優先

set_stty.sh內容:
#!/bin/sh
LOGFILE=/tmp/set_stty.log
exec 3>> $LOGFILE && exec >& 3 && exec 2>&1
echo $SEQNUM $SUBSYSTEM $ACTION $DEVNAME
if [ "$SUBSYSTEM" = "tty" -a "$ACTION" = "add" ]
then
    echo ""
    echo "=============================="
    date "+%G-%m-%dT%H:%M:%S %z"
    echo "$SUBSYSTEM $ACTION"
    stty -F $DEVNAME raw speed 9600 -crtscts cs8 -parenb -cstopb
fi
exit $?  # 結束這個 script 並把當時的執行結果傳回(return)給呼叫這個 script 的任何程式。想要省略掉的話,也沒什麼問題,然而我們必須平時就養成撰寫程式的正確習慣,在 UNIX 系統上,任何程式、函式都必須要有傳回值,就算是不知道有誰會去用它。我們不希望看到那一天,當有人突然去用它的時候,就必須面對噩運。這看似小事一件,然而缺乏持續性對小節的正確習慣或態度。 by 翔

$SEQNUM $SUBSYSTEM $ACTION $DEVNAME 這些是uevents ,可以幫助我們在script裡面判斷
例如插入一次接板子的usb,在log中可以看到set_stty.sh跑了兩次
ex.
echo $SEQNUM $SUBSYSTEM $ACTION $DEVNAME 這行印到/tmp/set_stty.log的內容:
2355 usb-serial add "(空)"
2356 tty add /dev/ttyUSB1

實測:
重開機後,呼叫串口的web api ,有正常返回值

參考資料:
http://king70327.blogspot.jp/2011/12/linux-centosusbscript.html

javascript去檢測(類似ping)區網有無這個ip

http://stackoverflow.com/questions/4282151/is-it-possible-to-ping-a-server-from-javascript
修改後:
ping = function(ip, callback) {
 if (!this.inUse) {
  this.status = 'unchecked';
  this.inUse = true;
  this.callback = callback;
  this.ip = ip;
  var _that = this;
  this.img = new Image();
  this.img.onload = function() {
   _that.inUse = false;
   _that.callback('responded');

  };
  this.img.onerror = function(e) {
   if (_that.inUse) {
    _that.inUse = false;
    _that.callback('responded', e);
   }

  };
  this.start = new Date().getTime();
  this.img.src = "http://" + ip;
  this.timer = setTimeout(function() {
   if (_that.inUse) {
    _that.inUse = false;
    _that.callback('timeout');
   }
  }, 1500);
 }
};

//使用:
new ping('192.168.0.88', function(status, e) {
 console.log(status);
});

有這個ip,在控制台會顯示 responded,沒有則會顯示timeout

PHP CLI筆記

$ php -m #列出所有modules
$ php -r "code" #類似perl -e 執行代碼
$ php -n # 不使用php.ini設定,用前面加time 可以看跑多快

arch 開機執行程式

前言:
每次重開機後,主機與serial port的stty設定都會跑掉,所以想在開機時去設定(重新插拔USB接口設定不會跑掉)

https://raymii.org/s/tutorials/rc.local_support_on_Arch_Linux_and_systemd.html
1. 編輯 /etc/rc.local (如果沒有就自己建一個)
2. 把 /etc/rc.local 權限設成 755,注意:因為是bash,最前面要寫 #!/usr/bin/bash,例:
#!/usr/bin/bash
touch /tmp/1
stty -F /dev/ttyUSB1 raw speed 9600 -crtscts cs8 -parenb -cstopb

3. 編輯 /usr/lib/systemd/system/rc-local.service:
[Unit]
Description=/etc/rc.local compatibility

[Service]
Type=oneshot
ExecStart=/etc/rc.local
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

4. 執行 下面這個指令,他會產生一個symlink 到 /etc/systemd/system/multi-user.target.wants/ 下面
# systemctl enable rc-local.service
Created symlink from /etc/systemd/system/multi-user.target.wants/rc-local.service to /usr/lib/systemd/system/rc-local.service.

5. 手動檢測:
# systemctl start rc-local.service

實測結果:
重開機後
touch /tmp/1 會正常執行(執行身份是root),但stty 把他印到/tmp/1 (  stty >> /tmp/1 )則是一片空白,這可能要看開機message... 這挺複雜的....
這位網友遇到同樣的問題: http://www.gobsd.org/viewtopic.php?f=4&t=3239
最後暫時用每次呼叫web api時都設定stty,這會讓使用者每次多等0.3s
之後可以嘗試用cronjob看看

參考資料:
http://stackoverflow.com/questions/18903512/set-up-serial-on-start-up-raspberry-pi # Raspberry Pi 在rc.local設定stty的答案被採納

2014年12月17日 星期三

減少PHP-Serial的I/O等待時間

繼前篇 用php透過usb和rs232串連控制MPU電路板
dummy.php:
echo "\ntime 0:".round(microtime(true) * 1000);
include 'PhpSerial.php';

echo "\ntime 1:".round(microtime(true) * 1000);
`stty -F /dev/ttyUSB0 raw speed 9600 -crtscts cs8 -parenb -cstopb`;
echo "\ntime 2:".round(microtime(true) * 1000);
// Let's start the class
$serial = new PhpSerial();
echo "\ntime 3:".round(microtime(true) * 1000);
// First we must specify the device. This works on both linux and windows (if
// your linux serial device is /dev/ttyS0 for COM1, etc)
$serial->deviceSet("/dev/ttyUSB0");
echo "\ntime 4:".round(microtime(true) * 1000);
// We can change the baud rate, parity, length, stop bits, flow control
$serial->confBaudRate(9600);
echo "\ntime 5:".round(microtime(true) * 1000);
$serial->confParity("none");
echo "\ntime 6:".round(microtime(true) * 1000);
$serial->confCharacterLength(8);
echo "\ntime 7:".round(microtime(true) * 1000);
$serial->confStopBits(1);
echo "\ntime 8:".round(microtime(true) * 1000);
$serial->confFlowControl("none");
echo "\ntime 9:".round(microtime(true) * 1000);
// Then we need to open it
$serial->deviceOpen();

// To write into
echo "\ntime A:".round(microtime(true) * 1000);
$serial->sendMessage("O(00,02,1)E");

測試:
$ time sudo php -n dummy.php ( -n 是不走php.ini的設定,因為我之前browscap.ini設定太肥會delay)

time 0:1418786501622
time 1:1418786501623
time 2:1418786501890
time 3:1418786501890
time 4:1418786501890
time 5:1418786502156
time 6:1418786502423
time 7:1418786502690
time 8:1418786502956
time 9:1418786503223
time A:1418786503223
time B:1418786504957 # 後面sleep了一秒,讓燈關掉
real    0m3.373s
user    0m0.007s
sys     0m0.003s

在 PHP-Serial API的底層,每叫一次function ( new PhpSerial()、$serial->deviceSet、$serial->confBaudRate )都會用stty去檢查一次,每次stty檢查都會在IO上delay 0.3秒,所以我們現在假設你的裝置都連結配置好,將多餘的設定和stty檢查拿掉

更改PhpSerial.php:
+++ b/PhpSerial.php
@@ -32,22 +32,27 @@ class PhpSerial
      * @var bool
      */
     public $autoFlush = true;
+    public $_check_stty = true;
 
     /**
      * Constructor. Perform some checks about the OS and setserial
      *
      * @return PhpSerial
      */
-    public function PhpSerial()
+    public function PhpSerial($param)
     {
+        $this->_check_stty = (isset($param['check_stty']))? $param['check_stty'] : $this->_check
         setlocale(LC_ALL, "en_US");
 
         $sysName = php_uname();
         if (substr($sysName, 0, 5) === "Linux") {
             $this->_os = "linux";
+            if (!$this->_check_stty) {
+                register_shutdown_function(array($this, "deviceClose"));
+                return false;
+            }
@@ -86,9 +91,12 @@ class PhpSerial
      */
     public function deviceSet($device)
     {
+        if (!$this->_check_stty) {
+            $this->_device = $device;
+            $this->_dState = SERIAL_DEVICE_SET;
+            return false;
+        }

修改dummy.php
echo "\ntime 0:".round(microtime(true) * 1000);
include 'PhpSerial.php';

echo "\ntime 1:".round(microtime(true) * 1000);
echo "\ntime 2:".round(microtime(true) * 1000);
$serial = new PhpSerial(array('check_stty'=> false));
echo "\ntime 3:".round(microtime(true) * 1000);
$serial->deviceSet("/dev/ttyUSB0");
echo "\ntime 4:".round(microtime(true) * 1000);
$serial->deviceOpen();

echo "\ntime A:".round(microtime(true) * 1000);
$serial->sendMessage("O(00,02,1)E");

測試:
$ time sudo php -n dummy.php

time 0:1418787683165
time 1:1418787683165
time 2:1418787683165
time 3:1418787683165
time 4:1418787683165
time A:1418787683166
time B:1418787684896 # 後面sleep了一秒,讓燈關掉
real    0m1.774s
user    0m0.000s
sys     0m0.007s



2014年12月8日 星期一

列出sublime裝了哪些套件

在Packages Controll中
ctrl+shift+p 輸入list packages

在設定檔中
Preferences -> Browse Packages -> 搜尋檔案 Package Control.sublime-settings
用sublime打開
(Win 7 免安裝版)
C:\Users\bear\Desktop\Sublime Text 2.0.2\Data\Packages\User\Package Control.sublime-settings
我Win7的sublime裝的套件:
{
"installed_packages":
[
"AngularJS",
"CSS Extended Completions",
"CSS Snippets",
"Emmet",
"HTML Snippets",
"HTML-CSS-JS Prettify",
"HTMLAttributes",
"HTMLEntity Snippets",
"jQuery",
"ModernPerl",
"Package Control",
"SFTP"
]
}

Arch:
{
"installed_packages":
[
"AngularJS",
"CakePHP (Native)",
"Codecs33",
"CodeIgniter Snippets",
"CodeIgniter Utilities",
"ConvertToUTF8",
"DocBlockr",
"Emmet",
"GoSublime",
"Handlebars",
"HTML Snippets",
"HTML-CSS-JS Prettify",
"HTMLAttributes",
"jQuery",
"Seti_UI",
"SFTP",
"SideBarEnhancements",
"SublimeCodeIntel",
"Tag",
"Text Pastry",
"TrailingSpaces"
]
}

Debian:
{
    "installed_packages":
    [
        "AngularJS",
        "CakePHP (Native)",
        "CodeIgniter Snippets",
        "ConvertToUTF8",
        "CSS Completions",
        "CSS3",
        "DocBlockr",
        "Emmet",
        "Handlebars",
        "HTML Snippets",
        "HTML-CSS-JS Prettify",
        "HTML5",
        "HTMLAttributes",
        "InputHelper",
        "JavaScript & NodeJS Snippets",
        "jQuery",
        "jQuery Mobile Snippets",
        "jQueryDocs",
        "PHP Completions Kit",
        "PhpDoc",
        "Sass",
        "SFTP",
        "SideBarEnhancements",
        "SublimeLinter"
    ]
}

Windows 7 Sublime 3
"installed_packages":
[
    "Alignment",
    "AngularJS",
    "CodeFormatter",
    "ConvertToUTF8",
    "DocBlockr",
    "Emmet",
    "Handlebars",
    "HTML Snippets",
    "HTML-CSS-JS Prettify",
    "HTMLAttributes",
    "JavaScript Snippets",
    "jQuery",
    "JsFormat",
    "JSLint",
    "Package Control",
    "phpfmt",
    "SFTP",
    "SideBarEnhancements",
    "Smarty",
    "SqlBeautifier",
    "SublimeCodeIntel",
    "Text Pastry",
    "TrailingSpaces",
    "Xdebug Client"
]

ThinkPad 20170722
{
"bootstrapped": true,
"in_process_packages":
[
],
"installed_packages":
[
"Alignment",
"CodeFormatter",
"ConvertToUTF8",
"DocBlockr",
"Emmet",
"HTML Snippets",
"HTML Underscore Syntax",
"HTML-CSS-JS Prettify",
"HTMLAttributes",
"JavaScript Snippets",
"jQuery",
"JsFormat",
  "Minifier",
"Package Control",
"SFTP",
"SideBarEnhancements",
"SqlBeautifier",
"SublimeCodeIntel",
"Text Pastry",
"TrailingSpaces",
"Underscorejs snippets",
"Xdebug Client"
]
}
跳板機 20190630 - latest  之後轉phpstorm
{
"bootstrapped": true,
"in_process_packages":
[
],
"installed_packages":
[
"Alignment",
"Blade Snippets",
"Case Conversion",
"CodeFormatter",
"ConvertToUTF8",
"Diffy",
"DocBlockr",
"Emmet",
"HTML Snippets",
"HTML Underscore Syntax",
"HTML-CSS-JS Prettify",
"HTMLAttributes",
"JavaScript Snippets",
"jQuery",
"JsFormat",
"Laravel 5 Snippets",
"Laravel Blade Highlighter",
"Laravel Migrations Snippets",
"Minifier",
"Package Control",
"PHP Completions Kit",
"SFTP",
"SideBarEnhancements",
"SqlBeautifier",
"SublimeCodeIntel",
"Text Pastry",
"TrailingSpaces",
"Underscorejs snippets"
]
}

20220316 ThinkPad
{
"bootstrapped": true,
"in_process_packages":
[
],
"installed_packages":
[
"Alignment",
"Case Conversion",
"CodeFormatter",
"ConvertToUTF8",
"Diffy",
"Dockerfile Syntax Highlighting",
"Generic Config",
"Hosts",
"jQuery",
"Log Highlight",
"MoveTab",
"nginx",
"Package Control",
"SideBarEnhancements",
"SqlBeautifier",
"SublimeCodeIntel",
"Text Pastry",
"TrailingSpaces",
"Vue Syntax Highlight",
],
}



ThinkPad 20170722 )Key Bindings: 
[
{ "keys": ["ctrl+k", "s"], "command": "set_mark" },
// XDebug
{ "keys": ["ctrl+k", "alt+s"], "command": "xdebug_watch" },
{ "keys": ["ctrl+k", "alt+c"], "command": "xdebug_watch", "args": {"clear": true} },
{ "keys": ["ctrl+k", "alt+e"], "command": "xdebug_evaluate" },
{ "keys": ["ctrl+k", "alt+1"], "command": "xdebug_clear_all_breakpoints" },
{ "keys": ["ctrl+k", "alt+2"], "command": "xdebug_conditional_breakpoint" },
{ "keys": ["ctrl+k", "alt+3"], "command": "xdebug_session_start", "args": {"launch_browser": true} },
]

ThinkPad 20170722 )Settings:
{
"font_size": 12,
"ignored_packages":
[
"Vintage"
],
"word_wrap": false
}

( NII-48 20190528 ) Preferences.sublime-settings
{
    "color_scheme": "Monokai.sublime-color-scheme",
    "detect_indentation": false,
    "font_face": "Consolas",
    "font_size": 12,
    "ignored_packages":
    [
        "Vintage"
    ],
    "tab_size": 4,
    "theme": "Default.sublime-theme",
    "translate_tabs_to_spaces": true,
    "update_check": false,
    "word_wrap": false,
    "default_line_ending": "unix"  // 避免CRLF錯誤
}

20200411 新增installed_packages: Dockerfile Syntax Highlighting
20220316 新增installed_packages: MoveTab
20220828 新增:Compare Side-By-Side  。棄用:Diffy


參考資料:
http://stackoverflow.com/questions/16412678/exporting-sublime-text-configuration-and-installed-packages

2014年12月4日 星期四

JMDM-COM10MR繼電器使用心得

上淘寶買了 10路繼電器輸出模塊 負載220V25A 串口通訊 串口控制器(JMDM-COM10MR,深圳市精敏数字机器有限公司)
内含:
JMDM-COM10MR 繼電器
12V電源適配器(可選24V) - 紅接1 黑接3
RS232 傳輸線 ( 要接USB需另買RS232轉USB傳輸線 )

共有10路輸出:
背面
側面(紅色數字為第幾號開關)
側面 (紅色數字為第幾號開關)
Linux控制方式:
事前設定:( /dev/ttyUSB0非唯一,依你繼電器插入後linux所抓到的device,可能是/dev/ttyUSBx )
# stty -F /dev/ttyUSB0 raw speed 9600 -crtscts cs8 -parenb -cstopb
# chmod 777 /dev/ttyUSB0
接收:
# cat /dev/ttyUSB0

查詢:
# echo -en 'O(00,40,1)E' > /dev/ttyUSB0 # 命令控制器返回第 1 路~第 10 路数据
OA(00,0000000000)E  # cat /dev/ttyUSB0收到的結果

控制:控制成功繼電器會發出開關的聲音,可用萬用表測有沒有迴路,中間和左邊兩個有通為0關閉,中間和右邊兩個有通為1打開)
# echo -en 'O(00,00,1)E' > /dev/ttyUSB0 # 所有继电器输出全開
OA(00,1111111111)E  # 用'O(00,40,1)E'查詢,在cat /dev/ttyUSB0收到的結果
# echo -en 'O(00,00,0)E' > /dev/ttyUSB0 # 所有继电器输出全關
OA(00,0000000000)E  # 用'O(00,40,1)E'查詢,在cat /dev/ttyUSB0收到的結果
# echo -en 'O(00,01,1)E' > /dev/ttyUSB0 # 第 1路继电器输出"开启"
OA(00,1000000000)E  # 用'O(00,40,1)E'查詢,在cat /dev/ttyUSB0收到的結果
# echo -en 'O(00,01,0)E' > /dev/ttyUSB0 # 第 1路继电器输出"關閉"
OA(00,0000000000)E  # 用'O(00,40,1)E'查詢,在cat /dev/ttyUSB0收到的結果
# echo -en 'O(00,02,1)E' > /dev/ttyUSB0 # 第 2路继电器输出"开启"
OA(00,0100000000)E  # 用'O(00,40,1)E'查詢,在cat /dev/ttyUSB0收到的結果
# echo -en 'O(00,02,0)E' > /dev/ttyUSB0 # 第 2路继电器输出"關閉"
OA(00,0100000000)E  # 用'O(00,40,1)E'查詢,在cat /dev/ttyUSB0收到的結果

注意:
1. 勿傳送hex,傳送的是字符(ASCII)
2. 淘宝和pdf文档里 关闭指令:O ( 00,N,0)E 开启指令:O ( 00,N,1)E
O ( 00,N,1)E => "(" 前後多了空白 所以没反应... 要把空白去掉,继电器吃到错误的代码不会报错回来

同時先關再開某個output(同時送兩個指令)到繼電器:
# echo -en 'O(00,00,0)E O(00,01,1)E' > /dev/ttyUSB1 #中間以一個空格隔開,就能同時關閉所有電燈再開某個電燈,而不會為了等serial port而慢一秒亮燈。

Windows(Win7)控制方式:
賣家會提供windows的執行檔(免安裝和安裝板)
安裝板裝好後要另外把他們提供的dll檔放到該目錄下
更新Win 7 的Prolific USB-to-Serial Comm Port 的驅動程式(電腦需連上網路)
( 開始 -> 設備和打印機 -> "未指定"中的Prolific USB-to-Serial Comm Port 右鍵 -> 屬性 -> 硬件 -> 屬性 -> 驅動程序 -> 更新驅動程序 )
設定COM port
開始 -> 設備和打印機 -> "未指定"中的Prolific USB-to-Serial Comm Port 右鍵 -> 屬性 -> 硬件 -> 屬性 -> 端口設置 -> 高級 -> COM端口號選"COM2"
廠商提供的應用程式 通信串口選擇:串口一 ( 注意必須在打開程式時預設選擇串口一,不然報錯後依然跑不動,串口設錯請設定串口後關閉程式重開,勿點擊按鈕讓程式自動關閉 )



2014年12月1日 星期一

linux .d資料夾的意思

linux中常看到許多.d的資料夾,如
/etc/php/conf.d/
/etc/init.d/

Generally when you see that *.d convention, it means "this is a directory holding a bunch of configuration fragments which will be merged together into configuration for some service."
翻譯:一般來說,當你看到*.d的常規,它的意思是"這是一個目錄拿著一群將被合併為設定一些服務設定的片段。"

例如,
init.d 中存放的就是一系列系统服务的管理(启动与停止)脚本。
当系统升级有新的 *.conf 时,只需简单的替换原来的,因为用户和其他程序添加的配置都以单独文件的形式存放在 .d 文件夹中,不会受到影响。


參考資料:
http://unix.stackexchange.com/questions/4029/what-does-the-d-stand-for-in-directory-names
http://zhidao.baidu.com/question/297983472.html