97_PiXtendV2.pm 64 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008
  1. ##############################################################################
  2. # $Id: 97_PiXtendV2.pm 17149 2018-08-16 15:06:50Z PiXtend $
  3. # 97_PiXtendV2.pm
  4. #
  5. # Modul to control PiXtendV2
  6. #
  7. # define <name> PiXtendV2 <optional>
  8. #
  9. ##############################################################################
  10. #
  11. # This file is part of the PiXtend(R) Project.
  12. #
  13. # For more information about PiXtend(R) and this program,
  14. # see <http://www.PiXtend.de> or <http://www.PiXtend.com>
  15. #
  16. # Copyright (C) 2014-2018 Tobias Sperling
  17. # Qube Solutions GmbH, Arbachtalstr. 6
  18. # 72800 Eningen, Germany
  19. #
  20. # This program is free software: you can redistribute it and/or modify
  21. # it under the terms of the GNU General Public License as published by
  22. # the Free Software Foundation, either version 3 of the License, or
  23. # (at your option) any later version.
  24. #
  25. # This program is distributed in the hope that it will be useful,
  26. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  27. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  28. # GNU General Public License for more details.
  29. #
  30. # You should have received a copy of the GNU General Public License
  31. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  32. #
  33. ##############################################################################
  34. package main;
  35. use strict;
  36. use warnings;
  37. use Time::HiRes qw(gettimeofday usleep);
  38. my $modul_ver = "1.02";
  39. #####################################
  40. # Configuration for Model -S-
  41. #####################################
  42. my @PiXtendV2S_Set = (
  43. "_JumperSettingAI0:10V,5V",
  44. "_JumperSettingAI1:10V,5V",
  45. "_GPIO0Ctrl:input,output,DHT11,DHT22",
  46. "_GPIO1Ctrl:input,output,DHT11,DHT22",
  47. "_GPIO2Ctrl:input,output,DHT11,DHT22",
  48. "_GPIO3Ctrl:input,output,DHT11,DHT22",
  49. "_GPIOPullupsEnable:no,yes",
  50. "_WatchdogEnable:disabled,125ms,1s,8s",
  51. "_StateLEDDisable:no,yes",
  52. "Reset:noArg",
  53. "SafeState:noArg",
  54. "RetainCopy:off,on",
  55. "RetainEnable:off,on",
  56. "DigitalDebounce01:textField",
  57. "DigitalDebounce23:textField",
  58. "DigitalDebounce45:textField",
  59. "DigitalDebounce67:textField",
  60. "DigitalOut0:on,off,toggle",
  61. "DigitalOut1:on,off,toggle",
  62. "DigitalOut2:on,off,toggle",
  63. "DigitalOut3:on,off,toggle",
  64. "RelayOut0:on,off,toggle",
  65. "RelayOut1:on,off,toggle",
  66. "RelayOut2:on,off,toggle",
  67. "RelayOut3:on,off,toggle",
  68. "GPIOOut0:on,off,toggle",
  69. "GPIOOut1:on,off,toggle",
  70. "GPIOOut2:on,off,toggle",
  71. "GPIOOut3:on,off,toggle",
  72. "GPIODebounce01:textField",
  73. "GPIODebounce23:textField",
  74. "PWM0Ctrl0:textField",
  75. "PWM0Ctrl1:slider,0,1,65535",
  76. "PWM0A:slider,0,1,65535",
  77. "PWM0B:slider,0,1,65535",
  78. "PWM1Ctrl0:textField",
  79. "PWM1Ctrl1:slider,0,1,255",
  80. "PWM1A:slider,0,1,255",
  81. "PWM1B:slider,0,1,255",
  82. "AnalogOut0:slider,0.00,0.01,10.00,1",
  83. "AnalogOut1:slider,0.00,0.01,10.00,1",
  84. "RetainDataOut:textField"
  85. );
  86. my @PiXtendV2S_Get = (
  87. "Version:noArg",
  88. "SysState:noArg",
  89. "UCState:noArg",
  90. "UCWarnings:noArg",
  91. "DigitalIn0:noArg",
  92. "DigitalIn1:noArg",
  93. "DigitalIn2:noArg",
  94. "DigitalIn3:noArg",
  95. "DigitalIn4:noArg",
  96. "DigitalIn5:noArg",
  97. "DigitalIn6:noArg",
  98. "DigitalIn7:noArg",
  99. "AnalogIn0:noArg",
  100. "AnalogIn1:noArg",
  101. "GPIOIn0:noArg",
  102. "GPIOIn1:noArg",
  103. "GPIOIn2:noArg",
  104. "GPIOIn3:noArg",
  105. "Sensor0:temperature,humidity",
  106. "Sensor1:temperature,humidity",
  107. "Sensor2:temperature,humidity",
  108. "Sensor3:temperature,humidity",
  109. "RetainDataIn:textField"
  110. );
  111. sub BufferWrite_S($$) {
  112. my ($buffer, $hash) = @_;
  113. if($hash->{DataOut}{DigitalDebounce01}) {$buffer->[9] = ($hash->{DataOut}{DigitalDebounce01});}
  114. if($hash->{DataOut}{DigitalDebounce23}) {$buffer->[10] = ($hash->{DataOut}{DigitalDebounce23});}
  115. if($hash->{DataOut}{DigitalDebounce45}) {$buffer->[11] = ($hash->{DataOut}{DigitalDebounce45});}
  116. if($hash->{DataOut}{DigitalDebounce67}) {$buffer->[12] = ($hash->{DataOut}{DigitalDebounce67});}
  117. if($hash->{DataOut}{DigitalOut}) {$buffer->[13] = ($hash->{DataOut}{DigitalOut});}
  118. if($hash->{DataOut}{RelayOut}) {$buffer->[14] = ($hash->{DataOut}{RelayOut});}
  119. if($hash->{DataOut}{GPIOCtrl0}) {$buffer->[15] = ($hash->{DataOut}{GPIOCtrl0});}
  120. if($hash->{DataOut}{GPIOOut}) {$buffer->[16] = ($hash->{DataOut}{GPIOOut});}
  121. if($hash->{DataOut}{GPIODebounce01}) {$buffer->[17] = ($hash->{DataOut}{GPIODebounce01});}
  122. if($hash->{DataOut}{GPIODebounce23}) {$buffer->[18] = ($hash->{DataOut}{GPIODebounce23});}
  123. if($hash->{DataOut}{PWMCtrl00}) {$buffer->[19] = ($hash->{DataOut}{PWMCtrl00});}
  124. if($hash->{DataOut}{PWMCtrl01}) {$buffer->[20] = (($hash->{DataOut}{PWMCtrl01}) & 0xFF);
  125. $buffer->[21] = (($hash->{DataOut}{PWMCtrl01}) >> 8);}
  126. if($hash->{DataOut}{PWM0a}) {$buffer->[22] = (($hash->{DataOut}{PWM0a}) & 0xFF);
  127. $buffer->[23] = (($hash->{DataOut}{PWM0a}) >> 8);}
  128. if($hash->{DataOut}{PWM0b}) {$buffer->[24] = (($hash->{DataOut}{PWM0b}) & 0xFF);
  129. $buffer->[25] = (($hash->{DataOut}{PWM0b}) >> 8);}
  130. if($hash->{DataOut}{PWMCtrl10}) {$buffer->[26] = ($hash->{DataOut}{PWMCtrl10});}
  131. if($hash->{DataOut}{PWMCtrl11}) {$buffer->[27] = (($hash->{DataOut}{PWMCtrl11}) & 0xFF);
  132. $buffer->[28] = (($hash->{DataOut}{PWMCtrl11}) >> 8);}
  133. if($hash->{DataOut}{PWM1a}) {$buffer->[29] = (($hash->{DataOut}{PWM1a}) & 0xFF);
  134. $buffer->[30] = (($hash->{DataOut}{PWM1a}) >> 8);}
  135. if($hash->{DataOut}{PWM1b}) {$buffer->[31] = (($hash->{DataOut}{PWM1b}) & 0xFF);
  136. $buffer->[32] = (($hash->{DataOut}{PWM1b}) >> 8);}
  137. for(my $i=0; $i < ($hash->{RetainSize}); $i++){
  138. if($hash->{DataOut}{"RetainDataOut".$i}) {$buffer->[33+$i] = ($hash->{DataOut}{"RetainDataOut".$i});}
  139. }
  140. }
  141. sub BufferRead_S($$) {
  142. my ($buffer, $hash) = @_;
  143. my $str;
  144. readingsBeginUpdate($hash);
  145. readingsBulkUpdateIfChanged($hash, "Firmware", $buffer->[0], 0);
  146. readingsBulkUpdateIfChanged($hash, "Hardware", $buffer->[1], 0);
  147. readingsBulkUpdateIfChanged($hash, "Model", pack("C",$buffer->[2]), 0);
  148. readingsBulkUpdateIfChanged($hash, "UCState", $buffer->[3], 1);
  149. readingsBulkUpdateIfChanged($hash, "UCWarnings", $buffer->[4], 1);
  150. #DigitalIn
  151. for(my $i=0; $i < 8; $i++){
  152. if($buffer->[9] & (1<<$i)) { readingsBulkUpdateIfChanged($hash, "DigitalIn$i", "on", 1);}
  153. else { readingsBulkUpdateIfChanged($hash, "DigitalIn$i", "off", 1);}
  154. }
  155. #AnalogIn
  156. $str = sprintf("%.2f", (($buffer->[10] | ($buffer->[11] << 8))*($hash->{DataOut}{JumperAI0})/1024));
  157. readingsBulkUpdateIfChanged($hash, "AnalogIn0", $str, 1);
  158. $str = sprintf("%.2f", (($buffer->[12] | ($buffer->[13] << 8))*($hash->{DataOut}{JumperAI1})/1024));
  159. readingsBulkUpdateIfChanged($hash, "AnalogIn1", $str, 1);
  160. #GPIOIn
  161. for(my $i=0; $i < 4; $i++){
  162. if($buffer->[14] & (1<<$i)) { readingsBulkUpdateIfChanged($hash, "GPIOIn$i", "on", 1);}
  163. else { readingsBulkUpdateIfChanged($hash, "GPIOIn$i", "off", 1);}
  164. }
  165. #DHTs
  166. for(my $i=0; $i < 4; $i++){
  167. my $temp = ($buffer->[15+(4*$i)] | ($buffer->[16+(4*$i)] << 8));
  168. my $humi = ($buffer->[17+(4*$i)] | ($buffer->[18+(4*$i)] << 8));
  169. if($temp == 65535 && $humi == 65535)
  170. {
  171. $temp = "Sensor not connected";
  172. $humi = $temp;
  173. }
  174. else
  175. {
  176. if($hash->{DataOut}{"GPIO".$i."DHT"})
  177. {
  178. if(($hash->{DataOut}{"GPIO".$i."DHT"}) eq "dht11")
  179. {
  180. $temp = sprintf("%.1f", ($temp/256));
  181. $humi = sprintf("%.1f", ($humi/256));
  182. }
  183. elsif(($hash->{DataOut}{"GPIO".$i."DHT"}) eq "dht22")
  184. {
  185. if($temp & (1<<15))
  186. {
  187. $temp &= ~(1<<15);
  188. $temp /= (-10);
  189. }
  190. else
  191. {
  192. $temp /= 10;
  193. }
  194. $temp = sprintf("%.1f", $temp);
  195. $humi = sprintf("%.1f", ($humi/10));
  196. }
  197. }
  198. else
  199. {
  200. $temp = "Function not enabled";
  201. $humi = $temp;
  202. }
  203. }
  204. readingsBulkUpdateIfChanged($hash, "Sensor".$i."T", $temp, 1);
  205. readingsBulkUpdateIfChanged($hash, "Sensor".$i."H", $humi, 1);
  206. }
  207. $str = "";
  208. for(my $i=0; $i < ($hash->{RetainSize}); $i++){
  209. $str .= $buffer->[33+$i]." ";
  210. }
  211. readingsBulkUpdateIfChanged($hash, "RetainDataIn", $str, 1);
  212. readingsEndUpdate($hash, 1);
  213. }
  214. #####################################
  215. # Configuration for Model -L-
  216. #####################################
  217. my @PiXtendV2L_Set = (
  218. "_JumperSettingAI0:10V,5V",
  219. "_JumperSettingAI1:10V,5V",
  220. "_JumperSettingAI2:10V,5V",
  221. "_JumperSettingAI3:10V,5V",
  222. "_GPIO0Ctrl:input,output,DHT11,DHT22",
  223. "_GPIO1Ctrl:input,output,DHT11,DHT22",
  224. "_GPIO2Ctrl:input,output,DHT11,DHT22",
  225. "_GPIO3Ctrl:input,output,DHT11,DHT22",
  226. "_GPIOPullupsEnable:no,yes",
  227. "_WatchdogEnable:disabled,125ms,1s,8s",
  228. "_StateLEDDisable:no,yes",
  229. "Reset:noArg",
  230. "SafeState:noArg",
  231. "RetainCopy:off,on",
  232. "RetainEnable:off,on",
  233. "DigitalDebounce01:textField",
  234. "DigitalDebounce23:textField",
  235. "DigitalDebounce45:textField",
  236. "DigitalDebounce67:textField",
  237. "DigitalDebounce89:textField",
  238. "DigitalDebounce1011:textField",
  239. "DigitalDebounce1213:textField",
  240. "DigitalDebounce1415:textField",
  241. "DigitalOut0:on,off,toggle",
  242. "DigitalOut1:on,off,toggle",
  243. "DigitalOut2:on,off,toggle",
  244. "DigitalOut3:on,off,toggle",
  245. "DigitalOut4:on,off,toggle",
  246. "DigitalOut5:on,off,toggle",
  247. "DigitalOut6:on,off,toggle",
  248. "DigitalOut7:on,off,toggle",
  249. "DigitalOut8:on,off,toggle",
  250. "DigitalOut9:on,off,toggle",
  251. "DigitalOut10:on,off,toggle",
  252. "DigitalOut11:on,off,toggle",
  253. "RelayOut0:on,off,toggle",
  254. "RelayOut1:on,off,toggle",
  255. "RelayOut2:on,off,toggle",
  256. "RelayOut3:on,off,toggle",
  257. "GPIOOut0:on,off,toggle",
  258. "GPIOOut1:on,off,toggle",
  259. "GPIOOut2:on,off,toggle",
  260. "GPIOOut3:on,off,toggle",
  261. "GPIODebounce01:textField",
  262. "GPIODebounce23:textField",
  263. "PWM0Ctrl0:textField",
  264. "PWM0Ctrl1:slider,0,1,65535",
  265. "PWM0A:slider,0,1,65535",
  266. "PWM0B:slider,0,1,65535",
  267. "PWM1Ctrl0:textField",
  268. "PWM1Ctrl1:slider,0,1,65535",
  269. "PWM1A:slider,0,1,65535",
  270. "PWM1B:slider,0,1,65535",
  271. "PWM2Ctrl0:textField",
  272. "PWM2Ctrl1:slider,0,1,65535",
  273. "PWM2A:slider,0,1,65535",
  274. "PWM2B:slider,0,1,65535",
  275. "AnalogOut0:slider,0.00,0.01,10.00,1",
  276. "AnalogOut1:slider,0.00,0.01,10.00,1",
  277. "RetainDataOut:textField"
  278. );
  279. my @PiXtendV2L_Get = (
  280. "Version:noArg",
  281. "SysState:noArg",
  282. "UCState:noArg",
  283. "UCWarnings:noArg",
  284. "DigitalIn0:noArg",
  285. "DigitalIn1:noArg",
  286. "DigitalIn2:noArg",
  287. "DigitalIn3:noArg",
  288. "DigitalIn4:noArg",
  289. "DigitalIn5:noArg",
  290. "DigitalIn6:noArg",
  291. "DigitalIn7:noArg",
  292. "DigitalIn8:noArg",
  293. "DigitalIn9:noArg",
  294. "DigitalIn10:noArg",
  295. "DigitalIn11:noArg",
  296. "DigitalIn12:noArg",
  297. "DigitalIn13:noArg",
  298. "DigitalIn14:noArg",
  299. "DigitalIn15:noArg",
  300. "AnalogIn0:noArg",
  301. "AnalogIn1:noArg",
  302. "AnalogIn2:noArg",
  303. "AnalogIn3:noArg",
  304. "AnalogIn4:noArg",
  305. "AnalogIn5:noArg",
  306. "GPIOIn0:noArg",
  307. "GPIOIn1:noArg",
  308. "GPIOIn2:noArg",
  309. "GPIOIn3:noArg",
  310. "Sensor0:temperature,humidity",
  311. "Sensor1:temperature,humidity",
  312. "Sensor2:temperature,humidity",
  313. "Sensor3:temperature,humidity",
  314. "RetainDataIn:textField"
  315. );
  316. sub BufferWrite_L($$) {
  317. my ($buffer, $hash) = @_;
  318. if($hash->{DataOut}{DigitalDebounce01}) {$buffer->[9] = ($hash->{DataOut}{DigitalDebounce01});}
  319. if($hash->{DataOut}{DigitalDebounce23}) {$buffer->[10] = ($hash->{DataOut}{DigitalDebounce23});}
  320. if($hash->{DataOut}{DigitalDebounce45}) {$buffer->[11] = ($hash->{DataOut}{DigitalDebounce45});}
  321. if($hash->{DataOut}{DigitalDebounce67}) {$buffer->[12] = ($hash->{DataOut}{DigitalDebounce67});}
  322. if($hash->{DataOut}{DigitalDebounce89}) {$buffer->[13] = ($hash->{DataOut}{DigitalDebounce89});}
  323. if($hash->{DataOut}{DigitalDebounce1011}) {$buffer->[14] = ($hash->{DataOut}{DigitalDebounce1011});}
  324. if($hash->{DataOut}{DigitalDebounce1213}) {$buffer->[15] = ($hash->{DataOut}{DigitalDebounce1213});}
  325. if($hash->{DataOut}{DigitalDebounce1415}) {$buffer->[16] = ($hash->{DataOut}{DigitalDebounce1415});}
  326. if($hash->{DataOut}{DigitalOut}) {$buffer->[17] = (($hash->{DataOut}{DigitalOut}) & 0xFF);
  327. $buffer->[18] = (($hash->{DataOut}{DigitalOut}) >> 8);}
  328. if($hash->{DataOut}{RelayOut}) {$buffer->[19] = ($hash->{DataOut}{RelayOut});}
  329. if($hash->{DataOut}{GPIOCtrl0}) {$buffer->[20] = ($hash->{DataOut}{GPIOCtrl0});}
  330. if($hash->{DataOut}{GPIOOut}) {$buffer->[21] = ($hash->{DataOut}{GPIOOut});}
  331. if($hash->{DataOut}{GPIODebounce01}) {$buffer->[22] = ($hash->{DataOut}{GPIODebounce01});}
  332. if($hash->{DataOut}{GPIODebounce23}) {$buffer->[23] = ($hash->{DataOut}{GPIODebounce23});}
  333. if($hash->{DataOut}{PWMCtrl00}) {$buffer->[24] = ($hash->{DataOut}{PWMCtrl00});}
  334. if($hash->{DataOut}{PWMCtrl01}) {$buffer->[25] = (($hash->{DataOut}{PWMCtrl01}) & 0xFF);
  335. $buffer->[26] = (($hash->{DataOut}{PWMCtrl01}) >> 8);}
  336. if($hash->{DataOut}{PWM0a}) {$buffer->[27] = (($hash->{DataOut}{PWM0a}) & 0xFF);
  337. $buffer->[28] = (($hash->{DataOut}{PWM0a}) >> 8);}
  338. if($hash->{DataOut}{PWM0b}) {$buffer->[29] = (($hash->{DataOut}{PWM0b}) & 0xFF);
  339. $buffer->[30] = (($hash->{DataOut}{PWM0b}) >> 8);}
  340. if($hash->{DataOut}{PWMCtrl10}) {$buffer->[31] = ($hash->{DataOut}{PWMCtrl10});}
  341. if($hash->{DataOut}{PWMCtrl11}) {$buffer->[32] = (($hash->{DataOut}{PWMCtrl11}) & 0xFF);
  342. $buffer->[33] = (($hash->{DataOut}{PWMCtrl11}) >> 8);}
  343. if($hash->{DataOut}{PWM1a}) {$buffer->[34] = (($hash->{DataOut}{PWM1a}) & 0xFF);
  344. $buffer->[35] = (($hash->{DataOut}{PWM1a}) >> 8);}
  345. if($hash->{DataOut}{PWM1b}) {$buffer->[36] = (($hash->{DataOut}{PWM1b}) & 0xFF);
  346. $buffer->[37] = (($hash->{DataOut}{PWM1b}) >> 8);}
  347. if($hash->{DataOut}{PWMCtrl20}) {$buffer->[38] = ($hash->{DataOut}{PWMCtrl20});}
  348. if($hash->{DataOut}{PWMCtrl21}) {$buffer->[39] = (($hash->{DataOut}{PWMCtrl21}) & 0xFF);
  349. $buffer->[40] = (($hash->{DataOut}{PWMCtrl21}) >> 8);}
  350. if($hash->{DataOut}{PWM2a}) {$buffer->[41] = (($hash->{DataOut}{PWM2a}) & 0xFF);
  351. $buffer->[42] = (($hash->{DataOut}{PWM2a}) >> 8);}
  352. if($hash->{DataOut}{PWM2b}) {$buffer->[43] = (($hash->{DataOut}{PWM2b}) & 0xFF);
  353. $buffer->[44] = (($hash->{DataOut}{PWM2b}) >> 8);}
  354. for(my $i=0; $i < ($hash->{RetainSize}); $i++){
  355. if($hash->{DataOut}{"RetainDataOut".$i}) {$buffer->[45+$i] = ($hash->{DataOut}{"RetainDataOut".$i});}
  356. }
  357. }
  358. sub BufferRead_L($$) {
  359. my ($buffer, $hash) = @_;
  360. my $str;
  361. readingsBeginUpdate($hash);
  362. readingsBulkUpdateIfChanged($hash, "Firmware", $buffer->[0], 0);
  363. readingsBulkUpdateIfChanged($hash, "Hardware", $buffer->[1], 0);
  364. readingsBulkUpdateIfChanged($hash, "Model", pack("C",$buffer->[2]), 0);
  365. readingsBulkUpdateIfChanged($hash, "UCState", $buffer->[3], 1);
  366. readingsBulkUpdateIfChanged($hash, "UCWarnings", $buffer->[4], 1);
  367. #DigitalIn
  368. for(my $i=0; $i < 8; $i++){
  369. if($buffer->[9] & (1<<$i)) { readingsBulkUpdateIfChanged($hash, "DigitalIn$i", "on", 1);}
  370. else { readingsBulkUpdateIfChanged($hash, "DigitalIn$i", "off", 1);}
  371. }
  372. for(my $i=8; $i < 16; $i++){
  373. if($buffer->[10] & (1<<($i-8))) { readingsBulkUpdateIfChanged($hash, "DigitalIn$i", "on", 1);}
  374. else { readingsBulkUpdateIfChanged($hash, "DigitalIn$i", "off", 1);}
  375. }
  376. #AnalogIn
  377. $str = sprintf("%.2f", (($buffer->[11] | ($buffer->[12] << 8))*($hash->{DataOut}{JumperAI0})/1024));
  378. readingsBulkUpdateIfChanged($hash, "AnalogIn0", $str, 1);
  379. $str = sprintf("%.2f", (($buffer->[13] | ($buffer->[14] << 8))*($hash->{DataOut}{JumperAI1})/1024));
  380. readingsBulkUpdateIfChanged($hash, "AnalogIn1", $str, 1);
  381. $str = sprintf("%.2f", (($buffer->[15] | ($buffer->[16] << 8))*($hash->{DataOut}{JumperAI0})/1024));
  382. readingsBulkUpdateIfChanged($hash, "AnalogIn2", $str, 1);
  383. $str = sprintf("%.2f", (($buffer->[17] | ($buffer->[18] << 8))*($hash->{DataOut}{JumperAI1})/1024));
  384. readingsBulkUpdateIfChanged($hash, "AnalogIn3", $str, 1);
  385. $str = sprintf("%.2f", (($buffer->[19] | ($buffer->[20] << 8))*0.02015840023));
  386. readingsBulkUpdateIfChanged($hash, "AnalogIn4", $str, 1);
  387. $str = sprintf("%.2f", (($buffer->[21] | ($buffer->[22] << 8))*0.02015840023));
  388. readingsBulkUpdateIfChanged($hash, "AnalogIn5", $str, 1);
  389. #GPIOIn
  390. for(my $i=0; $i < 4; $i++){
  391. if($buffer->[23] & (1<<$i)) { readingsBulkUpdateIfChanged($hash, "GPIOIn$i", "on", 1);}
  392. else { readingsBulkUpdateIfChanged($hash, "GPIOIn$i", "off", 1);}
  393. }
  394. #DHTs
  395. for(my $i=0; $i < 4; $i++){
  396. my $temp = ($buffer->[24+(4*$i)] | ($buffer->[25+(4*$i)] << 8));
  397. my $humi = ($buffer->[26+(4*$i)] | ($buffer->[27+(4*$i)] << 8));
  398. if($temp == 65535 && $humi == 65535)
  399. {
  400. $temp = "Sensor not connected";
  401. $humi = $temp;
  402. }
  403. else
  404. {
  405. if($hash->{DataOut}{"GPIO".$i."DHT"})
  406. {
  407. if(($hash->{DataOut}{"GPIO".$i."DHT"}) eq "dht11")
  408. {
  409. $temp = sprintf("%.1f", ($temp/256));
  410. $humi = sprintf("%.1f", ($humi/256));
  411. }
  412. elsif(($hash->{DataOut}{"GPIO".$i."DHT"}) eq "dht22")
  413. {
  414. if($temp & (1<<15))
  415. {
  416. $temp &= ~(1<<15);
  417. $temp /= (-10);
  418. }
  419. else
  420. {
  421. $temp /= 10;
  422. }
  423. $temp = sprintf("%.1f", $temp);
  424. $humi = sprintf("%.1f", ($humi/10));
  425. }
  426. }
  427. else
  428. {
  429. $temp = "Function not enabled";
  430. $humi = $temp;
  431. }
  432. }
  433. readingsBulkUpdateIfChanged($hash, "Sensor".$i."T", $temp, 1);
  434. readingsBulkUpdateIfChanged($hash, "Sensor".$i."H", $humi, 1);
  435. }
  436. $str = "";
  437. for(my $i=0; $i < ($hash->{RetainSize}); $i++){
  438. $str .= $buffer->[45+$i]." ";
  439. }
  440. readingsBulkUpdateIfChanged($hash, "RetainDataIn", $str, 1);
  441. readingsEndUpdate($hash, 1);
  442. }
  443. #####################################
  444. # General Functions
  445. #####################################
  446. #####################################
  447. sub PiXtendV2_Initialize($) {
  448. my ($hash) = @_;
  449. $hash->{DefFn} = 'PiXtendV2_Define';
  450. $hash->{UndefFn} = 'PiXtendV2_Undef';
  451. $hash->{SetFn} = 'PiXtendV2_Set';
  452. $hash->{GetFn} = 'PiXtendV2_Get';
  453. $hash->{AttrFn} = 'PiXtendV2_Attr';
  454. $hash->{AttrList} = "PiXtend_GetFormat:text,value PiXtend_Parameter ".$readingFnAttributes;
  455. }
  456. #####################################
  457. sub PiXtendV2_Define($$) {
  458. my ($hash, $def) = @_;
  459. my @param = split("[ \t][ \t]*", $def);
  460. if(scalar(@param) < 2 or scalar(@param) > 3)
  461. {
  462. return "Wrong syntax: use define <name> PiXtendV2 <optional>";
  463. }
  464. eval{ require "sys/ioctl.ph" };
  465. if($@){ return "ioctl.ph is not available but needed"; }
  466. if(scalar(@param) eq 2 or $param[2] eq "S")
  467. {
  468. $hash->{Set} = \@PiXtendV2S_Set;
  469. $hash->{Get} = \@PiXtendV2S_Get;
  470. $hash->{SPI}{Write} = \&BufferWrite_S;
  471. $hash->{SPI}{Read} = \&BufferRead_S;
  472. $hash->{SPI}{Length} = 67;
  473. $hash->{SPI}{Speed} = 1100000;
  474. $hash->{SPI}{Dev0} = "/dev/spidev0.0";
  475. $hash->{SPI}{Dev1} = "/dev/spidev0.1";
  476. $hash->{SPI}{Enable} = "/sys/class/gpio/";
  477. $hash->{SPI}{Model} = 83;
  478. $hash->{RetainSize} = 32;
  479. $hash->{DataOut}{JumperAI0} = 10;
  480. $hash->{DataOut}{JumperAI1} = 10;
  481. }
  482. elsif($param[2] eq "L")
  483. {
  484. $hash->{Set} = \@PiXtendV2L_Set;
  485. $hash->{Get} = \@PiXtendV2L_Get;
  486. $hash->{SPI}{Write} = \&BufferWrite_L;
  487. $hash->{SPI}{Read} = \&BufferRead_L;
  488. $hash->{SPI}{Length} = 111;
  489. $hash->{SPI}{Speed} = 1100000;
  490. $hash->{SPI}{Dev0} = "/dev/spidev0.0";
  491. $hash->{SPI}{Dev1} = "/dev/spidev0.1";
  492. $hash->{SPI}{Enable} = "/sys/class/gpio/";
  493. $hash->{SPI}{Model} = 76;
  494. $hash->{RetainSize} = 64;
  495. $hash->{DataOut}{JumperAI0} = 10;
  496. $hash->{DataOut}{JumperAI1} = 10;
  497. $hash->{DataOut}{JumperAI2} = 10;
  498. $hash->{DataOut}{JumperAI3} = 10;
  499. $hash->{DataIn}{UnitAI4} = "mA";
  500. $hash->{DataIn}{UnitAI5} = "mA";
  501. }
  502. else
  503. {
  504. return "Parameter <$param[2]> not supported";
  505. }
  506. my $ret = undef;
  507. $ret = Check_Device($hash->{SPI}{Dev0});
  508. if($ret){ return "$ret"; }
  509. $ret = Check_Device($hash->{SPI}{Enable}."export");
  510. if($ret){ return "$ret"; }
  511. $hash->{STATE} = "defined";
  512. SPI_Transfer($hash);
  513. $attr{$hash->{NAME}}{icon} = 'RPi';
  514. $attr{$hash->{NAME}}{devStateIcon} = 'defined:rc_YELLOW active:rc_GREEN error:rc_RED';
  515. return undef;
  516. }
  517. #####################################
  518. sub PiXtendV2_Undef($$) {
  519. my ($hash, $arg) = @_;
  520. RemoveInternalTimer($hash, "SPI_Transfer");
  521. SPI_Disable($hash);
  522. UC_Reset($hash);
  523. return undef;
  524. }
  525. #####################################
  526. sub PiXtendV2_Attr ($$$$)
  527. {
  528. my ( $cmd, $name, $attrName, $attrValue ) = @_;
  529. my $hash = $defs{$name};
  530. if($cmd eq "set")
  531. {
  532. #GetFormat
  533. if($attrName eq "PiXtend_GetFormat")
  534. {
  535. if($attrValue eq "text" or $attrValue eq "value")
  536. {
  537. }
  538. else
  539. {
  540. return "Unknown value $attrValue for $attrName, choose one of: text, value";
  541. }
  542. }
  543. #Parameter
  544. if($attrName eq "PiXtend_Parameter")
  545. {
  546. my @coms = split(/ /, $attrValue);
  547. for(my $i=0; $i < @coms; $i++)
  548. {
  549. my @param = split(/:/, $coms[$i]);
  550. if(index($param[0], "_") != -1)
  551. {
  552. my $ret = PiXtendV2_Set($hash, $name, $param[0], $param[1]);
  553. if(defined($ret))
  554. {
  555. return $ret;
  556. }
  557. }
  558. else
  559. {
  560. return "Unknown command $param[0]. Only set commands with a leading '_' sign can be used.";
  561. }
  562. }
  563. }
  564. }
  565. return undef;
  566. }
  567. #####################################
  568. sub PiXtendV2_Get($$@) {
  569. my ($hash, $name, $cmd, @param) = @_;
  570. my @InList = @{$hash->{Get}};
  571. foreach my $c (@InList)
  572. {
  573. if(index($c, ":") != -1)
  574. {
  575. $c = substr($c,0,index($c,":"));
  576. }
  577. $c = lc($c);
  578. }
  579. $cmd = lc($cmd);
  580. if(grep($_ eq $cmd, @InList) > 0)
  581. {
  582. my $str = undef;
  583. my $val = undef;
  584. #Version
  585. if($cmd eq "version")
  586. {
  587. $val = ReadingsVal($name, "Model", "?")."-".ReadingsVal($name, "Hardware", "?")."-".ReadingsVal($name, "Firmware", "?");
  588. $str = "FHEM-Modul-Version [$modul_ver], PiXtend-Version [$val]";
  589. }
  590. #SysState
  591. elsif($cmd eq "sysstate")
  592. {
  593. $val = $hash->{STATE};
  594. $str = "System state is [$val]";
  595. }
  596. #UCState
  597. elsif($cmd eq "ucstate")
  598. {
  599. $val = ReadingsVal($name, "UCState", "?");
  600. $str = "Microcontroller state is [$val]";
  601. }
  602. #UCWarnings
  603. elsif($cmd eq "ucwarnings")
  604. {
  605. $val = ReadingsVal($name, "UCWarnings", "?");
  606. $str = "Microcontroller warnings are [$val]";
  607. }
  608. #DigitalIn
  609. elsif(index($cmd, "digitalin") != -1)
  610. {
  611. $cmd =~ s/digitalin//;
  612. $val = ReadingsVal($name, "DigitalIn$cmd", undef);
  613. if(defined($val))
  614. {
  615. $str = "DigitalIn$cmd is [$val]";
  616. }
  617. }
  618. #AnalogIn
  619. elsif(index($cmd, "analogin") != -1)
  620. {
  621. $cmd =~ s/analogin//;
  622. $val = ReadingsVal($name, "AnalogIn$cmd", undef);
  623. if(defined($val))
  624. {
  625. if($hash->{DataIn}{"UnitAI$cmd"})
  626. {
  627. my $unit = $hash->{DataIn}{"UnitAI$cmd"};
  628. $str = "AnalogIn$cmd is [$val] $unit";
  629. }
  630. else
  631. {
  632. $str = "AnalogIn$cmd is [$val] V";
  633. }
  634. }
  635. }
  636. #GPIOIn
  637. elsif(index($cmd, "gpioin") != -1)
  638. {
  639. $cmd =~ s/gpioin//;
  640. $val = ReadingsVal($name, "GPIOIn$cmd", undef);
  641. if(defined($val))
  642. {
  643. $str = "GPIOIn$cmd is [$val]";
  644. }
  645. }
  646. #DHTs
  647. elsif(index($cmd, "sensor") != -1)
  648. {
  649. $cmd =~ s/sensor//;
  650. if(lc($param[0]) eq "temperature")
  651. {
  652. $val = ReadingsVal($name, "Sensor".$cmd."T", undef);
  653. if(defined($val) && index($val, "not") == -1)
  654. {
  655. $str = "For Sensor$cmd temperature is [$val] &deg;C";
  656. }
  657. elsif(index($val, "not") != -1)
  658. {
  659. $str = "$val for Sensor$cmd";
  660. }
  661. }
  662. elsif(lc($param[0]) eq "humidity")
  663. {
  664. $val = ReadingsVal($name, "Sensor".$cmd."H", undef);
  665. if(defined($val) && index($val, "not") == -1)
  666. {
  667. $str = "For Sensor$cmd humidity is [$val] %";
  668. }
  669. elsif(index($val, "not") != -1)
  670. {
  671. $str = "$val for Sensor$cmd";
  672. }
  673. }
  674. else
  675. {
  676. $val = "Unknown value $param[0] for Sensorx, choose one of: temperature, humidity";
  677. $str = $val;
  678. }
  679. }
  680. #Retain
  681. elsif($cmd eq "retaindatain")
  682. {
  683. $str = ReadingsVal($name, "RetainDataIn", undef);
  684. if(defined($str))
  685. {
  686. if(int($param[0]) >= 0 && int($param[0]) < ($hash->{RetainSize}))
  687. {
  688. my @vals = split(/ /, $str);
  689. $val = $vals[$param[0]];
  690. $str = "Value for RetainDataIn$param[0] is [$val]";
  691. }
  692. else
  693. {
  694. $val = "Unknown Index $param[0] for RetainDataIn, index must be between 0 and ($hash->{RetainSize}-1)";
  695. $str = $val;
  696. }
  697. }
  698. }
  699. if (defined($str) && defined($val))
  700. {
  701. if(AttrVal($name, "PiXtend_GetFormat", "?") eq "value")
  702. {
  703. return $val;
  704. }
  705. else
  706. {
  707. return $str;
  708. }
  709. }
  710. }
  711. else
  712. {
  713. return "Unknown argument $cmd, choose one of ". join(" ", @{$hash->{Get}});
  714. }
  715. return undef;
  716. }
  717. #####################################
  718. sub PiXtendV2_Set($$@){
  719. my ($hash, $name, $cmd, @param) = @_;
  720. my @outList = @{$hash->{Set}};
  721. foreach my $c (@outList)
  722. {
  723. if(index($c, ":") != -1)
  724. {
  725. $c = substr($c,0,index($c,":"));
  726. }
  727. $c = lc($c);
  728. }
  729. $cmd = lc($cmd);
  730. if(grep($_ eq $cmd, @outList) > 0)
  731. {
  732. #Reset
  733. if(index($cmd, "reset") != -1)
  734. {
  735. UC_Reset($hash);
  736. }
  737. #Parameter
  738. ###############
  739. elsif(index($cmd, "_jumpersettingai") != -1)
  740. {
  741. $cmd =~ s/_jumpersettingai//;
  742. if(lc($param[0]) eq "10v")
  743. {
  744. ($hash->{DataOut}{"JumperAI".$cmd}) = 10;
  745. }
  746. elsif(lc($param[0]) eq "5v")
  747. {
  748. ($hash->{DataOut}{"JumperAI".$cmd}) = 5;
  749. }
  750. else
  751. {
  752. return "Unknown value $param[0] for JumperSetting, choose one of: 10V, 5V";
  753. }
  754. }
  755. elsif(index($cmd, "_gpio") != -1 and index($cmd, "ctrl") != -1)
  756. {
  757. $cmd =~ s/_gpio//;
  758. $cmd =~ s/ctrl//;
  759. my $no = 0;
  760. if($cmd < 4){$no = 0;}
  761. elsif($cmd < 8){$no = 1; $cmd -= 4;}
  762. else{ return "Unknown number for GPIOxCtrl";}
  763. if(lc($param[0]) eq "input")
  764. {
  765. ($hash->{DataOut}{"GPIOCtrl".$no}) &= ~ (1<<($cmd+4));
  766. ($hash->{DataOut}{"GPIOCtrl".$no}) &= ~(1<<$cmd);
  767. ($hash->{DataOut}{"GPIO".($no*4+$cmd)."DHT"}) = undef;
  768. }
  769. elsif(lc($param[0]) eq "output")
  770. {
  771. ($hash->{DataOut}{"GPIOCtrl".$no}) &= ~ (1<<($cmd+4));
  772. ($hash->{DataOut}{"GPIOCtrl".$no}) |= (1<<$cmd);
  773. ($hash->{DataOut}{"GPIO".($no*4+$cmd)."DHT"}) = undef;
  774. }
  775. elsif(lc($param[0]) eq "dht11" or lc($param[0]) eq "dht22")
  776. {
  777. ($hash->{DataOut}{"GPIOCtrl".$no}) |= (1<<($cmd+4));
  778. ($hash->{DataOut}{"GPIO".($no*4+$cmd)."DHT"}) = lc($param[0]);
  779. }
  780. else
  781. {
  782. return "Unknown value $param[0] for GPIOxCtrl, choose one of: input, output, DHT11, DHT22";
  783. }
  784. }
  785. elsif(index($cmd, "_gpiopullupsenable") != -1)
  786. {
  787. if(lc($param[0]) eq "no")
  788. {
  789. ($hash->{DataOut}{UCCtrl1}) &= ~(1<<4);
  790. }
  791. elsif(lc($param[0]) eq "yes")
  792. {
  793. ($hash->{DataOut}{UCCtrl1}) |= (1<<4);
  794. }
  795. else
  796. {
  797. return "Unknown value $param[0] for GPIOPullupsEnable, choose one of: no, yes";
  798. }
  799. }
  800. elsif(index($cmd, "_watchdogenable") != -1)
  801. {
  802. if(lc($param[0]) eq "disabled")
  803. {
  804. ($hash->{DataOut}{UCCtrl0}) = (($hash->{DataOut}{UCCtrl0}) & 0xF0) | 0;
  805. }
  806. elsif(lc($param[0]) eq "125ms")
  807. {
  808. ($hash->{DataOut}{UCCtrl0}) = (($hash->{DataOut}{UCCtrl0}) & 0xF0) | 4;
  809. }
  810. elsif(lc($param[0]) eq "1s")
  811. {
  812. ($hash->{DataOut}{UCCtrl0}) = (($hash->{DataOut}{UCCtrl0}) & 0xF0) | 7;
  813. }
  814. elsif(lc($param[0]) eq "8s")
  815. {
  816. ($hash->{DataOut}{UCCtrl0}) = (($hash->{DataOut}{UCCtrl0}) & 0xF0) | 10;
  817. }
  818. else
  819. {
  820. return "Unknown value $param[0] for WatchdogEnable, choose one of: disabled, 125ms, 1s, 8s";
  821. }
  822. }
  823. elsif(index($cmd, "_stateleddisable") != -1)
  824. {
  825. if(lc($param[0]) eq "no")
  826. {
  827. ($hash->{DataOut}{UCCtrl1}) &= ~(1<<3);
  828. }
  829. elsif(lc($param[0]) eq "yes")
  830. {
  831. ($hash->{DataOut}{UCCtrl1}) |= (1<<3);
  832. }
  833. else
  834. {
  835. return "Unknown value $param[0] for StateLEDDisable, choose one of: no, yes";
  836. }
  837. }
  838. elsif(index($cmd, "safestate") != -1)
  839. {
  840. ($hash->{DataOut}{UCCtrl1}) |= (1<<0);
  841. }
  842. elsif(index($cmd, "retaincopy") != -1)
  843. {
  844. if(lc($param[0]) eq "off")
  845. {
  846. ($hash->{DataOut}{UCCtrl1}) &= ~(1<<1);
  847. }
  848. elsif(lc($param[0]) eq "on")
  849. {
  850. ($hash->{DataOut}{UCCtrl1}) |= (1<<1);
  851. }
  852. else
  853. {
  854. return "Unknown value $param[0] for RetainCopy, choose one of: off, on";
  855. }
  856. }
  857. elsif(index($cmd, "retainenable") != -1)
  858. {
  859. if(lc($param[0]) eq "off")
  860. {
  861. ($hash->{DataOut}{UCCtrl1}) &= ~(1<<2);
  862. }
  863. elsif(lc($param[0]) eq "on")
  864. {
  865. ($hash->{DataOut}{UCCtrl1}) |= (1<<2);
  866. }
  867. else
  868. {
  869. return "Unknown value $param[0] for RetainEnable, choose one of: off, on";
  870. }
  871. }
  872. ###############
  873. #RelayOut
  874. elsif(index($cmd, "relayout") != -1)
  875. {
  876. $cmd =~ s/relayout//;
  877. if(lc($param[0]) eq "off")
  878. {
  879. ($hash->{DataOut}{RelayOut}) &= ~(1<<$cmd);
  880. }
  881. elsif(lc($param[0]) eq "on")
  882. {
  883. ($hash->{DataOut}{RelayOut}) |= (1<<$cmd);
  884. }
  885. elsif(lc($param[0]) eq "toggle")
  886. {
  887. ($hash->{DataOut}{RelayOut}) ^= (1<<$cmd);
  888. }
  889. else
  890. {
  891. return "Unknown value $param[0] for RelayOut, choose one of: on, off, toggle";
  892. }
  893. }
  894. #DigitalOut
  895. elsif(index($cmd, "digitalout") != -1)
  896. {
  897. $cmd =~ s/digitalout//;
  898. if(lc($param[0]) eq "off")
  899. {
  900. ($hash->{DataOut}{DigitalOut}) &= ~(1<<$cmd);
  901. }
  902. elsif(lc($param[0]) eq "on")
  903. {
  904. ($hash->{DataOut}{DigitalOut}) |= (1<<$cmd);
  905. }
  906. elsif(lc($param[0]) eq "toggle")
  907. {
  908. ($hash->{DataOut}{DigitalOut}) ^= (1<<$cmd);
  909. }
  910. else
  911. {
  912. return "Unknown value $param[0] for DigitalOutput, choose one of: on, off, toggle";
  913. }
  914. }
  915. #DigitalDebounce
  916. elsif(index($cmd, "digitaldebounce") != -1)
  917. {
  918. $cmd =~ s/digitaldebounce//;
  919. $hash->{DataOut}{"DigitalDebounce".$cmd} = Check_Range(0,255,$param[0]);
  920. }
  921. #GPIODebounce
  922. elsif(index($cmd, "gpiodebounce") != -1)
  923. {
  924. $cmd =~ s/gpiodebounce//;
  925. $hash->{DataOut}{"GPIODebounce".$cmd} = Check_Range(0,255,$param[0]);
  926. }
  927. #GPIOOut
  928. elsif(index($cmd, "gpioout") != -1)
  929. {
  930. $cmd =~ s/gpioout//;
  931. if(lc($param[0]) eq "off")
  932. {
  933. ($hash->{DataOut}{GPIOOut}) &= ~(1<<$cmd);
  934. }
  935. elsif(lc($param[0]) eq "on")
  936. {
  937. ($hash->{DataOut}{GPIOOut}) |= (1<<$cmd);
  938. }
  939. elsif(lc($param[0]) eq "toggle")
  940. {
  941. ($hash->{DataOut}{GPIOOut}) ^= (1<<$cmd);
  942. }
  943. else
  944. {
  945. return "Unknown value $param[0] for GPIOOut, choose one of: on, off, toggle";
  946. }
  947. }
  948. #AnalogOut
  949. elsif(index($cmd, "analogout") != -1)
  950. {
  951. $cmd =~ s/analogout//;
  952. if(index($param[0], ".") != -1)
  953. {
  954. if($param[0] >= 0.00 && $param[0] <= 10.00)
  955. {
  956. DAC_Transfer($hash, ($param[0]*1023/10), $cmd);
  957. }
  958. else
  959. {
  960. return "Unknown value $param[0] for AnalogOut, choose a voltage between 0.00 and 10.00";
  961. }
  962. }
  963. else
  964. {
  965. if(int($param[0]) >= 0 && int($param[0]) <= 1023)
  966. {
  967. DAC_Transfer($hash, $param[0], $cmd);
  968. }
  969. else
  970. {
  971. return "Unknown value $param[0] for AnalogOut, choose a number between 0 and 1023";
  972. }
  973. }
  974. }
  975. #PWM
  976. elsif(index($cmd, "pwm") != -1)
  977. {
  978. $cmd =~ s/pwm//;
  979. if(index($cmd, "ctrl") != -1)
  980. {
  981. $cmd =~ s/ctrl//;
  982. $hash->{DataOut}{"PWMCtrl".$cmd} = Check_Range(0,65535,$param[0]);
  983. }
  984. elsif(index($cmd, "a") != -1 or index($cmd, "b") != -1)
  985. {
  986. $hash->{DataOut}{"PWM".$cmd} = Check_Range(0,65535,$param[0]);
  987. }
  988. else
  989. {
  990. return "Unknown command for PWM";
  991. }
  992. }
  993. #Retain
  994. elsif(index($cmd, "retaindataout") != -1)
  995. {
  996. if(@param == 2)
  997. {
  998. if(int($param[0]) < ($hash->{RetainSize}))
  999. {
  1000. if(int($param[1]) >= 0 && int($param[1]) <= 255)
  1001. {
  1002. $hash->{DataOut}{"RetainDataOut".$param[0]} = $param[1];
  1003. }
  1004. else
  1005. {
  1006. return "Unknown value $param[1] for RetainDataOut, choose a number between 0 and 255";
  1007. }
  1008. }
  1009. else
  1010. {
  1011. return "Unknown Index $param[0] for RetainDataOut, index must be between 0 and ($hash->{RetainSize}-1)";
  1012. }
  1013. }
  1014. else
  1015. {
  1016. return "Too few parameters for RetainDataOut, 2 are expected";
  1017. }
  1018. }
  1019. }
  1020. else
  1021. {
  1022. return "Unknown argument $cmd, choose one of ". join(" ", @{$hash->{Set}});
  1023. }
  1024. return undef;
  1025. }
  1026. #####################################
  1027. sub Check_Range ($$$) {
  1028. my ($min, $max, $val) = @_;
  1029. if($val < $min){return $min;}
  1030. if($val > $max){return $max;}
  1031. else{return $val;}
  1032. }
  1033. #####################################
  1034. sub Check_Device ($) {
  1035. my ($dev) = @_;
  1036. my $ret = undef;
  1037. if(-e $dev) {
  1038. if(-r $dev) {
  1039. unless(-w $dev) {
  1040. $ret = ': Error! Device not writable: '.$dev . '. Please change access rights for fhem user (sudo adduser fhem gpio; sudo adduser fhem spi; sudo reboot).';
  1041. }
  1042. } else {
  1043. $ret = ': Error! Device not readable: '.$dev . '. Please change access rights for fhem user (sudo adduser fhem gpio; sudo adduser fhem spi; sudo reboot).';
  1044. }
  1045. } else {
  1046. $ret = ': Error! Device not found: ' .$dev . '. Please change access rights for fhem user (sudo adduser fhem gpio; sudo adduser fhem spi; sudo reboot) or check if kernelmodules must be loaded.';
  1047. }
  1048. return $ret;
  1049. }
  1050. #####################################
  1051. sub SPI_GetIOCMD ($) {
  1052. my $arg = (1 << 30);
  1053. $arg |= (($_[0]*32) << 16);
  1054. $arg |= (107 << 8);
  1055. return $arg;
  1056. }
  1057. #####################################
  1058. sub calc_crc16($$$){
  1059. my ($beg, $end, $buff) = @_;
  1060. my $crc = 0xFFFF;
  1061. for(my $i=$beg; $i <= $end; $i++){
  1062. $crc ^= $$buff[$i];
  1063. for(my $k=0; $k < 8; ++$k)
  1064. {
  1065. if($crc & 1)
  1066. {
  1067. $crc = ($crc >> 1) ^ 0xA001;
  1068. }
  1069. else
  1070. {
  1071. $crc = ($crc >> 1);
  1072. }
  1073. }
  1074. }
  1075. return $crc;
  1076. }
  1077. #####################################
  1078. sub DAC_Transfer ($) {
  1079. my ($hash, $val, $chn) = @_;
  1080. $val = ($val<<2);
  1081. $val |= (1<<12);
  1082. $val |= ($chn<<15);
  1083. $val = pack("n", $val);
  1084. my $freq = $hash->{SPI}{Speed};
  1085. $freq = pack("L", $freq);
  1086. my $device = $hash->{SPI}{Dev1};
  1087. my $handler = undef;
  1088. my $ret = sysopen($handler, $device, O_RDWR);
  1089. if($ret == 1){
  1090. ioctl($handler, 0x40046b04, $freq);
  1091. syswrite($handler, $val);
  1092. close($handler);
  1093. return undef;
  1094. }
  1095. else
  1096. {
  1097. return "error";
  1098. }
  1099. }
  1100. #####################################
  1101. sub SPI_Transfer ($) {
  1102. my ($hash) = @_;
  1103. my $len = $hash->{SPI}{Length};
  1104. my $freq = $hash->{SPI}{Speed};
  1105. my $device = $hash->{SPI}{Dev0};
  1106. my $handler = undef;
  1107. my $ret = sysopen($handler, $device, O_RDWR);
  1108. if($ret == 1){
  1109. SPI_Enable($hash);
  1110. my @buffer = (0) x $len;
  1111. $buffer[0] = ($hash->{SPI}{Model});
  1112. if($hash->{DataOut}{UCCtrl0}){$buffer[2] = ($hash->{DataOut}{UCCtrl0});}
  1113. if($hash->{DataOut}{UCCtrl1}){$buffer[3] = ($hash->{DataOut}{UCCtrl1});}
  1114. ($buffer[7], $buffer[8]) = unpack("C*", pack("S", calc_crc16(0,6, \@buffer)));
  1115. $hash->{SPI}{Write}->(\@buffer, $hash);
  1116. ($buffer[$len-2], $buffer[$len-1]) = unpack("C*", pack("S", calc_crc16(9,($len-3), \@buffer)));
  1117. if($hash->{DataOut}{UCCtrl1}){($hash->{DataOut}{UCCtrl1}) &= ~(1<<0);}
  1118. my $struct;
  1119. for(my $i=0; $i < $len; $i++){
  1120. $buffer[$i] = pack("Q", $buffer[$i]);
  1121. my $ptr = unpack("L", pack("P", $buffer[$i]));
  1122. if($i == $len-1)
  1123. {
  1124. $struct .= pack("QQLLSCCL", $ptr, $ptr, 1, $freq, 10, 8, 0, 0);
  1125. }
  1126. else
  1127. {
  1128. $struct .= pack("QQLLSCCL", $ptr, $ptr, 1, $freq, 0, 8, 0, 0);
  1129. }
  1130. }
  1131. my $iocmd = SPI_GetIOCMD($len);
  1132. ioctl($handler, $iocmd, $struct);
  1133. for(my $i=0; $i < $len; $i++) {$buffer[$i] = unpack("Q", $buffer[$i]);}
  1134. if(unpack("S", pack("C2", $buffer[7], $buffer[8])) eq calc_crc16(0,6, \@buffer) and
  1135. unpack("S", pack("C2", $buffer[$len-2], $buffer[$len-1])) eq calc_crc16(9,($len-3), \@buffer))
  1136. {
  1137. if($buffer[2] eq $hash->{SPI}{Model})
  1138. {
  1139. $hash->{SPI}{Read}->(\@buffer, $hash);
  1140. $hash->{STATE} = "active";
  1141. $hash->{ErrorMsg} = "-";
  1142. }
  1143. else
  1144. {
  1145. $hash->{STATE} = "error";
  1146. $hash->{ErrorMsg} = "Wrong model selected";
  1147. }
  1148. }
  1149. else
  1150. {
  1151. $hash->{STATE} = "error";
  1152. $hash->{ErrorMsg} = "SPI-Transfer error";
  1153. }
  1154. }
  1155. else
  1156. {
  1157. $hash->{STATE} = "error";
  1158. $hash->{ErrorMsg} = "Couldn't open SPI device";
  1159. }
  1160. InternalTimer(gettimeofday()+0.1, "SPI_Transfer", $hash);
  1161. return undef;
  1162. }
  1163. #####################################
  1164. sub SPI_Enable($){
  1165. my ($hash) = @_;
  1166. my ($handler) = undef;
  1167. my $ret = sysopen($handler, $hash->{SPI}{Enable}."export", O_WRONLY);
  1168. syswrite($handler, 24);
  1169. $ret = sysopen($handler, $hash->{SPI}{Enable}."gpio24/direction", O_WRONLY);
  1170. syswrite($handler, "out", 3);
  1171. $ret = sysopen($handler, $hash->{SPI}{Enable}."gpio24/value", O_WRONLY);
  1172. syswrite($handler, "1", 1);
  1173. close($handler);
  1174. return 1;
  1175. }
  1176. #####################################
  1177. sub SPI_Disable(){
  1178. my ($hash) = @_;
  1179. my ($handler) = undef;
  1180. my $ret = sysopen($handler, $hash->{SPI}{Enable}."unexport", O_WRONLY);
  1181. syswrite($handler, 24);
  1182. close($handler);
  1183. return 1;
  1184. }
  1185. #####################################
  1186. sub UC_Reset()
  1187. {
  1188. my ($hash) = @_;
  1189. my ($handler) = undef;
  1190. my $ret = sysopen($handler, $hash->{SPI}{Enable}."export", O_WRONLY);
  1191. syswrite($handler, 23);
  1192. $ret = sysopen($handler, $hash->{SPI}{Enable}."gpio23/direction", O_WRONLY);
  1193. syswrite($handler, "out", 3);
  1194. $ret = sysopen($handler, $hash->{SPI}{Enable}."gpio23/value", O_WRONLY);
  1195. syswrite($handler, "1", 1);
  1196. usleep(1000);
  1197. $ret = sysopen($handler, $hash->{SPI}{Enable}."gpio23/value", O_WRONLY);
  1198. syswrite($handler, "0", 1);
  1199. close($handler);
  1200. return 1;
  1201. }
  1202. 1;
  1203. =pod
  1204. =item device
  1205. =item summary Allows to access the PiXtendV2 (PLC).
  1206. =item summary_DE Erm&ouml;glicht den Zugriff auf den PiXtendV2 (SPS)
  1207. =begin html
  1208. <a name="PiXtendV2"></a>
  1209. <h3>PiXtendV2</h3>
  1210. <ul>
  1211. PiXtend is a programmable logic controller (PLC) based on the Raspberry Pi.
  1212. This FHEM-module allows to access the functions of the PiXtendV2-Board through the FHEM interface.
  1213. PiXtend offers a variety of digital and analog inputs and outputs which are designed for industry standards
  1214. and safe connections and thus is ideally suited for home automation.
  1215. For more information about PiXtend(R) and this FHEM-module, see
  1216. <a href="http://www.PiXtend.de" target="_blank">www.PiXtend.de</a> or
  1217. <a href="http://www.PiXtend.com" target="_blank">www.PiXtend.com</a>.
  1218. <br><br>
  1219. <a name="PiXtendV2Define"></a>
  1220. <b>Define</b>
  1221. <ul>
  1222. <code>define &lt;name&gt; PiXtendV2 &lt;optional&gt;</code>
  1223. <br><br>
  1224. The parameter "optional" is used to determine the hardware model, e.g. S or L. If the parameter is not used a FHEM device for model S is created automatically.
  1225. <br><br>
  1226. Example:
  1227. <ul>
  1228. <code>define pix PiXtendV2</code> &emsp;&emsp;&emsp;=> creates a FHEM device for model S<br>
  1229. <code>define pix PiXtendV2 S</code> &emsp;&emsp;=> creates a FHEM device for model S<br>
  1230. <code>define pix PiXtendV2 L</code> &emsp;&emsp;=> creates a FHEM device for model L<br>
  1231. </ul>
  1232. </ul>
  1233. <br>
  1234. <a name="PiXtendV2Set"></a>
  1235. <b>Set</b>
  1236. <ul>
  1237. Commands to configure the basic settings of the PiXtend start with an "_".<br>
  1238. If a command supports multiple channels the "#"-sign has to be replaced with the channel number.<br>
  1239. All Set-commands are case insensitive to guarantee an easy use.<br>
  1240. For more information see the manuel for PiXtendV2 in the
  1241. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1242. of our homepage.
  1243. <br><br>
  1244. Example:
  1245. <ul>
  1246. <code>set pix relayOut0 on</code><br>
  1247. <code>set pix Relayout0 On</code><br>
  1248. <code>set pix rElAyoUT0 oFf</code><br>
  1249. </ul>
  1250. <br><br>
  1251. <li>_GPIO#Ctrl [input,output,DHT11,DHT22]<br>
  1252. With this setting the GPIO can be configured as [input], [output] or as [DHT11] or [DHT22] as well, if a DHT sensor is connected to this GPIO.
  1253. If a DHT is selected and connected, the GPIO can't simultaniously be used as a normal GPIO but the temperatur and humidity is read automatically.
  1254. <br><br></li>
  1255. <li>_GPIOPullupsEnable [yes,no]<br>
  1256. This setting enables [yes] or disables [no] the possibility to set the internal pullup resistors via GPIOOut setting for all GPIOs.
  1257. <br><br></li>
  1258. <li>_JumperSettingAI# [5V,10V]<br>
  1259. This setting affects the calculation of the voltage on the analog inputs and refers to the actual setting of the physical jumper on the PiXtend-Board [5V,10V].
  1260. The default value is [10V] if no jumper is used.
  1261. <br><br></li>
  1262. <li>_StateLEDDisable [yes,no]<br>
  1263. This setting disables [yes] or enables [no] the state LED on the PiXtend. If the LED is disabled it won't light up in case of an error.
  1264. <br><br></li>
  1265. <li>_WatchdogEnable [disable,125ms,1s,8s]<br>
  1266. This setting allows to configure the watchdog timer. If the watchdog is configured, the PiXtend will go to safe state if no valid data transfer has
  1267. occured within the selected timeout and thus can't be accessed anymore without a reset.
  1268. <br><br></li>
  1269. <li>AnalogOut# []<br>
  1270. Sets the analog output to the selected voltage. The value can be a voltage between 0 V and 10 V
  1271. or a raw value between 0 and 1023. To set the value to a voltage the value has to include a
  1272. "." even if it is an even number.
  1273. <br><br>
  1274. Example:
  1275. <ul>
  1276. <code>set pix analogout0 2.5</code> &emsp;&emsp;=> sets analog output 0 to 2.5 V<br>
  1277. <code>set pix analogout0 4.0</code> &emsp;&emsp;=> sets analog output 0 to 4 V<br>
  1278. <code>set pix analogout0 223</code> &emsp;&emsp;=> sets analog output 0 to 10*(233/1024) = 1.09 V
  1279. </ul>
  1280. <br><br></li>
  1281. <li>DigitalDebounce# [0-255]<br>
  1282. Allows to debounce the digital inputs. A setting always affects two channels. So DigitalDebounce01 affects DigitalIn0 and DigitalIn1.
  1283. The resulting delay is calculated by (selected value)*(100 ms). The selected value can be any number between 0 and 255.
  1284. Debouncing can be useful if a switch or button is connected to this input.
  1285. <br><br>
  1286. Example:
  1287. <ul>
  1288. <code>set pix digitaldebounce01 20</code> &emsp;&emsp;=> debounces DigitalIn0 and DigitalIn1 over (20*100ms) = 2s
  1289. </ul>
  1290. <br><br></li>
  1291. <li>DigitalOut# [on,off,toggle]<br>
  1292. Set the digital output HIGH [on] or LOW [off] or [toggle]s it.
  1293. <br><br></li>
  1294. <li>GPIODebounce# [0-255]<br>
  1295. Allows to debounce the GPIO inputs. A setting always affects two channels. So GPIODebounce01 affects GPIOIn0 and GPIOIn1.
  1296. The resulting delay is calculated by (selected value)*(100 ms). The selected value can be any number between 0 and 255.
  1297. Debouncing can be useful if a switch or button is connected to this input.
  1298. <br><br>
  1299. Example:
  1300. <ul>
  1301. <code>set pix gpiodebounce23 33</code> &emsp;&emsp;=> debounces GPIOIn2 and GPIOIn3 over (33*100ms) = 3.3s
  1302. </ul>
  1303. <br><br></li>
  1304. <li>GPIOOut# [on,off,toggle]<br>
  1305. Set the GPIO to HIGH [on] or LOW [off] or [toggle]s it, if it is configured as an output.
  1306. If it is configured as an input, this command can enable [on] or disable [off] or [toggle] the internal pullup resistor for that GPIO,
  1307. but therefore pullups have to be enabled globally via _GPIOPullupsEnable.
  1308. <br><br></li>
  1309. <li>PWM<br>
  1310. The PiXtendV2 supports various PWM-Modes, which can be configured with this settings.
  1311. For example a servo-mode to control servo-motors, a frequency-mode or a duty-cycle-mode are supported.
  1312. For more information see the manuel for PiXtendV2 in the
  1313. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1314. of our homepage.
  1315. <br><br>
  1316. PWM#Ctrl0 needs a value between 0 and 255<br>
  1317. PWM#Ctrl1 needs a value between 0 and 65535 (or a value between 0 and 255, see exception for model -S-)<br>
  1318. PWM#A/B needs a value between 0 and 65535 (or a value between 0 and 255, see exception for model -S-)
  1319. <br><br></li>
  1320. <li>RelayOut# [on,off,toggle]<br>
  1321. Set the relay to HIGH [on] or LOW [off] or [toggle]s it.
  1322. <br><br></li>
  1323. <li>Reset<br>
  1324. Resets the controller on the PiXtend, for example if it is in safe state and allows to access it again.
  1325. <br><br></li>
  1326. <li>RetainCopy [on,off]<br>
  1327. If RetainCopy is enabled [on] the RetainDataOut that is written to the PiXtend will be received in RetainDataIn again.
  1328. This can be useful in some situations to see which data was send to the PiXtend.
  1329. If it is disabled [off] the last stored data will be received.
  1330. <br><br></li>
  1331. <li>RetainDataOut [0-(RetainSize-1)] [0-255]<br>
  1332. The PiXtendV2 supports the storage of retain data. If enabled, this data is stored in case of a power failure or if it is triggered by a watchdog timeout or the safe state command.
  1333. The retain data is organized in bytes and each byte can be written individually with a value between 0 and 255.<br>
  1334. As first parameter the command needs the byte index which is between 0 and the (RetainSize-1). The RetainSize is shown in the "Internals".
  1335. As the second parameter a value is expected which should be stored.
  1336. <br><br>
  1337. Example:
  1338. <ul>
  1339. <code>set pix retaindataout 0 34</code> &emsp;&emsp;&emsp;=> stores 34 in retain-data-byte 0<br>
  1340. <code>set pix retaindataout 30 222</code> &emsp;&emsp;=> stores 222 in retain-data-byte 30
  1341. </ul>
  1342. <br><br></li>
  1343. <li>RetainEnable [on,off]<br>
  1344. The function of storing retain data on the PiXtend has to be enabled [on], otherwise no data is stored [off].
  1345. The memory in which the data is stored supports 10.000 write-cycles.
  1346. So the storage of retain data should only be used if it is really necessary.
  1347. <br><br></li>
  1348. <li>SafeState<br>
  1349. This setting allows to force the PiXtend to enter the safe state . If retain storage is enabled the data will be stored. In safe state the PiXtend won't communicate with FHEM and can't be configured anymore.
  1350. To restart the PiXtend a reset has to be done.
  1351. <br><br></li>
  1352. </ul>
  1353. <br>
  1354. <a name="PiXtendV2Get"></a>
  1355. <b>Get</b>
  1356. <ul>
  1357. If a command supports multiple channels the "#"-sign has to be replaced with the channel number.<br>
  1358. All Get-commands are case insensitive to guarantee an easy use.<br>
  1359. For more information see the manuel for PiXtendV2 in the
  1360. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1361. of our homepage.
  1362. The values can be returned as a string where the actual value is inside squared brackets or as raw values.
  1363. To change the returned value the attribute "PiXtend_GetFormat" has to be set.
  1364. <br><br>
  1365. <li>AnalogIn#<br>
  1366. Returns the Value of the selected analog input.
  1367. The result depends on the selected _JumperSettingAI# and the actual physical jumper position on the board, as well as the kind of measurement.
  1368. For example AnalogIn4 and AnalogIn5 on model -L- are used to measure a current instead of a voltage.
  1369. <br><br></li>
  1370. <li>DigitalIn#<br>
  1371. Returns the state on (HIGH) or off (LOW) of the digital input.
  1372. <br><br></li>
  1373. <li>GPIOIn#<br>
  1374. Returns the state on (HIGH) or off (LOW) of the GPIO, independant of its configuration (input, output, ..).
  1375. <br><br></li>
  1376. <li>RetainDataIn [0-(RetainSize-1)]<br>
  1377. Returns the value of the selected RetainDataIn-byte.
  1378. <br><br></li>
  1379. <li>Sensor# [temperature,humidity]<br>
  1380. If a DHT-Sensor is connected to the corresponding GPIO and the _GPIO#Ctrl is set to DHT11 or DHT22 the
  1381. temperature and humidity are measured and can be read.
  1382. <br><br>
  1383. Example:
  1384. <ul>
  1385. <code>set pix _GPIO0Ctrl DHT11</code><br>
  1386. <code>get pix Sensor0 temperature</code>
  1387. </ul>
  1388. <br><br></li>
  1389. <li>SysState<br>
  1390. Returns the system state [defined, active, error] of the FHEM module.
  1391. <br><br></li>
  1392. <li>UCState<br>
  1393. Returns the state of the PiXtend. If it is 1 everything is fine. If it is greater than 1 an error occured or is present and the PiXtend can't be configured.
  1394. For more information see the manuel for PiXtendV2 in the
  1395. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1396. of our homepage.
  1397. <br><br></li>
  1398. <li>UCWarnings<br>
  1399. Returns a value that represents the PiXtend warnings.
  1400. For more information see the manuel for PiXtendV2 in the
  1401. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1402. of our homepage.
  1403. <br><br></li>
  1404. <li>Version<br>
  1405. Returns the FHEM-module version and the microcontroller version [Model-Hardware-Firmware].
  1406. <br><br></li>
  1407. </ul>
  1408. <br>
  1409. <a name="PiXtendV2Readings"></a>
  1410. <b>Readings</b>
  1411. <ul>
  1412. The FHEM-module for PiXtendV2 supports multiple readings from which most of them trigger an event when they have changed.
  1413. The meaning of the readings is similar to the Get-commands.
  1414. <br><br>
  1415. <li>AnalogIn#<br>
  1416. Shows the result of the measurment on the analog inputs in V or mA.
  1417. <br><br></li>
  1418. <li>DigitalIn#<br>
  1419. Shows the state on (HIGH) or off (LOW) of the digital inputs.
  1420. <br><br></li>
  1421. <li>Firmware<br>
  1422. Shows the firmware version.
  1423. <br><br></li>
  1424. <li>GPIOIn#<br>
  1425. Shows the state on (HIGH) or off (LOW) of the GPIOs, independant of their configuration (input, output, ..).
  1426. <br><br></li>
  1427. <li>Hardware<br>
  1428. Shows the hardware version.
  1429. <br><br></li>
  1430. <li>Model<br>
  1431. Shows the model.
  1432. <br><br></li>
  1433. <li>RetainDataIn<br>
  1434. Shows the values of the RetainDataIn.
  1435. The values of RetainDataIn are combined in one row, whereby the most left value represents Byte0 / RetainDataIn0.
  1436. Each value is seperated by an " " and thus can be parsed very easy in perl:
  1437. <br><br>
  1438. Example:
  1439. <ul>
  1440. <code>my ($str) = ReadingsVal(pix, "RetainDataIn", "?")</code><br>
  1441. <code>if($str ne "?"){</code><br>
  1442. &emsp;<code>my @val = split(/ /, $str);</code> &emsp;&emsp;=> $val[0] contains Byte0, $val[1] Byte1, ...<br>
  1443. &emsp;<code>...</code><br>
  1444. <code>}</code>
  1445. </ul>
  1446. <br><br></li>
  1447. <li>Sensor#T/H<br>
  1448. Shows the temperature (T) in &deg;C and the humidity (H) in % of the sensor that is connected to the corresponding GPIO.
  1449. <br><br></li>
  1450. <li>UCState<br>
  1451. Shows the state of the PiXtend. If it is 1 everything is fine. If it is greater than 1 an error occured or is present and the PiXtend can't be configured.
  1452. For more information see the manuel for PiXtendV2 in the
  1453. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1454. of our homepage.
  1455. <br><br></li>
  1456. <li>UCWarnings<br>
  1457. Shows a value that represents the PiXtend warnings.
  1458. For more information see the manuel for PiXtendV2 in the
  1459. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">download section</a>
  1460. of our homepage.
  1461. <br><br></li>
  1462. </ul>
  1463. <br>
  1464. <a name="PiXtendV2Attr"></a>
  1465. <b>Attributes</b>
  1466. <ul>
  1467. The attribute name is case-sensitive.
  1468. <br><br>
  1469. <li>PiXtend_GetFormat [text,value]<br>
  1470. Changes the style in which the values of the Get commands are returned. They can be returned as a message [text] or as a raw [value].
  1471. Default is the presentation as a message.
  1472. <br><br></li>
  1473. <li>PiXtend_Parameter<br>
  1474. With this attribute the base configuration (Set commands with a leading "_") can be saved as an attribute.
  1475. Attributes are stored in the config file. Single commands are seperated with a space " " and each value is seperated by a ":".
  1476. <br><br>
  1477. Example:
  1478. <ul>
  1479. <code>attr pix PiXtend_Parameter _gpio0ctrl:dht11 _gpio3ctrl:dht22</code>
  1480. </ul>
  1481. <br><br></li>
  1482. </ul>
  1483. <br>
  1484. </ul>
  1485. =end html
  1486. =begin html_DE
  1487. <a name="PiXtendV2"></a>
  1488. <h3>PiXtendV2</h3>
  1489. <ul>
  1490. PiXtend ist eine speicherprogrammierbare Steuerung auf Basis des Raspberry Pi.
  1491. Dieses FHEM-Modul erm&ouml;glicht dabei den Zugriff auf die Funktionen des PiXtendV2-Boards in der FHEM-Oberfl&auml;che.
  1492. Der PiXtend bietet dabei eine Vielzahl an digitalen und analogen Ein- und Ausg&auml;ngen, die nach Industrie-Standards ausgelegt sind
  1493. und ist aufgrund der sicheren Anschl&uuml;sse auch ideal f&uuml;r die Hausautomatisierung geeignet.
  1494. F&uuml;r mehr Informationen &uuml;ber PiXtend(R) und das FHEM-Modul besuchen Sie unsere Website
  1495. <a href="http://www.PiXtend.de" target="_blank">www.PiXtend.de</a> oder
  1496. <a href="http://www.PiXtend.com" target="_blank">www.PiXtend.com</a>.
  1497. <br><br>
  1498. <a name="PiXtendV2Define"></a>
  1499. <b>Define</b>
  1500. <ul>
  1501. <code>define &lt;name&gt; PiXtendV2 &lt;optional&gt;</code>
  1502. <br><br>
  1503. Der Parameter "optional" bestimmt f&uuml;r welches Hardware-Modell ein FHEM-Ger&auml;t angelegt werden soll, z.B. S oder L.
  1504. Wird der Parameter weggelassen, wird automatisch ein FHEM-Ger&auml;t f&uuml;r Model -S- angelegt.
  1505. <br><br>
  1506. Beispiel:
  1507. <ul>
  1508. <code>define pix PiXtendV2</code> &emsp;&emsp;&emsp;=> erzeugt ein FHEM-Ger&auml;t f&uuml;r Model S<br>
  1509. <code>define pix PiXtendV2 S</code> &emsp;&emsp;=> erzeugt ein FHEM-Ger&auml;t f&uuml;r Model S<br>
  1510. <code>define pix PiXtendV2 L</code> &emsp;&emsp;=> erzeugt ein FHEM-Ger&auml;t f&uuml;r Model L<br>
  1511. </ul>
  1512. </ul>
  1513. <br>
  1514. <a name="PiXtendV2Set"></a>
  1515. <b>Set</b>
  1516. <ul>
  1517. Kommandos um die Basiskonfiguration f&uuml;r den PiXtend durchzuf&uuml;hren, beginnen mit einem "_".<br>
  1518. Unterst&uuml;tzt ein Kommando mehrere Kan&auml;le, muss das "#"-Zeichen durch die Kanal-Nummer ersetzt werden.<br>
  1519. Alle Set-Kommandos sind unabh&auml;ngig von der Gro&szlig;-/Kleinschreibung um die einfache Benutzung zu erm&ouml;glichen.<br>
  1520. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1521. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1522. unserer Hompage nach.
  1523. <br><br>
  1524. Beispiel:
  1525. <ul>
  1526. <code>set pix relayOut0 on</code><br>
  1527. <code>set pix Relayout0 On</code><br>
  1528. <code>set pix rElAyoUT0 oFf</code><br>
  1529. </ul>
  1530. <br><br>
  1531. <li>_GPIO#Ctrl [input,output,DHT11,DHT22]<br>
  1532. Mit dieser Einstellung kann die Funktion des GPIO eingestellt werden. [input], [output] oder [DHT11] und [DHT22] wenn ein DHT-Sensor an den GPIO angeschlossen ist.
  1533. Wenn ein DHT-Sensor angeschlossen ist und verwendet wird, kann die normale Funktion des GPIO als Eingang/Ausgang nicht gleichzeitig verwendet werden.
  1534. <br><br></li>
  1535. <li>_GPIOPullupsEnable [yes,no]<br>
  1536. Diese Einstellung aktiviert [yes] oder deaktiviert [no] f&uuml;r alle GPIOs die M&ouml;glichkeit die internen PullUp-Widerst&auml;nde durch GPIOOut zu setzen.
  1537. <br><br></li>
  1538. <li>_JumperSettingAI# [5V,10V]<br>
  1539. Diese Einstellung beeinflusst die Berechnung der Spannung durch die analogen Eing&auml;nge und bezieht sich dabei auf die tats&auml;chliche Position des Jumpers
  1540. auf dem PiXtend-Board [5V,10V]. Wenn kein Jumper verwendet wird, entspricht das der Standardeinstellung von [10V].
  1541. <br><br></li>
  1542. <li>_StateLEDDisable [yes,no]<br>
  1543. Diese Einstellung deaktiviert [yes] oder aktiviert [no] die Status-LED auf dem PiXtend. Wenn die LED deaktiviert ist, leuchtet sie im Fehlerfall nicht auf.
  1544. <br><br></li>
  1545. <li>_WatchdogEnable [disable,125ms,1s,8s]<br>
  1546. Diese Einstellung erm&ouml;glicht die Konfiguration des Watchdog-Timers. Wenn der Watchdog konfiguriert ist, geht der PiXtend in den Sicheren Zustand
  1547. &uuml;ber, falls innerhalb der eingestellten Zeit keine g&uuml;ltige &Uuml;bertragung zwischen PiXtend und Raspberry Pi stattgefunden hat.
  1548. Im Sicheren Zustand kann der PiXtend erst wieder angesprochen werden, nachdem ein Reset des PiXtend durchgef&uuml;hrt wurde.
  1549. <br><br></li>
  1550. <li>AnalogOut# []<br>
  1551. Stellt am analogen Ausgang eine Spannung ein. Der &uuml;bergebene Wert kann eine Spannung zwischen 0 V und 10 V
  1552. oder ein Rohwert zwischen 0 und 1023 sein. Um den Wert als Spannung zu &uuml;bergeben, muss der Wert ein "." enthalten,
  1553. auch wenn der Wert ganzzahlig ist.
  1554. <br><br>
  1555. Beispiel:
  1556. <ul>
  1557. <code>set pix analogout0 2.5</code> &emsp;&emsp;=> Setzt den analogen Ausgang 0 auf 2,5 V<br>
  1558. <code>set pix analogout0 4.0</code> &emsp;&emsp;=> Setzt den analogen Ausgang 0 auf 4 V<br>
  1559. <code>set pix analogout0 223</code> &emsp;&emsp;=> Setzt den analogen Ausgang 0 auf 10*(233/1024) = 1,09 V
  1560. </ul>
  1561. <br><br></li>
  1562. <li>DigitalDebounce# [0-255]<br>
  1563. Erm&ouml;glicht das Entprellen der digitalen Eing&auml;nge. Die Einstellung beeinflusst dabei immer zwei Kan&auml;le.
  1564. DigitalDebounce01 beeinflusst somit DigitalIn0 und DigitalIn1.
  1565. Die resultierende Verz&ouml;gerung berechnet sich dabei durch (eingestellten Wert)*(100 ms).
  1566. Der &uuml;bergebene Wert kann eine beliebige Zahl zwischen 0 und 255 sein.
  1567. Entprellen kann sinnvoll sein, falls an den Eing&auml;ngen Schalter oder Taster angeschlossen sind.
  1568. <br><br>
  1569. Beispiel:
  1570. <ul>
  1571. <code>set pix digitaldebounce01 20</code> &emsp;&emsp;=> entprellt DigitalIn0 und DigitalIn1 &uuml;ber (20*100ms) = 2s
  1572. </ul>
  1573. <br><br></li>
  1574. <li>DigitalOut# [on,off,toggle]<br>
  1575. Setzt den digitalen Ausgang auf HIGH [on] oder LOW [off] oder [toggle]t ihn.
  1576. <br><br></li>
  1577. <li>GPIODebounce# [0-255]<br>
  1578. Erm&ouml;glicht das Entprellen der GPIO Eing&auml;nge. Die Einstellung beeinflusst dabei immer zwei Kan&auml;le.
  1579. GPIODebounce01 beeinflusst somit GPIOIn0 und GPIOIn1.
  1580. Die resultierende Verz&ouml;gerung berechnet sich dabei durch (eingestellten Wert)*(100 ms).
  1581. Der &uuml;bergebene Wert kann eine beliebige Zahl zwischen 0 und 255 sein.
  1582. Entprellen kann sinnvoll sein, falls an den Eing&auml;ngen Schalter oder Taster angeschlossen sind.
  1583. <br><br>
  1584. Beispiel:
  1585. <ul>
  1586. <code>set pix gpiodebounce23 33</code> &emsp;&emsp;=> entprellt GPIOIn2 und GPIOIn3 &uuml;ber (33*100ms) = 3,3s
  1587. </ul>
  1588. <br><br></li>
  1589. <li>GPIOOut# [on,off,toggle]<br>
  1590. Setzt den GPIO auf HIGH [on] oder LOW [off] oder [toggle]t ihn, falls er als Ausgang konfiguriert ist.
  1591. Wenn der GPIO als Eingang konfiguriert ist, kann mit diesem Kommando der interne PullUp-Widerstand aktiviert [on], deaktiviert [off] oder
  1592. ge[toggle]t werden. Dazu muss die M&ouml;glichkeit allerdings global durch _GPIOPullupsEnable aktiviert werden.
  1593. <br><br></li>
  1594. <li>PWM<br>
  1595. PiXtendV2 unterst&uuml;tzt mehrere PWM-Modi, die mit diesen Einstellungen konfiguriert werden k&ouml;nnen.
  1596. Zum Beispiel wird ein Servo-Mode um Modellbau-Servomotoren anzusteuern, ein Frequency-Mode oder ein Duty-Cycle-Mode unterst&uuml;zt.
  1597. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1598. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1599. unserer Hompage nach.
  1600. <br><br>
  1601. PWM#Ctrl0 ben&ouml;tigt einen Wert zwischen 0 und 255<br>
  1602. PWM#Ctrl1 ben&ouml;tigt einen Wert zwischen 0 und 65535 (oder einen Wert zwischen 0 und 255, siehe Ausnahme Model -S-)<br>
  1603. PWM#A/B ben&ouml;tigt einen Wert zwischen 0 und 65535 (oder einen Wert zwischen 0 und 255, siehe Ausnahme Model -S-)
  1604. <br><br></li>
  1605. <li>RelayOut# [on,off,toggle]<br>
  1606. Setzt das Relay auf HIGH [on] oder LOW [off] oder [toggle]t es.
  1607. <br><br></li>
  1608. <li>Reset<br>
  1609. Setzt den Controller auf dem PiXtend zur&uuml;ck, z.B. wenn er sich im Sicheren Zustand befindet, um ihn erneut konfigurieren zu k&ouml;nnen.
  1610. <br><br></li>
  1611. <li>RetainCopy [on,off]<br>
  1612. Wenn RetainCopy aktiviert [on] ist, werden die geschriebenen Daten RetainDataOut vom PiXtend in RetainDataIn zur&uuml;ckgegeben.
  1613. Die Aktivierung kann in Situationen sinnvoll sein, wenn &uuml;berpr&uuml;ft werden soll, welche Daten an den PiXtend geschickt wurden.
  1614. Ist die Funktion deaktiviert [off] werden die zuletzt gespeicherten Daten in RetainDataIn zur&uuml;ckgegeben.
  1615. <br><br></li>
  1616. <li>RetainDataOut [0-(RetainSize-1)] [0-255]<br>
  1617. Der PiXtendV2 unterst&uuml;zt die Speicherung remanenter/persistenter Daten - auch Retain genannt. Diese Daten werden im Falle
  1618. einer Betribsspannungsunterbrechung, beim Ausl&ouml;sen des Watchdog-Timers oder beim Entritt in den Sicheren Zustand gespeichert,
  1619. sofern diese Funktion aktiviert wurde. Die Retain-Daten sind dabei in Bytes organisiert, wobei jedes Byte
  1620. individuell mit einem Wert zwischen 0 und 255 beschrieben werden kann.<br>
  1621. Als ersten Parameter erwartet das Kommando den Index des Bytes, der zwischen 0 und (RetainSize-1) liegt. RetainSize ist in den "Internals" zu finden.
  1622. Als zweiter Parameter wird der Wert erwartet, der gespeichert werden soll.
  1623. <br><br>
  1624. Beispiel:
  1625. <ul>
  1626. <code>set pix retaindataout 0 34</code> &emsp;&emsp;&emsp;=> speichert 34 in Retain-Data-Byte 0<br>
  1627. <code>set pix retaindataout 30 222</code> &emsp;&emsp;=> speichert 222 in Retain-Data-Byte 30
  1628. </ul>
  1629. <br><br></li>
  1630. <li>RetainEnable [on,off]<br>
  1631. Die Funktion um Retain-Daten auf dem PiXtend zu speichern muss erst aktiviert [on] werden. Andernfalls [off] werden keine Daten gespeichert.
  1632. Es ist zu beachten, dass f&uuml;r den Retain-Speicherbereich 10.000 Schreibzyklen unterst&uuml;tzt werden. Dementsprechend
  1633. sollte die Funktion nur aktiviert werden, wenn sie tats&auml;chlich ben&ouml;tigt wird.
  1634. <br><br></li>
  1635. <li>SafeState<br>
  1636. Mit dieser Einstellung kann der PiXtend in den Sicheren Zustand versetzt werden. Wenn die Retain-Speicherung aktiviert ist, werden die Daten gesichert.
  1637. Im Sicheren Zustand kommuniziert der PiXtend nicht mehr mit FHEM. Um den PiXtend neuzustarten muss ein Reset durchgef&uuml;hrt werden.
  1638. <br><br></li>
  1639. </ul>
  1640. <br>
  1641. <a name="PiXtendV2Get"></a>
  1642. <b>Get</b>
  1643. <ul>
  1644. Unterst&uuml;tzt ein Kommando mehrere Kan&auml;le, muss das "#"-Zeichen durch die Kanal-Nummer ersetzt werden.<br>
  1645. Alle Get-Kommandos sind unabh&auml;ngig von der Gro&szlig;-/Kleinschreibung um die einfache Benutzung zu erm&ouml;glichen.<br>
  1646. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1647. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1648. unserer Hompage nach.<br>
  1649. Die Werte k&ouml;nnen als Text, wobei die Werte in eckigen Klammern stehen oder als rohe Werte zur&uuml;ckgegeben werden.
  1650. Die Einstellung f&uuml;r das Format ist in den Attributen ("PiXtend_GetFormat") zu finden.
  1651. <br><br>
  1652. <li>AnalogIn#<br>
  1653. Gibt den Wert des ausgew&auml;hlten analogen Eingangs zur&uuml;ck.
  1654. Der Wert h&auml;ngt dabei von der Einstellung _JumperSettingAI# und der tats&auml;chlichen Jumper-Position auf dem Board ab, sowie der Messmethode des Kanals ab.
  1655. AnalogIn4 und AnalogIn5 bei Modell -L- sind z.B. Stromeing&auml;nge.
  1656. <br><br></li>
  1657. <li>DigitalIn#<br>
  1658. Gibt den Status on (HIGH) oder off (LOW) des digitalen Eingangs zur&uuml;ck.
  1659. <br><br></li>
  1660. <li>GPIOIn#<br>
  1661. Gibt den Status on (HIGH) oder off (LOW) des GPIOs zur&uuml;ck, unabh&auml;ngig von der Konfiguration (input, output, ..).
  1662. <br><br></li>
  1663. <li>RetainDataIn [0-(RetainSize-1)]<br>
  1664. Gibt den Wert des ausgew&auml;hlten RetainDataIn-Bytes zur&uuml;ck.
  1665. <br><br></li>
  1666. <li>Sensor# [temperature,humidity]<br>
  1667. Wenn ein DHT-Sensor an den entsprechenden GPIO angeschlossen ist und _GPIO#Ctrl auf DHT11 oder DHT22 gesetzt ist
  1668. wird die Temperatur und Luftfeuchtigkeit gemessen und kann ausgelesen werden.
  1669. <br><br>
  1670. Beispiel:
  1671. <ul>
  1672. <code>set pix _GPIO0Ctrl DHT11</code><br>
  1673. <code>get pix Sensor0 temperature</code>
  1674. </ul>
  1675. <br><br></li>
  1676. <li>SysState<br>
  1677. Gibt den Systemstatus [defined, active, error] des FHEM-Moduls zur&uuml;ck.
  1678. <br><br></li>
  1679. <li>UCState<br>
  1680. Gibt den Status des PiXtend zur&uuml;ck. Ist der Status 1, ist alles in Ordnung. Ist der Status allerdings gr&ouml;&szlig;er als 1 ist ein Fehler aufgetreten
  1681. oder steht noch an. In diesem Fall kann der PiXtend nicht konfiguriert werden.
  1682. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1683. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1684. unserer Hompage nach.
  1685. <br><br></li>
  1686. <li>UCWarnings<br>
  1687. Der zur&uuml;ckgegebene Wert repr&auml;sentiert die Warnungen des PiXtendV2.
  1688. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1689. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1690. unserer Hompage nach.
  1691. <br><br></li>
  1692. <li>Version<br>
  1693. Gibt die Version des FHEM-Moduls sowie die PiXtend-Version [Model-Hardware-Firmware] zur&uuml;ck.
  1694. <br><br></li>
  1695. </ul>
  1696. <br>
  1697. <a name="PiXtendV2Readings"></a>
  1698. <b>Readings</b>
  1699. <ul>
  1700. Das FHEM-Modul des PiXtend unterst&uuml;zt mehrere Readings, von denen die meisten ein Event ausl&ouml;sen, sobald sie sich &auml;ndern.
  1701. Die Bedeutung der Readings ist &auml;hnlich zu den Get-Kommandos.
  1702. <br><br>
  1703. <li>AnalogIn#<br>
  1704. Zeigt das Ergebnis der Messungen der analogen Eing&auml;nge in V beziehungsweise in mA an.
  1705. <br><br></li>
  1706. <li>DigitalIn#<br>
  1707. Zeigt den Status on (HIGH) oder off (LOW) der digitalen Eing&auml;nge an.
  1708. <br><br></li>
  1709. <li>Firmware<br>
  1710. Zeigt die Firmware-Version an.
  1711. <br><br></li>
  1712. <li>GPIOIn#<br>
  1713. Zeigt den Status on (HIGH) oder off (LOW) der GPIOs, unabh&auml;ngig von deren Konfiguration (input, output, ..).
  1714. <br><br></li>
  1715. <li>Hardware<br>
  1716. Zeigt die Hardware-Version an.
  1717. <br><br></li>
  1718. <li>Model<br>
  1719. Zeigt das Model an.
  1720. <br><br></li>
  1721. <li>RetainDataIn<br>
  1722. Zeigt die Werte von RetainDataIn an. Die Werte von RetainDataIn sind dabei in einer Zeile
  1723. zusammengefasst. Der am weitsten links stehende Wert entspricht Byte0 / RetainDataIn0.
  1724. Die Werte sind durch ein Leerzeichen " " voneinander getrennt und k&ouml;nnen somit einfach in Perl ausgewertet werden:
  1725. <br><br>
  1726. Beispiel:
  1727. <ul>
  1728. <code>my ($str) = ReadingsVal(pix, "RetainDataIn", "?")</code><br>
  1729. <code>if($str ne "?"){</code><br>
  1730. &emsp;<code>my @val = split(/ /, $str);</code> &emsp;&emsp;=> $val[0] enth&auml;lt nun Byte0, $val[1] Byte1, usw<br>
  1731. &emsp;<code>...</code><br>
  1732. <code>}</code>
  1733. </ul>
  1734. <br><br></li>
  1735. <li>Sensor#T/H<br>
  1736. Zeigt die Temperatur (T) in &deg;C und die Luftfeuchtigkeit (H) in % des Sensors an, der an den entsprechenden GPIO angeschlossen ist.
  1737. <br><br></li>
  1738. <li>UCState<br>
  1739. Zeigt den Status des PiXtend an. Ist der Status 1, ist alles in Ordnung. Ist der Status allerdings gr&ouml;&szlig;er als 1 ist ein Fehler aufgetreten
  1740. oder steht noch an. In diesem Fall kann der PiXtend nicht konfiguriert werden.
  1741. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1742. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1743. unserer Hompage nach.
  1744. <br><br></li>
  1745. <li>UCWarnings<br>
  1746. Der angezeigte Wert repr&auml;sentiert die Warnungen des PiXtendV2.
  1747. F&uuml;r mehr Informationen sehen Sie bitte im Handbuch f&uuml;r den PiXtendV2 im
  1748. <a href="http://www.PiXtend.de/PiXtend/downloads/" target="_blank">Downloadbereich</a>
  1749. unserer Hompage nach.
  1750. <br><br></li>
  1751. </ul>
  1752. <br>
  1753. <a name="PiXtendV2Attr"></a>
  1754. <b>Attributes</b>
  1755. <ul>
  1756. F&uuml;r den Attribut-Namen muss die Gro&szlig;-/Kleinschreibung beachtet werden.
  1757. <br><br>
  1758. <li>PiXtend_GetFormat [text,value]<br>
  1759. &Auml;ndert die Darstellung, wie die Werte durch die Get-Kommandos zur&uuml;ckgegeben werden. Die Werte k&ouml;nnen entweder in einer Nachricht [text] oder als rohe Werte [value] zur&uuml;ckgegeben werden.
  1760. Standard ist die Ausgabe als Text.
  1761. <br><br></li>
  1762. <li>PiXtend_Parameter<br>
  1763. Dieses Attribut kann verwendet werden, um die Einstellungen zur Basiskonfiguration (Set-Kommandos beginnend mit "_") als Attribut zu speichern. Attribute werden im Gegensatz zu Set-Kommandos in der Config-Datei gespeichert.<br>
  1764. Einzelne Kommandos werden durch ein Leerzeichen voneinander getrennt und erhalten ihre Werte nach einem Doppelpunkt.
  1765. <br><br>
  1766. Beispiel:
  1767. <ul>
  1768. <code>attr pix PiXtend_Parameter _gpio0ctrl:dht11 _gpio3ctrl:dht22</code>
  1769. </ul>
  1770. <br><br></li>
  1771. </ul>
  1772. <br>
  1773. </ul>
  1774. =end html_DE
  1775. =cut