http://www.ethersex.de/api.php?action=feedcontributions&user=Sittner&feedformat=atomEthersex_Wiki - User contributions [en]2024-03-28T16:59:56ZUser contributionsMediaWiki 1.30.0http://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=769Onewire (Deutsch)2012-07-14T12:32:16Z<p>Sittner: /* Abfrage per SNMP */</p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
│ │ [*] Onewire Polling │ │ <br />
│ │ (375) Time between discoveries in 0.8s steps │ │ <br />
│ │ (12) Time between polling in 0.8s steps │ │ <br />
│ │ [*] ECMD 1w list with values │ │ <br />
│ │ (10) Maximum sensor count │ │ <br />
<br />
Im Polling-Modus werden die Sensoren im Hintergrund abgefragt, so dass die Werte<br />
bei Bedarf direkt zur Verfügung stehen und nicht erst gewandelt bzw.<br />
eingelesen werden müssen. Der Intervall zwischen den Discoveries und zwischen<br />
den Abfragen der Werte kann getrennt eingestellt werden. Die Option<br />
'''ECMD 1w list with values''' bietet die Möglichkeit, die aktuellen Werte<br />
bei Aufruf von '''1w list''' mit ausgeben zu lassen. So können darauf folgende<br />
'''1w get''' Kommandos entfallen.<br />
<br />
Da zur Pufferung der Werte, ROM-Codes, etc. RAM-Speicher benötigt wird, muss<br />
per '''Maximum sensor count''' angegeben werden, für wie viele Sensoren Speicher<br />
reserviert wird.<br />
<br />
= Benennung von Sensoren =<br />
<br />
│ │ [*] Onewire naming support │ │ <br />
│ │ (10) Maximum sensor count │ │ <br />
<br />
Um den Sensoren sinnvolle Namen zu geben besteht die Möglichkeit im EEPROM<br />
eine entsprechende Zuweisungstabelle anzulegen (ROM-Code -> Name). Die Namen werden<br />
bei bei Aufruf von '''1w list''' mit ausgegeben. Dazu gibt es<br />
folgende ECMD Kommandos:<br />
<br />
1w name list<br />
<br />
Auflistung der aktuellen Zuweisungen (Spalten: ID, ROM-Code, Name). Die ID bezeichnet<br />
die Position in der Zuweisungstabelle und kann u.a. dazu benutzt werden, Sensoren<br />
bei SNMP-Abfragen eindeutig zu referenzieren.<br />
<br />
1w name set <ID> <ROM-Code> <Name><br />
<br />
Erstellt einen entsprechenden Tabelleneintrag.<br />
<br />
1w name clear <ID><br />
<br />
Löscht die Felder eines Tabelleneintrags.<br />
<br />
1w name save<br />
<br />
Speichert die aktuelle Tabelle im EEPROM<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder, wenn das Argument <hexcode><br />
weggelassen wird, aller angeschlossener Sensoren. Im Polling-Modus wird dieses Kommando ignoriert.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
Falls Polling-Support aktiviert wurde können die Sensorwerte per SNMP abgefragt werden.<br />
Mit Naming-Support stehen auch die Namen per SNMP zur Verfügung und die Index-Nummern sind<br />
fix auf die Position in der Namenstabelle festgelegt. Dies ist sehr hilfreich, um bestimmte<br />
Sensoren über den SNMP-Index anzusprechen.<br />
<br />
Es gibt folgende OIDs:<br />
<br />
* .1.3.6.1.4.1.39967.3.1.<idx> : ROM-Code des Sensors<br />
* .1.3.6.1.4.1.39967.3.2.<idx> : Sensor-Name (nur mit Naming-Support)<br />
* .1.3.6.1.4.1.39967.3.3.<idx> : Temperaturwert in Centigrad<br />
* .1.3.6.1.4.1.39967.3.4.<idx> : 0 = Sensor nicht vorhanden, 1 = Sensor vorhanden<br />
<br />
Hier ein Beispiel:<br />
<br />
<pre><br />
# snmpwalk -Osn -c public -v 1 192.168.255.90 1.3.6.1.4.1.39967.3<br />
.1.3.6.1.4.1.39967.3.1.0 = STRING: "1080cff6010800f9"<br />
.1.3.6.1.4.1.39967.3.1.1 = STRING: "10c8cff60108002d"<br />
.1.3.6.1.4.1.39967.3.1.2 = STRING: "1029f6dc0108002f"<br />
.1.3.6.1.4.1.39967.3.1.3 = STRING: "10f2d0f60108001c"<br />
.1.3.6.1.4.1.39967.3.1.4 = STRING: "105a17f70108001d"<br />
.1.3.6.1.4.1.39967.3.1.5 = STRING: "10b8d8f601080098"<br />
.1.3.6.1.4.1.39967.3.1.6 = STRING: "104dedf601080057"<br />
.1.3.6.1.4.1.39967.3.1.7 = STRING: "10011af701080027"<br />
.1.3.6.1.4.1.39967.3.1.8 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.39967.3.1.9 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.39967.3.2.0 = STRING: "kessel"<br />
.1.3.6.1.4.1.39967.3.2.1 = STRING: "warmwasser"<br />
.1.3.6.1.4.1.39967.3.2.2 = STRING: "aussen"<br />
.1.3.6.1.4.1.39967.3.2.3 = STRING: "speicher"<br />
.1.3.6.1.4.1.39967.3.2.4 = STRING: "heizung vl"<br />
.1.3.6.1.4.1.39967.3.2.5 = STRING: "heizung rl"<br />
.1.3.6.1.4.1.39967.3.2.6 = STRING: "boiler vl"<br />
.1.3.6.1.4.1.39967.3.2.7 = STRING: "boiler rl"<br />
.1.3.6.1.4.1.39967.3.2.8 = ""<br />
.1.3.6.1.4.1.39967.3.2.9 = ""<br />
.1.3.6.1.4.1.39967.3.3.0 = INTEGER: 334<br />
.1.3.6.1.4.1.39967.3.3.1 = INTEGER: 467<br />
.1.3.6.1.4.1.39967.3.3.2 = INTEGER: 127<br />
.1.3.6.1.4.1.39967.3.3.3 = INTEGER: 185<br />
.1.3.6.1.4.1.39967.3.3.4 = INTEGER: 318<br />
.1.3.6.1.4.1.39967.3.3.5 = INTEGER: 269<br />
.1.3.6.1.4.1.39967.3.3.6 = INTEGER: 366<br />
.1.3.6.1.4.1.39967.3.3.7 = INTEGER: 291<br />
.1.3.6.1.4.1.39967.3.3.8 = INTEGER: 0<br />
.1.3.6.1.4.1.39967.3.3.9 = INTEGER: 0<br />
.1.3.6.1.4.1.39967.3.4.0 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.1 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.2 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.3 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.4 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.5 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.6 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.7 = INTEGER: 1<br />
.1.3.6.1.4.1.39967.3.4.8 = INTEGER: 0<br />
.1.3.6.1.4.1.39967.3.4.9 = INTEGER: 0<br />
</pre><br />
<br />
= Codebeispiele =<br />
<br />
* [[Onewire/Example/PHP (Deutsch) | PHP]]<br />
* [[Onewire/Example/Perl (Deutsch) | Perl]]<br />
* [[Onewire/Example/Python | Python]]<br />
* [[Onewire/Example/Shell | sh/bash]]<br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Tanklevel&diff=768Tanklevel2012-07-14T12:31:16Z<p>Sittner: /* SNMP support */</p>
<hr />
<div>{{i18n|Tanklevel}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Tank level meter<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]], [[ADC]], [[Cron]] (optional) <br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/tanklevel https://github.com/ethersex/ethersex/tree/master/services/tanklevel]<br />
}}<br />
<br />
Tanklevel provides an application for measurement of tank levels by hydrostatic pressure.<br />
<br />
== Internals ==<br />
<br />
You need an aquarium air pump, some kind of pipe/tube, a Freescale MPX5050DP<br />
pressure sensor and an relay for the pump. Parameters are configurable by ECMD<br />
and stored in EEPROM.<br />
<br />
== Configuration ==<br />
<br />
│ │ (0) ADC channel │ │ <br />
│ │ [ ] Measure on system startup │ │ <br />
│ │ [ ] Measure at 12 am and 12 pm │ │ <br />
│ │ [ ] Inverted pump output │ │ <br />
│ │ [ ] Check lock input │ │ <br />
│ │ [ ] Inverted lock input │ │ <br />
│ │ [ ] Inline tank level │ │ <br />
<br />
* ADC channel - ADC channel that is connected to the MPX5050DP pressure sensor.<br />
* Measure on system startup - Start initial measurement at system startup.<br />
* Measure at 12 am and 12 pm - Start measurement at fixed time. Can be changed in services/cron/cron_static.c.<br />
* Inverted pump output - Output pin for pump is inverted.<br />
* Check lock input - Check lock pin before measurement and wait if needed. This is used to delay the measurement e.g. if the oil burner is running.<br />
* Inverted lock input - Lock input pin is inverted.<br />
* Inline tank level - Inline a page to query the tank level.<br />
<br />
== Pinning ==<br />
<br />
Example pinning from pinning/hardware/netio.m4:<br />
<br />
ifdef(`conf_TANKLEVEL', `<br />
pin(TANKLEVEL_PUMP, PC3, OUTPUT)<br />
')<br />
ifdef(`conf_TANKLEVEL_LOCK', `<br />
pin(TANKLEVEL_LOCK, PA2, INPUT)<br />
')<br />
<br />
Meaning:<br />
<br />
* TANKLEVEL_PUMP - output pin for driving the pump relay<br />
* TANKLEVEL_LOCK - optional pin for external lock signal (see Configuration)<br />
<br />
== Mechanical setup ==<br />
<br />
+-------+<br />
|Sensor |<br />
+---+---+<br />
| +--------+<br />
+---------------+-+ Pump |<br />
| +--------+<br />
+------+------+<br />
| | |<br />
| | |<br />
|------|------|<br />
| | |<br />
| | |<br />
| | |<br />
+-------------+<br />
Tank<br />
<br />
See the following example:<br />
<br />
[[File:Tanklevel_pump_assy.jpg|Pump assembly|177px]]<br />
[[File:Tanklevel_tank_assy.jpg|Tank assembly|100px]]<br />
<br />
== Electrical setup ==<br />
<br />
Electrical setup is quite simple. Connect the TANK_PUMP port with an relay<br />
(usually via an Transistor as current amp) and the output of the Sensor<br />
with the selected ADC channel (have a look at the datasheet for power supply<br />
decoupling and output filtering). Select a optimal Vref for the ADC if<br />
possible. Schematic could look like this:<br />
<br />
[[File:Tanklevel_schem.png|Electrical setup]]<br />
<br />
== Parameters ==<br />
<br />
Parameters can be viewed/set by ECMD commands:<br />
<br />
* sensor_offset - zero offset of the pressure sensor in mV<br />
* med_density - medium density in g/ltr (default of 840 for fuel oil)<br />
* ltr_per_m - Ltr per meter tank level<br />
* ltr_full - Tank capacity in ltr<br />
* raise_time - Pump time (in 1/50 secs)<br />
* hold_time - Hold time before measurement (in 1/50 secs)<br />
<br />
== SNMP support ==<br />
<br />
If SNMP is enabled the level can be queried by this OID's:<br />
<br />
* .1.3.6.1.4.1.39967.4.0 = INTEGER: current level in ltr<br />
* .1.3.6.1.4.1.39967.4.1 = INTEGER: tank capacity in ltr<br />
* .1.3.6.1.4.1.39967.4.2 = INTEGER: timestamp of last measurement (unix date)<br />
* .1.3.6.1.4.1.39967.4.3 = STRING: timestamp of last measurement (clear text)</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=510Onewire (Deutsch)2012-04-20T15:14:19Z<p>Sittner: </p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
│ │ [*] Onewire Polling │ │ <br />
│ │ (375) Time between discoveries in 0.8s steps │ │ <br />
│ │ (12) Time between polling in 0.8s steps │ │ <br />
│ │ [*] ECMD 1w list with values │ │ <br />
│ │ (10) Maximum sensor count │ │ <br />
<br />
Im Polling-Modus werden die Sensoren im Hintergrund abgefragt, so dass die Werte<br />
bei Bedarf direkt zur Verfügung stehen und nicht erst gewandelt bzw.<br />
eingelesen werden müssen. Der Intervall zwischen den Discoveries und zwischen<br />
den Abfragen der Werte kann getrennt eingestellt werden. Die Option<br />
'''ECMD 1w list with values''' bietet die Möglichkeit, die aktuellen Werte<br />
bei Aufruf von '''1w list''' mit ausgeben zu lassen. So können darauf folgende<br />
'''1w get''' Kommandos entfallen.<br />
<br />
Da zur Pufferung der Werte, ROM-Codes, etc. RAM-Speicher benötigt wird, muss<br />
per '''Maximum sensor count''' angegeben werden, für wie viele Sensoren Speicher<br />
reserviert wird.<br />
<br />
= Benennung von Sensoren =<br />
<br />
│ │ [*] Onewire naming support │ │ <br />
│ │ (10) Maximum sensor count │ │ <br />
<br />
Um den Sensoren sinnvolle Namen zu geben besteht die Möglichkeit im EEPROM<br />
eine entsprechende Zuweisungstabelle anzulegen (ROM-Code -> Name). Die Namen werden<br />
bei bei Aufruf von '''1w list''' mit ausgegeben. Dazu gibt es<br />
folgende ECMD Kommandos:<br />
<br />
1w name list<br />
<br />
Auflistung der aktuellen Zuweisungen (Spalten: ID, ROM-Code, Name). Die ID bezeichnet<br />
die Position in der Zuweisungstabelle und kann u.a. dazu benutzt werden, Sensoren<br />
bei SNMP-Abfragen eindeutig zu referenzieren.<br />
<br />
1w name set <ID> <ROM-Code> <Name><br />
<br />
Erstellt einen entsprechenden Tabelleneintrag.<br />
<br />
1w name clear <ID><br />
<br />
Löscht die Felder eines Tabelleneintrags.<br />
<br />
1w name save<br />
<br />
Speichert die aktuelle Tabelle im EEPROM<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder, wenn das Argument <hexcode><br />
weggelassen wird, aller angeschlossener Sensoren. Im Polling-Modus wird dieses Kommando ignoriert.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
Falls Polling-Support aktiviert wurde können die Sensorwerte per SNMP abgefragt werden.<br />
Mit Naming-Support stehen auch die Namen per SNMP zur Verfügung und die Index-Nummern sind<br />
fix auf die Position in der Namenstabelle festgelegt. Dies ist sehr hilfreich, um bestimmte<br />
Sensoren über den SNMP-Index anzusprechen.<br />
<br />
Es gibt folgende OIDs:<br />
<br />
* .1.3.6.1.4.1.2021.13.23.3.1.<idx> : ROM-Code des Sensors<br />
* .1.3.6.1.4.1.2021.13.23.3.2.<idx> : Sensor-Name (nur mit Naming-Support)<br />
* .1.3.6.1.4.1.2021.13.23.3.3.<idx> : Temperaturwert in Centigrad<br />
* .1.3.6.1.4.1.2021.13.23.3.4.<idx> : 0 = Sensor nicht vorhanden, 1 = Sensor vorhanden<br />
<br />
Hier ein Beispiel:<br />
<br />
<pre><br />
# snmpwalk -Osn -c public -v 1 192.168.255.90 1.3.6.1.4.1.2021.13.23.3<br />
.1.3.6.1.4.1.2021.13.23.3.1.0 = STRING: "1080cff6010800f9"<br />
.1.3.6.1.4.1.2021.13.23.3.1.1 = STRING: "10c8cff60108002d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.2 = STRING: "1029f6dc0108002f"<br />
.1.3.6.1.4.1.2021.13.23.3.1.3 = STRING: "10f2d0f60108001c"<br />
.1.3.6.1.4.1.2021.13.23.3.1.4 = STRING: "105a17f70108001d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.5 = STRING: "10b8d8f601080098"<br />
.1.3.6.1.4.1.2021.13.23.3.1.6 = STRING: "104dedf601080057"<br />
.1.3.6.1.4.1.2021.13.23.3.1.7 = STRING: "10011af701080027"<br />
.1.3.6.1.4.1.2021.13.23.3.1.8 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.1.9 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.2.0 = STRING: "kessel"<br />
.1.3.6.1.4.1.2021.13.23.3.2.1 = STRING: "warmwasser"<br />
.1.3.6.1.4.1.2021.13.23.3.2.2 = STRING: "aussen"<br />
.1.3.6.1.4.1.2021.13.23.3.2.3 = STRING: "speicher"<br />
.1.3.6.1.4.1.2021.13.23.3.2.4 = STRING: "heizung vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.5 = STRING: "heizung rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.6 = STRING: "boiler vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.7 = STRING: "boiler rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.8 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.2.9 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.3.0 = INTEGER: 334<br />
.1.3.6.1.4.1.2021.13.23.3.3.1 = INTEGER: 467<br />
.1.3.6.1.4.1.2021.13.23.3.3.2 = INTEGER: 127<br />
.1.3.6.1.4.1.2021.13.23.3.3.3 = INTEGER: 185<br />
.1.3.6.1.4.1.2021.13.23.3.3.4 = INTEGER: 318<br />
.1.3.6.1.4.1.2021.13.23.3.3.5 = INTEGER: 269<br />
.1.3.6.1.4.1.2021.13.23.3.3.6 = INTEGER: 366<br />
.1.3.6.1.4.1.2021.13.23.3.3.7 = INTEGER: 291<br />
.1.3.6.1.4.1.2021.13.23.3.3.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.3.9 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.0 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.1 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.2 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.3 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.4 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.5 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.6 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.7 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.9 = INTEGER: 0<br />
</pre><br />
<br />
= Codebeispiele =<br />
<br />
* [[Onewire/Example/PHP (Deutsch) | PHP]]<br />
* [[Onewire/Example/Perl (Deutsch) | Perl]]<br />
* [[Onewire/Example/Python | Python]]<br />
* [[Onewire/Example/Shell | sh/bash]]<br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=509Onewire (Deutsch)2012-04-20T14:58:58Z<p>Sittner: /* Polling Modus */</p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
│ │ [*] Onewire Polling │ │ <br />
│ │ (375) Time between discoveries in 0.8s steps │ │ <br />
│ │ (12) Time between polling in 0.8s steps │ │ <br />
│ │ [*] ECMD 1w list with values │ │ <br />
│ │ (10) Maximum sensor count │ │ <br />
<br />
Im Polling-Modus werden die Sensoren im Hintergrund abgefragt, so dass die Werte<br />
bei Bedarf direkt zur Verfügung stehen und nicht erst gewandelt bzw.<br />
eingelesen werden müssen. Der Intervall zwischen den Discoveries und zwischen<br />
den Abfragen der Werte kann getrennt eingestellt werden. Die Option<br />
'''ECMD 1w list with values''' bietet die Möglichkeit, die aktuellen Werte<br />
bei Aufruf von '''1w list''' mit ausgeben zu lassen. So können darauf folgende<br />
'''1w get''' Kommandos entfallen.<br />
<br />
Da zur Pufferung der Werte, ROM-Codes, etc. RAM-Speicher benötigt wird, muss<br />
per '''Maximum sensor count''' angegeben werden, für wie viele Sensoren Speicher<br />
reserviert wird.<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder, wenn das Argument <hexcode><br />
weggelassen wird, aller angeschlossener Sensoren. Im Polling-Modus wird dieses Kommando ignoriert.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
Falls Polling-Support aktiviert wurde können die Sensorwerte per SNMP abgefragt werden.<br />
Mit Naming-Support stehen auch die Namen per SNMP zur Verfügung und die Index-Nummern sind<br />
fix auf die Position in der Namenstabelle festgelegt. Dies ist sehr hilfreich, um bestimmte<br />
Sensoren über den SNMP-Index anzusprechen.<br />
<br />
Es gibt folgende OIDs:<br />
<br />
* .1.3.6.1.4.1.2021.13.23.3.1.<idx> : ROM-Code des Sensors<br />
* .1.3.6.1.4.1.2021.13.23.3.2.<idx> : Sensor-Name (nur mit Naming-Support)<br />
* .1.3.6.1.4.1.2021.13.23.3.3.<idx> : Temperaturwert in Centigrad<br />
* .1.3.6.1.4.1.2021.13.23.3.4.<idx> : 0 = Sensor nicht vorhanden, 1 = Sensor vorhanden<br />
<br />
Hier ein Beispiel:<br />
<br />
<pre><br />
# snmpwalk -Osn -c public -v 1 192.168.255.90 1.3.6.1.4.1.2021.13.23.3<br />
.1.3.6.1.4.1.2021.13.23.3.1.0 = STRING: "1080cff6010800f9"<br />
.1.3.6.1.4.1.2021.13.23.3.1.1 = STRING: "10c8cff60108002d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.2 = STRING: "1029f6dc0108002f"<br />
.1.3.6.1.4.1.2021.13.23.3.1.3 = STRING: "10f2d0f60108001c"<br />
.1.3.6.1.4.1.2021.13.23.3.1.4 = STRING: "105a17f70108001d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.5 = STRING: "10b8d8f601080098"<br />
.1.3.6.1.4.1.2021.13.23.3.1.6 = STRING: "104dedf601080057"<br />
.1.3.6.1.4.1.2021.13.23.3.1.7 = STRING: "10011af701080027"<br />
.1.3.6.1.4.1.2021.13.23.3.1.8 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.1.9 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.2.0 = STRING: "kessel"<br />
.1.3.6.1.4.1.2021.13.23.3.2.1 = STRING: "warmwasser"<br />
.1.3.6.1.4.1.2021.13.23.3.2.2 = STRING: "aussen"<br />
.1.3.6.1.4.1.2021.13.23.3.2.3 = STRING: "speicher"<br />
.1.3.6.1.4.1.2021.13.23.3.2.4 = STRING: "heizung vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.5 = STRING: "heizung rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.6 = STRING: "boiler vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.7 = STRING: "boiler rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.8 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.2.9 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.3.0 = INTEGER: 334<br />
.1.3.6.1.4.1.2021.13.23.3.3.1 = INTEGER: 467<br />
.1.3.6.1.4.1.2021.13.23.3.3.2 = INTEGER: 127<br />
.1.3.6.1.4.1.2021.13.23.3.3.3 = INTEGER: 185<br />
.1.3.6.1.4.1.2021.13.23.3.3.4 = INTEGER: 318<br />
.1.3.6.1.4.1.2021.13.23.3.3.5 = INTEGER: 269<br />
.1.3.6.1.4.1.2021.13.23.3.3.6 = INTEGER: 366<br />
.1.3.6.1.4.1.2021.13.23.3.3.7 = INTEGER: 291<br />
.1.3.6.1.4.1.2021.13.23.3.3.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.3.9 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.0 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.1 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.2 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.3 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.4 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.5 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.6 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.7 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.9 = INTEGER: 0<br />
</pre><br />
<br />
= Codebeispiele =<br />
<br />
* [[Onewire/Example/PHP (Deutsch) | PHP]]<br />
* [[Onewire/Example/Perl (Deutsch) | Perl]]<br />
* [[Onewire/Example/Python | Python]]<br />
* [[Onewire/Example/Shell | sh/bash]]<br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=495Onewire (Deutsch)2012-04-14T10:22:39Z<p>Sittner: /* Onewire Befehle */</p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder, wenn das Argument <hexcode><br />
weggelassen wird, aller angeschlossener Sensoren. Im Polling-Modus wird dieses Kommando ignoriert.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
Falls Polling-Support aktiviert wurde können die Sensorwerte per SNMP abgefragt werden.<br />
Mit Naming-Support stehen auch die Namen per SNMP zur Verfügung und die Index-Nummern sind<br />
fix auf die Position in der Namenstabelle festgelegt. Dies ist sehr hilfreich, um bestimmte<br />
Sensoren über den SNMP-Index anzusprechen.<br />
<br />
Es gibt folgende OIDs:<br />
<br />
* .1.3.6.1.4.1.2021.13.23.3.1.<idx> : ROM-Code des Sensors<br />
* .1.3.6.1.4.1.2021.13.23.3.2.<idx> : Sensor-Name (nur mit Naming-Support)<br />
* .1.3.6.1.4.1.2021.13.23.3.3.<idx> : Temperaturwert in Centigrad<br />
* .1.3.6.1.4.1.2021.13.23.3.4.<idx> : 0 = Sensor nicht vorhanden, 1 = Sensor vorhanden<br />
<br />
Hier ein Beispiel:<br />
<br />
<pre><br />
# snmpwalk -Osn -c public -v 1 192.168.255.90 1.3.6.1.4.1.2021.13.23.3<br />
.1.3.6.1.4.1.2021.13.23.3.1.0 = STRING: "1080cff6010800f9"<br />
.1.3.6.1.4.1.2021.13.23.3.1.1 = STRING: "10c8cff60108002d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.2 = STRING: "1029f6dc0108002f"<br />
.1.3.6.1.4.1.2021.13.23.3.1.3 = STRING: "10f2d0f60108001c"<br />
.1.3.6.1.4.1.2021.13.23.3.1.4 = STRING: "105a17f70108001d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.5 = STRING: "10b8d8f601080098"<br />
.1.3.6.1.4.1.2021.13.23.3.1.6 = STRING: "104dedf601080057"<br />
.1.3.6.1.4.1.2021.13.23.3.1.7 = STRING: "10011af701080027"<br />
.1.3.6.1.4.1.2021.13.23.3.1.8 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.1.9 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.2.0 = STRING: "kessel"<br />
.1.3.6.1.4.1.2021.13.23.3.2.1 = STRING: "warmwasser"<br />
.1.3.6.1.4.1.2021.13.23.3.2.2 = STRING: "aussen"<br />
.1.3.6.1.4.1.2021.13.23.3.2.3 = STRING: "speicher"<br />
.1.3.6.1.4.1.2021.13.23.3.2.4 = STRING: "heizung vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.5 = STRING: "heizung rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.6 = STRING: "boiler vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.7 = STRING: "boiler rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.8 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.2.9 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.3.0 = INTEGER: 334<br />
.1.3.6.1.4.1.2021.13.23.3.3.1 = INTEGER: 467<br />
.1.3.6.1.4.1.2021.13.23.3.3.2 = INTEGER: 127<br />
.1.3.6.1.4.1.2021.13.23.3.3.3 = INTEGER: 185<br />
.1.3.6.1.4.1.2021.13.23.3.3.4 = INTEGER: 318<br />
.1.3.6.1.4.1.2021.13.23.3.3.5 = INTEGER: 269<br />
.1.3.6.1.4.1.2021.13.23.3.3.6 = INTEGER: 366<br />
.1.3.6.1.4.1.2021.13.23.3.3.7 = INTEGER: 291<br />
.1.3.6.1.4.1.2021.13.23.3.3.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.3.9 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.0 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.1 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.2 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.3 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.4 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.5 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.6 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.7 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.9 = INTEGER: 0<br />
</pre><br />
<br />
= Beispiele =<br />
<br />
== sh oder bash ==<br />
<br />
Einfaches SH (Linux Shell) Script von stesie (irc) zum Auslesen von einem Wert<br />
(udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
SENSORID=10529f7001080016<br />
#ESEXIP=2001:6f8:1209:23:42::17 #IPv6 Adresse<br />
ESEXIP=192.168.255.90<br />
<br />
#IPv6<br />
#echo 1w convert $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1 <br />
#echo 1w get $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //' <br />
<br />
#IPv4<br />
echo 1w convert $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1<br />
echo 1w get $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //'<br />
</source><br />
<br />
bash Script von Tron12 zum Auslesen aller Werte<br />
(Achtung Port 2701 ist nicht standard!! Sowie udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
#<br />
# netcat-openbsd 1.89-3ubuntu2<br />
<br />
NETIOIP="-4 192.168.178.249"<br />
<br />
#für IPv6:<br />
#NETIOIP="-6 2001:6f8:1209:23:42::17"<br />
<br />
NETIOPORT="2702"<br />
<br />
N_DATE=`echo date | nc -u $NETIOIP $NETIOPORT -q 1 ` <br />
N_GET_ID=`echo 1w list | nc -u $NETIOIP $NETIOPORT -q 1 | grep -qe OK || exit 1`<br />
<br />
echo "Date: $N_DATE"<br />
echo "---------------------------------"<br />
<br />
for i in $N_GET_ID<br />
do<br />
tmp=`echo 1w convert $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null | grep -qe OK || exit 1`<br />
tmp=`echo 1w get $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null `<br />
echo "Sensor: $i :: $tmp"<br />
done<br />
</source><br />
<br />
== Perl ==<br />
<br />
Beispiel in Perl das alle Sensoren ermittelt und anschließend die Werte ausgibt.<br />
Benötigt wird das Modul NET das kein IPv6 kann<br />
<br />
<source lang="perl"><br />
#!/usr/bin/perl -w<br />
#Auslesen der 1 Wire Sensoren an einem AVR-NET-IO mit ethersex<br />
<br />
use strict;<br />
use Net::Telnet ();<br />
<br />
my $esexip="192.168.255.90";<br />
my $esexport="2701";<br />
my $esex;<br />
my @sensor;<br />
my $sensor;<br />
my $dummy;<br />
my $temp;<br />
<br />
$esex = Net::Telnet->new || die "kann Ethersex nicht finden";;<br />
$esex->open(Host => $esexip,<br />
Port => $esexport,<br />
Timeout => 2);<br />
<br />
#Alles Sensor-IDs auslesen und dem Array @sensor zuweisen<br />
$esex->print("1w list");<br />
($sensor) = $esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
@sensor=split(/\s+/, $sensor);<br />
print "@sensor","\n"; #Kontrollausgabe<br />
<br />
my $zahler=@sensor;<br />
print "Anzahl der Elemente :",$zahler,"\n\n";<br />
<br />
#Alles Sensore Temperatur einlesen<br />
$esex->print("1w convert");<br />
$esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
<br />
#Sensor ID inklusive Wert ausgeben<br />
foreach (@sensor) {<br />
$esex->print("1w get $_");<br />
<br />
($dummy,$temp)=$esex->waitfor(Match =>'/[-]?\d+\.\d+/',<br />
Timeout => 5);<br />
<br />
print "Temperatur vom ID ",$_,": ",$temp," C°","\n";<br />
}<br />
</source><br />
<br />
== Python ==<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
<br />
from socket import *<br />
<br />
def connectEP():<br />
s = socket(AF_INET, SOCK_STREAM)<br />
s.settimeout(5)<br />
s.connect(("192.168.5.3", 2701))<br />
return s<br />
<br />
def getTemperature():<br />
s.send("1w list\n")<br />
sensors = []<br />
sensors_result = {}<br />
<br />
# list aller Sensoren<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if not response: break<br />
if response != "OK":<br />
sensors.append(response)<br />
else:<br />
break<br />
<br />
# wert konvertieren<br />
for sensor in sensors:<br />
s.send("1w convert " + sensor + "\n")<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if response == "OK":<br />
break <br />
<br />
# wert auslesen <br />
s.send("1w get " + sensor + "\n")<br />
response = s.recv(1024).rstrip("\n").lstrip()<br />
sensors_result[sensor] = response<br />
return(sensors_result)<br />
<br />
s = connectEP()<br />
for sensor, value in getTemperature().iteritems():<br />
print sensor + " " + value<br />
</source><br />
<br />
== PHP ==<br />
<br />
<source lang="php"><br />
<br />
<html><br />
<br />
<head><br />
<title>ethersex php example</title><br />
</head><br />
<br />
<body><br />
<br />
<?php<br />
<br />
define(IP, '192.168.10.9'); // deine ethersex ip adresse<br />
define(PORT, 2701); // standard port im image<br />
<br />
request("1w convert");<br />
<br />
$response = request("1w list");<br />
$explode = explode("\n", $response);<br />
<br />
for ($i=0; $i < count($explode)-2; $i++) {<br />
echo "Sensor: " . trim($explode[$i]);<br />
echo " -- Wert: " . request("1w get " . $explode[$i]);<br />
echo "<br>\n";<br />
}<br />
<br />
function request($request) {<br />
$rs = fsockopen(IP, PORT);<br />
<br />
if (!$rs) {<br />
$response = "Kann Verbindung nicht aufbauen!";<br />
}<br />
else {<br />
$response ="";<br />
$request = "!" . $request . "\r\n";<br />
<br />
fputs($rs, $request);<br />
<br />
while (!feof($rs)) {<br />
$response .= fgets($rs, 128);<br />
}<br />
fclose($rs);<br />
}<br />
<br />
return $response;<br />
}<br />
<br />
?><br />
<br />
</body><br />
</source><br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=494Onewire (Deutsch)2012-04-14T09:39:54Z<p>Sittner: /* Abfrage per SNMP */</p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder wenn das Argument <hexcode><br />
weggelassen wird aller angeschlossener Sensoren.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
Falls Polling-Support aktiviert wurde können die Sensorwerte per SNMP abgefragt werden.<br />
Mit Naming-Support stehen auch die Namen per SNMP zur Verfügung und die Index-Nummern sind<br />
fix auf die Position in der Namenstabelle festgelegt. Dies ist sehr hilfreich, um bestimmte<br />
Sensoren über den SNMP-Index anzusprechen.<br />
<br />
Es gibt folgende OIDs:<br />
<br />
* .1.3.6.1.4.1.2021.13.23.3.1.<idx> : ROM-Code des Sensors<br />
* .1.3.6.1.4.1.2021.13.23.3.2.<idx> : Sensor-Name (nur mit Naming-Support)<br />
* .1.3.6.1.4.1.2021.13.23.3.3.<idx> : Temperaturwert in Centigrad<br />
* .1.3.6.1.4.1.2021.13.23.3.4.<idx> : 0 = Sensor nicht vorhanden, 1 = Sensor vorhanden<br />
<br />
Hier ein Beispiel:<br />
<br />
<pre><br />
# snmpwalk -Osn -c public -v 1 192.168.255.90 1.3.6.1.4.1.2021.13.23.3<br />
.1.3.6.1.4.1.2021.13.23.3.1.0 = STRING: "1080cff6010800f9"<br />
.1.3.6.1.4.1.2021.13.23.3.1.1 = STRING: "10c8cff60108002d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.2 = STRING: "1029f6dc0108002f"<br />
.1.3.6.1.4.1.2021.13.23.3.1.3 = STRING: "10f2d0f60108001c"<br />
.1.3.6.1.4.1.2021.13.23.3.1.4 = STRING: "105a17f70108001d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.5 = STRING: "10b8d8f601080098"<br />
.1.3.6.1.4.1.2021.13.23.3.1.6 = STRING: "104dedf601080057"<br />
.1.3.6.1.4.1.2021.13.23.3.1.7 = STRING: "10011af701080027"<br />
.1.3.6.1.4.1.2021.13.23.3.1.8 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.1.9 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.2.0 = STRING: "kessel"<br />
.1.3.6.1.4.1.2021.13.23.3.2.1 = STRING: "warmwasser"<br />
.1.3.6.1.4.1.2021.13.23.3.2.2 = STRING: "aussen"<br />
.1.3.6.1.4.1.2021.13.23.3.2.3 = STRING: "speicher"<br />
.1.3.6.1.4.1.2021.13.23.3.2.4 = STRING: "heizung vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.5 = STRING: "heizung rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.6 = STRING: "boiler vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.7 = STRING: "boiler rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.8 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.2.9 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.3.0 = INTEGER: 334<br />
.1.3.6.1.4.1.2021.13.23.3.3.1 = INTEGER: 467<br />
.1.3.6.1.4.1.2021.13.23.3.3.2 = INTEGER: 127<br />
.1.3.6.1.4.1.2021.13.23.3.3.3 = INTEGER: 185<br />
.1.3.6.1.4.1.2021.13.23.3.3.4 = INTEGER: 318<br />
.1.3.6.1.4.1.2021.13.23.3.3.5 = INTEGER: 269<br />
.1.3.6.1.4.1.2021.13.23.3.3.6 = INTEGER: 366<br />
.1.3.6.1.4.1.2021.13.23.3.3.7 = INTEGER: 291<br />
.1.3.6.1.4.1.2021.13.23.3.3.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.3.9 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.0 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.1 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.2 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.3 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.4 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.5 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.6 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.7 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.9 = INTEGER: 0<br />
</pre><br />
<br />
= Beispiele =<br />
<br />
== sh oder bash ==<br />
<br />
Einfaches SH (Linux Shell) Script von stesie (irc) zum Auslesen von einem Wert<br />
(udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
SENSORID=10529f7001080016<br />
#ESEXIP=2001:6f8:1209:23:42::17 #IPv6 Adresse<br />
ESEXIP=192.168.255.90<br />
<br />
#IPv6<br />
#echo 1w convert $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1 <br />
#echo 1w get $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //' <br />
<br />
#IPv4<br />
echo 1w convert $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1<br />
echo 1w get $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //'<br />
</source><br />
<br />
bash Script von Tron12 zum Auslesen aller Werte<br />
(Achtung Port 2701 ist nicht standard!! Sowie udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
#<br />
# netcat-openbsd 1.89-3ubuntu2<br />
<br />
NETIOIP="-4 192.168.178.249"<br />
<br />
#für IPv6:<br />
#NETIOIP="-6 2001:6f8:1209:23:42::17"<br />
<br />
NETIOPORT="2702"<br />
<br />
N_DATE=`echo date | nc -u $NETIOIP $NETIOPORT -q 1 ` <br />
N_GET_ID=`echo 1w list | nc -u $NETIOIP $NETIOPORT -q 1 | grep -qe OK || exit 1`<br />
<br />
echo "Date: $N_DATE"<br />
echo "---------------------------------"<br />
<br />
for i in $N_GET_ID<br />
do<br />
tmp=`echo 1w convert $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null | grep -qe OK || exit 1`<br />
tmp=`echo 1w get $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null `<br />
echo "Sensor: $i :: $tmp"<br />
done<br />
</source><br />
<br />
== Perl ==<br />
<br />
Beispiel in Perl das alle Sensoren ermittelt und anschließend die Werte ausgibt.<br />
Benötigt wird das Modul NET das kein IPv6 kann<br />
<br />
<source lang="perl"><br />
#!/usr/bin/perl -w<br />
#Auslesen der 1 Wire Sensoren an einem AVR-NET-IO mit ethersex<br />
<br />
use strict;<br />
use Net::Telnet ();<br />
<br />
my $esexip="192.168.255.90";<br />
my $esexport="2701";<br />
my $esex;<br />
my @sensor;<br />
my $sensor;<br />
my $dummy;<br />
my $temp;<br />
<br />
$esex = Net::Telnet->new || die "kann Ethersex nicht finden";;<br />
$esex->open(Host => $esexip,<br />
Port => $esexport,<br />
Timeout => 2);<br />
<br />
#Alles Sensor-IDs auslesen und dem Array @sensor zuweisen<br />
$esex->print("1w list");<br />
($sensor) = $esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
@sensor=split(/\s+/, $sensor);<br />
print "@sensor","\n"; #Kontrollausgabe<br />
<br />
my $zahler=@sensor;<br />
print "Anzahl der Elemente :",$zahler,"\n\n";<br />
<br />
#Alles Sensore Temperatur einlesen<br />
$esex->print("1w convert");<br />
$esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
<br />
#Sensor ID inklusive Wert ausgeben<br />
foreach (@sensor) {<br />
$esex->print("1w get $_");<br />
<br />
($dummy,$temp)=$esex->waitfor(Match =>'/[-]?\d+\.\d+/',<br />
Timeout => 5);<br />
<br />
print "Temperatur vom ID ",$_,": ",$temp," C°","\n";<br />
}<br />
</source><br />
<br />
== Python ==<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
<br />
from socket import *<br />
<br />
def connectEP():<br />
s = socket(AF_INET, SOCK_STREAM)<br />
s.settimeout(5)<br />
s.connect(("192.168.5.3", 2701))<br />
return s<br />
<br />
def getTemperature():<br />
s.send("1w list\n")<br />
sensors = []<br />
sensors_result = {}<br />
<br />
# list aller Sensoren<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if not response: break<br />
if response != "OK":<br />
sensors.append(response)<br />
else:<br />
break<br />
<br />
# wert konvertieren<br />
for sensor in sensors:<br />
s.send("1w convert " + sensor + "\n")<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if response == "OK":<br />
break <br />
<br />
# wert auslesen <br />
s.send("1w get " + sensor + "\n")<br />
response = s.recv(1024).rstrip("\n").lstrip()<br />
sensors_result[sensor] = response<br />
return(sensors_result)<br />
<br />
s = connectEP()<br />
for sensor, value in getTemperature().iteritems():<br />
print sensor + " " + value<br />
</source><br />
<br />
== PHP ==<br />
<br />
<source lang="php"><br />
<br />
<html><br />
<br />
<head><br />
<title>ethersex php example</title><br />
</head><br />
<br />
<body><br />
<br />
<?php<br />
<br />
define(IP, '192.168.10.9'); // deine ethersex ip adresse<br />
define(PORT, 2701); // standard port im image<br />
<br />
request("1w convert");<br />
<br />
$response = request("1w list");<br />
$explode = explode("\n", $response);<br />
<br />
for ($i=0; $i < count($explode)-2; $i++) {<br />
echo "Sensor: " . trim($explode[$i]);<br />
echo " -- Wert: " . request("1w get " . $explode[$i]);<br />
echo "<br>\n";<br />
}<br />
<br />
function request($request) {<br />
$rs = fsockopen(IP, PORT);<br />
<br />
if (!$rs) {<br />
$response = "Kann Verbindung nicht aufbauen!";<br />
}<br />
else {<br />
$response ="";<br />
$request = "!" . $request . "\r\n";<br />
<br />
fputs($rs, $request);<br />
<br />
while (!feof($rs)) {<br />
$response .= fgets($rs, 128);<br />
}<br />
fclose($rs);<br />
}<br />
<br />
return $response;<br />
}<br />
<br />
?><br />
<br />
</body><br />
</source><br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=493Onewire (Deutsch)2012-04-14T09:37:32Z<p>Sittner: /* Abfrage per SNMP */</p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder wenn das Argument <hexcode><br />
weggelassen wird aller angeschlossener Sensoren.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
Falls Polling-Support aktiviert wurde können die Sensorwerte per SNMP abgefragt werden.<br />
Mit Naming-Support stehen auch die Namen per SNMP zur Verfügung und die Index-Nummern sind<br />
fix auf die Position in der Namenstabelle festgelegt. Dies ist sehr hilfreich, um bestimmte<br />
Sensoren über den SNMP-Index anzusprechen.<br />
<br />
Es gibt folgende OIDs:<br />
<br />
* .1.3.6.1.4.1.2021.13.23.3.1.<idx> : ROM-Code des Sensors<br />
* .1.3.6.1.4.1.2021.13.23.3.2.<idx> : Sensor-Name (nur mit Naming-Support)<br />
* .1.3.6.1.4.1.2021.13.23.3.3.<idx> : Temperaturwert in Centigrad<br />
* .1.3.6.1.4.1.2021.13.23.3.4.<idx> : 0 = Sensor nicht vorhanden, 1 = Sensor vorhanden<br />
<br />
Hier ein Beispiel:<br />
<br />
<pre><br />
# snmpwalk -Osn -c public -v 1 10.0.0.105 1.3.6.1.4.1.2021.13.23.3<br />
.1.3.6.1.4.1.2021.13.23.3.1.0 = STRING: "1080cff6010800f9"<br />
.1.3.6.1.4.1.2021.13.23.3.1.1 = STRING: "10c8cff60108002d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.2 = STRING: "1029f6dc0108002f"<br />
.1.3.6.1.4.1.2021.13.23.3.1.3 = STRING: "10f2d0f60108001c"<br />
.1.3.6.1.4.1.2021.13.23.3.1.4 = STRING: "105a17f70108001d"<br />
.1.3.6.1.4.1.2021.13.23.3.1.5 = STRING: "10b8d8f601080098"<br />
.1.3.6.1.4.1.2021.13.23.3.1.6 = STRING: "104dedf601080057"<br />
.1.3.6.1.4.1.2021.13.23.3.1.7 = STRING: "10011af701080027"<br />
.1.3.6.1.4.1.2021.13.23.3.1.8 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.1.9 = STRING: "0000000000000000"<br />
.1.3.6.1.4.1.2021.13.23.3.2.0 = STRING: "kessel"<br />
.1.3.6.1.4.1.2021.13.23.3.2.1 = STRING: "warmwasser"<br />
.1.3.6.1.4.1.2021.13.23.3.2.2 = STRING: "aussen"<br />
.1.3.6.1.4.1.2021.13.23.3.2.3 = STRING: "speicher"<br />
.1.3.6.1.4.1.2021.13.23.3.2.4 = STRING: "heizung vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.5 = STRING: "heizung rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.6 = STRING: "boiler vl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.7 = STRING: "boiler rl"<br />
.1.3.6.1.4.1.2021.13.23.3.2.8 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.2.9 = ""<br />
.1.3.6.1.4.1.2021.13.23.3.3.0 = INTEGER: 334<br />
.1.3.6.1.4.1.2021.13.23.3.3.1 = INTEGER: 467<br />
.1.3.6.1.4.1.2021.13.23.3.3.2 = INTEGER: 127<br />
.1.3.6.1.4.1.2021.13.23.3.3.3 = INTEGER: 185<br />
.1.3.6.1.4.1.2021.13.23.3.3.4 = INTEGER: 318<br />
.1.3.6.1.4.1.2021.13.23.3.3.5 = INTEGER: 269<br />
.1.3.6.1.4.1.2021.13.23.3.3.6 = INTEGER: 366<br />
.1.3.6.1.4.1.2021.13.23.3.3.7 = INTEGER: 291<br />
.1.3.6.1.4.1.2021.13.23.3.3.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.3.9 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.0 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.1 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.2 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.3 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.4 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.5 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.6 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.7 = INTEGER: 1<br />
.1.3.6.1.4.1.2021.13.23.3.4.8 = INTEGER: 0<br />
.1.3.6.1.4.1.2021.13.23.3.4.9 = INTEGER: 0<br />
</pre><br />
<br />
= Beispiele =<br />
<br />
== sh oder bash ==<br />
<br />
Einfaches SH (Linux Shell) Script von stesie (irc) zum Auslesen von einem Wert<br />
(udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
SENSORID=10529f7001080016<br />
#ESEXIP=2001:6f8:1209:23:42::17 #IPv6 Adresse<br />
ESEXIP=192.168.255.90<br />
<br />
#IPv6<br />
#echo 1w convert $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1 <br />
#echo 1w get $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //' <br />
<br />
#IPv4<br />
echo 1w convert $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1<br />
echo 1w get $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //'<br />
</source><br />
<br />
bash Script von Tron12 zum Auslesen aller Werte<br />
(Achtung Port 2701 ist nicht standard!! Sowie udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
#<br />
# netcat-openbsd 1.89-3ubuntu2<br />
<br />
NETIOIP="-4 192.168.178.249"<br />
<br />
#für IPv6:<br />
#NETIOIP="-6 2001:6f8:1209:23:42::17"<br />
<br />
NETIOPORT="2702"<br />
<br />
N_DATE=`echo date | nc -u $NETIOIP $NETIOPORT -q 1 ` <br />
N_GET_ID=`echo 1w list | nc -u $NETIOIP $NETIOPORT -q 1 | grep -qe OK || exit 1`<br />
<br />
echo "Date: $N_DATE"<br />
echo "---------------------------------"<br />
<br />
for i in $N_GET_ID<br />
do<br />
tmp=`echo 1w convert $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null | grep -qe OK || exit 1`<br />
tmp=`echo 1w get $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null `<br />
echo "Sensor: $i :: $tmp"<br />
done<br />
</source><br />
<br />
== Perl ==<br />
<br />
Beispiel in Perl das alle Sensoren ermittelt und anschließend die Werte ausgibt.<br />
Benötigt wird das Modul NET das kein IPv6 kann<br />
<br />
<source lang="perl"><br />
#!/usr/bin/perl -w<br />
#Auslesen der 1 Wire Sensoren an einem AVR-NET-IO mit ethersex<br />
<br />
use strict;<br />
use Net::Telnet ();<br />
<br />
my $esexip="192.168.255.90";<br />
my $esexport="2701";<br />
my $esex;<br />
my @sensor;<br />
my $sensor;<br />
my $dummy;<br />
my $temp;<br />
<br />
$esex = Net::Telnet->new || die "kann Ethersex nicht finden";;<br />
$esex->open(Host => $esexip,<br />
Port => $esexport,<br />
Timeout => 2);<br />
<br />
#Alles Sensor-IDs auslesen und dem Array @sensor zuweisen<br />
$esex->print("1w list");<br />
($sensor) = $esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
@sensor=split(/\s+/, $sensor);<br />
print "@sensor","\n"; #Kontrollausgabe<br />
<br />
my $zahler=@sensor;<br />
print "Anzahl der Elemente :",$zahler,"\n\n";<br />
<br />
#Alles Sensore Temperatur einlesen<br />
$esex->print("1w convert");<br />
$esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
<br />
#Sensor ID inklusive Wert ausgeben<br />
foreach (@sensor) {<br />
$esex->print("1w get $_");<br />
<br />
($dummy,$temp)=$esex->waitfor(Match =>'/[-]?\d+\.\d+/',<br />
Timeout => 5);<br />
<br />
print "Temperatur vom ID ",$_,": ",$temp," C°","\n";<br />
}<br />
</source><br />
<br />
== Python ==<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
<br />
from socket import *<br />
<br />
def connectEP():<br />
s = socket(AF_INET, SOCK_STREAM)<br />
s.settimeout(5)<br />
s.connect(("192.168.5.3", 2701))<br />
return s<br />
<br />
def getTemperature():<br />
s.send("1w list\n")<br />
sensors = []<br />
sensors_result = {}<br />
<br />
# list aller Sensoren<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if not response: break<br />
if response != "OK":<br />
sensors.append(response)<br />
else:<br />
break<br />
<br />
# wert konvertieren<br />
for sensor in sensors:<br />
s.send("1w convert " + sensor + "\n")<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if response == "OK":<br />
break <br />
<br />
# wert auslesen <br />
s.send("1w get " + sensor + "\n")<br />
response = s.recv(1024).rstrip("\n").lstrip()<br />
sensors_result[sensor] = response<br />
return(sensors_result)<br />
<br />
s = connectEP()<br />
for sensor, value in getTemperature().iteritems():<br />
print sensor + " " + value<br />
</source><br />
<br />
== PHP ==<br />
<br />
<source lang="php"><br />
<br />
<html><br />
<br />
<head><br />
<title>ethersex php example</title><br />
</head><br />
<br />
<body><br />
<br />
<?php<br />
<br />
define(IP, '192.168.10.9'); // deine ethersex ip adresse<br />
define(PORT, 2701); // standard port im image<br />
<br />
request("1w convert");<br />
<br />
$response = request("1w list");<br />
$explode = explode("\n", $response);<br />
<br />
for ($i=0; $i < count($explode)-2; $i++) {<br />
echo "Sensor: " . trim($explode[$i]);<br />
echo " -- Wert: " . request("1w get " . $explode[$i]);<br />
echo "<br>\n";<br />
}<br />
<br />
function request($request) {<br />
$rs = fsockopen(IP, PORT);<br />
<br />
if (!$rs) {<br />
$response = "Kann Verbindung nicht aufbauen!";<br />
}<br />
else {<br />
$response ="";<br />
$request = "!" . $request . "\r\n";<br />
<br />
fputs($rs, $request);<br />
<br />
while (!feof($rs)) {<br />
$response .= fgets($rs, 128);<br />
}<br />
fclose($rs);<br />
}<br />
<br />
return $response;<br />
}<br />
<br />
?><br />
<br />
</body><br />
</source><br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=492Onewire (Deutsch)2012-04-14T09:24:27Z<p>Sittner: </p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
Bei aktiviertem Naming-Support wird (per TAB getrennt) zusätzlich der Name ausgegeben. Außerdem<br />
kann mit '''ECMD 1w list with values (ONEWIRE_ECMD_LIST_VALUE_SUPPORT)''' der aktuelle Temperaturwert<br />
mit ausgegeben werden. Dies erspart zusätzliche '''1w get''' Aufrufe, setzt allerding Polling-Support<br />
vorraus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder wenn das Argument <hexcode><br />
weggelassen wird aller angeschlossener Sensoren.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den Webserver und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden. Das Beispiel zeigt die SVG-Version<br />
mit Naming-Support:<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin AVR-NET-IO Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
= Beispiele =<br />
<br />
== sh oder bash ==<br />
<br />
Einfaches SH (Linux Shell) Script von stesie (irc) zum Auslesen von einem Wert<br />
(udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
SENSORID=10529f7001080016<br />
#ESEXIP=2001:6f8:1209:23:42::17 #IPv6 Adresse<br />
ESEXIP=192.168.255.90<br />
<br />
#IPv6<br />
#echo 1w convert $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1 <br />
#echo 1w get $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //' <br />
<br />
#IPv4<br />
echo 1w convert $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1<br />
echo 1w get $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //'<br />
</source><br />
<br />
bash Script von Tron12 zum Auslesen aller Werte<br />
(Achtung Port 2701 ist nicht standard!! Sowie udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
#<br />
# netcat-openbsd 1.89-3ubuntu2<br />
<br />
NETIOIP="-4 192.168.178.249"<br />
<br />
#für IPv6:<br />
#NETIOIP="-6 2001:6f8:1209:23:42::17"<br />
<br />
NETIOPORT="2702"<br />
<br />
N_DATE=`echo date | nc -u $NETIOIP $NETIOPORT -q 1 ` <br />
N_GET_ID=`echo 1w list | nc -u $NETIOIP $NETIOPORT -q 1 | grep -qe OK || exit 1`<br />
<br />
echo "Date: $N_DATE"<br />
echo "---------------------------------"<br />
<br />
for i in $N_GET_ID<br />
do<br />
tmp=`echo 1w convert $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null | grep -qe OK || exit 1`<br />
tmp=`echo 1w get $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null `<br />
echo "Sensor: $i :: $tmp"<br />
done<br />
</source><br />
<br />
== Perl ==<br />
<br />
Beispiel in Perl das alle Sensoren ermittelt und anschließend die Werte ausgibt.<br />
Benötigt wird das Modul NET das kein IPv6 kann<br />
<br />
<source lang="perl"><br />
#!/usr/bin/perl -w<br />
#Auslesen der 1 Wire Sensoren an einem AVR-NET-IO mit ethersex<br />
<br />
use strict;<br />
use Net::Telnet ();<br />
<br />
my $esexip="192.168.255.90";<br />
my $esexport="2701";<br />
my $esex;<br />
my @sensor;<br />
my $sensor;<br />
my $dummy;<br />
my $temp;<br />
<br />
$esex = Net::Telnet->new || die "kann Ethersex nicht finden";;<br />
$esex->open(Host => $esexip,<br />
Port => $esexport,<br />
Timeout => 2);<br />
<br />
#Alles Sensor-IDs auslesen und dem Array @sensor zuweisen<br />
$esex->print("1w list");<br />
($sensor) = $esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
@sensor=split(/\s+/, $sensor);<br />
print "@sensor","\n"; #Kontrollausgabe<br />
<br />
my $zahler=@sensor;<br />
print "Anzahl der Elemente :",$zahler,"\n\n";<br />
<br />
#Alles Sensore Temperatur einlesen<br />
$esex->print("1w convert");<br />
$esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
<br />
#Sensor ID inklusive Wert ausgeben<br />
foreach (@sensor) {<br />
$esex->print("1w get $_");<br />
<br />
($dummy,$temp)=$esex->waitfor(Match =>'/[-]?\d+\.\d+/',<br />
Timeout => 5);<br />
<br />
print "Temperatur vom ID ",$_,": ",$temp," C°","\n";<br />
}<br />
</source><br />
<br />
== Python ==<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
<br />
from socket import *<br />
<br />
def connectEP():<br />
s = socket(AF_INET, SOCK_STREAM)<br />
s.settimeout(5)<br />
s.connect(("192.168.5.3", 2701))<br />
return s<br />
<br />
def getTemperature():<br />
s.send("1w list\n")<br />
sensors = []<br />
sensors_result = {}<br />
<br />
# list aller Sensoren<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if not response: break<br />
if response != "OK":<br />
sensors.append(response)<br />
else:<br />
break<br />
<br />
# wert konvertieren<br />
for sensor in sensors:<br />
s.send("1w convert " + sensor + "\n")<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if response == "OK":<br />
break <br />
<br />
# wert auslesen <br />
s.send("1w get " + sensor + "\n")<br />
response = s.recv(1024).rstrip("\n").lstrip()<br />
sensors_result[sensor] = response<br />
return(sensors_result)<br />
<br />
s = connectEP()<br />
for sensor, value in getTemperature().iteritems():<br />
print sensor + " " + value<br />
</source><br />
<br />
== PHP ==<br />
<br />
<source lang="php"><br />
<br />
<html><br />
<br />
<head><br />
<title>ethersex php example</title><br />
</head><br />
<br />
<body><br />
<br />
<?php<br />
<br />
define(IP, '192.168.10.9'); // deine ethersex ip adresse<br />
define(PORT, 2701); // standard port im image<br />
<br />
request("1w convert");<br />
<br />
$response = request("1w list");<br />
$explode = explode("\n", $response);<br />
<br />
for ($i=0; $i < count($explode)-2; $i++) {<br />
echo "Sensor: " . trim($explode[$i]);<br />
echo " -- Wert: " . request("1w get " . $explode[$i]);<br />
echo "<br>\n";<br />
}<br />
<br />
function request($request) {<br />
$rs = fsockopen(IP, PORT);<br />
<br />
if (!$rs) {<br />
$response = "Kann Verbindung nicht aufbauen!";<br />
}<br />
else {<br />
$response ="";<br />
$request = "!" . $request . "\r\n";<br />
<br />
fputs($rs, $request);<br />
<br />
while (!feof($rs)) {<br />
$response .= fgets($rs, 128);<br />
}<br />
fclose($rs);<br />
}<br />
<br />
return $response;<br />
}<br />
<br />
?><br />
<br />
</body><br />
</source><br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=491Onewire (Deutsch)2012-04-14T09:12:43Z<p>Sittner: </p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder wenn das Argument <hexcode><br />
weggelassen wird aller angeschlossener Sensoren.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den [[Webserver]] und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden.<br />
<br />
[[File:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin [[AVR-NET-IO]] Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[File:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[File:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[File:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
= Beispiele =<br />
<br />
== sh oder bash ==<br />
<br />
Einfaches SH (Linux Shell) Script von stesie (irc) zum Auslesen von einem Wert<br />
(udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
SENSORID=10529f7001080016<br />
#ESEXIP=2001:6f8:1209:23:42::17 #IPv6 Adresse<br />
ESEXIP=192.168.255.90<br />
<br />
#IPv6<br />
#echo 1w convert $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1 <br />
#echo 1w get $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //' <br />
<br />
#IPv4<br />
echo 1w convert $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1<br />
echo 1w get $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //'<br />
</source><br />
<br />
bash Script von Tron12 zum Auslesen aller Werte<br />
(Achtung Port 2701 ist nicht standard!! Sowie udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
#<br />
# netcat-openbsd 1.89-3ubuntu2<br />
<br />
NETIOIP="-4 192.168.178.249"<br />
<br />
#für IPv6:<br />
#NETIOIP="-6 2001:6f8:1209:23:42::17"<br />
<br />
NETIOPORT="2702"<br />
<br />
N_DATE=`echo date | nc -u $NETIOIP $NETIOPORT -q 1 ` <br />
N_GET_ID=`echo 1w list | nc -u $NETIOIP $NETIOPORT -q 1 | grep -qe OK || exit 1`<br />
<br />
echo "Date: $N_DATE"<br />
echo "---------------------------------"<br />
<br />
for i in $N_GET_ID<br />
do<br />
tmp=`echo 1w convert $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null | grep -qe OK || exit 1`<br />
tmp=`echo 1w get $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null `<br />
echo "Sensor: $i :: $tmp"<br />
done<br />
</source><br />
<br />
== Perl ==<br />
<br />
Beispiel in Perl das alle Sensoren ermittelt und anschließend die Werte ausgibt.<br />
Benötigt wird das Modul NET das kein IPv6 kann<br />
<br />
<source lang="perl"><br />
#!/usr/bin/perl -w<br />
#Auslesen der 1 Wire Sensoren an einem AVR-NET-IO mit ethersex<br />
<br />
use strict;<br />
use Net::Telnet ();<br />
<br />
my $esexip="192.168.255.90";<br />
my $esexport="2701";<br />
my $esex;<br />
my @sensor;<br />
my $sensor;<br />
my $dummy;<br />
my $temp;<br />
<br />
$esex = Net::Telnet->new || die "kann Ethersex nicht finden";;<br />
$esex->open(Host => $esexip,<br />
Port => $esexport,<br />
Timeout => 2);<br />
<br />
#Alles Sensor-IDs auslesen und dem Array @sensor zuweisen<br />
$esex->print("1w list");<br />
($sensor) = $esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
@sensor=split(/\s+/, $sensor);<br />
print "@sensor","\n"; #Kontrollausgabe<br />
<br />
my $zahler=@sensor;<br />
print "Anzahl der Elemente :",$zahler,"\n\n";<br />
<br />
#Alles Sensore Temperatur einlesen<br />
$esex->print("1w convert");<br />
$esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
<br />
#Sensor ID inklusive Wert ausgeben<br />
foreach (@sensor) {<br />
$esex->print("1w get $_");<br />
<br />
($dummy,$temp)=$esex->waitfor(Match =>'/[-]?\d+\.\d+/',<br />
Timeout => 5);<br />
<br />
print "Temperatur vom ID ",$_,": ",$temp," C°","\n";<br />
}<br />
</source><br />
<br />
== Python ==<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
<br />
from socket import *<br />
<br />
def connectEP():<br />
s = socket(AF_INET, SOCK_STREAM)<br />
s.settimeout(5)<br />
s.connect(("192.168.5.3", 2701))<br />
return s<br />
<br />
def getTemperature():<br />
s.send("1w list\n")<br />
sensors = []<br />
sensors_result = {}<br />
<br />
# list aller Sensoren<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if not response: break<br />
if response != "OK":<br />
sensors.append(response)<br />
else:<br />
break<br />
<br />
# wert konvertieren<br />
for sensor in sensors:<br />
s.send("1w convert " + sensor + "\n")<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if response == "OK":<br />
break <br />
<br />
# wert auslesen <br />
s.send("1w get " + sensor + "\n")<br />
response = s.recv(1024).rstrip("\n").lstrip()<br />
sensors_result[sensor] = response<br />
return(sensors_result)<br />
<br />
s = connectEP()<br />
for sensor, value in getTemperature().iteritems():<br />
print sensor + " " + value<br />
</source><br />
<br />
== PHP ==<br />
<br />
<source lang="php"><br />
<br />
<html><br />
<br />
<head><br />
<title>ethersex php example</title><br />
</head><br />
<br />
<body><br />
<br />
<?php<br />
<br />
define(IP, '192.168.10.9'); // deine ethersex ip adresse<br />
define(PORT, 2701); // standard port im image<br />
<br />
request("1w convert");<br />
<br />
$response = request("1w list");<br />
$explode = explode("\n", $response);<br />
<br />
for ($i=0; $i < count($explode)-2; $i++) {<br />
echo "Sensor: " . trim($explode[$i]);<br />
echo " -- Wert: " . request("1w get " . $explode[$i]);<br />
echo "<br>\n";<br />
}<br />
<br />
function request($request) {<br />
$rs = fsockopen(IP, PORT);<br />
<br />
if (!$rs) {<br />
$response = "Kann Verbindung nicht aufbauen!";<br />
}<br />
else {<br />
$response ="";<br />
$request = "!" . $request . "\r\n";<br />
<br />
fputs($rs, $request);<br />
<br />
while (!feof($rs)) {<br />
$response .= fgets($rs, 128);<br />
}<br />
fclose($rs);<br />
}<br />
<br />
return $response;<br />
}<br />
<br />
?><br />
<br />
</body><br />
</source><br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=File:Onewire-svg.png&diff=490File:Onewire-svg.png2012-04-14T09:11:04Z<p>Sittner: </p>
<hr />
<div></div>Sittnerhttp://www.ethersex.de/index.php?title=File:Netio-1wire_normal.png&diff=489File:Netio-1wire normal.png2012-04-14T09:10:50Z<p>Sittner: </p>
<hr />
<div></div>Sittnerhttp://www.ethersex.de/index.php?title=File:Netio-1wire.png&diff=488File:Netio-1wire.png2012-04-14T09:10:39Z<p>Sittner: </p>
<hr />
<div></div>Sittnerhttp://www.ethersex.de/index.php?title=File:Ds18s20-par-pinout.jpg&diff=487File:Ds18s20-par-pinout.jpg2012-04-14T09:10:20Z<p>Sittner: </p>
<hr />
<div></div>Sittnerhttp://www.ethersex.de/index.php?title=Onewire_(Deutsch)&diff=486Onewire (Deutsch)2012-04-14T09:06:03Z<p>Sittner: Created page with "{{i18n|Onewire}} {{Module |NAME=Onewire |MENUCONFIG={{I/O}}->Onewire support |STATUS={{stable}} |PINNING=yes |ECMD={{has_ecmd}} |CONTROL6={{has_control6}} |DEPENDS=ECMD [[HT…"</p>
<hr />
<div>{{i18n|Onewire}}<br />
<br />
{{Module<br />
|NAME=Onewire<br />
|MENUCONFIG={{I/O}}->Onewire support<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|CONTROL6={{has_control6}}<br />
|DEPENDS=[[ECMD]] [[HTTPD]] (optional) [[SNMP]] (optional)<br />
|REQUIRES= -<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/hardware/onewire https://github.com/ethersex/ethersex/tree/master/hardware/onewire]<br />
}}<br />
<br />
Ethersex kann 1-wire Temperatursensoren mit [[ECMD]] auflisten und abfragen. Es wird eine reine<br />
Softwareimplementierung des Protokolls benutzt, was keine weiteren Hardware erfordert, als die<br />
Temperatursensoren selbst.<br />
<br />
= Pinning =<br />
<br />
In der Standardkonfiguration liegt der Datapin des Buses auf PD6 (kann z.B. in der pinning/hardware/netio.m4<br />
oder pinning/hardware/etherrape.m4 geändert werden). Die Definition der Pins erfolgt mit:<br />
<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PXn, PXm)<br />
</source><br />
<br />
wobei PXn und PNm Pins auf PORTX sind.<br />
<br />
Jeder Pin zwischen und einschließlich PXn und PXm bildet einen eingenständigen Onewire Bus.<br />
Du kannst bis zu acht Busse auf einem PORT definieren (alle Busse müssen auf dem selben PORT liegen!)<br />
<br />
== Beispiele ==<br />
<br />
Wenn Du nur einen einzigen Bus benötigst, definiere den Bereich wie folgt:<br />
<br />
'''PORTD: PIN2'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD2)<br />
</source><br />
<br />
Für drei Busse würde das ganze etwa so aussehen:<br />
<br />
'''PORTD: PIN2, PIN3, PIN4'''<br />
<source lang=c><br />
ONEWIRE_PORT_RANGE(PD2, PD4)<br />
</source><br />
<br />
= Polling Modus =<br />
<br />
= Benennung von Sensoren =<br />
<br />
= Unterstützte Hardware =<br />
<br />
Folgende 1-wire Hardware wird momentan durch Ethersex unterstützt:<br />
* DS1820 (Temperatursensor)<br />
* DS18B20 (Temperatursensor)<br />
* DS1822 (Temperatursensor)<br />
* DS2502 (EEPROM)<br />
* DS2450 (4 Kanal ADC)<br />
<br />
= Onewire Befehle =<br />
<br />
unter Linux als erstes netcat starten (hierbei natürlich die IP ggf modifizieren): <br />
<br />
netcat 192.168.0.15 2701<br />
<br />
danach am prompt:<br />
<br />
1w list<br />
<br />
Gibt eine Liste mit Hexcodes aller angeschlossenen und erkannten Onewire(tm) Sensoren aus.<br />
<br />
1w convert <hexcode><br />
<br />
Veranlasst eine Temperaturmessung des addressierten Sensors, oder wenn das Argument <hexcode><br />
weggelassen wird aller angeschlossener Sensoren.<br />
<br />
1w get <hexcode><br />
<br />
Gibt die gemessene Temperatur eines Sensors aus.<br />
<br />
= Einbindung in die [[HTTPD]]-Weboberfläche =<br />
<br />
Unter httpd/embed/ow.ht.m4, bzw httpd/embed/Xow.ht.m4 liegt eine Weboberflaeche, die alle Sensoren erkennt<br />
und ihre aktuelle Temperatur regelmässig per Ajax abfragt und anzeigt. Im Falle von Xow.ht.m4 wird sogar<br />
Graph der Temperatur mittels SVG gemalt. Um die Dateien einzubinden, muss man einfach bei aktiviertem<br />
Onewiresupport den [[Webserver]] und das Datei Inlining aktivieren.<br />
<br />
Die Dateien können dann unter ow.ht bzw. unter Xow.ht angezeigt werden.<br />
<br />
[[Bild:onewire-svg.png]]<br />
<br />
= Anschluss AVR-NET-IO =<br />
Für das Pollin [[AVR-NET-IO]] Board können die Sensoren DS18S20+ , <br />
<br />
normal Betrieb<br />
<br />
[[Bild:netio-1wire_normal.png]]<br />
<br />
parasitären Modus<br />
<br />
[[Bild:netio-1wire.png]]<br />
<br />
Anmerkung: Wenn man beim Net-IO nicht alle Analogeingänge benötigt, lässt sich der 1-Wire-Bus auch an der<br />
Schraubklemme ADC1 ganz gut aufschalten. Vorteil ist, dass man gleich alle passenden Spannungen (GND, +5V)<br />
an den beiden nebenliegenden Schraubklemmen hat. Das Pinning muss dann entspechend in der kann in der Datei<br />
pinning/hardware/netio.m4 von PD6 auf PA4 geändert werden. Vorteil dieser Konfiguration ist, dass man den<br />
DB-25-Verbinder zum Anschluss der Relaisplatine K8IO von Pollin frei hat und den EXT Steckverbinder zum<br />
Anschluss eines LCD über ein 4bit-Interface nutzen kann, ohne die Erweiterungsplatine von Pollin zu benötigen.<br />
<br />
Pinbelegung:<br />
<br />
[[Bild:ds18s20-par-pinout.jpg]]<br />
<br />
= Anschluss Etherrape =<br />
<br />
Die Schaltung je nach parasitärem oder normalem Betriebsmodus kann aus der NetIO Skizze übernommen werden.<br />
Data liegt auf PORTD an Pin 7:<br />
<br />
PORTD<br />
+---+<br />
|x x|<br />
|x X| <- Pin 7<br />
|x x<br />
|x x|<br />
|x x|<br />
+---+<br />
<br />
Direkt neben PORTD befinden sich 2 Pins mit GND und 5V als Beschriftung. <br />
GND kann als GND und 5V als Vcc genutzt werden.<br />
<br />
= Einbindung in [[Control6]] =<br />
<br />
Die Sensoren können mit '''ONEWIRE_GET''' einfach abgefragt werden. Die Funktion führt automatisch ein<br />
''convert'' aus, es sind also keine zwei Schritte erforderlich wie bei dem Zugriff über [[ECMD]].<br />
Die Rückgabe erfolgt (analog der Funktion '''KTY_GET''') in Centigrad, also Temperatur * 10.<br />
Hier vielleicht ein kleines Beispiel, das die Daten per [[SYSLOG]] ausgibt sobald sich die Temperatur<br />
um mehr als ein Grad zur letzten Messung verändert hat.<br />
<br />
<pre><br />
int16_t Temperatur;<br />
int16_t Temperatur_alt;<br />
<br />
CONTROL_START<br />
<br />
THREAD(read_temp)<br />
Temperatur = ONEWIRE_GET(10d85594010800eb);<br />
ON abs(Temperatur-Temperatur_alt)>10 DO<br />
div_t res = div(Temperatur,10);<br />
SYSLOG("temperature changed %d.%d",res.quot,res.rem)<br />
Temperatur_alt = Temperatur;<br />
END<br />
WAIT(15);<br />
THREAD_END(read_temp)<br />
<br />
ON STARTUP DO<br />
Temperatur = Temperatur_alt = 0;<br />
THREAD_START(read_temp);<br />
END<br />
<br />
CONTROL_END<br />
</pre><br />
<br />
= Abfrage per [[SNMP]] =<br />
<br />
= Beispiele =<br />
<br />
== sh oder bash ==<br />
<br />
Einfaches SH (Linux Shell) Script von stesie (irc) zum Auslesen von einem Wert<br />
(udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
SENSORID=10529f7001080016<br />
#ESEXIP=2001:6f8:1209:23:42::17 #IPv6 Adresse<br />
ESEXIP=192.168.255.90<br />
<br />
#IPv6<br />
#echo 1w convert $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1 <br />
#echo 1w get $SENSORID | nc6 -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //' <br />
<br />
#IPv4<br />
echo 1w convert $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | grep -qe OK || exit 1<br />
echo 1w get $SENSORID | nc -u $ESEXIP 2701 -q 1 2>/dev/null | sed -e 's/Temperatur: //'<br />
</source><br />
<br />
bash Script von Tron12 zum Auslesen aller Werte<br />
(Achtung Port 2701 ist nicht standard!! Sowie udp support muss enabled sein oder option -u nicht verwenden!)<br />
<br />
<source lang="bash"><br />
#! /bin/sh<br />
#<br />
# netcat-openbsd 1.89-3ubuntu2<br />
<br />
NETIOIP="-4 192.168.178.249"<br />
<br />
#für IPv6:<br />
#NETIOIP="-6 2001:6f8:1209:23:42::17"<br />
<br />
NETIOPORT="2702"<br />
<br />
N_DATE=`echo date | nc -u $NETIOIP $NETIOPORT -q 1 ` <br />
N_GET_ID=`echo 1w list | nc -u $NETIOIP $NETIOPORT -q 1 | grep -qe OK || exit 1`<br />
<br />
echo "Date: $N_DATE"<br />
echo "---------------------------------"<br />
<br />
for i in $N_GET_ID<br />
do<br />
tmp=`echo 1w convert $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null | grep -qe OK || exit 1`<br />
tmp=`echo 1w get $i | nc -u $NETIOIP $NETIOPORT -q 1 2>/dev/null `<br />
echo "Sensor: $i :: $tmp"<br />
done<br />
</source><br />
<br />
== Perl ==<br />
<br />
Beispiel in Perl das alle Sensoren ermittelt und anschließend die Werte ausgibt.<br />
Benötigt wird das Modul NET das kein IPv6 kann<br />
<br />
<source lang="perl"><br />
#!/usr/bin/perl -w<br />
#Auslesen der 1 Wire Sensoren an einem AVR-NET-IO mit ethersex<br />
<br />
use strict;<br />
use Net::Telnet ();<br />
<br />
my $esexip="192.168.255.90";<br />
my $esexport="2701";<br />
my $esex;<br />
my @sensor;<br />
my $sensor;<br />
my $dummy;<br />
my $temp;<br />
<br />
$esex = Net::Telnet->new || die "kann Ethersex nicht finden";;<br />
$esex->open(Host => $esexip,<br />
Port => $esexport,<br />
Timeout => 2);<br />
<br />
#Alles Sensor-IDs auslesen und dem Array @sensor zuweisen<br />
$esex->print("1w list");<br />
($sensor) = $esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
@sensor=split(/\s+/, $sensor);<br />
print "@sensor","\n"; #Kontrollausgabe<br />
<br />
my $zahler=@sensor;<br />
print "Anzahl der Elemente :",$zahler,"\n\n";<br />
<br />
#Alles Sensore Temperatur einlesen<br />
$esex->print("1w convert");<br />
$esex->waitfor(Timeout => 2,<br />
String => "OK");<br />
<br />
#Sensor ID inklusive Wert ausgeben<br />
foreach (@sensor) {<br />
$esex->print("1w get $_");<br />
<br />
($dummy,$temp)=$esex->waitfor(Match =>'/[-]?\d+\.\d+/',<br />
Timeout => 5);<br />
<br />
print "Temperatur vom ID ",$_,": ",$temp," C°","\n";<br />
}<br />
</source><br />
<br />
== Python ==<br />
<br />
<source lang="python"><br />
#!/usr/bin/python<br />
<br />
from socket import *<br />
<br />
def connectEP():<br />
s = socket(AF_INET, SOCK_STREAM)<br />
s.settimeout(5)<br />
s.connect(("192.168.5.3", 2701))<br />
return s<br />
<br />
def getTemperature():<br />
s.send("1w list\n")<br />
sensors = []<br />
sensors_result = {}<br />
<br />
# list aller Sensoren<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if not response: break<br />
if response != "OK":<br />
sensors.append(response)<br />
else:<br />
break<br />
<br />
# wert konvertieren<br />
for sensor in sensors:<br />
s.send("1w convert " + sensor + "\n")<br />
while 1:<br />
response = s.recv(1024).rstrip("\n")<br />
if response == "OK":<br />
break <br />
<br />
# wert auslesen <br />
s.send("1w get " + sensor + "\n")<br />
response = s.recv(1024).rstrip("\n").lstrip()<br />
sensors_result[sensor] = response<br />
return(sensors_result)<br />
<br />
s = connectEP()<br />
for sensor, value in getTemperature().iteritems():<br />
print sensor + " " + value<br />
</source><br />
<br />
== PHP ==<br />
<br />
<source lang="php"><br />
<br />
<html><br />
<br />
<head><br />
<title>ethersex php example</title><br />
</head><br />
<br />
<body><br />
<br />
<?php<br />
<br />
define(IP, '192.168.10.9'); // deine ethersex ip adresse<br />
define(PORT, 2701); // standard port im image<br />
<br />
request("1w convert");<br />
<br />
$response = request("1w list");<br />
$explode = explode("\n", $response);<br />
<br />
for ($i=0; $i < count($explode)-2; $i++) {<br />
echo "Sensor: " . trim($explode[$i]);<br />
echo " -- Wert: " . request("1w get " . $explode[$i]);<br />
echo "<br>\n";<br />
}<br />
<br />
function request($request) {<br />
$rs = fsockopen(IP, PORT);<br />
<br />
if (!$rs) {<br />
$response = "Kann Verbindung nicht aufbauen!";<br />
}<br />
else {<br />
$response ="";<br />
$request = "!" . $request . "\r\n";<br />
<br />
fputs($rs, $request);<br />
<br />
while (!feof($rs)) {<br />
$response .= fgets($rs, 128);<br />
}<br />
fclose($rs);<br />
}<br />
<br />
return $response;<br />
}<br />
<br />
?><br />
<br />
</body><br />
</source><br />
<br />
[[Category:Ethersex]]<br />
[[Category:StepByStep]]<br />
[[Category:Onewire]]<br />
<br />
= Bezugsquellen =<br />
* Laut Michael Schultz (k1w1) hat er immer DS1820 auf Lager und kann sie sehr günstig weiterverkaufen. Auch Mindermengen. Mail: ethersex [AT] keyb [DOT] de</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=485Cron2012-04-08T08:18:45Z<p>Sittner: /* Define cronjob in source code: ecmd command */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' in your browser for instance. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (as the result of a blackout for instance) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
As you may have noticed this functionality is also be covered by the static cron daemon, wich even consumes<br />
less resources. But there are some advantages:<br />
<br />
* No need to add code to a foreign module (clarity of cron_static.c suffers with every additional module)<br />
* You can remove the cronjob at runtime<br />
* You can pass extra data to the callback funtion<br />
<br />
The function to be called by the daemon has to have the signature '''void func(char* data)''' and should ''not''<br />
be defined in cron/cron.c but in the particular module that uses the cron functionality.<br />
<br />
# Include 'cron/cron.h' in your module<br />
# Call the function '''cron_jobinsert_callback''' from your initialization function to insert cronjobs on startup of ethersex.<br />
# The semantic of the function parameters is:<br />
* Minute, -1 as wildcard, -2 means every 2nd minute, etc.<br />
* Hour, -1 as wildcard, -2 means every 2nd hour, etc.<br />
* Day, -1 as wildcard, -2 means every 2nd day, etc.<br />
* Month, -1 as wildcard, -2 means every 2nd month, etc.<br />
* Day of week, 1 = Sunday, 2 = Monday, 4 = Tuesday, 8 = Wednesday, 16 = Thursday, 32 = Friday, 64 = Saturday or adding of multiple values<br />
* Number of repeats, INFINIT_RUNNING for never ending, 1=once, etc.<br />
* Position to add to the cron list (CRON_APPEND = add to end)<br />
* Callback function<br />
* Size of extra data<br />
* Pointer to extra data<br />
<br />
Example taken from the test entry file:<br />
void test(void* data) { /* do something */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extra data is cool stuff. Stella PWM for instance uses it to store the chanel no and the<br />
target value. If the cronjob is executed, it's extra data is passed to the callback<br />
function and can be processed. Please keep in mind that the pointer to extra data<br />
has to be the result of a call to malloc, which allocates the memory on the heap.<br />
(Example: '''char* extra = malloc(2);''' for 2 bytes on the heap)<br />
<br />
Don't care about freeing the allocated memory. The cron daemon will do this job.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
The static cron daemon is limited to use callback functions. With the dynamic cron daemon you<br />
are even able to call ecmd commands (set output pins, control Stella PWM, reset ethersex, etc.)<br />
<br />
Here an example of a function call to insert such a job:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=484Cron2012-04-08T08:12:50Z<p>Sittner: /* Define cronjob in source code: callback function */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' in your browser for instance. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (as the result of a blackout for instance) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
As you may have noticed this functionality is also be covered by the static cron daemon, wich even consumes<br />
less resources. But there are some advantages:<br />
<br />
* No need to add code to a foreign module (clarity of cron_static.c suffers with every additional module)<br />
* You can remove the cronjob at runtime<br />
* You can pass extra data to the callback funtion<br />
<br />
The function to be called by the daemon has to have the signature '''void func(char* data)''' and should ''not''<br />
be defined in cron/cron.c but in the particular module that uses the cron functionality.<br />
<br />
# Include 'cron/cron.h' in your module<br />
# Call the function '''cron_jobinsert_callback''' from your initialization function to insert cronjobs on startup of ethersex.<br />
# The semantic of the function parameters is:<br />
* Minute, -1 as wildcard, -2 means every 2nd minute, etc.<br />
* Hour, -1 as wildcard, -2 means every 2nd hour, etc.<br />
* Day, -1 as wildcard, -2 means every 2nd day, etc.<br />
* Month, -1 as wildcard, -2 means every 2nd month, etc.<br />
* Day of week, 1 = Sunday, 2 = Monday, 4 = Tuesday, 8 = Wednesday, 16 = Thursday, 32 = Friday, 64 = Saturday or adding of multiple values<br />
* Number of repeats, INFINIT_RUNNING for never ending, 1=once, etc.<br />
* Position to add to the cron list (CRON_APPEND = add to end)<br />
* Callback function<br />
* Size of extra data<br />
* Pointer to extra data<br />
<br />
Example taken from the test entry file:<br />
void test(void* data) { /* do something */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extra data is cool stuff. Stella PWM for instance uses it to store the chanel no and the<br />
target value. If the cronjob is executed, it's extra data is passed to the callback<br />
function and can be processed. Please keep in mind that the pointer to extra data<br />
has to be the result of a call to malloc, which allocates the memory on the heap.<br />
(Example: '''char* extra = malloc(2);''' for 2 bytes on the heap)<br />
<br />
Don't care about freeing the allocated memory. The cron daemon will do this job.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=483Cron2012-04-08T07:59:49Z<p>Sittner: /* Define cronjob in source code: callback function */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' in your browser for instance. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (as the result of a blackout for instance) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
As you may have noticed this functionality is also be covered by the static cron daemon, wich even consumes<br />
less resources. But there are some advantages:<br />
<br />
* No need to add code to a foreign module (clarity of cron_static.c suffers with every additional module)<br />
* You can remove the cronjob at runtime<br />
* You can pass extra data to the callback funtion<br />
<br />
The function to be called by the daemon has to have the signature '''void func(char* data)''' and should ''not''<br />
be defined in cron/cron.c but in the particular module that uses the cron functionality.<br />
<br />
# Include 'cron/cron.h' in your module<br />
# Call the function '''cron_jobinsert_callback''' from your initialization function to insert cronjobs on startup of ethersex.<br />
# The semantic of the function parameters is:<br />
* Minute, -1 as wildcard, -2 means every 2nd minute, etc.<br />
* Hour, -1 as wildcard, -2 means every 2nd hour, etc.<br />
* Day, -1 as wildcard, -2 means every 2nd day, etc.<br />
* Month, -1 as wildcard, -2 means every 2nd month, etc.<br />
* Day of week, 1 = Sunday, 2 = Monday, 4 = Tuesday, 8 = Wednesday, 16 = Thursday, 32 = Friday, 64 = Saturday or adding of multiple values<br />
* Number of repeats, INFINIT_RUNNING for never ending, 1=once, etc.<br />
* Position to add to the cron list (CRON_APPEND = add to end)<br />
* Callback function<br />
* Size of extra data<br />
* Pointer to extra data<br />
<br />
Example taken from the test entry file:<br />
void test(void* data) { /* do something */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extra data is cool stuff. Stella PWM for instance uses it to store the chanel no and the<br />
target value. If the cronjob is executed, it's extra data is passed to the callback<br />
function and can be processed. Please keep in mind that the pointer to extra data<br />
has be be the result of a call to malloc, which allocates the memory on the heap.<br />
(Example: '''char* extra = malloc(2);''' for 2 bytes on the heap)<br />
<br />
Don't care about freeing the allocated memory. The cron daemon will do this job.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=482Cron2012-04-08T07:55:58Z<p>Sittner: /* Mark job as anacron job via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' in your browser for instance. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (as the result of a blackout for instance) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=481Cron2012-04-08T07:54:55Z<p>Sittner: /* View jobs via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' in your browser for instance. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (i.e. as the result of a blackout) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=458Cron2012-04-06T15:46:22Z<p>Sittner: /* Mark job as anacron job via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (i.e. as the result of a blackout) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=457Cron2012-04-06T12:41:24Z<p>Sittner: /* Mark job as anacron job via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
This flag provides a kind of anacron functionality which is intended for jobs that set specific states.<br />
Take the circulation pump of a central heating as example. If the pump has to be switched on at<br />
6.00 and switched off at 9.00 this could be realized by a simple cron job. But if the controller<br />
reboots at 7.00 (i.e. as the result of an blackout) the pump will not be switched on till 6.00 of the<br />
following day. The same counts in case of a time skip by NTP updates.<br />
<br />
To solve this problem all anacron jobs that falls in the skiped time range will be executed (in case of<br />
boot this means from 1.1.1970 till the current time), each job just one time and in correct order (latest<br />
execution time counts). To keep the runtime of the decision loop short, the starting point in the past<br />
is limited to <current time> - CRON_ANACRON_MAXAGE secs. Default is one day (86400 secs).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=456Cron2012-04-06T12:16:15Z<p>Sittner: /* Write persistent jobs to VFS/EEPROM via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' all persistent jobs will be stored in VFS/EEPROM.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=455Cron (Deutsch)2012-04-06T12:13:48Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder<br />
einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt<br />
werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim<br />
Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum<br />
bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche<br />
Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben<br />
Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in das Struktur-Array ''events'' vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren per ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Job als anacron-Job markieren per ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das anacron flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=454Cron2012-04-06T12:11:53Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' mark job N for UTC time<br />
<br />
'''cron utc N 0''' remove UTC flag<br />
<br />
'''cron utc N''' show current state<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' mark job N as anacron job<br />
<br />
'''cron anacron N 0''' remove anacron flag<br />
<br />
'''cron anacron N''' show current state<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=453Cron2012-04-06T12:09:39Z<p>Sittner: /* Mark job as persistent via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' mark job N as persistent<br />
<br />
'''cron persistent N 0''' remove persistent flag<br />
<br />
'''cron persistent N''' show current state<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=452Cron2012-04-06T12:08:17Z<p>Sittner: /* Add jobs via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH and DAYOFWEEK can be -1 (as wildcard).<br />
<br />
ECMD: The ecmd command to be executed.<br />
<br />
After creating the new job it's position in the list will be displayed.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=451Cron2012-04-06T12:04:33Z<p>Sittner: /* Remove jobs via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' removes the Nth job (start counting at 0) from the cron list. Caution! '''cron rm'''<br />
without paramater removes ALL jobs without confirmation request!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=450Cron2012-04-06T12:00:10Z<p>Sittner: /* View jobs via ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Simply execute the ecmd command '''cron list''' i.e. in your browser. All jobs will be displayed, two lines<br />
for each job. The first line contains the job attributes (position, repeats, ecmd/callback job, use UTC, etc.),<br />
the second line shows the timing data (MIN HOUR DAY MONTH DAYOFWEEK) and the ecmd command/address of the<br />
callback function to be executed.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=449Cron2012-04-06T11:52:59Z<p>Sittner: /* Static Cron Daemon */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
The function to be called from the daemon has to have the signature '''void func(void)'''<br />
and has to be defined in cron_static/cron_static.c.<br />
<br />
Furthermore you have to insert a rule of the type ''cron_static_event_t'' to the<br />
structure array ''events''. The meaning of the values are minute, hour, day, month, days of week,<br />
callback function and a flag if UTC or local time is used (in that order).<br />
<br />
A value of -1 is a wildcard. The entries are checked every minute, so an entry with all wildcards will<br />
be executed every minute.<br />
<br />
Values less than -1 mean "every x-th minute/hour/etc.". So in case of -4 in the minute field the job<br />
will be executed every 4th minute.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=448Cron2012-04-06T11:39:33Z<p>Sittner: /* Menuconfig */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
The module needs the current time to function properly. So you have to select at least one time source.<br />
To enable crontabs in ethersex select<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=447Cron2012-04-06T11:35:40Z<p>Sittner: /* Preconditions */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Both approaches have in common that you need to define a function that is called from the con daemon at<br />
a appropriate time. The function signature, however, varies dependend on the choosen implementation.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben<br />
Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=446Cron2012-04-05T08:06:52Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Cron daemon manage cron jobs. This rules define repeated or unique events that call certain commands.<br />
<br />
Cron jobs are implemented in two flavors: a static list that is defined at compile time and not changeable<br />
at runtime, and a dynamic approach, which loads the joblist to the RAM at statup. Jobs can be added and<br />
removed at runtime.<br />
<br />
== Preconditions ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum<br />
bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche<br />
Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben<br />
Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Static Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamic Cron Daemon ==<br />
=== View jobs via ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Remove jobs via ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Add jobs via ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Mark job as persistent via ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Write persistent jobs to VFS/EEPROM via ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Mark job for UTC time via ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Mark job as anacron job via ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Define cronjob in source code: callback function ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Define cronjob in source code: ecmd command ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=445Cron2012-04-05T07:51:04Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=444Cron (Deutsch)2012-04-05T07:50:34Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Cron daemon<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder<br />
einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt<br />
werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim<br />
Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum<br />
bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche<br />
Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben<br />
Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren per ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Job als anacron-Job markieren per ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=443Cron (Deutsch)2012-04-05T07:46:27Z<p>Sittner: /* Job als anacron Job markieren per ecmd */</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder<br />
einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt<br />
werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim<br />
Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum<br />
bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche<br />
Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben<br />
Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren per ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Job als anacron-Job markieren per ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron-Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron-Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötig lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=442Cron (Deutsch)2012-04-05T07:38:41Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder<br />
einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt<br />
werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim<br />
Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum<br />
bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche<br />
Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben<br />
Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen<br />
Jobs angezeigt, pro Job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen,<br />
ecmd/Callback-Job, UTC-Zeit, u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK)<br />
und der ecmd Befehl bzw. die Callback Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm'''<br />
ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren per ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Job als anacron Job markieren per ecmd ===<br />
<br />
Dieses Flag bietet eine Art anacron Funktion. Gedacht ist dies für Jobs, die bestimmte Stati setzen.<br />
Ein Beispiel wäre die Zirkulationspumpe einer Heizung. Angenommen die Pumpe soll um 6.00 Uhr<br />
eingesaltet und um 9.00 wieder ausgeschaltet werden, könnte das natürlich auch mit normalen Jobs<br />
erledigt werden. Sollte der Controller allerdings um 7.00 neu booten (z.B. wg. Stromausfall) bliebe<br />
Pumpe bis zum nächsten Tag 6.00 ausgeschaltet. Ähnliches gilt für grössere Zeitsprünge durch NTP-Updates.<br />
<br />
Um das Problem zu lösen, werden alle anacron Jobs nachgezogen, die innerhalb des übersprungenen Zeitraums<br />
(also vom 1.1.1970 bis zur aktuellen Zeit im Falle das Boots) hätten ausgeführt werden müssen, wobei jeder<br />
Job nur einmal ausgeführt wird und auch in der korrekten Reihenfolge (jüngstes Ausführungsdatum zählt).<br />
Damit die Schleife zum Ermitteln der Jobs nicht unnötog lange dauert, ist der Startzeitpunkt in der<br />
Vergangenheit auf <Aktuelle Zeit> - CRON_ANACRON_MAXAGE Sekunden beschränkt. Voreingestellt ist hier<br />
ein Tag (86400 Sekunden).<br />
<br />
'''cron anacron N 1''' markiere den Nten Job als anacron Job<br />
<br />
'''cron anacron N 0''' löscht das UTC flag<br />
<br />
'''cron anacron N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem<br />
jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert.<br />
Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben<br />
und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss,<br />
sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden.<br />
(Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern.<br />
Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=441Cron (Deutsch)2012-04-04T17:56:08Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen jobs angezeigt,<br />
pro job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen, ecmd/Callback-Job, UTC-Zeit,<br />
u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK) und der ecmd Befehl bzw. die Callback<br />
Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm''' ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren per ecmd ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert. Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss, sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden. (Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern. Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=440Cron (Deutsch)2012-04-04T17:53:17Z<p>Sittner: </p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}<br />
<br />
Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen jobs angezeigt,<br />
pro job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen, ecmd/Callback-Job, UTC-Zeit,<br />
u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK) und der ecmd Befehl bzw. die Callback<br />
Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm''' ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert. Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss, sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden. (Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern. Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron_(Deutsch)&diff=439Cron (Deutsch)2012-04-04T17:50:55Z<p>Sittner: Created page with "Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden könn…"</p>
<hr />
<div>Der Cron daemon verwaltet so genannte cron jobs. Diese Regeln definieren bestimmte immer wiederkehrende oder einmalige Zeitpunkte zu denen dann Kommandos ausgeführt werden können.<br />
<br />
Cronjobs sind auf zweifache Weise in Ethersex implementiert. Eine statische Liste, die zur Compilierzeit bestimmt werden muss und danach auch nicht mehr beeinflusst werden kann und einen dynamischen Ansatz, bei dem die Jobs beim Start von Ethersex in den Ram geladen werden. Danach können nach belieben Jobs entfernt und hinzugefügt werden.<br />
<br />
== Voraussetzungen ==<br />
Beide Ansätze haben gemeinsam, dass du erst einmal eine Funktion definieren musst, welche vom Cron daemon zum bestimmten Zeitpunkt aufgerufen werden kann. Die Funktionssignatur sieht allerdings, abhängig davon welche Implementierung du wählst, leicht anders aus.<br />
<br />
== Menuconfig ==<br />
Das Modul benötigt allerdings die aktuelle Zeit um richtig funktionieren zu können. Du musst daher im selben Untermenü mindestens eine Zeitquelle ebenfalls einschalten.<br />
Um Crontabs in ethersex zu aktivieren, wählt man im Menü<br />
<br />
│ │ Load a Default Configuration ---><br />
│ │ ...<br />
│ │ Applications ---><br />
│ │ ...<br />
│ │ [*] Cron daemon ---><br />
│ │ [ ] Cron daemon (static jobs)<br />
<br />
== Statischer Cron Daemon ==<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben '''void func(void)'''<br />
und muss direkt in cron_static/cron_static.c definiert werden.<br />
<br />
Es muss dann nur noch eine Regel in die Array Struktur events vom Typ ''cron_static_event_t'' eingefügt werden.<br />
Die Werte der Reihenfolge nach stehen für Minute, Stunde, Tag, Monat, Wochentag, Callback Funktion und ob UTC<br />
oder die lokale Zeitzone benutzt werden soll.<br />
<br />
Eine -1 steht für einen Platzhalter. Da die Einträge ca. jede Minute<br />
einmal geprüft werden, wird also ein Eintrag mit nur Platzhalter Werten auch ca. jede Minute ausgeführt.<br />
<br />
Werte unter -1 haben die Bedeutung von "jede x-te Minute/Stunde/etc". Also ein Wert von -4<br />
an der Minutenstelle bedeutet, dass der Crontab jede 4te Minute ausgeführt wird.<br />
<br />
== Dynamischer Cron Daemon ==<br />
=== Auslesen per ecmd ===<br />
Einfach den ecmd Befehl '''cron list''' zum Beispiel in deinem Browser ausführen. Es werden alle aktuellen jobs angezeigt,<br />
pro job zwei Zeilen. Die erste Zeile enthält die Attribute des Jobs (Position, Wiederholungen, ecmd/Callback-Job, UTC-Zeit,<br />
u.s.w.), in der zweiten Zeile werden die Zeitdaten (MIN HOUR DAY MONTH DAYOFWEEK) und der ecmd Befehl bzw. die Callback<br />
Addresse angezeigt.<br />
<br />
=== Entfernen per ecmd ===<br />
'''cron rm N''' entfernt den Nten Job (fängt bei 0 an zu zählen) aus der cron Liste. Vorsicht! '''cron rm''' ohne Parameter entfernt ALLE cron jobs, und das ohne vorher nachzufragen!<br />
<br />
=== Hinzufügen per ecmd ===<br />
'''cron add MIN HOUR DAY MONTH DAYOFWEEK ECMD'''<br />
<br />
MIN HOUR DAY MONTH und DAYOFWEEK können -1 (als Platzhalterfunktion) annehmen.<br />
<br />
ECMD: Der ecmd Befehl, der ausgeführt werden soll.<br />
<br />
Nach dem Anlegen wird die Position des neuen Jobs in der Liste ausgegeben.<br />
<br />
=== Job als persistent markieren per ecmd ===<br />
'''cron persistent N 1''' macht den Nten Job persistent<br />
<br />
'''cron persistent N 0''' löscht das persistent flag<br />
<br />
'''cron persistent N''' zeigt den aktuellen Status an<br />
<br />
=== Persistente Jobs ins VFS/EEPROM schreiben per ecmd ===<br />
'''cron save''' alle als persistent markierten Jobs werden im VFS/EEPROM abgespeichert.<br />
<br />
=== Job für UTC-Zeit markieren ===<br />
'''cron utc N 1''' setzt den Nten Job auf UTC<br />
<br />
'''cron utc N 0''' löscht das UTC flag<br />
<br />
'''cron utc N''' zeigt den aktuellen Status an<br />
<br />
=== Cronjob im Quelltext definieren: Callback Funktion ===<br />
Wer scharf hinsieht, erkennt, dass diese Funktionalität auch durch den statischen Cron Daemon abgedeckt wird.<br />
Der statische Dienst verbraucht dabei sogar weniger Ressourcen. Aber, hier die Vorteile des dynamischen Dienstes:<br />
<br />
* Du musst keinen Quelltext in ein fremdes Modul einfügen (Übersichtlichkeit der cron_static.c nimmt mit jedem weiterem Modul ab)<br />
* Du kannst zur Laufzeit den cronjob auch wieder entfernen.<br />
* Du kannst Extradaten an die Callback Funktion übergeben<br />
<br />
Die Funktion, welche der Daemon aufrufen soll, muss folgende Signatur haben<br />
'''void func(char* data)''' und sollte ''nicht'' in der cron/cron.c Datei definiert werden, sondern in dem jeweiligen Modul, welche die Cron Funktionalität nutzen will.<br />
<br />
# Binde in dein Modul die Datei 'cron/cron.h' ein.<br />
# Nutze die Callback Variante des Cron-Einfügen Befehls '''cron_jobinsert_callback''' in der Initalisierungsfunktion deines Moduls um beim Start von ethersex cronjobs hinzuzufügen.<br />
# Die Funktionsparameter haben die folgende Semantik:<br />
* Minute, -1 für ignorieren, -2 für jede 2te Minute etc<br />
* Stunde, -1 für ignorieren, -2 für jede 2te Stunde etc<br />
* Tag, -1 für ignorieren, -2 für jeden 2te Tag etc<br />
* Monat, -1 für ignorieren, -2 für jeden 2te Monat etc<br />
* Wochentag, 1 für Sonntag, 2 für Montag, 4 für Dienstag, 8 für Mittwoch, 16 für Donnerstag, 32 für Freitag, 64 für Samstag oder eine Addition daraus<br />
* Wiederholen, INFINIT_RUNNING für endlos, 1=einmal etc<br />
* Position des Crons in der Cronliste (CRON_APPEND, wenn angehängt werden soll)<br />
* Callback Funktion<br />
* Größe von Extradaten<br />
* Extradaten<br />
<br />
Beispiel aus der Test Einträge Datei:<br />
void test(void* data) { /* tu was */ }<br />
// in init<br />
cron_jobinsert_callback(-1, -2, -1, -1, -1, INFINIT_RUNNING, CRON_APPEND, test, 0, NULL);<br />
<br />
Extradaten sind eine ziemlich coole Sache. Stella PWM zum Beispiel speichert darin Lichtkanal und Zielwert. Beim Aktivieren des Cronjobs wird der Zeiger auf diese Extradaten dann an die Callback Funktion mit übergeben und diese stehen direkt zur Verfügung.<br />
Bitte beachte hierbei aber, dass der Pointer auf die Extradaten durch einen Malloc Aufruf gewonnen werden muss, sprich die Speicherstelle für die Extradaten müssen vorher auf dem Heap allokiert werden. (Beispiel: '''char* extra = malloc(2);''' für 2 Bytes auf dem Heap)<br />
<br />
Du musst und solltest dich nicht um die Freigabe des allokierten Speichers kümmern. Dies erledigt der Cron daemon bereits.<br />
<br />
=== Cronjob im Quelltext definieren: Ecmd aufrufen ===<br />
Der statische cron daemon bot die Möglichkeit eine Funktion zu gegebenem Zeitpunkt aufzurufen. Wenn du jedoch<br />
den dynamischen Dienst nutzt, kannst du auch ecmd Befehle zeitabhängig aufrufen lassen<br />
(z.B. Pins setzen, Stella PWM kontrollieren, ethersex reseten etc).<br />
<br />
Die Funktion die du in dein Modul hierfür einbauen musst, lautet folgendermaßen:<br />
<br />
cron_jobinsert_ecmd(-1, -2, -1, -1, 127, INFINIT_RUNNING, CRON_APPEND, "ECMD");</div>Sittnerhttp://www.ethersex.de/index.php?title=Cron&diff=438Cron2012-04-04T17:34:25Z<p>Sittner: Created page with "{{i18n|Cron}} {{Module |NAME=Tank level meter |MENUCONFIG={{Applications}}->Cron daemon |STATUS={{stable}} |PINNING=no |ECMD={{has_ecmd}} |DEPENDS=ECMD, Clock |REQUIRES= …"</p>
<hr />
<div>{{i18n|Cron}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Cron daemon<br />
|STATUS={{stable}}<br />
|PINNING=no<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]]<br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/cron https://github.com/ethersex/ethersex/tree/master/services/cron]<br />
}}</div>Sittnerhttp://www.ethersex.de/index.php?title=Tanklevel&diff=437Tanklevel2012-04-02T14:49:28Z<p>Sittner: </p>
<hr />
<div>{{i18n|Tanklevel}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Tank level meter<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]], [[ADC]], [[Cron]] (optional) <br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/tanklevel https://github.com/ethersex/ethersex/tree/master/services/tanklevel]<br />
}}<br />
<br />
Tanklevel provides an application for measurement of tank levels by hydrostatic pressure.<br />
<br />
== Internals ==<br />
<br />
You need an aquarium air pump, some kind of pipe/tube, a Freescale MPX5050DP<br />
pressure sensor and an relay for the pump. Parameters are configurable by ECMD<br />
and stored in EEPROM.<br />
<br />
== Configuration ==<br />
<br />
│ │ (0) ADC channel │ │ <br />
│ │ [ ] Measure on system startup │ │ <br />
│ │ [ ] Measure at 12 am and 12 pm │ │ <br />
│ │ [ ] Inverted pump output │ │ <br />
│ │ [ ] Check lock input │ │ <br />
│ │ [ ] Inverted lock input │ │ <br />
│ │ [ ] Inline tank level │ │ <br />
<br />
* ADC channel - ADC channel that is connected to the MPX5050DP pressure sensor.<br />
* Measure on system startup - Start initial measurement at system startup.<br />
* Measure at 12 am and 12 pm - Start measurement at fixed time. Can be changed in services/cron/cron_static.c.<br />
* Inverted pump output - Output pin for pump is inverted.<br />
* Check lock input - Check lock pin before measurement and wait if needed. This is used to delay the measurement e.g. if the oil burner is running.<br />
* Inverted lock input - Lock input pin is inverted.<br />
* Inline tank level - Inline a page to query the tank level.<br />
<br />
== Pinning ==<br />
<br />
Example pinning from pinning/hardware/netio.m4:<br />
<br />
ifdef(`conf_TANKLEVEL', `<br />
pin(TANKLEVEL_PUMP, PC3, OUTPUT)<br />
')<br />
ifdef(`conf_TANKLEVEL_LOCK', `<br />
pin(TANKLEVEL_LOCK, PA2, INPUT)<br />
')<br />
<br />
Meaning:<br />
<br />
* TANKLEVEL_PUMP - output pin for driving the pump relay<br />
* TANKLEVEL_LOCK - optional pin for external lock signal (see Configuration)<br />
<br />
== Mechanical setup ==<br />
<br />
+-------+<br />
|Sensor |<br />
+---+---+<br />
| +--------+<br />
+---------------+-+ Pump |<br />
| +--------+<br />
+------+------+<br />
| | |<br />
| | |<br />
|------|------|<br />
| | |<br />
| | |<br />
| | |<br />
+-------------+<br />
Tank<br />
<br />
See the following example:<br />
<br />
[[File:Tanklevel_pump_assy.jpg|Pump assembly|177px]]<br />
[[File:Tanklevel_tank_assy.jpg|Tank assembly|100px]]<br />
<br />
== Electrical setup ==<br />
<br />
Electrical setup is quite simple. Connect the TANK_PUMP port with an relay<br />
(usually via an Transistor as current amp) and the output of the Sensor<br />
with the selected ADC channel (have a look at the datasheet for power supply<br />
decoupling and output filtering). Select a optimal Vref for the ADC if<br />
possible. Schematic could look like this:<br />
<br />
[[File:Tanklevel_schem.png|Electrical setup]]<br />
<br />
== Parameters ==<br />
<br />
Parameters can be viewed/set by ECMD commands:<br />
<br />
* sensor_offset - zero offset of the pressure sensor in mV<br />
* med_density - medium density in g/ltr (default of 840 for fuel oil)<br />
* ltr_per_m - Ltr per meter tank level<br />
* ltr_full - Tank capacity in ltr<br />
* raise_time - Pump time (in 1/50 secs)<br />
* hold_time - Hold time before measurement (in 1/50 secs)<br />
<br />
== SNMP support ==<br />
<br />
If SNMP is enabled the level can be queried by this OID's:<br />
<br />
* .1.3.6.1.4.1.2021.13.23.4.0 = INTEGER: current level in ltr<br />
* .1.3.6.1.4.1.2021.13.23.4.1 = INTEGER: tank capacity in ltr<br />
* .1.3.6.1.4.1.2021.13.23.4.2 = INTEGER: timestamp of last measurement (unix date)<br />
* .1.3.6.1.4.1.2021.13.23.4.3 = STRING: timestamp of last measurement (clear text)</div>Sittnerhttp://www.ethersex.de/index.php?title=Tanklevel&diff=436Tanklevel2012-04-02T14:22:29Z<p>Sittner: </p>
<hr />
<div>{{i18n|Tanklevel}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Tank level meter<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]], [[ADC]], [[Cron]] (optional) <br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/tanklevel https://github.com/ethersex/ethersex/tree/master/services/tanklevel]<br />
}}<br />
<br />
Tanklevel provides an application for measurement of tank levels by hydrostatic pressure.<br />
<br />
== Internals ==<br />
<br />
You need an aquarium air pump, some kind of pipe/tube, a Freescale MPX5050DP<br />
pressure sensor and an relay for the pump. Parameters are configurable by ECMD<br />
and stored in EEPROM.<br />
<br />
== Configuration ==<br />
<br />
│ │ (0) ADC channel │ │ <br />
│ │ [ ] Measure on system startup │ │ <br />
│ │ [ ] Measure at 12 am and 12 pm │ │ <br />
│ │ [ ] Inverted pump output │ │ <br />
│ │ [ ] Check lock input │ │ <br />
│ │ [ ] Inverted lock input │ │ <br />
│ │ [ ] Inline tank level │ │ <br />
<br />
* ADC channel - ADC channel that is connected to the MPX5050DP pressure sensor.<br />
* Measure on system startup - Start initial measurement at system startup.<br />
* Measure at 12 am and 12 pm - Start measurement at fixed time. Can be changed in services/cron/cron_static.c.<br />
* Inverted pump output - Output pin for pump is inverted.<br />
* Check lock input - Check lock pin before measurement and wait if needed. This is used to delay the measurement e.g. if the oil burner is running.<br />
* Inverted lock input - Lock input pin is inverted.<br />
* Inline tank level - Inline a page to query the tank level.<br />
<br />
== Pinning ==<br />
<br />
Example pinning from pinning/hardware/netio.m4:<br />
<br />
ifdef(`conf_TANKLEVEL', `<br />
pin(TANKLEVEL_PUMP, PC3, OUTPUT)<br />
')<br />
ifdef(`conf_TANKLEVEL_LOCK', `<br />
pin(TANKLEVEL_LOCK, PA2, INPUT)<br />
')<br />
<br />
Meaning:<br />
<br />
* TANKLEVEL_PUMP - output pin for driving the pump relay<br />
* TANKLEVEL_LOCK - optional pin for external lock signal (see Configuration)<br />
<br />
== Mechanical setup ==<br />
<br />
+-------+<br />
|Sensor |<br />
+---+---+<br />
| +--------+<br />
+---------------+-+ Pump |<br />
| +--------+<br />
+------+------+<br />
| | |<br />
| | |<br />
|------|------|<br />
| | |<br />
| | |<br />
| | |<br />
+-------------+<br />
Tank<br />
<br />
See the following example:<br />
<br />
[[File:Tanklevel_pump_assy.jpg|Pump assembly|177px]]<br />
[[File:Tanklevel_tank_assy.jpg|Tank assembly|100px]]<br />
<br />
== Electrical setup ==<br />
<br />
Electrical setup is quite simple. Connect the TANK_PUMP port with an relay<br />
(usually via an Transistor as current amp) and the output of the Sensor<br />
with the selected ADC channel (have a look at the datasheet for power supply<br />
decoupling and output filtering). Select a optimal Vref for the ADC if<br />
possible. Schematic could look like this:<br />
<br />
[[File:Tanklevel_schem.png|Electrical setup]]<br />
<br />
== Parameters ==<br />
<br />
Parameters can be viewed/set by ECMD commands:<br />
<br />
* sensor_offset - zero offset of the pressure sensor in mV<br />
* med_density - medium density in g/ltr (default of 840 for fuel oil)<br />
* ltr_per_m - Ltr per meter tank level<br />
* ltr_full - Tank capacity in ltr<br />
* raise_time - Pump time (in 1/50 secs)<br />
* hold_time - Hold time before measurement (in 1/50 secs)</div>Sittnerhttp://www.ethersex.de/index.php?title=Tanklevel&diff=435Tanklevel2012-04-02T13:32:34Z<p>Sittner: </p>
<hr />
<div>{{i18n|Tanklevel}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Tank level meter<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]], [[ADC]], [[Cron]] (optional) <br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/tanklevel https://github.com/ethersex/ethersex/tree/master/services/tanklevel]<br />
}}<br />
<br />
Tanklevel provides an application for measurement of tank levels by hydrostatic pressure.<br />
<br />
== Internals ==<br />
<br />
You need an aquarium air pump, some kind of pipe/tube, a Freescale MPX5050DP<br />
pressure sensor and an relay for the pump. Parameters are configurable by ECMD<br />
and stored in EEPROM.<br />
<br />
== Mechanical setup ==<br />
<br />
+-------+<br />
|Sensor |<br />
+---+---+<br />
| +--------+<br />
+---------------+-+ Pump |<br />
| +--------+<br />
+------+------+<br />
| | |<br />
| | |<br />
|------|------|<br />
| | |<br />
| | |<br />
| | |<br />
+-------------+<br />
Tank<br />
<br />
See the following example:<br />
<br />
[[File:Tanklevel_pump_assy.jpg|Pump assembly|177px]]<br />
[[File:Tanklevel_tank_assy.jpg|Tank assembly|100px]]<br />
<br />
== Electrical setup ==<br />
<br />
Electrical Setup is quite simple. Connect the TANK_PUMP port with an relay<br />
(usually via an Transistor as current amp) and the output of the Sensor<br />
with the selected ADC channel (have a look at the datasheet for power supply<br />
decoupling and output filtering). Select a optimal Vref for the ADC if<br />
possible. Schematic could look like this:<br />
<br />
[[File:Tanklevel_schem.png|Electrical setup]]</div>Sittnerhttp://www.ethersex.de/index.php?title=File:Tanklevel_tank_assy.jpg&diff=434File:Tanklevel tank assy.jpg2012-04-02T13:21:48Z<p>Sittner: Tanklevel tank assembly</p>
<hr />
<div>Tanklevel tank assembly</div>Sittnerhttp://www.ethersex.de/index.php?title=File:Tanklevel_pump_assy.jpg&diff=433File:Tanklevel pump assy.jpg2012-04-02T13:19:36Z<p>Sittner: Tanklevel pump assembly</p>
<hr />
<div>Tanklevel pump assembly</div>Sittnerhttp://www.ethersex.de/index.php?title=File:Tanklevel_schem.png&diff=432File:Tanklevel schem.png2012-04-02T13:18:43Z<p>Sittner: Tanklevel electrical setup</p>
<hr />
<div>Tanklevel electrical setup</div>Sittnerhttp://www.ethersex.de/index.php?title=Tanklevel&diff=431Tanklevel2012-04-02T13:15:26Z<p>Sittner: </p>
<hr />
<div>{{i18n|Tanklevel}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Tank level meter<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]], [[ADC]], [[Cron]] (optional) <br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/tanklevel https://github.com/ethersex/ethersex/tree/master/services/tanklevel]<br />
}}<br />
<br />
Tanklevel provides an application for measurement of tank levels by hydrostatic pressure.<br />
<br />
== Internals ==<br />
<br />
You need an aquarium air pump, some kind of pipe/tube, a Freescale MPX5050DP<br />
pressure sensor and an relay for the pump. Parameters are configurable by ECMD<br />
and stored in EEPROM.<br />
<br />
== Mechanical setup ==<br />
<br />
+-------+<br />
|Sensor |<br />
+---+---+<br />
| +--------+<br />
+---------------+-+ Pump |<br />
| +--------+<br />
+------+------+<br />
| | |<br />
| | |<br />
|------|------|<br />
| | |<br />
| | |<br />
| | |<br />
+-------------+<br />
Tank<br />
<br />
== Electrical setup ==<br />
<br />
Electrical Setup is quite simple. Connect the TANK_PUMP port with an relay<br />
(usually via an Transistor as current amp) and the output of the Sensor<br />
with the selected ADC channel (have a look at the datasheet for power supply<br />
decoupling and output filtering). Select a optimal Vref for the ADC if<br />
possible.</div>Sittnerhttp://www.ethersex.de/index.php?title=Tanklevel&diff=430Tanklevel2012-04-02T13:05:30Z<p>Sittner: Created page with "{{i18n|Tanklevel}} {{Module |NAME=Tank level meter |MENUCONFIG={{Applications}}->Tank level meter |STATUS={{stable}} |PINNING=yes |ECMD={{has_ecmd}} |DEPENDS=ECMD, Clock,…"</p>
<hr />
<div>{{i18n|Tanklevel}}<br />
{{Module<br />
|NAME=Tank level meter<br />
|MENUCONFIG={{Applications}}->Tank level meter<br />
|STATUS={{stable}}<br />
|PINNING=yes<br />
|ECMD={{has_ecmd}}<br />
|DEPENDS=[[ECMD]], [[Clock]], [[ADC]], [[Cron]] (optional) <br />
|REQUIRES=<br />
|CODE=[https://github.com/ethersex/ethersex/tree/master/services/tanklevel https://github.com/ethersex/ethersex/tree/master/services/tanklevel]<br />
}}</div>Sittner