前言: 話說前陣子爸爸家陽台不斷出現米奇老鼠,立刻清理陽台所有東西,然後又跟市政部門反映問題,可是情況還沒有好轉,米老鼠來完一隻又一隻,我爸陽台在老鼠界應該是網紅打卡聖地(誤),要不然就是米奇老鼠版米奇林三星餐廳(?) 雖然我們抓到了三隻,到上兩個禮拜為止還有至少一隻一直抓不到,每天淩晨還會來吃事後煙留下老鼠屎,真_北。 這隻老鼠對傳統攻擊有抗性,有IT9朋友前陣子用Raspberry pi自製了一台electric mouse trap ,用pi的超聲波雷達放在鞋盒裡,鞋盒裡有一堆食物,底部佈了鐵網,偵測到有老鼠進去以後立即關門通9V電,通個1分鐘再放牠離開,大推我自己也造一台 (Youtube片搜尋一大堆,人類真變態啊,朋友好變態啊)。可是我覺得這樣又好像有點太殘忍,不如先偵測牠們什麼時候來,嚇嚇牠們看看有沒有效果再說吧。 目的: 用Raspberry pi及手上有的感測器弄一隻放陽台用來偵測和嚇嚇老鼠的東西,並把紀錄圖像化到雲端給老爸使用。 邏輯及設計: 當老鼠進入偵測範圍,Motion Sensor偵測到生物活動Raspberry pi 處理來自Motion Sensor的訊號,如果夠強的話開始準備作出回應 Raspberry pi在Angry cats sounds中隨機選出叫聲,再經由Speaker輸出貓叫聲 Raspberry pi指示強光元件發出強光束照射目標 把偵測計數上傳到雲端圖表 材料: Sensor 在網路上看了一些Raspberry pi wild animal camera ,很多也是用Motion Sensor先偵測動物再來,我用的是PIR Motion Sensor被動式紅外線感測器,有低耗電成本便宜的好處。[1],而且可手動調整靈敏度及反應時間。 PIR Motion Sensor就是下面這個 圖片來源: learn.adafruit.com 可手動調整敏感度還有反應時間,這個有點不好調,要試好多遍才找到最佳位置。 可以在Raspbian中輸入pinout查詢GPIO避免插錯 圖片來源: learn.adafruit.com . 一台Raspberry pi 這次使用較舊的Raspberry pi model B+ 萬一老鼠生氣被咬爛錢包也不太痛 . ...
前言:
公司經常會遇到一些不是給使用者用的程式,例如一些格式轉換程式,一些上傳到某些地方的程式,或者背景服務等等。這些服務具有一共通點:
以下是小弟最近利上執行引擎的概念幫公司寫的小軟體,希望可以給各位大大分享一下,有錯誤的話請賜教。
目的:
把資料庫的某一資料表(table)轉成XML, 並自動上傳到指定FTP位置。這個小軟體要具有:
1. email功能: 上傳成功或失敗需要發email通知資訊部門某位同事。
2. 紀錄檔(log)功能: 運行時產生相關程序的記錄,包括exception。
3. 上傳到FTP伺服器前要先備份。
4. 產生的XML檔案名稱將來可能會有修改。
設計:
要表達一個系統的設計,至少要表明兩種關係
由以上需求可知,如果我們在物件導向分析的類別圖(Class diagram)中開始設計類別,可以以功能區分最初版本的5個類別,分別是:
Program.cs: 提供軟體核心作業流程。
xmlManager.cs: 提供轉換成XML的相關功能。
emailManager.cs: 提供傳送電子郵件的功能。
ftpManager.cs: 提供ftp上載的功能。
logManager.cs: 提供記錄檔相關功能。
它們這些物件與物件之間的關係,可以用UML中的Class diagram表達:
Coding技術解說:
app.config檔案:
這是官方的參數設定檔案
讀取app.config的參數:
這裡要注意放在FtpWebRequest中的伺服器位置要遁守URI-Uniform resource identifier規則。
Truncate資料表
假設已經存在一dataset, 現在要Truncate Dataset相關資料庫中的table, 最簡單的方法如下:
發送電子郵件
1. http://www.dotspace.idv.tw/Jyemii/umlcolumn/articles/umlwriting/UMLBasics/UMLBasics.htm UML入門:統一建模語言入門
2. http://www.wretch.cc/blog/smalltide/11664739 Introduce UML Class Diagram
3. http://msdn.microsoft.com/ MSDN.
4. http://www.vcskicks.com/csharp_ftp_upload.php C# FTP Upload
公司經常會遇到一些不是給使用者用的程式,例如一些格式轉換程式,一些上傳到某些地方的程式,或者背景服務等等。這些服務具有一共通點:
- 參數設定很多,如SMTP Server, 資料庫IP。
- 要經常改變參數設定。
以下是小弟最近利上執行引擎的概念幫公司寫的小軟體,希望可以給各位大大分享一下,有錯誤的話請賜教。
目的:
把資料庫的某一資料表(table)轉成XML, 並自動上傳到指定FTP位置。這個小軟體要具有:
1. email功能: 上傳成功或失敗需要發email通知資訊部門某位同事。
2. 紀錄檔(log)功能: 運行時產生相關程序的記錄,包括exception。
3. 上傳到FTP伺服器前要先備份。
4. 產生的XML檔案名稱將來可能會有修改。
設計:
要表達一個系統的設計,至少要表明兩種關係
- Class 之間的關係
- 觸發事件的先後次序
由以上需求可知,如果我們在物件導向分析的類別圖(Class diagram)中開始設計類別,可以以功能區分最初版本的5個類別,分別是:
Program.cs: 提供軟體核心作業流程。
xmlManager.cs: 提供轉換成XML的相關功能。
emailManager.cs: 提供傳送電子郵件的功能。
ftpManager.cs: 提供ftp上載的功能。
logManager.cs: 提供記錄檔相關功能。
它們這些物件與物件之間的關係,可以用UML中的Class diagram表達:
- 虛線指的是這一個class可以存取的檔案。
- 實心菱型在UML中解釋是Composition(組合), 意思相當於has a, 就是說被指向的Class(xmlManager跟logManager)是菱型端的Class(Program.cs)不可缺少的一部分, 當Program.cs被消滅的時候xmlManager跟logManager就一齊消失了,同理當Program.cs出現的時候一定要有xmlManager跟logManager這兩個Class.
還是不明白? 再舉一個例子。例如一台汽車具有四個輪子,汽車本身就是Program.cs,輪子就是 xmlManager跟logManager。當輪子消失的時候,汽車也不能跑了。 - 空心菱型在UML中解釋是Aggregation(聚合)。是一種大家不依賴大家也可以獨立運行,比較弱的關係。xmlManager跟emailManager還有ftpManager就是這種關係,整支程式就算沒有email也是可以跑得順順的。同理,emailManager自己可以控制發電郵的機制,完全不需要這隻轉換程式的幫助。拿回上面的例子來說,就像汽車跟人的關係,汽車沒有人開還是汽車,人沒車也是獨立的個體。
Class定好以後,可以利用sequence diagram來表達Class的流程圖。下面是整個程式流程的簡化版本:(圖太小, 按一下可看全圖)
- main是整個程式的還輯控制核心元件。
Coding技術解說:
app.config檔案:
這是官方的參數設定檔案
- 如要儲存連接db的connectionString,如下:
- 如要儲存其他參數設定, 如下:
這裡共包含12項參數,包括
* XML檔案存放位置
* XML檔案備份位置
* XML產生的檔案名稱
* XML上傳到FTP後的名稱
* FTP伺服器IP
* FTP伺服器登入名稱
* FTP伺服器登入密碼
* FTP伺服器登入後要去的路徑
* SMTP伺服器IP
* 郵件發出者
* 電子郵件清單(用";"分隔)
* log存放的位置
<connectionStrings>
<add name="SQRConnectionString" connectionString="Data Source=xxx.xxx.xxx.xxx;Initial Catalog=xxx;User ID=xxxx;Password=xxx" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="smtp" value="" />
<add key="xmlLocal" value="/result/" />
<add key="xmlBkp" value="/bkp/" />
<add key="resultName" value="xxx.xml" />
<add key="FTPtargetFileName" value="xxx.xml" />
<add key="FTPhost" value="ftp://xxx.xxx.xxx.xxx" />
<add key="FTPusername" value="xxx" />
<add key="FTPpassword" value="xxx" />
<add key="FTPremoteDir" value="/csv/" />
<add key="smtp" value="xxx.xxx.xxx.xxx" />
<add key="smtpFrom" value="terencemak84@gmail.com" />
<add key="smtpTo" value="terencemak84@gmail.com;terencemak84@gmail.com" />
<add key="logLocation" value="/log/" />
<add key="ClientSettingsProvider.ServiceUri" value="" />
</appSettings>
讀取app.config的參數:
- 讀取資料庫可用
- 讀取其他參數可用
var dbsettings = ConfigurationManager.ConnectionStrings["SQLConnectionString"]; //read sql setting
ConfigurationManager.AppSettings["參數key名稱"]
- 先把資料庫轉成Dataset (請參考之前的教學資料庫篇)
- 假設Dataset為ds, 輸出成XML可以寫成即可。
ds.WriteXml("路徑\檔案名稱")
檢查檔案是否已經存在
- 可利用FileInfo類別中的 File.exists方法。
bool result = false;
string ResultFileLocation = xmlManager.getXmlLocalResultPath() + ConfigurationManager.AppSettings["resultName"];
FileInfo resultFile = new FileInfo(ResultFileLocation);
if (resultFile.Exists)
{
result = true;
}
else
{
result = false;
}
return result;
移動檔案
- 可利用File.MoveTo()方法。如下面例子只要把移動路徑跟檔案名稱丟進方法就可以了。
public static void bkpResultXml()
{
if (ResultXmlExist() == true)
{
string bkpResultFileLocation = xmlManager.getXmlLocalResultPath();
FileInfo bkpResultFile = new FileInfo(bkpResultFileLocation + ConfigurationManager.AppSettings["resultName"]);
string bkpLocation = xmlManager.getXmlLocalBkpPath();
bkpResultFile.MoveTo(bkpLocation + DateTime.Now.ToString("yyyyMMddhhmmss")+"_"+ ConfigurationManager.AppSettings["resultName"]);
}
}
ftp上傳檔案
利用C#上傳檔案到ftp伺服器需要用WebRequest及WebResponse兩個類別, 使用步驟如下:
利用C#上傳檔案到ftp伺服器需要用WebRequest及WebResponse兩個類別, 使用步驟如下:
- 宣告一FtpWebResponse 及 FtpWebRequest物件.
- 在FtpWebRequest物件中指定ftp server的位置, 相關路徑及檔案名稱
- Method指定為上傳.
- 利用Credentials指定ftp登入名稱及密碼
- 設定些相關參數
- 把檔案轉換成byte資料流
- 上傳
- 接收回覆訊息
public static void FTPUpload( Uri serverUri, string sourceFile, string ftpDirectory, string targetFileName, string username, string pwd, out bool success, out string responseMsg)
{
success = false;
//建立物件
FtpWebResponse ftpUploadResponse=null;
FtpWebRequest UpdRequest = (FtpWebRequest)WebRequest.Create(serverUri+ftpDirectory + targetFileName);
//方法設為上傳
UpdRequest.Method = WebRequestMethods.Ftp.UploadFile;
//設定登入使用者及密碼
UpdRequest.Credentials = new NetworkCredential(username, pwd);
//設定參數
UpdRequest.UsePassive = true;
UpdRequest.UseBinary = true;
UpdRequest.KeepAlive = false;
//load file
//把檔案轉換成byte陣列的資料流
FileStream fileStream = File.OpenRead(sourceFile);
byte[] buffer = new byte[fileStream.Length];
fileStream.Read(buffer, 0, buffer.Length);
fileStream.Close();
//開始上傳資料流
Stream requestStream = UpdRequest.GetRequestStream();
requestStream.Write(buffer, 0, buffer.Length); //從buffer中的第0個位元開始上傳到buffer.length這個地方
requestStream.Close();
success = true;
ftpUploadResponse = (FtpWebResponse)UpdRequest.GetResponse(); //回覆訊息
responseMsg = ftpUploadResponse.StatusDescription;
}
這裡要注意放在FtpWebRequest中的伺服器位置要遁守URI-Uniform resource identifier規則。
Truncate資料表
假設已經存在一dataset, 現在要Truncate Dataset相關資料庫中的table, 最簡單的方法如下:
SqlCommand cmd = new SqlCommand(string.Format("TRUNCATE TABLE {0}", ds.Tables["DataSet資料表名稱"]), conn);
cmd.ExecuteNonQuery();
發送電子郵件
public static void sendMail(string mailServerIP, string fromMail, string toMail, string subject, string content )
{
try
{
//宣告一SMTP物件
SmtpClient smtpclient = new SmtpClient();
//SMTP伺服器IP
smtpclient.Host = mailServerIP;
//新增一mail
MailMessage msgMail = new MailMessage();
//加入收件者
msgMail.To.Add(toMail);
MailAddress ma = new MailAddress(fromMail);
msgMail.From = ma;
msgMail.Subject = subject;
msgMail.Body = content;
msgMail.IsBodyHtml = true;
//send!
smtpclient.Send(msgMail);
}
catch
{
}
}
2. http://www.wretch.cc/blog/smalltide/11664739 Introduce UML Class Diagram
3. http://msdn.microsoft.com/ MSDN.
4. http://www.vcskicks.com/csharp_ftp_upload.php C# FTP Upload
Comments
Post a Comment