├── iot.doc ├── iot.pdf ├── iot.docx ├── struct.bmp ├── struct.dot ├── Makefile ├── README.md ├── template.tex ├── struct.ps └── iot.md /iot.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-doc/HEAD/iot.doc -------------------------------------------------------------------------------- /iot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-doc/HEAD/iot.pdf -------------------------------------------------------------------------------- /iot.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-doc/HEAD/iot.docx -------------------------------------------------------------------------------- /struct.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-doc/HEAD/struct.bmp -------------------------------------------------------------------------------- /struct.dot: -------------------------------------------------------------------------------- 1 | digraph G{ 2 | compound=true; 3 | 4 | subgraph cluster0{ 5 | RaspberryPi->Hardware; 6 | Hardware->RaspberryPi[label="Serial Commucation"]; 7 | } 8 | subgraph cluster1{ 9 | Server->RaspberryPi [label="GET/POST"]; 10 | RaspberryPi->Server; 11 | Browser->Server [label="CRUD"]; 12 | Server->Browser [label="Ajax"]; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: docx 2 | 3 | docx: 4 | sed 's/
/}/g' iot2.md > iot3.md
 6 | 	sed 's/<\/code><\/pre>/~~~~ /g' iot3.md > iot2.md
 7 | 	pandoc iot2.md -o iot.docx --toc --smart --highlight-style=pygments
 8 | 	rm iot2.md iot3.md
 9 | 
10 | pdf:
11 | 	sed 's/
/}/g' iot2.md > iot3.md
13 | 	sed 's/<\/code><\/pre>/~~~~ /g' iot3.md > iot2.md
14 | 	sed 's/.bmp/.ps/g' iot2.md > iot3.md
15 | 	pandoc --template=template.tex --latex-engine=xelatex iot3.md -o iot.pdf  --toc --smart --highlight-style=pygments
16 | 	@echo "remove the iot temp file"
17 | 	rm iot2.md iot3.md
18 | 
19 | img:
20 | 	dot struct.dot -Tbmp -o struct.bmp
21 | 	dot struct.dot -Tps -o struct.ps
22 | 


--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
 1 | ##安装pandoc##
 2 | 这是一个痛苦而又复杂的过程,当然也可以直接下载[Pandoc][0]
 3 | [0]:http://code.google.com/p/pandoc/downloads/list
 4 | 
 5 | ###安装ghc###
 6 | port安装ghc
 7 | 
 8 |      sudo port install ghc
 9 | 
