Refactorisé la partie mesure de puissance avec le transfo clip, ajouté une phase et trois phases. Faudrait maintenant refaire tous les liens photos qui sont cassés :-(
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 768 KiB After Width: | Height: | Size: 768 KiB |
|
Before Width: | Height: | Size: 801 KiB After Width: | Height: | Size: 801 KiB |
|
Before Width: | Height: | Size: 792 KiB After Width: | Height: | Size: 792 KiB |
|
Before Width: | Height: | Size: 834 KiB After Width: | Height: | Size: 834 KiB |
|
Before Width: | Height: | Size: 399 KiB After Width: | Height: | Size: 399 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 90 KiB After Width: | Height: | Size: 90 KiB |
13
Mesures/energy/transfo_courant_clip_1p/0_cron.lua
Normal file
@@ -0,0 +1,13 @@
|
||||
-- Petit script pour faire office de crontab pour les
|
||||
--mesures
|
||||
print("\n 0_cron.lua zf190917.0033 \n")
|
||||
|
||||
f= "flash_led_xfois.lua" if file.exists(f) then dofile(f) end
|
||||
flash_led_xfois()
|
||||
xfois =2
|
||||
|
||||
cron1=tmr.create()
|
||||
cron1:alarm(10*1000, tmr.ALARM_AUTO, function()
|
||||
blink_LED ()
|
||||
send_data()
|
||||
end)
|
||||
62
Mesures/energy/transfo_courant_clip_1p/0_get_data.lua
Normal file
@@ -0,0 +1,62 @@
|
||||
-- Lit le convertisseur ADC connecté sur le transformateur de courant
|
||||
-- pour mesurer le courant électrique de l'installation PV
|
||||
print("\n 0_get_data.lua zf191024.1037 \n")
|
||||
|
||||
-- Astuce de mesure:
|
||||
-- On converti le courant en tension avec la résistance de charge du
|
||||
-- transformateur de courant 1/800 et le mesure avec l'ADC
|
||||
-- Au lieu de découper la sinusoïde en 100 parties, c'est à dire toutes
|
||||
-- les 0.2ms (5'000x /s), pour en faire l'intégrale. On lit l'adc toutes
|
||||
-- les 11ms (91x /s) donc beaucoup plus lentement.
|
||||
-- Comme la sinusoïde fait 20ms et est répétitive, on balaye (par décalage)
|
||||
-- statistiquement la sinusoïde.
|
||||
-- On redresse l'alternance par rapport à la masse fictive (env 0.5),
|
||||
-- ce qui nous permet d'estimer une valeur RMS du courant
|
||||
-- quelque soit sa forme et on le somme sur 2.1 secondes
|
||||
-- Les mesures min et max ne sont là juste pour vérifier que nous sommes
|
||||
-- bien dans la plage de mesure avec le choix de la résistance de conversion
|
||||
-- la conversion courant/tension/puissance est faite avec une simple régle de 3
|
||||
|
||||
|
||||
zpow_cal=401 --puissance mesurée de la charge étalon
|
||||
zadc_cal=189 --valeur de l'adc pour zpow_cal
|
||||
zadc_offset=548
|
||||
|
||||
zadc_sum=0 zadc_offset_sum=0 znb_mes=0
|
||||
zadc_min=zadc_offset zadc_max=zadc_offset
|
||||
|
||||
if adc.force_init_mode(adc.INIT_ADC)
|
||||
then
|
||||
node.restart()
|
||||
return
|
||||
end
|
||||
|
||||
tmr_read_adc=tmr.create()
|
||||
tmr_read_adc:alarm(11, tmr.ALARM_AUTO, function()
|
||||
read_adc()
|
||||
end)
|
||||
|
||||
tmr_calc_rms=tmr.create()
|
||||
tmr_calc_rms:alarm(2.1*1000, tmr.ALARM_AUTO, function()
|
||||
calc_rms()
|
||||
end)
|
||||
|
||||
function read_adc()
|
||||
zadc=adc.read(0)
|
||||
if zadc<=zadc_min then zadc_min=zadc end
|
||||
if zadc>=zadc_max then zadc_max=zadc end
|
||||
zadc_offset_sum=zadc_offset_sum+zadc
|
||||
zadc=zadc-zadc_offset if zadc<=0 then zadc=zadc*-1 end
|
||||
zadc_sum=zadc_sum+zadc znb_mes=znb_mes+1
|
||||
end
|
||||
|
||||
function calc_rms()
|
||||
zadc_rms=math.floor(zadc_sum/znb_mes)
|
||||
if zadc_rms<=8 then zadc_rms=0 end
|
||||
zadc_offset=math.floor(zadc_offset_sum/znb_mes)
|
||||
zpower=math.floor(zadc_rms*zpow_cal/zadc_cal)
|
||||
if verbose then print(zadc_min,zadc_max,zadc_max-zadc_min,zadc_offset,zadc_rms,zpower.."W") end
|
||||
zadc_min=zadc_offset zadc_max=zadc_offset
|
||||
zadc_sum=0 zadc_offset_sum=0 znb_mes=0
|
||||
zadc_min=zadc_offset zadc_max=zadc_offset
|
||||
end
|
||||
27
Mesures/energy/transfo_courant_clip_1p/0_send_data.lua
Normal file
@@ -0,0 +1,27 @@
|
||||
-- Petit script pour envoyer les valeurs sur un serveur WEB (InfluxDB)
|
||||
-- via un http GET
|
||||
print("\n 0_send_data.lua zf190924.1043 \n")
|
||||
|
||||
function send_data()
|
||||
if verbose then print("send_data: ") end
|
||||
|
||||
zarg="energy,compteur=2 puissance="..zpower/1000
|
||||
if verbose then print("zarg: "..zarg) end
|
||||
|
||||
http.post(influxdb_url, 'Content-Type: application/x-www-form-urlencoded\r\n', zarg, function(code, data)
|
||||
-- print("toto")
|
||||
if (code < 0) then
|
||||
print("HTTP request failed")
|
||||
print("zuzu", code, data)
|
||||
else
|
||||
if verbose then print(code, data) end
|
||||
end
|
||||
-- print("tutu")
|
||||
end)
|
||||
-- print("titi")
|
||||
end
|
||||
|
||||
--[[
|
||||
zpower=450
|
||||
send_data()
|
||||
]]
|
||||
@@ -0,0 +1 @@
|
||||
{"url": "https://docs.google.com/open?id=1FtUf-Q_QLBBVBtHr425DvN2uAinou2QF8BK8UVaSdH4", "doc_id": "1FtUf-Q_QLBBVBtHr425DvN2uAinou2QF8BK8UVaSdH4", "email": "christian.zufferey@gmail.com"}
|
||||
151
Mesures/energy/transfo_courant_clip_1p/README.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# transfo_courant_clip
|
||||
|
||||
Petit projet pour mesurer la puissance d'un appareil électrique à partir de la mesure du courant avec un petit transformateur de courant qui se clips sur un conducteur avec un NodeMCU en LUA, et l'afficher sur Grafana avec une DB InfluxDB. Comme par exemple la production électrique d'une installation solaire photovoltaïque monophasée.
|
||||
|
||||
ATTENTION, dans ce projet, on ne tient pas compte du déphasage entre la tension et le courant (cos phy) !
|
||||
|
||||

|
||||
Petit transformateur de mesure du courant avec un rapport de 1/800 avec l'épissure pour la boucle de mesure de courant !
|
||||
|
||||

|
||||
C'est mon NodeMCU de banc tests, il y a un pont diviseur pour faire une masse fictive à +0.5V qui permet de mesurer les alternances négatives du courant et la résistance *convertisseur* de courant de la mesure en tension (U=R*I).
|
||||
|
||||

|
||||
On voit ici l'image du courant d'un foehn (450W) en petite vitesse. On voit bien que la partie négative de l'alternance est effacée. C'est à cause de la mise ne série d'une diode avec le corps de chauffe du foehn, c'est un moyen très simple de diminuer le puissance.
|
||||
|
||||

|
||||
On voit ici l'image du courant d'un foehn (450W) en grande vitesse. L'alternance est bien complète ici. On voit aussi qu'elle se trouve dans la plage des 1V du convertisseur ADC du NodeMCU grâce à l'astuce de la *masse fictive* de 0.5V.
|
||||
|
||||

|
||||
Vue globale de mon installation solaire, pour l'instant posée sur le sol, de 2x panneaux de 280W :-)
|
||||
|
||||

|
||||
Vue des deux onduleurs (un par panneau) qui injectent directement l'énergie produite dans le réseau électrique 220V de la maison.
|
||||
|
||||
|
||||
<br><bR>
|
||||
On peut voir ici, avec ce projet assez complet, toutes les possibilités offertes de la programmation des NodeMCU en LUA, en mode événementiel. <br>
|
||||
Choses qui ne seraient pas possible si on l'avait fait en C++ (mode Arduino), comme par exemple:
|
||||
|
||||
* serveur WEB Active Server Pages ZYX, permet de faire des pages HTML dynamiques avec du code LUA in line. Les pages HTML sont sauve dans la FLASH du NodeMCU
|
||||
* serveur WEB service pour le HUB concentrateur de mesures de différents NodeMCU (API GET)
|
||||
* serveur WEB pour l'affichage de la consommation électrique
|
||||
* serveur WEB pour l'IDE, modification du code source en remote directement depuis une page WEB, pas besoin d'IDE
|
||||
* crontab, horloge pour les mesures
|
||||
* serveur TELNET, utilisation de la console en remote pour le dépannage
|
||||
|
||||
Toutes les fonctions sont bien séparées dans des scripts, cela *complexifie* le projet mais ce qui facilite la portabilité entre les projets et aussi sa mise au point.
|
||||
|
||||
|
||||
|
||||
## Astuces de mesures de la puissance
|
||||
|
||||
Dans ce projet il y a 1x NodeMCU qui mesure la production électrique de mon installation solaire PV. On mesure le courant injecté dans le réseau électrique de la maison avec un petit transformateur de courant 1/800 *clipsé* sur la phase de l'onduleur.<br>
|
||||
* Comme le convertisseur ADC du NodeMCU ne peut mesurer que des valeurs positives comprises entre 0V et 1V, on ajoute une masse *fictive* au signal du transformateur de courant de 0.5V afin de *remonter* l'alternance négative.<br>
|
||||
Au lieu de *découper* la sinusoïde (50Hz) en 100 *parties*, c'est à dire toutes les 0.2ms (5'000x /s), pour en faire l'intégrale. On lit l'ADC toutes les 11ms (seulement 91x /s) donc beaucoup plus lentement.<br>
|
||||
* Comme la sinusoïde fait 20ms et est *répétitive*, on balaye (par *décalage*) statistiquement la sinusoïde.<br>
|
||||
* On *redresse* l'alternance par rapport à la masse fictive (env 0.5V), ce qui nous permet d'estimer une valeur RMS du courant quelque soit sa forme et on la moyenne sur une période de 2.1 secondes.<br>
|
||||
* Les mesures min et max ne sont là juste que pour vérifier que nous sommes bien dans la plage de mesure avec le choix de la résistance de *conversion* du transformateur de courant.<br>
|
||||
* Le calcul de la puissance mesurée est très simpliste, un simple ```P=U*I```. On ne tient donc pas compte ici du ```cos(phy)``` qui pourrait varier en fonction des charges inductives dans la maison !
|
||||
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
Il faut *flasher* le NodeMCU avec ce firmware:
|
||||
|
||||
https://github.com/zuzu59/NodeMCU_Lua/blob/master/Firmware/nodemcu-master-20-modules-2019-07-01-06-35-13-float.bin
|
||||
|
||||
|
||||
Avec ces modules:
|
||||
|
||||
```
|
||||
adc ds18b20 file gpio http i2c mdns mqtt net
|
||||
node ow pcm rtctime sntp spi tmr uart wifi ws2812
|
||||
```
|
||||
|
||||
|
||||
## Utilisation
|
||||
|
||||
### Distribution des rôles de NodeMCU
|
||||
|
||||
Comme la mesure de production électrique est faite avec 1x NodeMCU, il y a donc 1x fichier de *secrets*. C'est dans ce fichier de *secrets* qu'il y a l'information de l'adresse IP de la base de donnée InfluxDB !<br>
|
||||
|
||||
```
|
||||
secrets_energy.lua
|
||||
```
|
||||
|
||||
|
||||
|
||||
**ATTENTION, readme pas encore terminé, il faut encore modifier le readme depuis ici ! zf190922.1740**
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
### Affichage des températures en local sur le NodeMCU
|
||||
|
||||
On peut lire la température directement sur le NodeMCU au moyen de cet url (il faut modifier l'adresse IP du NodeMCU en question):
|
||||
|
||||
nodemcu 28 int, http://192.168.0.171/disp_temp.html
|
||||
|
||||
nodemcu 29 sud, http://192.168.0.180/disp_temp.html
|
||||
|
||||
nodemcu 30 nord, http://192.168.0.105/disp_temp.html
|
||||
|
||||
|
||||
### Affichage du petit serveur web du NodeMCU_Lua
|
||||
|
||||
Chaque NodeMCU a son propre serveur WEB, on peut l'accéder simplement depuis son adresse IP:
|
||||
|
||||
nodemcu 28 int, http://192.168.0.171
|
||||
|
||||
nodemcu 29 sud, http://192.168.0.180
|
||||
|
||||
nodemcu 30 nord, http://192.168.0.105
|
||||
|
||||
|
||||
### Modification du code source du NodeMCU en remote
|
||||
|
||||
Très pratique pour le debug, on peut directement modifier le code source Lua du NodeMCU en remote avec cet url:
|
||||
|
||||
nodemcu 28 int, http://192.168.0.171:88
|
||||
|
||||
nodemcu 29 sud, http://192.168.0.180:88
|
||||
|
||||
nodemcu 30 sord, http://192.168.0.105:88
|
||||
|
||||
|
||||
### Utilisation de la console du NodeMCU en remote
|
||||
|
||||
Très pratique pour le debug, on peut accéder à la console du NodeMCU en remote avec telnet:
|
||||
|
||||
nodemcu 28 int, **telnet -rN 192.168.0.171**
|
||||
|
||||
nodemcu 29 sud, **telnet -rN 192.168.0.180**
|
||||
|
||||
nodemcu 30 nord, **telnet -rN 192.168.0.105**
|
||||
|
||||
|
||||
## Visualisation sur ThingSpeak
|
||||
La totale en détail
|
||||
https://thingspeak.com/channels/817940
|
||||
|
||||
Seulement la corrélation entre les trois température
|
||||
https://thingspeak.com/apps/plugins/300559
|
||||
|
||||
|
||||
zf190922.1740
|
||||
|
||||
|
||||
pense bête:
|
||||
|
||||
```
|
||||
file.open("hello.lua","w+")
|
||||
file.writeline([[print("hello nodemcu")]])
|
||||
file.writeline([[print(node.heap())]])
|
||||
file.close()
|
||||
```
|
||||
19
Mesures/energy/transfo_courant_clip_1p/_secrets_energy.lua_
Normal file
@@ -0,0 +1,19 @@
|
||||
-- Petit script pour configurer les choses secrètes que l'on n'aimerait
|
||||
-- pas être exportées sur Internet (github)
|
||||
-- donc on ne met PAS des secrets dans le code !
|
||||
-- faut le mettre ailleurs que dans le dépôt !
|
||||
-- il faut le renommer en 'secrets_energy.lua' et sera exécuté
|
||||
-- par 'boot.lua' au moment du boot
|
||||
|
||||
function secrets()
|
||||
print("\n secrets_energy.lua zf190916.1458 \n")
|
||||
|
||||
cli_ssid="xxx"
|
||||
cli_pwd="xxx"
|
||||
|
||||
influxdb_url="http://xxx.yyy.zzz:8086/write?db=xxx&u=admin&p=xxx"
|
||||
print("influxdb_url: "..influxdb_url)
|
||||
|
||||
end
|
||||
secrets()
|
||||
secrets=nil
|
||||
55
Mesures/energy/transfo_courant_clip_1p/_zremote_cmd.txt
Normal file
@@ -0,0 +1,55 @@
|
||||
# Quelques commandes remote (luatool) à envoyer avec le plugin Atom-IDE-terminal de l'éditeur Atom
|
||||
# zf191026.0913
|
||||
|
||||
# si luatool ne marche pas sur le MAC, il faut lire ceci:
|
||||
# https://docs.google.com/document/d/1q64uK3IMOgEDdKaIAttbYuFt4GuLQ06k3FLeyfCsWLg/edit#heading=h.bmefcu67uwj0
|
||||
|
||||
# raccourcis clavier
|
||||
# CTRL+ALT+ENTER envoie au terminal la ligne de l'éditeur
|
||||
# SHIT+CTRL+` ouvre le terminal (attention, ne pas oublier de copier le *path* dans le *tree* et le changer)
|
||||
# ALT+CMD+F bascule entre le terminal et l'éditeur
|
||||
|
||||
# définitions à faire AVANT !
|
||||
export luatool_tty="/dev/cu.wchusbserial1410"
|
||||
export zIP="192.168.0.135"
|
||||
|
||||
|
||||
# ouvrir et fermer (ALT+n+.) une session telnet sur le NodeMCU avec l'adresse zIP)
|
||||
telnet -rN $zIP
|
||||
~.
|
||||
node.restart()
|
||||
=node.heap()
|
||||
|
||||
|
||||
# commandes lua pour ce projet
|
||||
verbose=true
|
||||
verbose=false
|
||||
|
||||
|
||||
#commandes luatool pour ce projet
|
||||
./luatool.py --ip $zIP -f 0_get_data.lua
|
||||
./luatool.py --ip $zIP -f 0_send_data.lua
|
||||
./luatool.py --ip $zIP -f cat.lua
|
||||
|
||||
|
||||
~.
|
||||
./luatool.py --ip $zIP -f head.lua
|
||||
telnet -rN $zIP
|
||||
dofile("head.lua")
|
||||
zhead("telnet_srv2.lua")
|
||||
|
||||
|
||||
./luatool.py --ip $zIP --zrestart
|
||||
|
||||
|
||||
# faire un cat d'un fichier sur le NodeMCU
|
||||
dofile("cat.lua")
|
||||
cat("boot2.lua")
|
||||
|
||||
|
||||
# commandes luatool
|
||||
./luatool.py -h
|
||||
./luatool.py --ip $zIP -i
|
||||
./luatool.py --ip $zIP -l
|
||||
./luatool.py --ip $zIP -f toto.lua -d
|
||||
./luatool.py --ip $zIP --delete toto.lua
|
||||
15
Mesures/energy/transfo_courant_clip_1p/boot.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
-- Scripts à charger après le boot pour démarrer le core system
|
||||
|
||||
print("\n boot.lua zf190916.2359 \n")
|
||||
|
||||
-- charge ses propres secrets
|
||||
f= "secrets_energy.lua" if file.exists(f) then dofile(f) end
|
||||
|
||||
--f= "led_rgb.lua" if file.exists(f) then dofile(f) end
|
||||
--f= "wifi_ap_start.lua" if file.exists(f) then dofile(f) end
|
||||
f= "wifi_ap_stop.lua" if file.exists(f) then dofile(f) end
|
||||
f= "wifi_cli_conf.lua" if file.exists(f) then dofile(f) end
|
||||
f= "wifi_cli_start.lua" if file.exists(f) then dofile(f) end
|
||||
f= "telnet_srv2.lua" if file.exists(f) then dofile(f) end
|
||||
f= "web_ide2.lua" if file.exists(f) then dofile(f) end
|
||||
f= "web_srv2.lua" if file.exists(f) then dofile(f) end
|
||||
22
Mesures/energy/transfo_courant_clip_1p/boot2.lua
Normal file
@@ -0,0 +1,22 @@
|
||||
-- Scripts à charger après le boot pour démarrer son appli
|
||||
|
||||
print("\n boot2.lua zf190917.0030 \n")
|
||||
|
||||
second_chance=nil
|
||||
function heartbeat()
|
||||
f= "flash_led_xfois.lua" if file.exists(f) then dofile(f) end
|
||||
flash_led_xfois()
|
||||
boottimer1=tmr.create()
|
||||
boottimer1:alarm(1*1000, tmr.ALARM_AUTO, function()
|
||||
xfois =2
|
||||
blink_LED ()
|
||||
end)
|
||||
end
|
||||
|
||||
f= "0_get_data.lua" if file.exists(f) then dofile(f) end
|
||||
f= "0_send_data.lua" if file.exists(f) then dofile(f) end
|
||||
f= "0_cron.lua" if file.exists(f) then dofile(f) end
|
||||
|
||||
f=nil
|
||||
heartbeat=nil
|
||||
--heartbeat()
|
||||
18
Mesures/energy/transfo_courant_clip_1p/cat.lua
Normal file
@@ -0,0 +1,18 @@
|
||||
-- fonction cat() pour afficher le contenu d'un fichier dans la flash
|
||||
print("\n cat.lua zf192026.0858 \n")
|
||||
|
||||
function cat(zfile)
|
||||
print("\n"..zfile.."\n-------------------------------")
|
||||
|
||||
zfilei = file.open(zfile, "r")
|
||||
i=1
|
||||
zline=file.readline()
|
||||
repeat
|
||||
-- print(i..": "..string.sub(zline,1,string.len(zline)-1))
|
||||
print(string.sub(zline,1,string.len(zline)-1))
|
||||
i=i+1 zline=file.readline()
|
||||
until zline== nil
|
||||
file.close(zfilei)
|
||||
|
||||
print("-------------------------------")
|
||||
end
|
||||
15
Mesures/energy/transfo_courant_clip_1p/dir.lua
Normal file
@@ -0,0 +1,15 @@
|
||||
-- fonction dir() pour afficher les fichiers dans la flash
|
||||
print("\n dir.lua zf180826.1019 \n")
|
||||
|
||||
function dir()
|
||||
print("\n-------------------------------")
|
||||
l=file.list() i=0
|
||||
for k,v in pairs(l) do
|
||||
i=i+v
|
||||
print(k..string.rep(" ",19-string.len(k)).." : "..v.." bytes")
|
||||
end
|
||||
print("-------------------------------")
|
||||
print('\nUsed: '..i..' bytes\nusage: dofile("file.lua")\n')
|
||||
end
|
||||
|
||||
dir()
|
||||
39
Mesures/energy/transfo_courant_clip_1p/flash_led_xfois.lua
Normal file
@@ -0,0 +1,39 @@
|
||||
-- programme pour faire clignoter x fois une LED avec un rapport on/off
|
||||
|
||||
function flash_led_xfois()
|
||||
print("\n flash_led_xfois.lua zf190601.1618 \n")
|
||||
|
||||
--zLED=0 --NodeMCU
|
||||
zLED=4 --EPS-M3
|
||||
zTm_On_LED = 50 --> en ms
|
||||
zTm_Off_LED = 100 --> en ms
|
||||
nbfois = 0
|
||||
gpio.write(zLED, gpio.HIGH)
|
||||
gpio.mode(zLED, gpio.OUTPUT)
|
||||
ztmr_Flash_LED = tmr.create()
|
||||
|
||||
function blink_LED ()
|
||||
if nbfois >= xfois then
|
||||
-- print(nbfois)
|
||||
nbfois = 0
|
||||
else
|
||||
if gpio.read(zLED)==gpio.HIGH then
|
||||
gpio.write(zLED, gpio.LOW)
|
||||
-- tmr.alarm(ztmr_Flash_LED, zTm_Off_LED, tmr.ALARM_SINGLE, blink_LED)
|
||||
ztmr_Flash_LED:alarm(zTm_Off_LED, tmr.ALARM_SINGLE, blink_LED)
|
||||
else
|
||||
gpio.write(zLED, gpio.HIGH)
|
||||
nbfois = nbfois+1
|
||||
-- tmr.alarm(ztmr_Flash_LED, zTm_On_LED, tmr.ALARM_SINGLE, blink_LED)
|
||||
ztmr_Flash_LED:alarm(zTm_On_LED, tmr.ALARM_SINGLE, blink_LED)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- xfois =2
|
||||
-- blink_LED ()
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
1
Mesures/energy/transfo_courant_clip_1p/goodies/a6.lua
Normal file
@@ -0,0 +1 @@
|
||||
-- programme pour faire un test depuis de le webide
|
||||
1
Mesures/energy/transfo_courant_clip_1p/goodies/a7.lua
Normal file
@@ -0,0 +1 @@
|
||||
-- programme pour faire un test depuis de le webide
|
||||
1
Mesures/energy/transfo_courant_clip_1p/goodies/a8.lua
Normal file
@@ -0,0 +1 @@
|
||||
-- programme pour faire un test depuis de le webide
|
||||
1
Mesures/energy/transfo_courant_clip_1p/goodies/a9.lua
Normal file
@@ -0,0 +1 @@
|
||||
-- programme pour faire un test depuis de le webide
|
||||
@@ -0,0 +1,6 @@
|
||||
-- Scripts pour afficher toutes les variables et fonctions en cours dans le système
|
||||
|
||||
print("\n a_tst_variable.lua zf190310.1525 \n")
|
||||
|
||||
for n in pairs (_G) do print(n) end
|
||||
|
||||
37
Mesures/energy/transfo_courant_clip_1p/goodies/led_rgb.lua
Normal file
@@ -0,0 +1,37 @@
|
||||
-- Scripts juste pour allumer ou éteindre une LED sur un ruban RGB
|
||||
-- tout sur la couleur: https://www.w3schools.com/colors/default.asp
|
||||
-- roue des couleurs: https://iro.js.org/?ref=oldsite
|
||||
|
||||
print("\n led_rgb.lua zf190303.1436 \n")
|
||||
|
||||
nbleds=3
|
||||
ws2812.init()
|
||||
myLedStrip = ws2812.newBuffer(nbleds, 3)
|
||||
|
||||
function RGB_clear()
|
||||
myLedStrip:fill(0, 0, 0) ws2812.write(myLedStrip)
|
||||
end
|
||||
|
||||
function RGB_reform(R1, G1, B1) --conversion de RGB à BRG
|
||||
rR1=B1 rG1=R1 rB1=G1
|
||||
end
|
||||
|
||||
function zled_rgb(num_led, R1, G1, B1, zpower)
|
||||
RGB_reform(R1, G1, B1)
|
||||
myLedStrip:set(num_led, rR1*zpower, rG1*zpower, rB1*zpower)
|
||||
ws2812.write(myLedStrip)
|
||||
end
|
||||
|
||||
function zled_write()
|
||||
ws2812.write(myLedStrip)
|
||||
end
|
||||
|
||||
|
||||
RGB_clear()
|
||||
|
||||
--[[
|
||||
zled_rgb(1,255,0,0,1)
|
||||
zled_rgb(2,0,255,0,1)
|
||||
zled_rgb(2,0,255,0,0.05)
|
||||
zled_rgb(3,0,0,255,1)
|
||||
]]
|
||||
12
Mesures/energy/transfo_courant_clip_1p/goodies/rm_files.lua
Normal file
@@ -0,0 +1,12 @@
|
||||
-- pour effacer TOUS les fichiers qui se trouve dans la flash du NodeMCU
|
||||
|
||||
print("\n rm_files.lua zf180907.1511 \n")
|
||||
|
||||
|
||||
l=file.list() i=0
|
||||
for k,v in pairs(l) do
|
||||
i=i+v
|
||||
file.remove(k)
|
||||
end
|
||||
print("-------------------------------")
|
||||
print("\nC'est tout effaced :-) \n")
|
||||
27
Mesures/energy/transfo_courant_clip_1p/goodies/t1.csv
Normal file
@@ -0,0 +1,27 @@
|
||||
ohm,%
|
||||
33,100
|
||||
36,96.77419355
|
||||
41,92.74193548
|
||||
45,88.70967742
|
||||
52,84.67741935
|
||||
56,80.64516129
|
||||
61,76.61290323
|
||||
67,72.58064516
|
||||
72,68.5483871
|
||||
79,64.51612903
|
||||
83,60.48387097
|
||||
91,56.4516129
|
||||
97,52.41935484
|
||||
104,48.38709677
|
||||
112,44.35483871
|
||||
117,40.32258065
|
||||
121,36.29032258
|
||||
128,32.25806452
|
||||
132,28.22580645
|
||||
139,24.19354839
|
||||
150,20.16129032
|
||||
166,16.12903226
|
||||
191,12.09677419
|
||||
207,8.064516129
|
||||
224,4.032258065
|
||||
240,0
|
||||
|
@@ -0,0 +1,19 @@
|
||||
-- Démarre le WIFI en mode AP
|
||||
|
||||
function wifi_ap_start()
|
||||
print("\n wifi_ap_start.lua zf190310.1511 \n")
|
||||
|
||||
local zmodewifi=wifi.getmode()
|
||||
if zmodewifi == wifi.NULLMODE then
|
||||
print("WIFI mode AP only")
|
||||
wifi.setmode(wifi.SOFTAP)
|
||||
elseif zmodewifi == wifi.STATION then
|
||||
print("WIFI mode AP+CLI")
|
||||
wifi.setmode(wifi.STATIONAP)
|
||||
end
|
||||
wifi.ap.config({ ssid = "NodeMCU "..wifi.ap.getmac(), pwd = "12345678" })
|
||||
--f= "wifi_info.lua" if file.exists(f) then dofile(f) end
|
||||
end
|
||||
|
||||
wifi_ap_start()
|
||||
wifi_ap_start=nil
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Petit script pour obtenir l'adresse IP du NodeMCU connecté sur un AP Wifi
|
||||
print("\n wifi_get_ip.lua zf181119.2318 \n")
|
||||
|
||||
wifitimer1=tmr.create()
|
||||
tmr.alarm(wifitimer1, 1000, tmr.ALARM_AUTO , function()
|
||||
if wifi.sta.getip() == nil then
|
||||
print("Connecting to AP...")
|
||||
else
|
||||
tmr.stop(wifitimer1)
|
||||
f= "wifi_info.lua" if file.exists(f) then dofile(f) end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Déconnecte le WIFI
|
||||
print("\n wifi_off.lua zf180822.0959 \n")
|
||||
|
||||
wifi.setmode(wifi.NULLMODE)
|
||||
|
||||
--[[
|
||||
print(wifi.NULLMODE, wifi.STATION, wifi.SOFTAP, wifi.STATIONAP)
|
||||
print(wifi.getmode())
|
||||
]]
|
||||
19
Mesures/energy/transfo_courant_clip_1p/head.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
-- fonction cat() pour afficher les 10 premières lignes d'un fichier dans la flash
|
||||
print("\n head.lua zf192026.0942 \n")
|
||||
|
||||
function zhead(zfile)
|
||||
print("\n"..zfile.."\n-------------------------------")
|
||||
|
||||
zfilei = file.open(zfile, "r")
|
||||
i=1
|
||||
zline=file.readline()
|
||||
repeat
|
||||
-- print(i..": "..string.sub(zline,1,string.len(zline)-1))
|
||||
print(string.sub(zline,1,string.len(zline)-1))
|
||||
i=i+1 zline=file.readline()
|
||||
if i>10 then break end
|
||||
until zline==nil
|
||||
file.close(zfilei)
|
||||
|
||||
print("-------------------------------")
|
||||
end
|
||||
BIN
Mesures/energy/transfo_courant_clip_1p/img/20190907_170403.jpg
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
Mesures/energy/transfo_courant_clip_1p/img/20190907_170414.jpg
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
Mesures/energy/transfo_courant_clip_1p/img/20190908_134444.jpg
Normal file
|
After Width: | Height: | Size: 768 KiB |
BIN
Mesures/energy/transfo_courant_clip_1p/img/20190908_213900.jpg
Normal file
|
After Width: | Height: | Size: 801 KiB |
BIN
Mesures/energy/transfo_courant_clip_1p/img/20190908_213927.jpg
Normal file
|
After Width: | Height: | Size: 792 KiB |
BIN
Mesures/energy/transfo_courant_clip_1p/img/20190908_221514.jpg
Normal file
|
After Width: | Height: | Size: 834 KiB |
63
Mesures/energy/transfo_courant_clip_1p/initz.lua
Normal file
@@ -0,0 +1,63 @@
|
||||
--Script de bootstrap, test au moment du boot qui a été la cause de boot.
|
||||
-- Si la cause est un power on ou une connexion depuis l'IDE, alors
|
||||
-- le script repair.lua pendant xx secondes avant de continuer
|
||||
--Source: https://nodemcu.readthedocs.io/en/master/en/modules/node/#nodebootreason
|
||||
|
||||
print("\n init.lua zf190917.0001 \n")
|
||||
|
||||
zswitch=3 --switch flash
|
||||
gpio.mode(zswitch, gpio.INT, gpio.PULLUP)
|
||||
|
||||
function hvbouton()
|
||||
gpio.trig(zswitch, "none")
|
||||
initalarme:unregister() initalarme2:unregister()
|
||||
f= "boot.lua" if file.exists(f) then dofile(f) end
|
||||
f= "boot2.lua" if file.exists(f) then dofile(f) end
|
||||
end
|
||||
|
||||
gpio.trig(zswitch, "both", hvbouton)
|
||||
|
||||
function second_chance()
|
||||
print("seconde chance...")
|
||||
f= "repair.lua" if file.exists(f) then dofile(f) end
|
||||
initalarme=tmr.create()
|
||||
initalarme:alarm(4*1000, tmr.ALARM_SINGLE, function()
|
||||
f= "boot.lua" if file.exists(f) then dofile(f) end
|
||||
end)
|
||||
initalarme2=tmr.create()
|
||||
initalarme2:alarm(30*1000, tmr.ALARM_SINGLE, function()
|
||||
gpio.trig(zswitch)
|
||||
hvbouton=nil
|
||||
zswitch=nil
|
||||
reset_reason=nil
|
||||
f= "boot2.lua" if file.exists(f) then dofile(f) end
|
||||
end)
|
||||
end
|
||||
|
||||
_, reset_reason = node.bootreason()
|
||||
print("reset_reason:",reset_reason)
|
||||
if reset_reason == 0 then
|
||||
print("power on")
|
||||
second_chance()
|
||||
elseif reset_reason == 4 then
|
||||
print("node.restart")
|
||||
gpio.trig(zswitch)
|
||||
hvbouton=nil
|
||||
second_chance=nil
|
||||
zswitch=nil
|
||||
reset_reason=nil
|
||||
f= "boot.lua" if file.exists(f) then dofile(f) end
|
||||
f= "boot2.lua" if file.exists(f) then dofile(f) end
|
||||
elseif reset_reason == 5 then
|
||||
print("dsleep wake up")
|
||||
f= "boot.lua" if file.exists(f) then dofile(f) end
|
||||
f= "boot2.lua" if file.exists(f) then dofile(f) end
|
||||
elseif reset_reason == 6 then
|
||||
print("external reset")
|
||||
second_chance()
|
||||
else
|
||||
print("autre raison")
|
||||
second_chance()
|
||||
end
|
||||
|
||||
|
||||
398
Mesures/energy/transfo_courant_clip_1p/luatool.py
Executable file
@@ -0,0 +1,398 @@
|
||||
#!/usr/bin/env python2
|
||||
# -*- coding: utf-8 -*-
|
||||
version = "0.6.5 zf191021.1558"
|
||||
|
||||
print("luatool.py ver " + version)
|
||||
|
||||
#Améliorations
|
||||
# Pour voir les améliorations il faut 'chercher' les zzz
|
||||
|
||||
|
||||
#
|
||||
# ESP8266 luatool
|
||||
# Author e-mail: 4ref0nt@gmail.com
|
||||
# Site: http://esp8266.ru
|
||||
# Contributions from: https://github.com/sej7278
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
||||
# Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
import sys
|
||||
import serial
|
||||
from time import sleep
|
||||
import socket
|
||||
import argparse
|
||||
from os.path import basename
|
||||
|
||||
|
||||
tqdm_installed = True
|
||||
try:
|
||||
from tqdm import tqdm
|
||||
except ImportError, e:
|
||||
if e.message == 'No module named tqdm':
|
||||
tqdm_installed = False
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
|
||||
class TransportError(Exception):
|
||||
"""Custom exception to represent errors with a transport
|
||||
"""
|
||||
def __init__(self, message):
|
||||
self.message = message
|
||||
|
||||
def __str__(self):
|
||||
return self.message
|
||||
|
||||
class AbstractTransport:
|
||||
def __init__(self):
|
||||
raise NotImplementedError('abstract transports cannot be instantiated.')
|
||||
|
||||
def close(self):
|
||||
raise NotImplementedError('Function not implemented')
|
||||
|
||||
def read(self, length):
|
||||
raise NotImplementedError('Function not implemented')
|
||||
|
||||
def writeln(self, data, check=1):
|
||||
raise NotImplementedError('Function not implemented')
|
||||
|
||||
def writer(self, data):
|
||||
self.writeln("file.writeline([==[" + data + "]==])\r")
|
||||
|
||||
def performcheck(self, expected):
|
||||
line = ''
|
||||
char = ''
|
||||
i = -1
|
||||
while char != chr(62): # '>'
|
||||
char = self.read(1)
|
||||
if char == '':
|
||||
raise Exception('No proper answer from MCU')
|
||||
if char == chr(13) or char == chr(10): # LF or CR
|
||||
if line != '':
|
||||
line = line.strip()
|
||||
# zzz191021 Affiche ce que l'on a reçu du NodeMCU
|
||||
if args.verbose:
|
||||
print("\n\nzread0957: {" + line + "\n}\n")
|
||||
|
||||
if line+'\r' == expected and not args.bar:
|
||||
sys.stdout.write(" -> ok")
|
||||
elif line+'\r' != expected:
|
||||
if line[:4] == "lua:":
|
||||
sys.stdout.write("\r\n\r\nLua ERROR: %s" % line)
|
||||
raise Exception('ERROR from Lua interpreter\r\n\r\n')
|
||||
else:
|
||||
expected = expected.split("\r")[0]
|
||||
sys.stdout.write("\r\n\r\nERROR")
|
||||
sys.stdout.write("\r\n send string : '%s'" % expected)
|
||||
sys.stdout.write("\r\n expected echo : '%s'" % expected)
|
||||
sys.stdout.write("\r\n but got answer : '%s'" % line)
|
||||
sys.stdout.write("\r\n\r\n")
|
||||
raise Exception('Error sending data to MCU\r\n\r\n')
|
||||
line = ''
|
||||
else:
|
||||
line += char
|
||||
if char == chr(62) and expected[i] == char:
|
||||
char = ''
|
||||
i += 1
|
||||
|
||||
|
||||
class SerialTransport(AbstractTransport):
|
||||
def __init__(self, port, baud, delay):
|
||||
self.port = port
|
||||
self.baud = baud
|
||||
self.serial = None
|
||||
self.delay = delay
|
||||
|
||||
try:
|
||||
self.serial = serial.Serial(port, baud)
|
||||
except serial.SerialException as e:
|
||||
raise TransportError(e.strerror)
|
||||
|
||||
self.serial.timeout = 3
|
||||
self.serial.interCharTimeout = 3
|
||||
|
||||
# zzz191021 juste après l'ouverture du port série, on attend le caractère '>'
|
||||
line = ''
|
||||
char = ''
|
||||
i = -1
|
||||
while char != chr(62): # '>'
|
||||
char = self.read(1)
|
||||
if char == '':
|
||||
raise Exception('No proper answer from MCU')
|
||||
line += char
|
||||
i += 1
|
||||
if args.verbose:
|
||||
print("line: ." + line + ".")
|
||||
|
||||
|
||||
def writeln(self, data, check=1):
|
||||
# zzz191020 on fait une petite pause avant l'envoi de chaque ligne
|
||||
sleep(self.delay)
|
||||
if self.serial.inWaiting() > 0:
|
||||
self.serial.flushInput()
|
||||
if len(data) > 0 and not args.bar:
|
||||
sys.stdout.write("\r\n->")
|
||||
sys.stdout.write(data.split("\r")[0])
|
||||
self.serial.write(data)
|
||||
# zzz191021 Affiche ce que l'on a envoyé au NodeMCU
|
||||
if args.verbose:
|
||||
print("\n\nzwrite0952: {" + data + "\n}\n")
|
||||
if check > 0:
|
||||
self.performcheck(data)
|
||||
elif not args.bar:
|
||||
sys.stdout.write(" -> send without check")
|
||||
|
||||
def read(self, length):
|
||||
return self.serial.read(length)
|
||||
|
||||
def close(self):
|
||||
self.serial.flush()
|
||||
self.serial.close()
|
||||
|
||||
|
||||
class TcpSocketTransport(AbstractTransport):
|
||||
def __init__(self, host, port):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.socket = None
|
||||
|
||||
try:
|
||||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
except socket.error as e:
|
||||
raise TransportError(e.strerror)
|
||||
|
||||
try:
|
||||
self.socket.connect((host, port))
|
||||
except socket.error as e:
|
||||
raise TransportError(e.strerror)
|
||||
# read intro from telnet server (see telnet_srv.lua)
|
||||
self.socket.recv(50)
|
||||
|
||||
def writeln(self, data, check=1):
|
||||
if len(data) > 0 and not args.bar:
|
||||
sys.stdout.write("\r\n->")
|
||||
sys.stdout.write(data.split("\r")[0])
|
||||
self.socket.sendall(data)
|
||||
if check > 0:
|
||||
self.performcheck(data)
|
||||
elif not args.bar:
|
||||
sys.stdout.write(" -> send without check")
|
||||
|
||||
def read(self, length):
|
||||
return self.socket.recv(length)
|
||||
|
||||
def close(self):
|
||||
self.socket.close()
|
||||
|
||||
|
||||
def decidetransport(cliargs):
|
||||
if cliargs.ip:
|
||||
data = cliargs.ip.split(':')
|
||||
host = data[0]
|
||||
if len(data) == 2:
|
||||
port = int(data[1])
|
||||
else:
|
||||
port = 23
|
||||
return TcpSocketTransport(host, port)
|
||||
else:
|
||||
return SerialTransport(cliargs.port, cliargs.baud, cliargs.delay)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# parse arguments or use defaults
|
||||
parser = argparse.ArgumentParser(description='ESP8266 Lua script uploader.')
|
||||
parser.add_argument('--bar', action='store_true', help='Show a progress bar for uploads instead of printing each line')
|
||||
parser.add_argument('--delay', default=0.03, help='Delay in seconds between each write, default 0.03 sec.', type=float)
|
||||
parser.add_argument('--delete', default=None, help='Delete a lua/lc file from device.')
|
||||
parser.add_argument('--ip', default=None, help='Connect via telnet server (--ip IP[:port])')
|
||||
parser.add_argument('--zrestart', action='store_true', help='Restart the NodeMCU.')
|
||||
parser.add_argument('-a', '--append', action='store_true', help='Append source file to destination file.')
|
||||
parser.add_argument('-b', '--baud', default=115200, help='Baudrate, default 115200')
|
||||
parser.add_argument('-c', '--compile', action='store_true', help='Compile lua to lc after upload')
|
||||
parser.add_argument('-d', '--dofile', action='store_true', help='Run the Lua script after upload')
|
||||
parser.add_argument('-e', '--echo', action='store_true', help='Echo output of MCU until script is terminated.')
|
||||
parser.add_argument('-f', '--src', default='main.lua', help='Source file on computer, default main.lua')
|
||||
parser.add_argument('-i', '--id', action='store_true', help='Query the modules chip id.')
|
||||
parser.add_argument('-l', '--list', action='store_true', help='List files on device')
|
||||
parser.add_argument('-p', '--port', default='/dev/ttyUSB0', help='Device name, default /dev/ttyUSB0')
|
||||
parser.add_argument('-r', '--restart', action='store_true', help='Restart MCU after upload')
|
||||
parser.add_argument('-t', '--dest', default=None, help='Destination file on MCU, default to source file name')
|
||||
parser.add_argument('-v', '--verbose', action='store_true', help="Show progress messages.")
|
||||
parser.add_argument('-w', '--wipe', action='store_true', help='Delete all lua/lc files on device.')
|
||||
args = parser.parse_args()
|
||||
|
||||
transport = decidetransport(args)
|
||||
|
||||
if args.bar and not tqdm_installed:
|
||||
sys.stdout.write("You must install the tqdm library to use the bar feature\n")
|
||||
sys.stdout.write("To install, at the prompt type: \"pip install tqdm\"\n")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if args.list:
|
||||
# zzz191020 Amélioré la sortie du listing des fichiers
|
||||
transport.writeln("print('\\n-----');local l = file.list();for k,v in pairs(l) do print(k..', size:'..v)end;print('-----\\n')\r", 0)
|
||||
while True:
|
||||
char = transport.read(1)
|
||||
if char == '' or char == chr(62): # '' or '>'
|
||||
break
|
||||
sys.stdout.write(char)
|
||||
sys.exit(0)
|
||||
|
||||
if args.id:
|
||||
transport.writeln("=node.chipid()\r", 0)
|
||||
id=""
|
||||
while True:
|
||||
char = transport.read(1)
|
||||
if char == '' or char == chr(62):
|
||||
break
|
||||
if char.isdigit():
|
||||
id += char
|
||||
print("\n"+id)
|
||||
sys.exit(0)
|
||||
|
||||
# zzz191020 Ajouté la fonction restart seule
|
||||
if args.zrestart:
|
||||
transport.writeln("node.restart()\r")
|
||||
sys.exit(0)
|
||||
|
||||
if args.wipe:
|
||||
transport.writeln("local l = file.list();for k,v in pairs(l) do print(k)end\r", 0)
|
||||
file_list = []
|
||||
fn = ""
|
||||
while True:
|
||||
char = transport.read(1)
|
||||
if char == '' or char == chr(62):
|
||||
break
|
||||
if char not in ['\r', '\n']:
|
||||
fn += char
|
||||
else:
|
||||
if fn:
|
||||
file_list.append(fn.strip())
|
||||
fn = ''
|
||||
for fn in file_list[1:]: # first line is the list command sent to device
|
||||
if args.verbose:
|
||||
sys.stderr.write("Delete file {} from device.\r\n".format(fn))
|
||||
transport.writeln("file.remove(\"" + fn + "\")\r")
|
||||
sys.exit(0)
|
||||
|
||||
if args.delete:
|
||||
transport.writeln("file.remove(\"" + args.delete + "\")\r")
|
||||
sys.exit(0)
|
||||
|
||||
if args.dest is None:
|
||||
args.dest = basename(args.src)
|
||||
# zzz191020 Affiche le fichier à envoyer
|
||||
print("File: " + args.src)
|
||||
|
||||
# open source file for reading
|
||||
try:
|
||||
try:
|
||||
f = open(args.src, "rt")
|
||||
except:
|
||||
import os
|
||||
base_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
f = open(os.path.join(base_dir, args.src), "rt")
|
||||
os.chdir(base_dir)
|
||||
except:
|
||||
sys.stderr.write("Could not open input file \"%s\"\n" % args.src)
|
||||
sys.exit(1)
|
||||
|
||||
# Verify the selected file will not exceed the size of the serial buffer.
|
||||
# The size of the buffer is 256. This script does not accept files with
|
||||
# lines longer than 230 characters to have some room for command overhead.
|
||||
num_lines = 0
|
||||
for ln in f:
|
||||
if len(ln) > 230:
|
||||
sys.stderr.write("File \"%s\" contains a line with more than 240 "
|
||||
"characters. This exceeds the size of the serial buffer.\n"
|
||||
% args.src)
|
||||
f.close()
|
||||
sys.exit(1)
|
||||
num_lines += 1
|
||||
|
||||
# Go back to the beginning of the file after verifying it has the correct
|
||||
# line length
|
||||
f.seek(0)
|
||||
|
||||
# set serial timeout
|
||||
if args.verbose:
|
||||
sys.stderr.write("Upload starting\r\n")
|
||||
|
||||
# remove existing file on device
|
||||
if args.append==False:
|
||||
if args.verbose:
|
||||
sys.stderr.write("Stage 1. Deleting old file from flash memory")
|
||||
transport.writeln("file.open(\"" + args.dest + "\", \"w\")\r")
|
||||
transport.writeln("file.close()\r")
|
||||
transport.writeln("file.remove(\"" + args.dest + "\")\r")
|
||||
else:
|
||||
if args.verbose:
|
||||
sys.stderr.write("[SKIPPED] Stage 1. Deleting old file from flash memory [SKIPPED]")
|
||||
|
||||
|
||||
# read source file line by line and write to device
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 2. Creating file in flash memory and write first line")
|
||||
if args.append:
|
||||
transport.writeln("file.open(\"" + args.dest + "\", \"a+\")\r")
|
||||
else:
|
||||
transport.writeln("file.open(\"" + args.dest + "\", \"w+\")\r")
|
||||
line = f.readline()
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 3. Start writing data to flash memory...")
|
||||
if args.bar:
|
||||
for i in tqdm(range(0, num_lines)):
|
||||
transport.writer(line.strip())
|
||||
line = f.readline()
|
||||
else:
|
||||
while line != '':
|
||||
transport.writer(line.strip())
|
||||
line = f.readline()
|
||||
|
||||
# close both files
|
||||
f.close()
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 4. Flush data and closing file")
|
||||
transport.writeln("file.flush()\r")
|
||||
transport.writeln("file.close()\r")
|
||||
|
||||
# compile?
|
||||
if args.compile:
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nStage 5. Compiling")
|
||||
transport.writeln("node.compile(\"" + args.dest + "\")\r")
|
||||
transport.writeln("file.remove(\"" + args.dest + "\")\r")
|
||||
|
||||
# restart or dofile
|
||||
if args.restart:
|
||||
transport.writeln("node.restart()\r")
|
||||
|
||||
if args.dofile: # never exec if restart=1
|
||||
transport.writeln("dofile(\"" + args.dest + "\")\r", 0)
|
||||
|
||||
if args.echo:
|
||||
if args.verbose:
|
||||
sys.stderr.write("\r\nEchoing MCU output, press Ctrl-C to exit")
|
||||
while True:
|
||||
sys.stdout.write(transport.read(1))
|
||||
|
||||
# close serial port
|
||||
transport.close()
|
||||
|
||||
# flush screen
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
if not args.bar:
|
||||
sys.stderr.write("\r\n--->>> All done <<<---\r\n")
|
||||
@@ -0,0 +1,52 @@
|
||||
t = require("ds18b20")
|
||||
pin = 3 -- gpio0 = 3, gpio2 = 4
|
||||
|
||||
local function readout(temp)
|
||||
if t.sens then
|
||||
print("Total number of DS18B20 sensors: ".. #t.sens)
|
||||
for i, s in ipairs(t.sens) do
|
||||
print(string.format(" sensor #%d address: %s%s", i, ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(s:byte(1,8)), s:byte(9) == 1 and " (parasite)" or ""))
|
||||
end
|
||||
end
|
||||
for addr, temp in pairs(temp) do
|
||||
print(string.format("Sensor %s: %s °C", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X'):format(addr:byte(1,8)), temp))
|
||||
end
|
||||
|
||||
-- Module can be released when it is no longer needed
|
||||
--t = nil
|
||||
--package.loaded["ds18b20"]=nil
|
||||
end
|
||||
|
||||
t:enable_debug()
|
||||
file.remove("ds18b20_save.lc") -- remove saved addresses
|
||||
print("=============================================", node.heap())
|
||||
print("first call, no addresses in flash, search is performed")
|
||||
t:read_temp(readout, pin, t.C)
|
||||
|
||||
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||
print("=============================================", node.heap())
|
||||
print("second readout, no new search, found addresses are used")
|
||||
t:read_temp(readout, pin)
|
||||
|
||||
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||
print("=============================================", node.heap())
|
||||
print("force search again")
|
||||
t:read_temp(readout, pin, nil, true)
|
||||
|
||||
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||
print("=============================================", node.heap())
|
||||
print("save search results")
|
||||
t:read_temp(readout, pin, nil, false, true)
|
||||
|
||||
tmr.create():alarm(2000, tmr.ALARM_SINGLE, function()
|
||||
print("=============================================", node.heap())
|
||||
print("use saved addresses")
|
||||
t.sens={}
|
||||
t:read_temp(readout, pin)
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
|
||||
end)
|
||||
@@ -0,0 +1,35 @@
|
||||
t = require('ds18b20')
|
||||
|
||||
port = 80
|
||||
pin = 3 -- gpio0 = 3, gpio2 = 4
|
||||
gconn = {} -- global variable for connection
|
||||
|
||||
function readout(temp)
|
||||
local resp = "HTTP/1.1 200 OK\nContent-Type: text/html\nRefresh: 5\n\n" ..
|
||||
"<!DOCTYPE HTML>" ..
|
||||
"<html><body>" ..
|
||||
"<b>ESP8266</b></br>"
|
||||
|
||||
for addr, temp in pairs(temp) do
|
||||
resp = resp .. string.format("Sensor %s: %s ℃</br>", ('%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8)), temp)
|
||||
end
|
||||
|
||||
resp = resp ..
|
||||
"Node ChipID: " .. node.chipid() .. "<br>" ..
|
||||
"Node MAC: " .. wifi.sta.getmac() .. "<br>" ..
|
||||
"Node Heap: " .. node.heap() .. "<br>" ..
|
||||
"Timer Ticks: " .. tmr.now() .. "<br>" ..
|
||||
"</html></body>"
|
||||
|
||||
gconn:send(resp)
|
||||
gconn:on("sent",function(conn) conn:close() end)
|
||||
end
|
||||
|
||||
srv=net.createServer(net.TCP)
|
||||
srv:listen(port,
|
||||
function(conn)
|
||||
gconn = conn
|
||||
-- t:read_temp(readout) -- default pin value is 3
|
||||
t:read_temp(readout, pin)
|
||||
end
|
||||
)
|
||||
223
Mesures/energy/transfo_courant_clip_1p/oldies/ds18b20.lua
Normal file
@@ -0,0 +1,223 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- DS18B20 one wire module for NODEMCU
|
||||
-- NODEMCU TEAM
|
||||
-- LICENCE: http://opensource.org/licenses/MIT
|
||||
-- @voborsky, @devsaurus, TerryE 26 Mar 2017
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
local modname = ...
|
||||
|
||||
-- Used modules and functions
|
||||
local table, string, ow, tmr, print, type, tostring, pcall, ipairs =
|
||||
table, string, ow, tmr, print, type, tostring, pcall, ipairs
|
||||
-- Local functions
|
||||
local ow_setup, ow_search, ow_select, ow_read, ow_read_bytes, ow_write, ow_crc8, ow_reset, ow_reset_search, ow_skip, ow_depower =
|
||||
ow.setup, ow.search, ow.select, ow.read, ow.read_bytes, ow.write, ow.crc8, ow.reset, ow.reset_search, ow.skip, ow.depower
|
||||
local node_task_post, node_task_LOW_PRIORITY = node.task.post, node.task.LOW_PRIORITY
|
||||
local string_char, string_dump = string.char, string.dump
|
||||
local now, tmr_create, tmr_ALARM_SINGLE = tmr.now, tmr.create, tmr.ALARM_SINGLE
|
||||
local table_sort, table_concat = table.sort, table.concat
|
||||
local math_floor = math.floor
|
||||
local file_open = file.open
|
||||
|
||||
table, string, tmr, ow = nil, nil, nil, nil
|
||||
|
||||
local DS18B20FAMILY = 0x28
|
||||
local DS1920FAMILY = 0x10 -- and DS18S20 series
|
||||
local CONVERT_T = 0x44
|
||||
local READ_SCRATCHPAD = 0xBE
|
||||
local READ_POWERSUPPLY= 0xB4
|
||||
local MODE = 1
|
||||
|
||||
local pin, cb, unit = 3
|
||||
local status = {}
|
||||
|
||||
local debugPrint = function() return end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Implementation
|
||||
--------------------------------------------------------------------------------
|
||||
local function enable_debug()
|
||||
debugPrint = function (...) print(now(),' ', ...) end
|
||||
end
|
||||
|
||||
local function to_string(addr, esc)
|
||||
if type(addr) == 'string' and #addr == 8 then
|
||||
return ( esc == true and
|
||||
'"\\%u\\%u\\%u\\%u\\%u\\%u\\%u\\%u"' or
|
||||
'%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X '):format(addr:byte(1,8))
|
||||
else
|
||||
return tostring(addr)
|
||||
end
|
||||
end
|
||||
|
||||
local function readout(self)
|
||||
local next = false
|
||||
local sens = self.sens
|
||||
local temp = self.temp
|
||||
for i, s in ipairs(sens) do
|
||||
if status[i] == 1 then
|
||||
ow_reset(pin)
|
||||
local addr = s:sub(1,8)
|
||||
ow_select(pin, addr) -- select the sensor
|
||||
ow_write(pin, READ_SCRATCHPAD, MODE)
|
||||
data = ow_read_bytes(pin, 9)
|
||||
|
||||
local t=(data:byte(1)+data:byte(2)*256)
|
||||
-- t is actually signed so process the sign bit and adjust for fractional bits
|
||||
-- the DS18B20 family has 4 fractional bits and the DS18S20s, 1 fractional bit
|
||||
t = ((t <= 32767) and t or t - 65536) *
|
||||
((addr:byte(1) == DS18B20FAMILY) and 625 or 5000)
|
||||
|
||||
if 1/2 == 0 then
|
||||
-- integer version
|
||||
if unit == 'F' then
|
||||
t = (t * 18)/10 + 320000
|
||||
elseif unit == 'K' then
|
||||
t = t + 2731500
|
||||
end
|
||||
local sgn = t<0 and -1 or 1
|
||||
local tA = sgn*t
|
||||
local tH=tA/10000
|
||||
local tL=(tA%10000)/1000 + ((tA%1000)/100 >= 5 and 1 or 0)
|
||||
|
||||
if tH and (t~=850000) then
|
||||
temp[addr]=(sgn<0 and "-" or "")..tH.."."..tL
|
||||
debugPrint(to_string(addr),(sgn<0 and "-" or "")..tH.."."..tL)
|
||||
status[i] = 2
|
||||
end
|
||||
-- end integer version
|
||||
else
|
||||
-- float version
|
||||
if t and (math_floor(t/10000)~=85) then
|
||||
t = t / 10000
|
||||
if unit == 'F' then
|
||||
t = t * 18/10 + 32
|
||||
elseif unit == 'K' then
|
||||
t = t + 27315/100
|
||||
end
|
||||
self.temp[addr]=t
|
||||
debugPrint(to_string(addr), t)
|
||||
status[i] = 2
|
||||
end
|
||||
-- end float version
|
||||
end
|
||||
end
|
||||
next = next or status[i] == 0
|
||||
end
|
||||
if next then
|
||||
node_task_post(node_task_LOW_PRIORITY, function() return conversion(self) end)
|
||||
else
|
||||
--sens = {}
|
||||
if cb then
|
||||
node_task_post(node_task_LOW_PRIORITY, function() return cb(temp) end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function conversion(self)
|
||||
local sens = self.sens
|
||||
local powered_only = true
|
||||
for _, s in ipairs(sens) do powered_only = powered_only and s:byte(9) ~= 1 end
|
||||
if powered_only then
|
||||
debugPrint("starting conversion: all sensors")
|
||||
ow_reset(pin)
|
||||
ow_skip(pin) -- select the sensor
|
||||
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||
for i, s in ipairs(sens) do status[i] = 1 end
|
||||
else
|
||||
for i, s in ipairs(sens) do
|
||||
if status[i] == 0 then
|
||||
local addr, parasite = s:sub(1,8), s:byte(9)
|
||||
debugPrint("starting conversion:", to_string(addr), parasite == 1 and "parasite" or " ")
|
||||
ow_reset(pin)
|
||||
ow_select(pin, addr) -- select the sensor
|
||||
ow_write(pin, CONVERT_T, MODE) -- and start conversion
|
||||
status[i] = 1
|
||||
if parasite == 1 then break end -- parasite sensor blocks bus during conversion
|
||||
end
|
||||
end
|
||||
end
|
||||
tmr_create():alarm(750, tmr_ALARM_SINGLE, function() return readout(self) end)
|
||||
end
|
||||
|
||||
local function _search(self, lcb, lpin, search, save)
|
||||
self.temp = {}
|
||||
if search then self.sens = {}; status = {} end
|
||||
local temp = self.temp
|
||||
local sens = self.sens
|
||||
pin = lpin or pin
|
||||
|
||||
local addr
|
||||
if not search and #sens == 0 then
|
||||
-- load addreses if available
|
||||
debugPrint ("geting addreses from flash")
|
||||
local s,check,a = pcall(dofile, "ds18b20_save.lc")
|
||||
if s and check == "ds18b20" then
|
||||
for i = 1, #a do sens[i] = a[i] end
|
||||
end
|
||||
debugPrint (#sens, "addreses found")
|
||||
end
|
||||
|
||||
ow_setup(pin)
|
||||
if search or #sens == 0 then
|
||||
ow_reset_search(pin)
|
||||
-- ow_target_search(pin,0x28)
|
||||
-- search the first device
|
||||
addr = ow_search(pin)
|
||||
else
|
||||
for i, s in ipairs(sens) do status[i] = 0 end
|
||||
end
|
||||
local function cycle()
|
||||
debugPrint("cycle")
|
||||
if addr then
|
||||
local crc=ow_crc8(addr:sub(1,7))
|
||||
if (crc==addr:byte(8)) and ((addr:byte(1)==DS1920FAMILY) or (addr:byte(1)==DS18B20FAMILY)) then
|
||||
ow_reset(pin)
|
||||
ow_select(pin, addr)
|
||||
ow_write(pin, READ_POWERSUPPLY, MODE)
|
||||
local parasite = (ow_read(pin)==0 and 1 or 0)
|
||||
sens[#sens+1]= addr..string_char(parasite) -- {addr=addr, parasite=parasite, status=0}
|
||||
debugPrint("contact: ", to_string(addr), parasite == 1 and "parasite" or " ")
|
||||
end
|
||||
addr = ow_search(pin)
|
||||
node_task_post(node_task_LOW_PRIORITY, cycle)
|
||||
else
|
||||
ow_depower(pin)
|
||||
-- place powered sensors first
|
||||
table_sort(sens, function(a, b) return a:byte(9)<b:byte(9) end) -- parasite
|
||||
-- save sensor addreses
|
||||
if save then
|
||||
debugPrint ("saving addreses to flash")
|
||||
|
||||
local addr_list = {}
|
||||
for i =1, #sens do
|
||||
local s = sens[i]
|
||||
addr_list[i] = to_string(s:sub(1,8), true)..('.."\\%u"'):format(s:byte(9))
|
||||
end
|
||||
local save_statement = 'return "ds18b20", {' .. table_concat(addr_list, ',') .. '}'
|
||||
debugPrint (save_statement)
|
||||
local save_file = file_open("ds18b20_save.lc","w")
|
||||
save_file:write(string_dump(loadstring(save_statement)))
|
||||
save_file:close()
|
||||
end
|
||||
-- end save sensor addreses
|
||||
if lcb then node_task_post(node_task_LOW_PRIORITY, lcb) end
|
||||
end
|
||||
end
|
||||
cycle()
|
||||
end
|
||||
|
||||
local function read_temp(self, lcb, lpin, lunit, force_search, save_search)
|
||||
cb, unit = lcb, lunit or unit
|
||||
_search(self, function() return conversion(self) end, lpin, force_search, save_search)
|
||||
end
|
||||
|
||||
-- Set module name as parameter of require and return module table
|
||||
local M = {
|
||||
sens = {},
|
||||
temp = {},
|
||||
C = 'C', F = 'F', K = 'K',
|
||||
read_temp = read_temp, enable_debug = enable_debug
|
||||
}
|
||||
_G[modname or 'ds18b20'] = M
|
||||
return M
|
||||
40
Mesures/energy/transfo_courant_clip_1p/oldies/thingspeak.mat
Normal file
@@ -0,0 +1,40 @@
|
||||
% Template MATLAB code for visualizing correlated data using the
|
||||
% SCATTER function.
|
||||
|
||||
% zf190728.1213
|
||||
|
||||
% Prior to running this MATLAB code template, assign the channel variables.
|
||||
% Set 'readChannelID' to the channel ID of the channel to read from.
|
||||
% Also, assign the read field IDs to the variables 'fieldID1', and 'fieldID2'.
|
||||
|
||||
% Replace the [] with channel ID to read data from:
|
||||
readChannelID = []];
|
||||
fieldID1 = 1;
|
||||
fieldID2 = 2;
|
||||
fieldID3 = 3;
|
||||
|
||||
% Channel Read API Key
|
||||
% If your channel is private, then enter the read API
|
||||
% Key between the '' below:
|
||||
readAPIKey = '';
|
||||
|
||||
%% Read Data %%
|
||||
|
||||
nbMesures = 200
|
||||
|
||||
% Read 1 data variable
|
||||
[data1, time1] = thingSpeakRead(readChannelID, 'Field', fieldID1, 'NumPoints', nbMesures, 'ReadKey', readAPIKey);
|
||||
|
||||
% Read 2 data variable
|
||||
[data2, time2] = thingSpeakRead(readChannelID, 'Field', fieldID2, 'NumPoints', nbMesures, 'ReadKey', readAPIKey);
|
||||
|
||||
% Read 3 data variable
|
||||
[data3, time3] = thingSpeakRead(readChannelID, 'Field', fieldID3, 'NumPoints', nbMesures, 'ReadKey', readAPIKey);
|
||||
|
||||
%% Visualize Data %%
|
||||
plot(time1,data1, time2,data2, time3,data3);
|
||||
|
||||
legend({'Tint 1er','Text sud','Text nord'});
|
||||
xlabel('Time (GMT ! )');
|
||||
ylabel('Temperature °C');
|
||||
title('Mesures température 1023 Crissier');
|
||||
|
After Width: | Height: | Size: 399 KiB |
BIN
Mesures/energy/transfo_courant_clip_1p/schemas/bread board.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
Mesures/energy/transfo_courant_clip_1p/schemas/schéma.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
29
Mesures/energy/transfo_courant_clip_1p/set_time.lua
Normal file
@@ -0,0 +1,29 @@
|
||||
-- Scripts pour régler l'horloge quand on est connecté en WIFI
|
||||
-- Permet aussi de 'compresser' le unix time afin de prendre moins de place dans les strings
|
||||
|
||||
print("\n set_time.lua zf190217.1426 \n")
|
||||
|
||||
--source: https://www.freeformatter.com/epoch-timestamp-to-date-converter.html
|
||||
|
||||
ztime2019 = 1546300800 -- Unix time pour le 1.1.2019
|
||||
|
||||
function set_time()
|
||||
sntp.sync(nil, nil, nil, 1)
|
||||
end
|
||||
|
||||
function ztime_compress(ztime_long)
|
||||
return ztime_long - ztime2019
|
||||
end
|
||||
|
||||
function ztime_uncompress(ztime_short)
|
||||
return ztime_short + ztime2019
|
||||
end
|
||||
|
||||
function ztime_format(ztime)
|
||||
tm = rtctime.epoch2cal(ztime + 3600)
|
||||
return(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"]))
|
||||
end
|
||||
|
||||
set_time()
|
||||
print(ztime_format(rtctime.get()))
|
||||
|
||||
39
Mesures/energy/transfo_courant_clip_1p/upload.sh
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
# Petit script pour télécharger facilement tout le binz
|
||||
#zf191023.0959
|
||||
|
||||
# S'il y a des erreurs lors d'un téléchargement, il faut simplement augmenter un peu le délai !
|
||||
# Il est préférable de télécharger en premier les *gros* fichiers .lua !
|
||||
|
||||
# ATTENTION: cela efface tout le NodeMCU !
|
||||
|
||||
echo "attention il n'est PAS à jour, zf191023.0959 !"
|
||||
exit
|
||||
|
||||
|
||||
luatool_tty="/dev/cu.wchusbserial1410"
|
||||
|
||||
echo ""
|
||||
read -p "ATTENTION, cela va effacer tout le NodeMCU !"
|
||||
read -p "Etes-vous vraiment certain ?"
|
||||
|
||||
chmod +x luatool.py
|
||||
|
||||
./luatool.py --port $luatool_tty -w
|
||||
./luatool.py --port $luatool_tty -l
|
||||
read -p "Est-ce bien vide ?"
|
||||
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.06 -f telnet_srv2.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f boot.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f boot2.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.03 -f flash_led_xfois.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f secrets_energy.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f wifi_ap_stop.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f wifi_cli_conf.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f wifi_cli_start.lua
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f wifi_info.lua
|
||||
|
||||
./luatool.py --port $luatool_tty -l
|
||||
read -p "Pas eu d'erreur, on part à fond avec le init.lua ?"
|
||||
./luatool.py --port $luatool_tty --bar --delay 0.001 -f initz.lua -t init.lua
|
||||
echo -e "\nC'est tout bon ;-)"
|
||||
159
Mesures/energy/transfo_courant_clip_1p/web_ide2.lua
Normal file
@@ -0,0 +1,159 @@
|
||||
-- Petit WEB IDE tout simple autonome
|
||||
-- ATTENTION: tourne sur le port 88 !
|
||||
|
||||
print("\n web_ide2.lua zf190706.1430 \n")
|
||||
|
||||
--[[
|
||||
XChip's NodeMCU IDE
|
||||
|
||||
Create, Edit and run NodeMCU files using your webbrowser.
|
||||
Examples:
|
||||
http://<mcu_ip>/ will list all the files in the MCU
|
||||
http://<mcu_ip>/newfile.lua displays the file on your browser
|
||||
http://<mcu_ip>/newfile.lua?edit allows to creates or edits the specified script in your browser
|
||||
http://<mcu_ip>/newfile.lua?run it will run the specified script and will show the returned value
|
||||
]]--
|
||||
|
||||
srv=net.createServer(net.TCP)
|
||||
srv:listen(88,function(conn)
|
||||
|
||||
local rnrn=0
|
||||
local Status = 0
|
||||
local DataToGet = 0
|
||||
local method=""
|
||||
local url=""
|
||||
local vars=""
|
||||
|
||||
conn:on("receive",function(conn,payload)
|
||||
|
||||
if Status==0 then
|
||||
_, _, method, url, vars = string.find(payload, "([A-Z]+) /([^?]*)%??(.*) HTTP")
|
||||
print(method, url, vars)
|
||||
end
|
||||
|
||||
if method=="POST" then
|
||||
|
||||
if Status==0 then
|
||||
--print("status", Status)
|
||||
_,_,DataToGet, payload = string.find(payload, "Content%-Length: (%d+)(.+)")
|
||||
if DataToGet~=nil then
|
||||
DataToGet = tonumber(DataToGet)
|
||||
--print(DataToGet)
|
||||
rnrn=1
|
||||
Status = 1
|
||||
else
|
||||
print("bad length")
|
||||
end
|
||||
end
|
||||
|
||||
-- find /r/n/r/n
|
||||
if Status==1 then
|
||||
--print("status", Status)
|
||||
local payloadlen = string.len(payload)
|
||||
local mark = "\r\n\r\n"
|
||||
local i
|
||||
for i=1, payloadlen do
|
||||
if string.byte(mark, rnrn) == string.byte(payload, i) then
|
||||
rnrn=rnrn+1
|
||||
if rnrn==5 then
|
||||
payload = string.sub(payload, i+1,payloadlen)
|
||||
file.open(url, "w")
|
||||
file.close()
|
||||
Status=2
|
||||
break
|
||||
end
|
||||
else
|
||||
rnrn=1
|
||||
end
|
||||
end
|
||||
if Status==1 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if Status==2 then
|
||||
--print("status", Status)
|
||||
if payload~=nil then
|
||||
DataToGet=DataToGet-string.len(payload)
|
||||
--print("DataToGet:", DataToGet, "payload len:", string.len(payload))
|
||||
file.open(url, "a+")
|
||||
file.write(payload)
|
||||
file.close()
|
||||
else
|
||||
conn:send("HTTP/1.1 200 OK\r\n\r\nERROR")
|
||||
Status=0
|
||||
end
|
||||
|
||||
if DataToGet==0 then
|
||||
conn:send("HTTP/1.1 200 OK\r\n\r\nOK")
|
||||
Status=0
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
DataToGet = -1
|
||||
|
||||
if url == "favicon.ico" then
|
||||
conn:send("HTTP/1.1 404 file not found")
|
||||
return
|
||||
end
|
||||
|
||||
conn:send("HTTP/1.1 200 OK\r\n\r\n")
|
||||
|
||||
-- it wants a file in particular
|
||||
if url~="" and vars=="" then
|
||||
DataToGet = 0
|
||||
return
|
||||
end
|
||||
|
||||
conn:send("<html><body><h1>NodeMCU IDE</h1>")
|
||||
|
||||
if vars=="edit" then
|
||||
conn:send("<script>function tag(c){document.getElementsByTagName('w')[0].innerHTML=c};\n")
|
||||
conn:send("var x=new XMLHttpRequest()\nx.onreadystatechange=function(){if(x.readyState==4) document.getElementsByName('t')[0].value = x.responseText; };\nx.open('GET',location.pathname,true)\nx.send()</script>")
|
||||
conn:send("<h2><a href='/'>Back to file list</a>\n")
|
||||
conn:send("<br><br><button onclick=\"tag('Saving');x.open('POST',location.pathname,true);\nx.onreadystatechange=function(){if(x.readyState==4) tag(x.responseText);};\nx.send(new Blob([document.getElementsByName('t')[0].value],{type:'text/plain'}));\">Save</button><a href='?run'>run</a><w></w>")
|
||||
conn:send("</h2><br><textarea name=t cols=110 rows=50></textarea></br>")
|
||||
end
|
||||
|
||||
if vars=="run" then
|
||||
conn:send("<verbatim>")
|
||||
local st, result=pcall(dofile, url)
|
||||
conn:send(tostring(result))
|
||||
conn:send("</verbatim>")
|
||||
end
|
||||
|
||||
if url=="" then
|
||||
local l = file.list();
|
||||
for k,v in pairs(l) do
|
||||
conn:send("<a href='"..k.."?edit'>"..k.."</a>, size:"..v.."<br>")
|
||||
end
|
||||
end
|
||||
|
||||
conn:send("</body></html>")
|
||||
|
||||
end)
|
||||
conn:on("sent",function(conn)
|
||||
if DataToGet>=0 and method=="GET" then
|
||||
if file.open(url, "r") then
|
||||
file.seek("set", DataToGet)
|
||||
local line=file.read(512)
|
||||
file.close()
|
||||
if line then
|
||||
conn:send(line)
|
||||
DataToGet = DataToGet + 512
|
||||
|
||||
if (string.len(line)==512) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
conn:close()
|
||||
end)
|
||||
end)
|
||||
print("listening, free:", node.heap())
|
||||
|
||||