10 | homebrew安装ghc
11 | 
12 |     brew install ghc
13 | 
14 | ###编译cabal###
15 | 
16 | Common Architecture for Building Applications and Libraries2
17 | 
18 | Cabal是Haskell用于构建应用程序和库的公共架构。
19 | 
20 | 简单的来说它是haskell的包管理,和上面的port、brew 命令类似。
21 | 
22 | 下载地址[http://haskell.org/cabal/][1]
23 | 
24 | [1]:http://haskell.org/cabal/
25 | 
26 | 解压后
27 | 
28 |     ghc --make Setup.hs
29 |     ./Setup configure
30 |     ./Setup build 
31 |     sudo ./Setup install
32 | 
33 | ###安装cabal###
34 | 
35 | 安装之前我们需要更新
36 | 
37 |     cabal update
38 | 
39 | 安装pandoc
40 | 
41 |     cabal install pandoc
42 | 
43 | 添加到PATH
44 | 
45 |      export PATH=/Users/fdhuang/.cabal/bin:$PATH
46 | 
47 | #markdown 转doc#
48 | 
49 |     pandoc iot.md -o iot.docx
50 | 
51 | #markdown 转pdf#
52 | 这里只针对于安装了mactex
53 | 
54 | ##安装mactex##
55 | 
56 | 下载地址:
57 | 
58 | [http://mirror.ctan.org/systems/mac/mactex/mactex-basic.pkg][2]
59 | 
60 | [2]:http://mirror.ctan.org/systems/mac/mactex/mactex-basic.pkg
61 | 
62 | 
63 | ##markdown转pdf##
64 | 
65 | 不含中文时
66 | 
67 |      pandoc doc.pandoc doc.pdf   
68 | 
69 | 含有中文时的简单作法
70 | 
71 |      pandoc --latex-engine=xelatex iot.md -o iot.pdf -V mainfont="SimSun"
72 | 
73 | 


--------------------------------------------------------------------------------
/template.tex:
--------------------------------------------------------------------------------
  1 | \documentclass[a4paper, 11pt]{article}
  2 | \usepackage{geometry} 		% 設定邊界
  3 | \geometry{
  4 |   top=1in,
  5 |   inner=1in,
  6 |   outer=1in,
  7 |   bottom=1in,
  8 |   headheight=3ex,
  9 |   headsep=2ex
 10 | }
 11 | \usepackage{tabu}
 12 | \usepackage[T1]{fontenc}
 13 | \usepackage{lmodern}
 14 | \usepackage{amssymb,amsmath}
 15 | \usepackage{ifxetex,ifluatex}
 16 | \usepackage{fixltx2e} % provides \textsubscript
 17 | % use upquote if available, for straight quotes in verbatim environments
 18 | \IfFileExists{upquote.sty}{\usepackage{upquote}}{}
 19 | \ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex
 20 |   \usepackage[utf8]{inputenc}
 21 | $if(euro)$
 22 |   \usepackage{eurosym}
 23 | $endif$
 24 | \else % if luatex or xelatex
 25 |   \usepackage{fontspec} 	% 允許設定字體
 26 |   \usepackage{xeCJK} 		% 分開設置中英文字型
 27 |   \setCJKmainfont{STSong} 	% 設定中文字型
 28 |   \setmainfont{Georgia} 	% 設定英文字型
 29 |   \setromanfont{Georgia} 	% 字型
 30 |   \setmonofont{Courier New}
 31 |   \linespread{1.2}\selectfont 	% 行距
 32 |   \XeTeXlinebreaklocale "zh" 	% 針對中文自動換行
 33 |   \XeTeXlinebreakskip = 0pt plus 1pt % 字與字之間加入0pt至1pt的間距,確保左右對整齊
 34 |   \parindent 0em 		% 段落縮進
 35 |   \setlength{\parskip}{20pt} 	% 段落之間的距離
 36 |   \ifxetex
 37 |     \usepackage{xltxtra,xunicode}
 38 |   \fi
 39 |   \defaultfontfeatures{Mapping=tex-text,Scale=MatchLowercase}
 40 |   \newcommand{\euro}{€}
 41 | $if(mainfont)$
 42 |     \setmainfont{$mainfont$}
 43 | $endif$
 44 | $if(sansfont)$
 45 |     \setsansfont{$sansfont$}
 46 | $endif$
 47 | $if(monofont)$
 48 |     \setmonofont{$monofont$}
 49 | $endif$
 50 | $if(mathfont)$
 51 |     \setmathfont{$mathfont$}
 52 | $endif$
 53 | \fi
 54 | % use microtype if available
 55 | \IfFileExists{microtype.sty}{\usepackage{microtype}}{}
 56 | $if(geometry)$
 57 | \usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
 58 | $endif$
 59 | $if(natbib)$
 60 | \usepackage{natbib}
 61 | \bibliographystyle{plainnat}
 62 | $endif$
 63 | $if(biblatex)$
 64 | \usepackage{biblatex}
 65 | $if(biblio-files)$
 66 | \bibliography{$biblio-files$}
 67 | $endif$
 68 | $endif$
 69 | $if(listings)$
 70 | \usepackage{listings}
 71 | $endif$
 72 | $if(lhs)$
 73 | \lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}
 74 | $endif$
 75 | $if(highlighting-macros)$
 76 | $highlighting-macros$
 77 | $endif$
 78 | $if(verbatim-in-note)$
 79 | \usepackage{fancyvrb}
 80 | $endif$
 81 | $if(tables)$
 82 | \usepackage{longtable}
 83 | $endif$
 84 | 
 85 | \usepackage{graphicx}
 86 | % We will generate all images so they have a width \maxwidth. This means
 87 | % that they will get their normal width if they fit onto the page, but
 88 | % are scaled down if they would overflow the margins.
 89 | \makeatletter
 90 | \def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth
 91 | \else\Gin@nat@width\fi}
 92 | \makeatother
 93 | \let\Oldincludegraphics\includegraphics
 94 | \renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=\maxwidth]{#1}}
 95 | 
 96 | \ifxetex
 97 |   \usepackage[setpagesize=false, % page size defined by xetex
 98 |               unicode=false, % unicode breaks when used with xetex
 99 |               xetex]{hyperref}
100 | \else
101 |   \usepackage[unicode=true]{hyperref}
102 | \fi
103 | \hypersetup{breaklinks=true,
104 |             bookmarks=true,
105 |             pdfauthor={$author-meta$},
106 |             pdftitle={$title-meta$},
107 |             colorlinks=true,
108 |             urlcolor=$if(urlcolor)$$urlcolor$$else$blue$endif$,
109 |             linkcolor=$if(linkcolor)$$linkcolor$$else$magenta$endif$,
110 |             pdfborder={0 0 0}}
111 | \urlstyle{same}  % don't use monospace font for urls
112 | $if(links-as-notes)$
113 | % Make links footnotes instead of hotlinks:
114 | \renewcommand{\href}[2]{#2\footnote{\url{#1}}}
115 | $endif$
116 | $if(strikeout)$
117 | \usepackage[normalem]{ulem}
118 | % avoid problems with \sout in headers with hyperref:
119 | \pdfstringdefDisableCommands{\renewcommand{\sout}{}}
120 | $endif$
121 | \setlength{\parindent}{0pt}
122 | %\setlength{\parskip}{6pt plus 2pt minus 1pt}
123 | \setlength{\emergencystretch}{3em}  % prevent overfull lines
124 | 
125 | \title{\huge 基于REST服务的最小物联网系统设计} % 設置標題,使用巨大字體
126 | \author{Phodal Huang} 		% 設置作者
127 | \date{February 2014} 		% 設置日期
128 | \usepackage{titling}
129 | \setlength{\droptitle}{-8em} 	% 將標題移動至頁面的上面
130 | 
131 | \usepackage{fancyhdr}
132 | \usepackage{lastpage}
133 | \pagestyle{fancyplain}
134 | 
135 | $if(numbersections)$
136 | \setcounter{secnumdepth}{5}
137 | $else$
138 | \setcounter{secnumdepth}{0}
139 | $endif$
140 | $if(verbatim-in-note)$
141 | \VerbatimFootnotes % allows verbatim text in footnotes
142 | $endif$
143 | $if(lang)$
144 | \ifxetex
145 |   \usepackage{polyglossia}
146 |   \setmainlanguage{$mainlang$}
147 | \else
148 |   \usepackage[$lang$]{babel}
149 | \fi
150 | $endif$
151 | $for(header-includes)$
152 | $header-includes$
153 | $endfor$
154 | 
155 | $if(title)$
156 | \title{$title$}
157 | $endif$
158 | \author{$for(author)$$author$$sep$ \and $endfor$}
159 | \date{$date$}
160 | 
161 | %%%%%% 设置字号 %%%%%%
162 | \newcommand{\chuhao}{\fontsize{42pt}{\baselineskip}\selectfont}
163 | \newcommand{\xiaochuhao}{\fontsize{36pt}{\baselineskip}\selectfont}
164 | \newcommand{\yihao}{\fontsize{28pt}{\baselineskip}\selectfont}
165 | \newcommand{\erhao}{\fontsize{21pt}{\baselineskip}\selectfont}
166 | \newcommand{\xiaoerhao}{\fontsize{18pt}{\baselineskip}\selectfont}
167 | \newcommand{\sanhao}{\fontsize{15.75pt}{\baselineskip}\selectfont}
168 | \newcommand{\sihao}{\fontsize{14pt}{\baselineskip}\selectfont}
169 | \newcommand{\xiaosihao}{\fontsize{12pt}{\baselineskip}\selectfont}
170 | \newcommand{\wuhao}{\fontsize{10.5pt}{\baselineskip}\selectfont}
171 | \newcommand{\xiaowuhao}{\fontsize{9pt}{\baselineskip}\selectfont}
172 | \newcommand{\liuhao}{\fontsize{7.875pt}{\baselineskip}\selectfont}
173 | \newcommand{\qihao}{\fontsize{5.25pt}{\baselineskip}\selectfont}
174 | 
175 | %%%% 设置 section 属性 %%%%
176 | \makeatletter
177 | \renewcommand\section{\@startsection{section}{1}{\z@}%
178 | {-1.5ex \@plus -.5ex \@minus -.2ex}%
179 | {.5ex \@plus .1ex}%
180 | {\normalfont\sihao\CJKfamily{STHeiti}}}
181 | \makeatother
182 | 
183 | %%%% 设置 subsection 属性 %%%%
184 | \makeatletter
185 | \renewcommand\subsection{\@startsection{subsection}{1}{\z@}%
186 | {-1.25ex \@plus -.5ex \@minus -.2ex}%
187 | {.4ex \@plus .1ex}%
188 | {\normalfont\xiaosihao\CJKfamily{STHeiti}}}
189 | \makeatother
190 | 
191 | %%%% 设置 subsubsection 属性 %%%%
192 | \makeatletter
193 | \renewcommand\subsubsection{\@startsection{subsubsection}{1}{\z@}%
194 | {-1ex \@plus -.5ex \@minus -.2ex}%
195 | {.3ex \@plus .1ex}%
196 | {\normalfont\xiaosihao\CJKfamily{STHeiti}}}
197 | \makeatother
198 | 
199 | %%%% 段落首行缩进两个字 %%%%
200 | \makeatletter
201 | \let\@afterindentfalse\@afterindenttrue
202 | \@afterindenttrue
203 | \makeatother
204 | \setlength{\parindent}{2em}  %中文缩进两个汉字位
205 | 
206 | 
207 | %%%% 下面的命令重定义页面边距,使其符合中文刊物习惯 %%%%
208 | \addtolength{\topmargin}{-2pt}
209 | \setlength{\oddsidemargin}{0.63cm}  % 3.17cm - 1 inch
210 | \setlength{\evensidemargin}{\oddsidemargin}
211 | \setlength{\textwidth}{14.66cm}
212 | \setlength{\textheight}{24.00cm}    % 24.62
213 | 
214 | %%%% 下面的命令设置行间距与段落间距 %%%%
215 | \linespread{1.4}
216 | % \setlength{\parskip}{1ex}
217 | \setlength{\parskip}{0.5\baselineskip}
218 | 
219 | 
220 | \begin{document}
221 | %%%% 定理类环境的定义 %%%%
222 | \newtheorem{example}{例}             % 整体编号
223 | \newtheorem{algorithm}{算法}
224 | \newtheorem{theorem}{定理}[section]  % 按 section 编号
225 | \newtheorem{definition}{定义}
226 | \newtheorem{axiom}{公理}
227 | \newtheorem{property}{性质}
228 | \newtheorem{proposition}{命题}
229 | \newtheorem{lemma}{引理}
230 | \newtheorem{corollary}{推论}
231 | \newtheorem{remark}{注解}
232 | \newtheorem{condition}{条件}
233 | \newtheorem{conclusion}{结论}
234 | \newtheorem{assumption}{假设}
235 | 
236 | %%%% 重定义 %%%%
237 | \renewcommand{\contentsname}{目录}  % 将Contents改为目录
238 | \renewcommand{\abstractname}{摘要}  % 将Abstract改为摘要
239 | \renewcommand{\refname}{参考文献}   % 将References改为参考文献
240 | \renewcommand{\indexname}{索引}
241 | \renewcommand{\figurename}{图}
242 | \renewcommand{\tablename}{表}
243 | \renewcommand{\appendixname}{附录}
244 | 
245 | \maketitle
246 | 
247 | $for(include-before)$
248 | $include-before$
249 | 
250 | $endfor$
251 | $if(toc)$
252 | {
253 | \hypersetup{linkcolor=black}
254 | \setcounter{tocdepth}{$toc-depth$}
255 | \tableofcontents
256 | }
257 | \newpage
258 | $endif$
259 | $body$
260 | 
261 | $if(natbib)$
262 | $if(biblio-files)$
263 | $if(biblio-title)$
264 | $if(book-class)$
265 | \renewcommand\bibname{$biblio-title$}
266 | $else$
267 | \renewcommand\refname{$biblio-title$}
268 | $endif$
269 | $endif$
270 | \bibliography{$biblio-files$}
271 | 
272 | $endif$
273 | $endif$
274 | $if(biblatex)$
275 | \printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$
276 | 
277 | $endif$
278 | $for(include-after)$
279 | $include-after$
280 | 
281 | $endfor$
282 | \end{document}
283 | 


--------------------------------------------------------------------------------
/struct.ps:
--------------------------------------------------------------------------------
  1 | %!PS-Adobe-3.0
  2 | %%Creator: graphviz version 2.34.0 (20140103.0956)
  3 | %%Title: G
  4 | %%Pages: (atend)
  5 | %%BoundingBox: (atend)
  6 | %%EndComments
  7 | save
  8 | %%BeginProlog
  9 | /DotDict 200 dict def
 10 | DotDict begin
 11 | 
 12 | /setupLatin1 {
 13 | mark
 14 | /EncodingVector 256 array def
 15 |  EncodingVector 0
 16 | 
 17 | ISOLatin1Encoding 0 255 getinterval putinterval
 18 | EncodingVector 45 /hyphen put
 19 | 
 20 | % Set up ISO Latin 1 character encoding
 21 | /starnetISO {
 22 |         dup dup findfont dup length dict begin
 23 |         { 1 index /FID ne { def }{ pop pop } ifelse
 24 |         } forall
 25 |         /Encoding EncodingVector def
 26 |         currentdict end definefont
 27 | } def
 28 | /Times-Roman starnetISO def
 29 | /Times-Italic starnetISO def
 30 | /Times-Bold starnetISO def
 31 | /Times-BoldItalic starnetISO def
 32 | /Helvetica starnetISO def
 33 | /Helvetica-Oblique starnetISO def
 34 | /Helvetica-Bold starnetISO def
 35 | /Helvetica-BoldOblique starnetISO def
 36 | /Courier starnetISO def
 37 | /Courier-Oblique starnetISO def
 38 | /Courier-Bold starnetISO def
 39 | /Courier-BoldOblique starnetISO def
 40 | cleartomark
 41 | } bind def
 42 | 
 43 | %%BeginResource: procset graphviz 0 0
 44 | /coord-font-family /Times-Roman def
 45 | /default-font-family /Times-Roman def
 46 | /coordfont coord-font-family findfont 8 scalefont def
 47 | 
 48 | /InvScaleFactor 1.0 def
 49 | /set_scale {
 50 |        dup 1 exch div /InvScaleFactor exch def
 51 |        scale
 52 | } bind def
 53 | 
 54 | % styles
 55 | /solid { [] 0 setdash } bind def
 56 | /dashed { [9 InvScaleFactor mul dup ] 0 setdash } bind def
 57 | /dotted { [1 InvScaleFactor mul 6 InvScaleFactor mul] 0 setdash } bind def
 58 | /invis {/fill {newpath} def /stroke {newpath} def /show {pop newpath} def} bind def
 59 | /bold { 2 setlinewidth } bind def
 60 | /filled { } bind def
 61 | /unfilled { } bind def
 62 | /rounded { } bind def
 63 | /diagonals { } bind def
 64 | /tapered { } bind def
 65 | 
 66 | % hooks for setting color 
 67 | /nodecolor { sethsbcolor } bind def
 68 | /edgecolor { sethsbcolor } bind def
 69 | /graphcolor { sethsbcolor } bind def
 70 | /nopcolor {pop pop pop} bind def
 71 | 
 72 | /beginpage {	% i j npages
 73 | 	/npages exch def
 74 | 	/j exch def
 75 | 	/i exch def
 76 | 	/str 10 string def
 77 | 	npages 1 gt {
 78 | 		gsave
 79 | 			coordfont setfont
 80 | 			0 0 moveto
 81 | 			(\() show i str cvs show (,) show j str cvs show (\)) show
 82 | 		grestore
 83 | 	} if
 84 | } bind def
 85 | 
 86 | /set_font {
 87 | 	findfont exch
 88 | 	scalefont setfont
 89 | } def
 90 | 
 91 | % draw text fitted to its expected width
 92 | /alignedtext {			% width text
 93 | 	/text exch def
 94 | 	/width exch def
 95 | 	gsave
 96 | 		width 0 gt {
 97 | 			[] 0 setdash
 98 | 			text stringwidth pop width exch sub text length div 0 text ashow
 99 | 		} if
100 | 	grestore
101 | } def
102 | 
103 | /boxprim {				% xcorner ycorner xsize ysize
104 | 		4 2 roll
105 | 		moveto
106 | 		2 copy
107 | 		exch 0 rlineto
108 | 		0 exch rlineto
109 | 		pop neg 0 rlineto
110 | 		closepath
111 | } bind def
112 | 
113 | /ellipse_path {
114 | 	/ry exch def
115 | 	/rx exch def
116 | 	/y exch def
117 | 	/x exch def
118 | 	matrix currentmatrix
119 | 	newpath
120 | 	x y translate
121 | 	rx ry scale
122 | 	0 0 1 0 360 arc
123 | 	setmatrix
124 | } bind def
125 | 
126 | /endpage { showpage } bind def
127 | /showpage { } def
128 | 
129 | /layercolorseq
130 | 	[	% layer color sequence - darkest to lightest
131 | 		[0 0 0]
132 | 		[.2 .8 .8]
133 | 		[.4 .8 .8]
134 | 		[.6 .8 .8]
135 | 		[.8 .8 .8]
136 | 	]
137 | def
138 | 
139 | /layerlen layercolorseq length def
140 | 
141 | /setlayer {/maxlayer exch def /curlayer exch def
142 | 	layercolorseq curlayer 1 sub layerlen mod get
143 | 	aload pop sethsbcolor
144 | 	/nodecolor {nopcolor} def
145 | 	/edgecolor {nopcolor} def
146 | 	/graphcolor {nopcolor} def
147 | } bind def
148 | 
149 | /onlayer { curlayer ne {invis} if } def
150 | 
151 | /onlayers {
152 | 	/myupper exch def
153 | 	/mylower exch def
154 | 	curlayer mylower lt
155 | 	curlayer myupper gt
156 | 	or
157 | 	{invis} if
158 | } def
159 | 
160 | /curlayer 0 def
161 | 
162 | %%EndResource
163 | %%EndProlog
164 | %%BeginSetup
165 | 14 default-font-family set_font
166 | 1 setmiterlimit
167 | % /arrowlength 10 def
168 | % /arrowwidth 5 def
169 | 
170 | % make sure pdfmark is harmless for PS-interpreters other than Distiller
171 | /pdfmark where {pop} {userdict /pdfmark /cleartomark load put} ifelse
172 | % make '<<' and '>>' safe on PS Level 1 devices
173 | /languagelevel where {pop languagelevel}{1} ifelse
174 | 2 lt {
175 |     userdict (<<) cvn ([) cvn load put
176 |     userdict (>>) cvn ([) cvn load put
177 | } if
178 | 
179 | %%EndSetup
180 | setupLatin1
181 | %%Page: 1 1
182 | %%PageBoundingBox: 36 36 347 292
183 | %%PageOrientation: Portrait
184 | 0 0 1 beginpage
185 | gsave
186 | 36 36 311 256 boxprim clip newpath
187 | 1 1 set_scale 0 rotate 40 40 translate
188 | % cluster0
189 | gsave
190 | 1 setlinewidth
191 | 0 0 0 graphcolor
192 | newpath 8 98 moveto
193 | 8 240 lineto
194 | 164 240 lineto
195 | 164 98 lineto
196 | closepath stroke
197 | grestore
198 | % cluster1
199 | gsave
200 | 1 setlinewidth
201 | 0 0 0 graphcolor
202 | newpath 172 8 moveto
203 | 172 150 lineto
204 | 295 150 lineto
205 | 295 8 lineto
206 | closepath stroke
207 | grestore
208 | % RaspberryPi
209 | gsave
210 | 1 setlinewidth
211 | 0 0 0 nodecolor
212 | 86 214 58.17 18 ellipse_path stroke
213 | 0 0 0 nodecolor
214 | 14 /Times-Roman set_font
215 | 51.39 208.4 moveto 69.21 (RaspberryPi) alignedtext
216 | grestore
217 | % Hardware
218 | gsave
219 | 1 setlinewidth
220 | 0 0 0 nodecolor
221 | 65 124 49.15 18 ellipse_path stroke
222 | 0 0 0 nodecolor
223 | 14 /Times-Roman set_font
224 | 37.41 118.4 moveto 55.19 (Hardware) alignedtext
225 | grestore
226 | % RaspberryPi->Hardware
227 | gsave
228 | 1 setlinewidth
229 | 0 0 0 edgecolor
230 | newpath 47.5 200.3 moveto
231 | 37.45 195.04 27.81 187.8 22 178 curveto
232 | 15.34 166.76 22.39 155.38 32.58 146.05 curveto
233 | stroke
234 | 0 0 0 edgecolor
235 | newpath 34.87 148.7 moveto
236 | 40.4 139.66 lineto
237 | 30.44 143.28 lineto
238 | closepath fill
239 | 1 setlinewidth
240 | solid
241 | 0 0 0 edgecolor
242 | newpath 34.87 148.7 moveto
243 | 40.4 139.66 lineto
244 | 30.44 143.28 lineto
245 | closepath stroke
246 | grestore
247 | % Server
248 | gsave
249 | 1 setlinewidth
250 | 0 0 0 nodecolor
251 | 216 124 36.36 18 ellipse_path stroke
252 | 0 0 0 nodecolor
253 | 14 /Times-Roman set_font
254 | 197.73 118.4 moveto 36.54 (Server) alignedtext
255 | grestore
256 | % RaspberryPi->Server
257 | gsave
258 | 1 setlinewidth
259 | 0 0 0 edgecolor
260 | newpath 122.31 199.67 moveto
261 | 135.68 193.96 150.57 186.61 163 178 curveto
262 | 174.98 169.7 186.63 158.51 195.94 148.55 curveto
263 | stroke
264 | 0 0 0 edgecolor
265 | newpath 198.74 150.67 moveto
266 | 202.87 140.91 lineto
267 | 193.56 145.97 lineto
268 | closepath fill
269 | 1 setlinewidth
270 | solid
271 | 0 0 0 edgecolor
272 | newpath 198.74 150.67 moveto
273 | 202.87 140.91 lineto
274 | 193.56 145.97 lineto
275 | closepath stroke
276 | grestore
277 | % Hardware->RaspberryPi
278 | gsave
279 | 1 setlinewidth
280 | 0 0 0 edgecolor
281 | newpath 53.3 141.55 moveto
282 | 47.3 152.16 42.27 166.13 47.52 178 curveto
283 | 49.47 182.41 52.29 186.51 55.52 190.23 curveto
284 | stroke
285 | 0 0 0 edgecolor
286 | newpath 53.05 192.71 moveto
287 | 62.59 197.31 lineto
288 | 58 187.76 lineto
289 | closepath fill
290 | 1 setlinewidth
291 | solid
292 | 0 0 0 edgecolor
293 | newpath 53.05 192.71 moveto
294 | 62.59 197.31 lineto
295 | 58 187.76 lineto
296 | closepath stroke
297 | 0 0 0 edgecolor
298 | 14 /Times-Roman set_font
299 | 48 163.4 moveto 115.48 (Serial Commucation) alignedtext
300 | grestore
301 | % Server->RaspberryPi
302 | gsave
303 | 1 setlinewidth
304 | 0 0 0 edgecolor
305 | newpath 211.81 141.96 moveto
306 | 208.13 153.58 201.65 168.55 191 178 curveto
307 | 178.44 189.14 162.23 196.76 146.31 201.95 curveto
308 | stroke
309 | 0 0 0 edgecolor
310 | newpath 145.06 198.67 moveto
311 | 136.48 204.89 lineto
312 | 147.06 205.38 lineto
313 | closepath fill
314 | 1 setlinewidth
315 | solid
316 | 0 0 0 edgecolor
317 | newpath 145.06 198.67 moveto
318 | 136.48 204.89 lineto
319 | 147.06 205.38 lineto
320 | closepath stroke
321 | 0 0 0 edgecolor
322 | 14 /Times-Roman set_font
323 | 205 163.4 moveto 65.34 (GET/POST) alignedtext
324 | grestore
325 | % Browser
326 | gsave
327 | 1 setlinewidth
328 | 0 0 0 nodecolor
329 | 233 34 43.14 18 ellipse_path stroke
330 | 0 0 0 nodecolor
331 | 14 /Times-Roman set_font
332 | 209.28 28.4 moveto 47.43 (Browser) alignedtext
333 | grestore
334 | % Server->Browser
335 | gsave
336 | 1 setlinewidth
337 | 0 0 0 edgecolor
338 | newpath 202.81 107.11 moveto
339 | 195.68 96.52 189.36 82.34 194.79 70 curveto
340 | 196.91 65.18 200.05 60.74 203.65 56.75 curveto
341 | stroke
342 | 0 0 0 edgecolor
343 | newpath 206.21 59.14 moveto
344 | 210.95 49.66 lineto
345 | 201.34 54.11 lineto
346 | closepath fill
347 | 1 setlinewidth
348 | solid
349 | 0 0 0 edgecolor
350 | newpath 206.21 59.14 moveto
351 | 210.95 49.66 lineto
352 | 201.34 54.11 lineto
353 | closepath stroke
354 | 0 0 0 edgecolor
355 | 14 /Times-Roman set_font
356 | 195 73.4 moveto 27.21 (Ajax) alignedtext
357 | grestore
358 | % Browser->Server
359 | gsave
360 | 1 setlinewidth
361 | 0 0 0 edgecolor
362 | newpath 231.37 52.29 moveto
363 | 230.22 62.7 228.45 76.19 226 88 curveto
364 | 225.44 90.69 224.78 93.48 224.08 96.25 curveto
365 | stroke
366 | 0 0 0 edgecolor
367 | newpath 220.66 95.47 moveto
368 | 221.39 106.04 lineto
369 | 227.41 97.32 lineto
370 | closepath fill
371 | 1 setlinewidth
372 | solid
373 | 0 0 0 edgecolor
374 | newpath 220.66 95.47 moveto
375 | 221.39 106.04 lineto
376 | 227.41 97.32 lineto
377 | closepath stroke
378 | 0 0 0 edgecolor
379 | 14 /Times-Roman set_font
380 | 229 73.4 moveto 38.9 (CRUD) alignedtext
381 | grestore
382 | endpage
383 | showpage
384 | grestore
385 | %%PageTrailer
386 | %%EndPage: 1
387 | %%Trailer
388 | %%Pages: 1
389 | %%BoundingBox: 36 36 347 292
390 | end
391 | restore
392 | %%EOF
393 | 


--------------------------------------------------------------------------------
/iot.md:
--------------------------------------------------------------------------------
   1 | ### 引言
   2 | 你可以将这个系统当成是你的毕业设计,或者用它来控制你想控制的东西,总之你可以用它来做一个最小的物联网系统。
   3 | 
   4 | **不过,在这里可能没有那么复杂的功能,因为强调的是最小。**
   5 | 
   6 | BareMinimum,这也是为什么我没有改Arduino上面的工程名的原因,因为它是最小的,(PS:大家都懂的,如果玩硬件)。物联网,这个东西一直很复杂,也不是很复杂,只是从硬件到软件涉及到的东西过多了,不止一点点。当然写在本文的方案也有很多,不止这一个,只是这个算是基本的最小的,仅此而已。(转载保留 [Phodal's
   7 | Blog](http://www.phodal.com/blog/bare-minimum-iot/) )
   8 | 
   9 | 关于
  10 | ----
  11 | 
  12 | 源码:[https://github.com/gmszone/iot](https://github.com/gmszone/iot)
  13 | 
  14 | 文档可能没有足够的详细,因为剩下的部分都可以Google到,这里就不写详细了。
  15 | 
  16 | ### 框架:
  17 | 
  18 | -   PHP Laravel 
  19 | -   jQuery (Javascript 主要用于Ajax)
  20 | -   jQuery Mobile(可选)(我觉得我有点懒,于是从原来做的项目直接拿了出来)
  21 | -   Bootstrap (可选) (其实没有多大实际用处,只是因为好看和jQuery Mobile一样)
  22 | 
  23 | ### 语言:
  24 | 
  25 | Processing/C/C++ : Arduino 
  26 | 
  27 | Python : Raspberry Pi 或者与之相近设备都可以使用,实现与 Arduino 串口通信
  28 | 
  29 | PHP 我学得不是很好,因为 Laravel 没有让我学好,但是让我能做想做的事。
  30 | 
  31 | ### 相关文章及专栏
  32 | 
  33 | -	CSDN - [Laravel专栏](http://blog.csdn.net/column/details/laravel.html)
  34 | 
  35 | 1.  [Laravel
  36 |     RESTful快速部署指南(一)](http://blog.csdn.net/phodal/article/details/15340355)
  37 | 2.  [Laravel
  38 |     RESTful快速部署指南(二)](http://blog.csdn.net/phodal/article/details/15364481)
  39 | 3.  [Laravel
  40 |     RESTful快速部署指南(三)](http://blog.csdn.net/phodal/article/details/15364481)
  41 | 
  42 | ### 相关知识
  43 | 
  44 | #### 软件
  45 | 
  46 | -   RESTful
  47 | -   Ajax
  48 | -   JSON
  49 | 
  50 | #### 硬件
  51 | 
  52 | -   硬件编程
  53 | -   串口通信
  54 | 
  55 | ### 关于服务器
  56 | 
  57 | -   Nginx 需要配置,具体配置可以参照 Github 上面的代码
  58 | -   LNMP 直接用上面的会比较简单,但是可能也会遇到一些问题。
  59 | -   Phpmyadmin 最好需要有这个,如果不是很精通 MySQL
  60 | 
  61 | ### 补充说明
  62 | 
  63 | Arduino 不是必需的,只要你懂得如何用你的芯片进行串口通信。
  64 | 
  65 | 考虑到 Raspberry Pi 的成本可能会有点高,你可以试着用 OpenWRT
  66 | Linux,主要用在路由器用的,上面可以跑 Python。或者等等过些时候的小米路由器,可以加这个在上面。
  67 | 
  68 | 如果你没有服务器没有 Raspberry
  69 | Pi,那就找个路由器来当服务器吧,相关文章如下 :
  70 | 
  71 | [Openwrt python,openwrt上使用Python](http://blog.csdn.net/phodal/article/details/8521712)
  72 | 
  73 | 对了,如果你觉得哪里有问题记得在 Github 上提出来,而不是在原文。
  74 | 
  75 | ### 注意
  76 | 
  77 | 
!请尽可能少用我的网站做测试
78 | 79 | 80 | 如何开始 81 | -------- 82 | 83 | $ git clone https://github.com/gmszone/iot.git 84 | $ cp iot/rest 85 | 86 | 创建一个新的数据库,如iot 编辑 app/config/database.php 87 | 88 |

  89 | 'mysql' => array(
  90 | 'driver' => 'mysql',
  91 | 'host' => 'localhost',
  92 | 'database' => 'iot',
  93 | 'username' => 'root',
  94 | 'password' => ' ',
  95 | 'charset' => 'utf8',
  96 | 'collation' => 'utf8_unicode_ci',
  97 | 'prefix' => '',
  98 | ),
  99 | 
100 | 101 | 102 | 配置nginx,添加,详细可参考nginx下面的配置 103 | 104 |

 105 | # include /etc/nginx/includes/enforce_non_www;
 106 | if ($host ~* ^www\.(.*))
 107 | {
 108 | set $host_without_www $1;
 109 | rewrite ^/(.*)$ $scheme://$host_without_www/$1 permanent;
 110 | }
 111 | 
 112 | # Check if file exists
 113 | if (!-e $request_filename)
 114 | {
 115 | rewrite ^/(.*)$ /index.php?/$1 last;
 116 | break;
 117 | }
 118 | 
119 | 120 | 121 | 测试 122 | 123 | ``` 124 | $ sudo python python/get.py 125 | ``` 126 | 127 | 128 | 再根据需要修改端口,视真实的端口而修改。 129 | 130 | ##关于物联网## 131 |
物联网(Internet of Things,缩写IOT)是一个基于互联网、传统电信网等信息承载体,让所有能够被独立寻址的普通物理对象实现互联互通的网络。 132 |
133 | 134 | 物联网一般为无线网,由于每个人周围的设备可以达到一千至五千个,所以物联网可能要包含500万亿至一千万亿个物体,在物联网上,每个人都可以应用电子标签将真实的物体上网联结,在物联网上都可以查找出它们的具体位置。通过物联网可以用中心计算机对机器、设备、人员进行集中管理、控制,也可以对家庭设备、汽车进行遥控,以及搜寻位置、防止物品被盗等各种应用。 135 | 136 | 简单的来说 Internet 是一个由计算机组成的网络,那么物联网就是一个由物体(Things)组成的网络,只不过其依赖于 Internet,是 Internet 的一部分。 137 | 138 | ##最小物联网系统## 139 | 这个也就是我们要讨论的主题了,我们要做的最小物联网系统其实也就相当于是一个平台。我们可以上传我们各种物体的信息,同时给予这些物体一些属性,我们也可以通过网络来控制这些物体,而他们之间也可以相互控制。因此,我们需要给他们提供一个网络,这就是RESTful的由来。 140 | 141 | 所以我们也稍微了解一下RESTful吧。 142 | 143 | ###RESTful### 144 | 145 |
REST 从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表征。获得这些表征致使这些应用程序转变了其状态。随着不断获取资源的表征,客户端应用不断地在转变着其状态,所谓表征状态转移(Representational State Transfer)。
146 | 147 | 我们的世界是由资源来组成的,一个物体也就相当于是一个资源,以这种方式来构建我们的物联网系统,在目前来说是再好不过的一个方案了。 148 | 149 |
REST架构就是希望能够统一这一类的Hypermedia Controls, 赋予他们标准的, 高度可扩展的标准语义及表现形式, 使得甚至无人工干预的机器与机器间的通用交互协议边的可能.
150 | 151 | 这个也就是我们的目的了,物联网最后的核心就是使物体与物体之间的交互成为可能。 152 | 153 | 那么,这里也就解释了为什么我们要用RESTful来做这个最小系统的原因了。 154 | 155 | ###最小系统中的RESTful### 156 | 157 | 例如,一个简单的例子, 158 | 列举所有物体状态, 159 | 160 | $ GET http://localhost/athome 161 | 162 | 呈现某一特定状态, 163 | 164 | $ GET http://localhost/athome/1/ 165 | 166 | 剩下的部分这里就不多说了,多说无益,可以自己谷歌去。 167 | 168 | 接着我们要讨论的就是系统框架 169 | 170 | ##系统框架## 171 | 172 | [image]: ./struct.bmp "系统框架" 173 | ![系统框架][image] 174 | 175 | ###为什么是 Raspberry Pi### 176 | 177 | Raspberry Pi 在这里只是充当了数据的发送和接收,虽然我们可以直接将 Raspberry Pi 作为控制的对象,但是将这个从中剥离来讲清楚系统的结构会更加简单。从而,可以让我们把核心注意力聚焦在要解决的问题上,也就是数据传送,每个部分都可以简单地从系统剥离出来,用另外的事物来替换。 178 | 179 | 180 | ###为什么是 Arduino### 181 | 182 | 这个问题的答案和上面是一样的,只是因为有些搞物联网是从软件过来的,对于他们来说去理解端口的难道可能有点大。所以,我们在简化系统设计的同时,也把系统的代码简化了。因为 Arduino 足够的简单,我们可以关心问题的本质,而不是如何去编程。 183 | 184 | ###为什么是Ajax### 185 | 186 |
AJAX即 "Asynchronous JavaScript and XML" (异步的 JavaScript 与 XML 技术),指的是一套综合了多项技术的浏览器端网页开发技术。 187 |
188 | 189 | 这里的目的只是在于演示如何运用这些数据,使它具有他应有的价值,而不在于技术本身。当然 ajax 不是必需的,如果你需要的只是用来控制这个灯。 190 | 191 | ###为什么是 Laravel### 192 | 只是因为个人喜爱,你也可以用 Ruby On Rails 来搭建这样一个功能,或者是 Java。只不过 PHP 在我的服务器上运行得挺不错的,而且我又不需要重新去写配置那些配置。 193 | 同时 Laravel 可以简单的开发我们所需要的功能,换句话说他是 PHP 世界的 Ruby On Rails。 194 | 195 | 196 | 这里不会再重述之前的问题,这里只是将需要的步骤一个个写下来,然后丢到这里好好说一下。至于 RESTful 是什么,前面已经介绍了,就不再重复了。那么下面,我们就用 Laravel 来搭建一个平台给物联网用的。 197 | 198 | ##安装 Laravel## 199 | 这个就比较简单了,不过在那之前你要有 gi t以及安装了 php 环境,这个在 linux 上面比较好实现,可以用 Raspberry Pi 或者是你的电脑来做这个,不一定用用上你的服务器。 200 | 201 | $ git clone https://github.com/laravel/laravel‎ 202 | 203 | 先 clone 这个 git,如果你没有安装好 PHP,请安装好,and go on。 204 | 205 | $ cd laravel 206 | 207 | laravel 用到了 php 的包管理工具 composer,于是我们还需要用到 composer,与 Laravel 相比也算是一个优雅的工具。 208 | 209 | $ curl -sS https://getcomposer.org/installer | php 210 | 211 | 这里推荐的是 linux 系统,如果你是 *nix 都是可以的(ps:mac os x属于unix分支),除了 windows,所以如果是 windows,请直接下载 212 | 213 | [Composer-Setup][composer] 214 | 215 | 然后让我们安装所需要的那些包 216 | 217 | $ php composer.phar install 218 | 219 | 当然这里用的是比较通用的,如果你是 *nix,有支持可以直接 220 | 221 | $ composer install 222 | 223 | 224 | ##配置MySQL## 225 | 这里并不会列举 MySQL 的安装方法,如果你是 openSUSE,可以 226 | 227 | $ zypper install mysql 228 | 229 | 这个也可以,不过最近我尽量到迁移到 MariaDB 了。 230 | 231 | $ zypper install mariadb 232 | 233 | 当然,最简单的方法是直接上官网。这里说的是修改 database.php 234 | 235 | app/config/database.php 236 | 237 | 要修改的就是这个 238 | 239 | 'mysql' => array( 240 | 'driver' => 'mysql', 241 | 'host' => 'localhost', 242 | 'database' => 'iot', 243 | 'username' => 'root', 244 | 'password' => '940217', 245 | 'charset' => 'utf8', 246 | 'collation' => 'utf8_unicode_ci', 247 | 'prefix' => '', 248 | ), 249 | 250 | 如果你已经有phpmyadmin,似乎对你来说已经很简单了,如果没有的话,就直接用 251 | 252 | $ mysql -uroot -p 253 | 254 | 来创建一个新的 255 | 256 | CREATE DATABASE IF NOT EXISTS iot default charset utf8 COLLATE utf8_general_ci; 257 | 258 | [composer]: https://getcomposer.org/Composer-Setup.exe 259 | 260 | 261 | 数据库的目的在于存储数据等等的闲话这里就不多说了,创建一个RESTful的目的在于产生下面的JSON格式数据,以便于我们在Android、Java、Python、jQuery等语言框架或者平台上可以调用,最主要的是可以直接用Ajax来产生更炫目的效果。 262 | 263 | { 264 | id: 1, 265 | temperature: 14, 266 | sensors1: 12, 267 | sensors2: 12, 268 | led1: 0 269 | } 270 | 271 | ##数据库迁移## 272 | 273 | 这个名字是源自于Ruby On Rails在那时候的印象,不直接使用MySQL的目的在于让我们可以专注于过程。 274 | 275 | ###创建表### 276 | 表的概念,类似于在Excel中的表,如果你真实不懂数据库。 277 | 让我们创建一个athomes的表,为什么是athomes,因为以前在写android程序的时候就叫的是athome,忽略掉这些次要的因素吧。 278 | 279 | $ php artisan migrate:make create_athomes_table 280 | 281 | 打开 app/database/migrations/***create_athomes_table.php这里的***是由日期和某些东西组成的,修改生成的代码为下面。 282 | 283 | use Illuminate\Database\Schema\Blueprint; 284 | use Illuminate\Database\Migrations\Migration; 285 | 286 | class CreateAthomesTable extends Migration { 287 | 288 | public function up() 289 | { 290 | Schema::create('athomes', function(Blueprint $table) 291 | { 292 | $table--->increments('id'); 293 | $table->float('temperature'); 294 | $table->float('sensors1'); 295 | $table->float('sensors2'); 296 | $table->boolean('led1'); 297 | $table->timestamps(); 298 | }); 299 | } 300 | 301 | public function down() 302 | { 303 | Schema::drop('athomes'); 304 | } 305 | 306 | } 307 | 308 | 意思大致就是id是自加的,也就是我们在localhost/athome/{id},当我们创建一个新的数据的时候,会自动加上去,最后一个timestamps批的是时间,会包含创建时间和修改时间。 309 | 剩下的temperature,sensors1,sensors2是小数,以及只有真和假的led1。 310 | 311 | ###数据库迁移### 312 | 我们只是写了我们需要的数据的格式而并没有丢到数据库里, 313 | 314 | $ php artisan migrate 315 | 316 | 这个就是我们执行迁移的命令,如果你用phpmyadmin可以直接打开查看,没有的话,可以。 317 | 318 | $ mysql -uroot -p 319 | 320 | use iot; 321 | select * from athomes; 322 | 323 | 就可以看到我们写的东西,那么接下来就是创建RESTful 服务了 324 | 325 | 326 | ##创建RESTful## 327 | 328 | 用下面的代码实现我们称之为Athomes控制器的创建 329 | 330 | $ php artisan controller:make AthomesController 331 | 332 | 就会在app/controllers下面生成下面的代码 333 | 334 | class AthomesController extends \BaseController { 335 | 336 | /** 337 | * Display a listing of the resource. 338 | * 339 | * @return Response 340 | */ 341 | public function index() 342 | { 343 | // 344 | } 345 | 346 | /** 347 | * Show the form for creating a new resource. 348 | * 349 | * @return Response 350 | */ 351 | public function create() 352 | { 353 | // 354 | } 355 | 356 | /** 357 | * Store a newly created resource in storage. 358 | * 359 | * @return Response 360 | */ 361 | public function store() 362 | { 363 | // 364 | } 365 | 366 | /** 367 | * Display the specified resource. 368 | * 369 | * @param int $id 370 | * @return Response 371 | */ 372 | public function show($id) 373 | { 374 | // 375 | } 376 | 377 | /** 378 | * Show the form for editing the specified resource. 379 | * 380 | * @param int $id 381 | * @return Response 382 | */ 383 | public function edit($id) 384 | { 385 | // 386 | } 387 | 388 | /** 389 | * Update the specified resource in storage. 390 | * 391 | * @param int $id 392 | * @return Response 393 | */ 394 | public function update($id) 395 | { 396 | // 397 | } 398 | 399 | /** 400 | * Remove the specified resource from storage. 401 | * 402 | * @param int $id 403 | * @return Response 404 | */ 405 | public function destroy($id) 406 | { 407 | // 408 | } 409 | 410 | } 411 | 412 | ###Laravel Resources### 413 | 414 | 上面的代码过于沉重,请让我用 Ctrl+C 来带来点知识吧。 415 | 416 | 417 | 所以我们只需要专注于创建 create, edit, show, destory 等等。好吧,你可能没有耐心了,但是在修改这个之前我们需要先在 418 | app/model 加个 class 419 | 420 | class Athomes extends Eloquent { 421 | protected $table = 'athomes'; 422 | } 423 | 424 | 如果你想要的只是控制器Athomes的代码的话。。 425 | 426 | 427 | class AthomesController extends \BaseController { 428 | 429 | /** 430 | * Display a listing of the resource. 431 | * 432 | * @return Response 433 | */ 434 | public $restful=true; 435 | 436 | protected $athome; 437 | 438 | public function __construct(Athomes $athome) 439 | { 440 | $this--->athome = $athome ; 441 | } 442 | 443 | public function index() 444 | { 445 | $maxid=Athomes::all(); 446 | return Response::json($maxid); 447 | } 448 | 449 | /** 450 | * Show the form for creating a new resource. 451 | * 452 | * @return Response 453 | */ 454 | public function create() 455 | { 456 | $maxid=Athomes::max('id'); 457 | return View::make('athome.create')->with('maxid',$maxid); 458 | } 459 | 460 | /** 461 | * Store a newly created resource in storage. 462 | * 463 | * @return Response 464 | */ 465 | public function store() 466 | { 467 | // validate 468 | // read more on validation at http://laravel.com/docs/validation 469 | $rules = array( 470 | 'led1'=>'required', 471 | 'sensors1' => 'required|numeric|Min:-50|Max:80', 472 | 'sensors2' => 'required|numeric|Min:-50|Max:80', 473 | 'temperature' => 'required|numeric|Min:-50|Max:80' 474 | ); 475 | $validator = Validator::make(Input::all(), $rules); 476 | 477 | // process the login 478 | if ($validator->fails()) { 479 | return Redirect::to('athome/create') 480 | ->withErrors($validator) 481 | ->withInput(Input::except('password')); 482 | } else { 483 | // store 484 | $nerd = new Athomes; 485 | $nerd->sensors1 = Input::get('sensors1'); 486 | $nerd->sensors2 = Input::get('sensors2'); 487 | $nerd->temperature = Input::get('temperature'); 488 | $nerd->led1 = Input::get('led1'); 489 | $nerd->save(); 490 | 491 | // redirect 492 | Session::flash('message', 'Successfully created athome!'); 493 | return Redirect::to('athome'); 494 | } 495 | } 496 | 497 | /** 498 | * Display the specified resource. 499 | * 500 | * @param int $id 501 | * @return Response 502 | */ 503 | public function show($id) 504 | { 505 | $myid=Athomes::find($id); 506 | $maxid=Athomes::where('id','=',$id) 507 | ->select('id','temperature','sensors1','sensors2','led1') 508 | ->get(); 509 | return Response::json($maxid); 510 | } 511 | 512 | /** 513 | * Show the form for editing the specified resource. 514 | * 515 | * @param int $id 516 | * @return Response 517 | */ 518 | public function edit($id) 519 | { 520 | // get the nerd 521 | $athome = Athomes::find($id); 522 | 523 | // show the edit form and pass the nerd 524 | return View::make('athome.edit') 525 | ->with('athome', $athome); 526 | } 527 | 528 | /** 529 | * Update the specified resource in storage. 530 | * 531 | * @param int $id 532 | * @return Response 533 | */ 534 | public function update($id) 535 | { 536 | // validate 537 | // read more on validation at http://laravel.com/docs/validation 538 | $rules = array( 539 | 'led1'=>'required|', 540 | 'sensors1' => 'required|numeric|Min:-50|Max:80', 541 | 'sensors2' => 'required|numeric|Min:-50|Max:80', 542 | 'temperature' => 'required|numeric|Min:-50|Max:80' 543 | ); 544 | $validator = Validator::make(Input::all(), $rules); 545 | 546 | // process the login 547 | if ($validator->fails()) { 548 | return Redirect::to('athome/' . $id . '/edit') 549 | ->withErrors($validator); 550 | } else { 551 | // store 552 | $nerd = Athomes::find($id); 553 | $nerd->sensors1 = Input::get('sensors1'); 554 | $nerd->sensors2 = Input::get('sensors2'); 555 | $nerd->temperature = Input::get('temperature'); 556 | $nerd->led1 = Input::get('led1'); 557 | $nerd->save(); 558 | 559 | // redirect 560 | Session::flash('message', 'Successfully created athome!'); 561 | return Redirect::to('athome'); 562 | } 563 | } 564 | 565 | /** 566 | * Remove the specified resource from storage. 567 | * 568 | * @param int $id 569 | * @return Response 570 | */ 571 | public function destroy($id) 572 | { 573 | // delete 574 | $athome = Athomes::find($id); 575 | $athome->delete(); 576 | if(is_null($athome)) 577 | { 578 | return Response::json('Todo not found', 404); 579 | } 580 | // redirect 581 | Session::flash('message', 'Successfully deleted the nerd!'); 582 | return Redirect::to('athome'); 583 | } 584 | 585 | } 586 | 587 | 希望你能读懂,没有的话,关注下一节。 588 | 589 | 下面这部分来自于之前的博客,这里就不多加论述了。 590 | 这个也就是我们要的模板, 591 | 592 | 修改 Create() 593 | ------------ 594 | 595 |

 596 | 	public function create()
 597 | 	{
 598 | 	    $maxid=Athomes::max('id');
 599 | 	    return View::make('athome.create')->with('maxid',$maxid);
 600 | 	}
 601 | 
602 | 603 | 604 | 这里需要在app/views/创建一个athome里面创建一个create.blade.php,至于maxid,暂时还不需要,后面会用到show。如果只需要模板,可以简化为 605 | 606 |

 607 | 	public function create()
 608 |     {
 609 |         return View::make('athome.create');
 610 |     }
 611 | 
612 | 613 | 这里只是对其中代码的进行一下说明。 614 | 615 | 创建表单 616 | -------- 617 | 618 | ### 创建表单之前 619 | 620 | 由于使用到了bootstrap以及bootstrap-select,记得添加css。 621 | 622 | 623 | 624 | 625 | 以及javascript 626 | 627 | 628 | 629 | 630 | 633 | 634 | 635 | ### 创建表单 636 | 637 | 这里用到的是之前提到的那个作者写下的,稍微修改了一下。 638 | 639 |
640 | {{ HTML::ul($errors->all()) }} 641 | {{ Form::open(array('url' => 'athome')) }} 642 | 643 |
644 | {{ Form::label('led1', '开关1') }} 645 | {{ Form::select('led1',array('关','开'),$selected=NULL,array('class'=>'selectpicker')) }} 646 | 647 |
648 | 649 |
650 | {{ Form::label('sensors1', 'sensors1') }} 651 | {{ Form::text('sensors1', Input::old('sensors1'), array('class' => 'form-control')) }} 652 |
653 | 654 |
655 | {{ Form::label('sensors2', 'sensors2') }} 656 | {{ Form::text('sensors2', Input::old('sensors2'), array('class' => 'form-control')) }} 657 |
658 | 659 |
660 | {{ Form::label('temperature', 'temperature') }} 661 | {{ Form::text('temperature', Input::old('temperature'), array('class' => 'form-control')) }} 662 |
663 | 664 | {{ Form::submit('Create!', array('class' => 'btn btn-primary')) }} 665 | 666 | {{ Form::close() }} 667 | 668 |
669 | 670 | 开关一开始打算用 checkbox,加上 bootstrap-switch 实现 671 | ON OFF 672 | 弱弱地觉得还是没掌握好的节奏,所以最后用 select 来实现。 673 | 674 | 还需要修改一下之前的 create(),添加一行 675 | 676 | return Redirect::to('athome'); 677 | 678 | 也就是添加完后,重定向到首页查看,最后例子给出的 create 如下 679 | 680 | public function store() 681 | { 682 | $rules = array( 683 | 'led1'=>'required', 684 | 'sensors1' => 'required|numeric|Min:-50|Max:80', 685 | 'sensors2' => 'required|numeric|Min:-50|Max:80', 686 | 'temperature' => 'required|numeric|Min:-50|Max:80' 687 | ); 688 | $validator = Validator::make(Input::all(), $rules); 689 | 690 | if ($validator->fails()) { 691 | return Redirect::to('athome/create') 692 | ->withErrors($validator); 693 | } else { 694 | // store 695 | $nerd = new Athomes; 696 | $nerd->sensors1 = Input::get('sensors1'); 697 | $nerd->sensors2 = Input::get('sensors2'); 698 | $nerd->temperature = Input::get('temperature'); 699 | $nerd->led1 = Input::get('led1'); 700 | $nerd->save(); 701 | 702 | Session::flash('message', 'Successfully created athome!'); 703 | return Redirect::to('athome'); 704 | } 705 | } 706 | 707 | 编辑 edit 708 | -------- 709 | 710 | 完整的 blade 模板文件 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | @yield('title') 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 |
728 | 729 |
730 |
731 | 732 |

Edit {{ $athome->id }}

733 | 734 | 735 | {{ HTML::ul($errors->all()) }} 736 | 737 | {{ Form::model($athome, array('route' => array('athome.update', $athome->id), 'method' => 'PUT')) }} 738 | 739 |
740 | {{ Form::label('led1', '开关1') }} 741 | {{ Form::select('led1',array('关','开'),$selected=NULL,array('class'=>'selectpicker')) }} 742 | 743 |
744 | 745 |
746 | {{ Form::label('sensors1', '传感器1') }} 747 | {{ Form::text('sensors1', Input::old('sensors1'), array('class' => 'form-control')) }} 748 |
749 | 750 |
751 | {{ Form::label('sensors2', '传感器2') }} 752 | {{ Form::text('sensors2', Input::old('sensors2'), array('class' => 'form-control')) }} 753 |
754 | 755 |
756 | {{ Form::label('temperature', '温度传感器') }} 757 | {{ Form::text('temperature', Input::old('temperature'), array('class' => 'form-control')) }} 758 |
759 | 760 | 761 | {{ Form::submit('Edit the Nerd!', array('class' => 'btn btn-primary')) }} 762 | 763 | {{ Form::close() }} 764 | 765 |
766 |
767 | 768 | 769 | 772 |
773 | 774 | 775 | 776 | 777 | 778 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 最后效果见:[http://b.phodal.com/][bphodal] 789 | 790 | 代码位置:[http://b.phodal.com/js/app.js][appjs] 791 | 792 | 我觉得似乎我把这个代码写长了,但是我不是故意,只是必需的。先观察 Ajax 部分: 793 | 794 | ##Ajax## 795 | 796 | 剥离后的Ajax部分代码如下所示,主要用的是 jQuery 框架的 getJSON 来实现的 797 | 798 | var dataLength = []; 799 | 800 | function drawTemp() { 801 | var zero = []; 802 | $.getJSON('/athome/', function(json) { 803 | var items = []; 804 | dataLength.push(json.length); 805 | $.each(json, function(key, val) { 806 | zero.push(val.temperature); 807 | }); 808 | }; 809 | 810 | 实际上,我们做的只是从 /athome/ 下面获取数据,再将数据堆到数组里面,再把这部分放到图形中。等等,什么是 Ajax? 811 | 812 | - AJAX : Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。 813 | - AJAX 不是新的编程语言,而是一种使用现有标准的新方法。 814 | - AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。 815 | 816 | JSON我们前面也已经了解过了,看看getJSON吧。 817 | 818 | ####jQuery. getJSON#### 819 | 方法定义:jQuery.getJSON( url, data, callback ) 820 | 821 | 通过get请求得到json数据 822 | 823 | - ·url 用于提供 json 数据的地址页 824 | - ·data(Optional) 用于传送到服务器的键值对 825 | - ·callback(Optional) 回调函数,json 数据请求成功后的处理函数 826 | 827 | 我想你似乎应该懂得了一点,就是在不刷新网页的同时,用 javascript 获取数据放到图表上,就这么简单。 828 | 829 | ##HighChart## 830 | 再省去一部分,摘自我原来的博客 831 | 832 | HIGHCHARTS 833 | Highcharts 是一个制作图表的纯 Javascript 类库,主要特性如下: 834 | 835 | - 兼容性:兼容当今所有的浏览器,包括 iPhone、IE 和火狐等等; 836 | - 对个人用户完全免费; 837 | - 纯 JS,无 BS; 838 | - 支持大部分的图表类型:直线图,曲线图、区域图、区域曲线图、柱状图、饼装图、散布图; 839 | - 跨语言:不管是 PHP、Asp.net 还是 Java 都可以使用,它只需要三个文件:一个是Highcharts 的核心文件 highcharts.js,还有 a canvas emulator for IE 和 Jquery类库或者 MooTools 类库; 840 | - 提示功能:鼠标移动到图表的某一点上有提示信息; 841 | - 放大功能:选中图表部分放大,近距离观察图表; 842 | - 易用性:无需要特殊的开发技能,只需要设置一下选项就可以制作适合自己的图表; 843 | - 时间轴:可以精确到毫秒; 844 | 845 | 不过因为项目原因,所以可能不会再使用这个,只对个人免费,现在的考虑是基于D3做一个新的。 846 | 847 | ###官方示例代码### 848 | 849 | $(function () { 850 | $('#container').highcharts({ 851 | title: { 852 | text: 'Monthly Average Temperature', 853 | x: -20 //center 854 | }, 855 | subtitle: { 856 | text: 'Source: WorldClimate.com', 857 | x: -20 858 | }, 859 | xAxis: { 860 | categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 861 | 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] 862 | }, 863 | yAxis: { 864 | title: { 865 | text: 'Temperature (°C)' 866 | }, 867 | plotLines: [{ 868 | value: 0, 869 | width: 1, 870 | color: '#808080' 871 | }] 872 | }, 873 | tooltip: { 874 | valueSuffix: '°C' 875 | }, 876 | legend: { 877 | layout: 'vertical', 878 | align: 'right', 879 | verticalAlign: 'middle', 880 | borderWidth: 0 881 | }, 882 | series: [{ 883 | name: 'Tokyo', 884 | data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6] 885 | }, { 886 | name: 'New York', 887 | data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5] 888 | }, { 889 | name: 'Berlin', 890 | data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0] 891 | }, { 892 | name: 'London', 893 | data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8] 894 | }] 895 | }); 896 | }); 897 | 898 | 我承认我也不想看这些代码,但是这样子似乎使原文的长度变长了。大部分人也省得去查找了。 899 | 900 | 所以我们要做的只是用数组代替data 901 | 902 | ##jQuery Mobile## 903 | 904 | 在首页上看到的那个效果是 jQuery Mobile。。 905 | 906 | 907 | [bphodal]:http://b.phodal.com/ 908 | [appjs]:http://b.phodal.com/js/app.js 909 | 910 | 911 | 这里写的数据通讯指的是两部分,一部分是与服务器,一部分是与单片机。这样设计的另外一个原因是,更好的分层,能让我们更好的理解这个系统。负责这个功能的这里用的是 Raspberry Pi,或者是你的PC两者都可以,我想你也看到了之前的代码。那么先让我们看看与服务器通信的这部分。 912 | 913 | ##服务器通讯## 914 | 示例中的代码是这样子的,如果你没有看懂的话,那么等等 。 915 | 916 | import json,urllib2 917 | 918 | url="http://b.phodal.com/athome/1" 919 | while True: 920 | status=json.load(urllib2.urlopen(url))[0]['led1'] 921 | 922 | ###GET### 923 | 924 | 看看get.py的代码,这个是没有压缩的,换句话说,会比较好理解一点 925 | 926 | import json 927 | import urllib2 928 | 929 | url="http://b.phodal.com/athome/1" 930 | 931 | while 1: 932 | date=urllib2.urlopen(url) 933 | result=json.load(date) 934 | status=result[0]['led1'] 935 | print status 936 | 937 | 这里做的事情有两件,一件是从服务器 GET,另外一个就是解析 JSON 数据。 938 | 939 | 如果你用的是 *nix,应该就自带 curl 了,可以试着用下面的命令来 GET 940 | 941 | $ curl http://b.phodal.com/athome/1 942 | 943 | 那么应该返回的是下面的结果 944 | 945 | [{"id":1,"temperature":14,"sensors1":12,"sensors2":12,"led1":0}] 946 | 947 | 用在python里面就是 948 | 949 | urllib2.open("http://b.phodal.com/athome/1") 950 | 951 | 952 | ###数据解析### 953 | python 带有 json 解析模块,我们在这里只需要用 json.load() 来解析获取下面的 date 就可以了 954 | 955 | result=json.load(date) 956 | 957 | 解析完的 result 相当于是C语言里面的数组,在这里相当于是一个二维数组,我们只需要 result[0]['led1'],在 python 里面叫做字典,意思就是和字典一样。 958 | 959 | "led1":0 960 | 961 | led1的值是 0,所以 result[0]['led1]的值是 0,如果你用过 Ruby,那么这个和其中的 Hash 差不多。 962 | 963 | 因此在这里我们拿到了服务器上面的控制状态的指令,也就是 0。我们还需要传给单片机,也就是 Arduino。。 964 | 965 | 在我们完成了前面的几部分之后,我们也需要把这最后一部分解决,这里更多的是硬件, Arduino 的存在可以让硬件更简单。 966 | 967 | ##Arduino## 968 | 969 |
Arduino 是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的arduino板)和软件(arduino IDE)。它适用于艺术家、设计师、爱好者和对于“互动”有兴趣的朋友们。
970 | 971 | 那么让我们先来看看我们写的代码。 972 | 973 | void setup() { 974 | Serial.begin(9600); 975 | pinMode(13,OUTPUT); 976 | } 977 | 978 | int serialData; 979 | void loop() { 980 | String inString = ""; 981 | while (Serial.available()> 0) 982 | { 983 | int inChar = Serial.read(); 984 | if (isDigit(inChar)) { 985 | inString += (char)inChar; 986 | } 987 | serialData=inString.toInt(); 988 | Serial.print(serialData); 989 | } 990 | if(serialData==1){ 991 | digitalWrite(13,HIGH); 992 | }else{ 993 | digitalWrite(13,LOW); 994 | } 995 | } 996 | 997 | 这个代码看上去似乎会有点复杂,但是让我们看点基础的,也就是由 Arduino 来控制一个 LED 的亮和灭。 998 | 999 | int led = 13; 1000 | 1001 | void setup() { 1002 | pinMode(led, OUTPUT); 1003 | } 1004 | 1005 | void loop() { 1006 | digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) 1007 | delay(1000); // wait for a second 1008 | digitalWrite(led, LOW); // turn the LED off by making the voltage LOW 1009 | delay(1000); // wait for a second 1010 | } 1011 | 1012 | 这个也就是来自于官方的示例程序,而我们要做的东西也和这个差不多,只是这个是自动的,上面那个是由串口通信来实现的。 1013 | 1014 | ##串口通信## 1015 | 1016 |
串行接口是一种可以将接受来自 CPU 的并行数据字符转换为连续的串行数据流发送出去,同时可将接受的串行数据流转换为并行的数据字符供给 CPU 的器件。一般完成这种功能的电路,我们称为串行接口电路。
1017 | 1018 | 简单地来说,我们誻就是用这个来实现通信的,用之前的 Raspberry Pi 发送 1 和 0 给 Arduino。那么我们在 Arduino 上就只是接受和执行,这个由 loop 里面的 if 来执行 1019 | 1020 | ###初始化串口### 1021 | 1022 | 如果你真心不喜欢51上的复杂的串口,那么我想 Arduino 又是解放双手的东西了。 1023 | 1024 | Serial.begin(9600); 1025 | 1026 | 这个就是串口初始化,速率为 9600。 1027 | 1028 | ###串口读取### 1029 | 1030 | 1031 | while (Serial.available()<0) 1032 | { 1033 | int inChar = Serial.read(); 1034 | if (isDigit(inChar)) { 1035 | inString += (char)inChar; 1036 | } 1037 | serialData=inString.toInt(); 1038 | 1039 | 用于读取的就是这么一行 1040 | 1041 | int inChar=Serial.read() 1042 | 1043 | 而下面的部分则是刚我们接收到的数据转换为1,由于接到的为 char 类型,那么我们需要转为转为 int 进行判断。 1044 | 1045 | ####为什么不直接用'1'#### 1046 | 1047 | 只是为了写给需要的同学用的,也可以直接在上面用 if(serialData=='1'),上面写可以让后期扩展的时候方便一点。 1048 | 1049 | 加上之前的部分,我们算是把开源的地方做了一个遍,因为 Windows Phone 需要在 Windows 8 上开发的原因,加上我没有 Macbook 以及 iPhone,所以在这里只会有一个 Android 的示例。当然,原因上也是一样的,相信这些也不会很难。 1050 | 1051 | 原理上和 Raspberry Pi 的原理很像,也就是GET数据,然后解析,也和服务端差不多。当然在最开始的代码里有拨打电话、发短信等等功能,只是我们似着简化系统为我们想要的理想化模型。 1052 | 1053 | 源码地址[Home-Anywhere][3] 1054 | ##Android开发## 1055 | 1056 | 写在这里的原因是,因为我也不太擅长,所以也给不了多少指导。只是我试着去写过这样一个程序,有了几个版本,所以算是知道怎样去开发,但是相比较于专业于我的人还是有很多不足,所以希望懂得的人给些建议和意见。 1057 | 1058 | ###浅析### 1059 | 我们需要的库和在 Raspberry Pi 上的类似,如果你不需要的话,可以看看之前的文章: 1060 | 1061 | [最小物联网系统(七)——与服务器通讯][comm] 1062 | 1063 | 因为CSDN上发这些文章已经没有足够的必要,在之前的部分文章实在上是针对这部分写的, 只是在自己的博客上梳理了一遍。 1064 | 1065 | 我们还要做的事情就是有一个 RESTful 的库,以及解析 JSON 用的。 1066 | 1067 | 于是就有了下面两个 1068 | 1069 | ####RESTclient#### 1070 | 这个类的原文在[calling-web-services-in-android-using-httpclient][2],专门用于 REST 用的,如果熟悉的人我想一看就知道了。 1071 | 1072 | ####GSON#### 1073 | 这个库来自于 Google,一个不错的库。 1074 | 1075 | 所以我们就构成了开发所需的两部分基础。 1076 | 1077 | ##Android## 1078 | 关于 Android 开发环境的配置这个网上有,最简单的办法是直接下载一个 Android Studio。 1079 | 1080 | 下面只是列举一些代码以及可能会遇到的问题。 1081 | 1082 | ###Android 4.0 Web问题### 1083 | 1084 | 如在源码里看到的那样, 1085 | 1086 | StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 1087 | .detectDiskReads() 1088 | .detectDiskWrites() 1089 | .detectNetwork() // or .detectAll() for all detectable problems 1090 | .penaltyLog() 1091 | .build()); 1092 | StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 1093 | .detectLeakedSqlLiteObjects() 1094 | .detectLeakedClosableObjects() 1095 | .penaltyLog() 1096 | .penaltyDeath() 1097 | .build()); 1098 | 1099 | 这部分用于Android 4.0的网络,2.*可以不需要。 1100 | 1101 | ###JSONObject 以及 JSONArray### 1102 | 1103 | 会产生下面这些代码的原因是下载下来的JSON数据是类似于二维数组,所以需要转换,下面的代码有些丑陋,但是可能工作得很好。 1104 | 1105 | JSONArray jArray = new JSONArray(client.getResponse()); 1106 | JSONObject jObj=jArray.getJSONObject(0); 1107 | 1108 | ###handlerData 的由来### 1109 | 1110 | public GsonBuilder gsonb = new GsonBuilder(); 1111 | public Gson gson = gsonb.create(); 1112 | typePhoData phoData; 1113 | 1114 | public handlerData(JSONObject jObj){ 1115 | phoData = gson.fromJson(jObj.toString(), 1116 | typePhoData.class); 1117 | } 1118 | public int get_id(){ 1119 | return phoData.id; 1120 | } 1121 | 1122 | public double get_sensors1(){ 1123 | return phoData.sensors1; 1124 | } 1125 | 1126 | public double get_sensors2(){ 1127 | return phoData.sensors2; 1128 | } 1129 | 1130 | public double get_temperature(){ 1131 | return phoData.temperature; 1132 | } 1133 | 1134 | public int get_led1(){ 1135 | return phoData.led1; 1136 | } 1137 | 1138 | public class typePhoData{ 1139 | public int led1; 1140 | public double temperature; 1141 | public double sensors1; 1142 | public double sensors2; 1143 | public int id; 1144 | } 1145 | 1146 | 在某些程度上,我好像将这些代码给复杂化了,直接放在原文里可能会好一点,不过造成这种错觉的主要原因可能是受 Java 语言的影响,不过从软件工程的某些角度上来说,这样应该会好一点。 1147 | 其他的: 1148 | 1149 | - typePhoData 的命名可能有些不尽人意,但是暂时没有想到一个合适的 1150 | - 用过几天 Ruby 后,似乎这个不算是一个问题 1151 | - 如果你要修改的话,相信这个接口也不难,也许比原来的简单,前提是你看过原来的代码。 1152 | 1153 | 整理完闭。 1154 | 1155 | ###REST POST### 1156 | 1157 | 如果你需要 POST,又懒得去看原文,那么 POST 代码在下面,只是因为我暂时没有时间去研究 Android 里面的这些,以及怎样继续这个项目,因为最小的话,似乎已经不再需要添加任何东西了。 1158 | 1159 | 1160 | RestClient clientPost = new RestClient(url); 1161 | clientPost.AddParam("temperature", "23.1"); 1162 | clientPost.AddParam("led", "true"); 1163 | clientPost.AddParam("title", "from android"); 1164 | clientPost.AddParam("more", "nEW tESET"); 1165 | try { 1166 | clientPost.Execute(RequestMethod.POST); 1167 | if(client.getResponseCode()!=200){ 1168 | vshow.setText(clientPost.getErrorMessage()); 1169 | } 1170 | String response2 = clientPost.getResponse(); 1171 | vshow.setText(response2.toString()); 1172 | } catch (Exception e) { 1173 | vshow.setText(e.toString()); 1174 | } 1175 | 1176 | 大致上是类似的,注意一下都是字符就行了。 1177 | 1178 | [comm]:http://www.phodal.com/blog/bare-minimum-iot-system-date-commucation/ 1179 | [2]:http://lukencode.com/2010/04/27/calling-web-services-in-android-using-httpclient/ 1180 | [3]:http://github.com/gmszone/Home-Anywhere 1181 | --------------------------------------------------------------------------------