├── weewx ├── empty └── ecowitt.py ├── images ├── empty ├── ecowitt_plugin1.png ├── ecowitt_plugin2.png ├── ecowitt_plugin3.png ├── ecowitt_block_modules1.png ├── ecowitt_block_modules2.png ├── ecowitt_block_modules3.png ├── ecowitt_block_airquality1.png └── ecowitt_block_airquality2.png ├── Meteotemplate ├── plugins │ └── ecowitt │ │ ├── ecowittVersion.txt │ │ ├── download.php │ │ ├── saveSettings.php │ │ ├── setup.php │ │ └── report │ │ └── index.php └── update │ ├── saveAPISettings.php │ └── apiSetup.php ├── weewx-ecowitt-1.2.tgz ├── meteotemplate-ecowitt-2.1.zip ├── Meteotemplate_block_lightningew_2.0.zip ├── Meteotemplate_block_ecowittModules_1.0.zip ├── Meteotemplate_block_airQualityEcowitt_1.1.zip ├── Meteotemplate_Altervista ├── README.txt └── index.php ├── post_ecowitt.sh ├── README.md └── index.php /weewx/empty: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/empty: -------------------------------------------------------------------------------- 1 | empty 2 | -------------------------------------------------------------------------------- /Meteotemplate/plugins/ecowitt/ecowittVersion.txt: -------------------------------------------------------------------------------- 1 | 2.1 2 | -------------------------------------------------------------------------------- /weewx-ecowitt-1.2.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/weewx-ecowitt-1.2.tgz -------------------------------------------------------------------------------- /images/ecowitt_plugin1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_plugin1.png -------------------------------------------------------------------------------- /images/ecowitt_plugin2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_plugin2.png -------------------------------------------------------------------------------- /images/ecowitt_plugin3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_plugin3.png -------------------------------------------------------------------------------- /meteotemplate-ecowitt-2.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/meteotemplate-ecowitt-2.1.zip -------------------------------------------------------------------------------- /images/ecowitt_block_modules1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_block_modules1.png -------------------------------------------------------------------------------- /images/ecowitt_block_modules2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_block_modules2.png -------------------------------------------------------------------------------- /images/ecowitt_block_modules3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_block_modules3.png -------------------------------------------------------------------------------- /images/ecowitt_block_airquality1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_block_airquality1.png -------------------------------------------------------------------------------- /images/ecowitt_block_airquality2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/images/ecowitt_block_airquality2.png -------------------------------------------------------------------------------- /Meteotemplate_block_lightningew_2.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/Meteotemplate_block_lightningew_2.0.zip -------------------------------------------------------------------------------- /Meteotemplate_block_ecowittModules_1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/Meteotemplate_block_ecowittModules_1.0.zip -------------------------------------------------------------------------------- /Meteotemplate_block_airQualityEcowitt_1.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/HEAD/Meteotemplate_block_airQualityEcowitt_1.1.zip -------------------------------------------------------------------------------- /Meteotemplate/plugins/ecowitt/download.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Meteotemplate_Altervista/README.txt: -------------------------------------------------------------------------------- 1 | If your Meteotemplate web is hosted on Altervista, you need to change the /report/index.php file with this one, due to restrictions on 2 | file_get_contents on Altervista. 3 | 4 | You also need to remove the whitelist restrictions: 5 | 6 | Go on the control panel of Altervista. 7 | Click on menù RESOURCES 8 | Look for the PHP panel 9 | Click on "Modify PHP settings" 10 | Move down the page until you find "Server to Server Connections" 11 | Put your mobilephone number in the form and follow the procedure with the SMS 12 | Click on the "Externa connection without restrictions" 13 | Clikc on Save 14 | -------------------------------------------------------------------------------- /post_ecowitt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Script to test the ecowitt_http_gateway 3 | curl -d "PASSKEY=0BA6979558C5D2ADB6B20F4B23A685AF&stationtype=GW1000_V1.4.7&dateutc=2019-05-28+07:33:48&tempinf=79.7&humidityin=76&baromrelin=29.719&baromabsin=29.719&tempf=79.3&humidity=70&winddir=277&windspeedmph=0.00&windgustmph=0.00&maxdailygust=0.00&solarradiation=0.00&uv=0&rainratein=0.000&eventrainin=0.000&hourlyrainin=0.000&dailyrainin=0.000&weeklyrainin=0.000&monthlyrainin=0.059&yearlyrainin=6.803&totalrainin=6.803&temp1f=78.44&humidity1=74&temp2f=82.04&humidity2=70&temp4f=82.94&humidity4=66&soilmoisture2=0&soilmoisture3=0&soilmoisture4=8&soilmoisture5=0&wh65batt=1&wh68batt=1.50&wh40batt=1.6&wh26batt=0&batt1=0&batt2=0&batt4=0&batt6=0&Siolbatt1=0.0&Siolbatt2=1.5&Siolbatt3=1.5&Siolbatt4=1.5&Siolbatt5=1.5&Siolbatt6=0.0&Siolbatt7=0.0&Siolbatt8=0.0&pm25batt1=0&pm25batt2=0&pm25batt3=0&pm25batt4=0&Freq=433M&model=GW1000" -X POST http://192.168.2.205/data/report/ 4 | -------------------------------------------------------------------------------- /Meteotemplate/plugins/ecowitt/saveSettings.php: -------------------------------------------------------------------------------- 1 | $variableValue){ 17 | $variables[] = array($variableName,$variableValue); 18 | } 19 | 20 | 21 | // Create file 22 | $string = "".PHP_EOL; 43 | 44 | // save settings file 45 | file_put_contents("settings.php",$string); 46 | 47 | // check file exists 48 | if(!file_exists("settings.php")){ 49 | echo ""; 50 | } 51 | else{ 52 | print ""; 53 | } 54 | ?> -------------------------------------------------------------------------------- /Meteotemplate/plugins/ecowitt/setup.php: -------------------------------------------------------------------------------- 1 | 35 | 36 | 44 | 45 | 46 | 47 | 48 | <?php echo $pageName?> 49 | 50 | 64 | 65 | 66 |
67 | 68 | 69 |
70 |
71 |

Ecowitt - Setup

72 |
73 | 74 | 75 | 78 | 81 | 82 | 83 | 86 | 89 | 90 | 91 | 94 | 100 | 101 | 102 | 106 | 112 | 113 | 114 | 115 | 121 | 122 | 123 | 127 | 128 | 129 | 133 | 134 | 135 | 148 | 149 |
76 | Meteotemplate server 77 | 79 | 80 |
84 | Meteotemplate admin password 85 | 87 | 88 |
92 | Record data in CSV format 93 | 95 | 99 |
103 | If you have the Ecowitt WS80, you can enable the Temperature correction method. 104 | The Solar Radiation, Wind Speed and Temp must be enabled to store data on database (normally is default) 105 | 107 | 111 |
116 |

117 | Set your Ecowitt GW1000 to send data to:
118 | path: 119 |

120 |
124 | Your Meteotemplate API file will be: http:// 125 |

126 |
130 | CSV data will be saved to: plugins/ecowitt/ 131 |

132 |
136 | http://".$_SERVER[HTTP_HOST].str_replace('setup.php', $file, $_SERVER[REQUEST_URI]).""; 142 | } 143 | ?> 144 | 145 | 146 |

147 |
150 |
151 | 152 |
153 |
154 |

155 |
156 | 157 | 158 | 159 | 160 | 161 | "; 168 | echo ""; 169 | echo ""; 170 | echo ""; 171 | } 172 | 173 | ?> 174 |
Log files (click on to download)Command
".$file."delete
175 |
176 |
177 | 178 | 179 | -------------------------------------------------------------------------------- /Meteotemplate/update/saveAPISettings.php: -------------------------------------------------------------------------------- 1 | $value){ 15 | $parameters[trim($key)] = $value; 16 | if($value==1){ 17 | $extraCols[] = trim($key); 18 | } 19 | } 20 | 21 | if(file_exists("apiSettings.txt")){ 22 | unlink("apiSettings.txt"); 23 | } 24 | file_put_contents("apiSettings.txt",json_encode($parameters)); 25 | 26 | // check if table already exists 27 | if(mysqli_num_rows(mysqli_query($con,"SHOW TABLES LIKE 'alldataExtra'")) > 0){ 28 | // table already exists 29 | // echo "Table already exists.
"; 30 | } 31 | else{ 32 | $query = 33 | " 34 | CREATE TABLE alldataExtra ( 35 | DateTime datetime NOT NULL PRIMARY KEY 36 | ) ENGINE = MyISAM DEFAULT CHARSET = utf8 COLLATE = utf8_unicode_ci; 37 | "; 38 | //echo $query; 39 | mysqli_query($con, $query); 40 | //echo "Creating extra data table...
"; 41 | 42 | // check if table was created successfully 43 | if( 44 | mysqli_num_rows( 45 | mysqli_query($con, 46 | " 47 | SHOW TABLES LIKE 'alldataExtra' 48 | " 49 | ) 50 | ) > 0 51 | or die ("Table was not created, please check your MySQL setup.") 52 | ){ 53 | //echo "Table created!
"; 54 | } 55 | } 56 | 57 | // echo "
Checking columns...
"; 58 | 59 | // add columns 60 | for($i=0;$iChecking column: ".$thisCol."
"; 63 | $query = "SHOW COLUMNS FROM `alldataExtra` LIKE '".$thisCol."'"; 64 | $result = mysqli_query($con, $query); 65 | $exists = (mysqli_num_rows($result)) ? true : false; 66 | if(!$exists){ 67 | //echo "This column does not exist, creating it.
"; 68 | if($thisCol=="UV"){ 69 | // UV 70 | $query = "ALTER TABLE `alldataExtra` ADD `UV` DECIMAL(3,1) NULL"; 71 | } 72 | else if($thisCol=="TIN" || $thisCol=="T1" || $thisCol=="T2" || $thisCol=="T3" || $thisCol=="T4" || $thisCol=="TS1" || $thisCol=="TS2" || $thisCol=="TS3" || $thisCol=="TS4"){ 73 | // extra temperature / indoor temperature / soil temperature [deg C] 74 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(3,1) NULL"; 75 | } 76 | else if($thisCol=="HIN" || $thisCol=="H1" || $thisCol=="H2" || $thisCol=="H3" || $thisCol=="H4"){ 77 | // extra humidity / indoor humidity [%] 78 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(4,1) NULL"; 79 | } 80 | else if($thisCol=="LT1" || $thisCol=="LT2" || $thisCol=="LT3" || $thisCol=="LT4"){ 81 | // leaf temperature 82 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(4,1) NULL"; 83 | } 84 | else if($thisCol=="LW1" || $thisCol=="LW2" || $thisCol=="LW3" || $thisCol=="LW4"){ 85 | // leaf wetness 86 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(4,1) NULL"; 87 | } 88 | else if($thisCol=="SD"){ 89 | // snow depth [mm] 90 | $query = "ALTER TABLE `alldataExtra` ADD `SD` DECIMAL(6,1) NULL"; 91 | } 92 | else if($thisCol=="SN"){ 93 | // snowfall [mm] 94 | $query = "ALTER TABLE `alldataExtra` ADD `SN` DECIMAL(5,1) NULL"; 95 | } 96 | else if($thisCol=="SM1" || $thisCol=="SM2" || $thisCol=="SM3" || $thisCol=="SM4"){ 97 | // soil moisture [%] 98 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(4,1) NULL"; 99 | } 100 | else if($thisCol=="L"){ 101 | // lightning count 102 | $query = "ALTER TABLE `alldataExtra` ADD `L` INT(4) NULL"; 103 | } 104 | else if($thisCol=="LD"){ 105 | // lightning count 106 | $query = "ALTER TABLE `alldataExtra` ADD `LD` INT(2) NULL"; 107 | } 108 | else if($thisCol=="LT"){ 109 | // lightning count 110 | $query = "ALTER TABLE `alldataExtra` ADD `LT` INT(10) NULL"; 111 | } 112 | else if($thisCol=="NL"){ 113 | // noise level [dB] 114 | $query = "ALTER TABLE `alldataExtra` ADD `NL` DECIMAL(4,1) NULL"; 115 | } 116 | else if($thisCol=="SS"){ 117 | // sunshine [h] 118 | $query = "ALTER TABLE `alldataExtra` ADD `SS` DECIMAL(4,1) NULL"; 119 | } 120 | else if($thisCol=="CO2_1" || $thisCol=="CO2_2" || $thisCol=="CO2_3" || $thisCol=="CO2_4"){ 121 | // CO2 [ppm] 122 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(5,1) NULL"; 123 | } 124 | else if($thisCol=="NO2_1" || $thisCol=="NO2_2" || $thisCol=="NO2_3" || $thisCol=="NO2_4"){ 125 | // NO2 [ppm] 126 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(5,1) NULL"; 127 | } 128 | else if($thisCol=="CO_1" || $thisCol=="CO_2" || $thisCol=="CO_3" || $thisCol=="CO_4"){ 129 | // CO [ppm] 130 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(5,1) NULL"; 131 | } 132 | else if($thisCol=="SO2_1" || $thisCol=="SO2_2" || $thisCol=="SO2_3" || $thisCol=="SO2_4"){ 133 | // SO2 [ppb] 134 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(5,1) NULL"; 135 | } 136 | else if($thisCol=="O3_1" || $thisCol=="O3_2" || $thisCol=="O3_3" || $thisCol=="O3_4"){ 137 | // O3 [ppb] 138 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(5,1) NULL"; 139 | } 140 | else if($thisCol=="PP1" || $thisCol=="PP2" || $thisCol=="PP3" || $thisCol=="PP4"){ 141 | // particulate pollution [ug/m3] 142 | $query = "ALTER TABLE `alldataExtra` ADD `".$thisCol."` DECIMAL(5,1) NULL"; 143 | } 144 | mysqli_query($con, $query); 145 | } 146 | else{ 147 | //echo "This column already exists, skipping.
"; 148 | } 149 | } 150 | 151 | // check file exists 152 | 153 | if(!file_exists("apiSettings.txt")){ 154 | echo ""; 155 | } 156 | else{ 157 | print ""; 158 | } 159 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ecowitt_http_gateway 2 | Simple HTTP gateway that receives data from GW1000 with Ecowitt protocol and resend data to Meteotemplate or csv, json, ecc.
3 | Example on: http://www.kwos.org/poggiocorese_ecowitt 4 |

5 | Install this gateway if you have a web server at home, like a Raspberry or something where you want to store weather data 6 | 7 | The GW1000 allows sending data both to Ecowitt.net and Wunderground, even to an external site as long as you select one 8 | of the two previous protocols.
9 | We know the Wunderground protocol and we know that it doesn't send UV and PM2.5 data, nor ground temperature or 10 | other additional sensors, so you need to select the Ecowitt protocol.
11 | 12 | Now to permit this script to work, we need a web server to which the GW1000 need to send data. 13 | 14 | REQUIREMENTS 15 |
16 | The web server must have these possibilities: 17 | - create a directory named /data/report (es. /var/www/html/data/report ) 18 | - in this directory will be put the index.php file 19 | 20 | So, the web site will look like: http://192.168.2.185/data/report/index.php
21 | In the GW1000 configuration it will be necessary writing only the IP address, es. 192.168.1.4 and specify the update rate.
22 |
23 | I recommend having this web server on a raspberry, in the same network of the GW1000, so the script can also be used to store data without losing them in case of Internet connection failure
24 | When the GW1000 will contact the web site, the index.php will do these functions: 25 | 26 | 1) creates a .JSON file in /var/log/ecowitt ( overwrited every update, contains only last data )
27 | 2) creates a .CSV file in /var/log/ecowitt ( appended every update, contains all data )
28 | 3) converts in metric all data a resend to a Meteotemplate web site on Internet
29 | 4) can create and send via FTP a file for the weather station registered on Meteonetwork.it 30 | 5) creates a weewx.txt file in /var/log/ecowitt for the [ecowitt.py](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/ecowitt.py) driver for WeeWX 31 | 32 | HOW TO INSTALL: 33 | - Install Apache 34 | - Install PHP 35 | - Install jq ( for JSON query ) 36 | - Create directory Es. /var/www/html/data/report/ 37 | - Create /var/log/ecowitt with chmod 777 38 | - Put file: index.php in /var/www/html/data/report/ 39 | - Configure index.php 40 | - Configure GW1000 to send data to your server 41 | 42 | Note:
43 | Look in /var/log/ecowitt to read fields using 'jq'
44 | jq -r '.tempc' weather_XXXXXXXXXXXXXXXX.json
45 | 46 | # 47 | # 48 | # ecowitt WeeWX driver 49 | 50 | The code has been written in Python 2.7.x. If you use Python 3, you have to convert it with 2to3 utility: https://docs.python.org/2/library/2to3.html 51 |

52 | This driver uses the Customized Upload method of GW1000. It can be every where in the network. It doesn't use any sniffing, interception method. 53 |

54 | Called ecowitt.py
55 | This driver works in two modes: 56 | 57 | - normal: reads data from a file generated by the [ecowitt_http_gateway](https://github.com/iz0qwm/ecowitt_http_gateway/blob/master/README.md#ecowitt_http_gateway) - Usually /var/log/ecowitt/weewx.txt
58 | name=value pair, for example:
59 | 60 | outTemp=79.3
61 | barometer=29.719
62 | pressure=29.719
63 | outHumidity=70
64 | 65 | - server: open a socket server that receives directly the GW1000. Configure it in the weewx.conf
66 | with the IP address where the GW1000 will connect to. Configure the GW1000 with the IP and the port, put / on the path. 67 | 68 | ## Automatic extension installation 69 | 70 | Run the extension installer: 71 | 72 | sudo wee_extension --install weewx-ecowitt-x.x.tgz 73 |

74 | Modify weewx.conf: 75 |
 76 | [Station]
 77 |      station_type = ecowitt
 78 | 
 79 | 
80 | Check the automatic addition at the end of weewx.conf:
81 |
 82 | 
 83 | [ecowitt]
 84 |      poll_interval = 65                    # number of seconds, just a little more than the GW1000 update time
 85 |      path = /var/log/ecowitt/weewx.txt     # location of data file generated by ecowitt_http_gateway used in mode=normal
 86 |      driver = weewx.drivers.ecowitt
 87 |      mode = normal                         # normal = use with ecowitt_http_gateway - server = directly connected to GW1000
 88 |      address = 192.168.2.185               # IP address of the PC where weewx is running in mode=server, to which GW1000 will connect to                
 89 |      port = 9999                           # port to which GW1000 will connect to in mode=server
 90 | 
 91 | 
92 | 93 | Restart weewx
94 |
 95 | 
 96 | sudo /etc/init.d/weewx stop
 97 | sudo /etc/init.d/weewx start
 98 | 
 99 | 
100 | ## Manual installation 101 | To use this driver, put the ecowitt.py file in the weewx drivers directory (i.e. /usr/share/weewx/weewx/drivers ), then make
102 | the following changes to weewx.conf:
103 |
104 |
105 | [Station]
106 |      station_type = ecowitt
107 | [ecowitt]
108 |      poll_interval = 65                    # number of seconds, just a little more than the GW1000 update time
109 |      path = /var/log/ecowitt/weewx.txt     # location of data file generated by ecowitt_http_gateway
110 |      driver = weewx.drivers.ecowitt
111 |      mode = normal                         # normal = use with ecowitt_http_gateway - server = directly connected to GW1000
112 |      address = 192.168.2.185               # IP address of the PC where weewx is running in mode=server, to which GW1000 will connect to                
113 |      port = 9999                           # port to which GW1000 will connect to in mode=server
114 | 
115 | 
116 | 117 | In the weewx.conf or skinf.conf use the following Labels 118 |
119 | [Labels]
120 |                 [[Generic]]
121 |                 # Sensor status indicators
122 |                 txBatteryStatus      = WH51-Soil
123 |                 windBatteryStatus    = WS80-Temp/Wind
124 |                 rainBatteryStatus    = WH40-Rain
125 |                 outTempBatteryStatus = WH31_1-Temp/Hum
126 |                 inTempBatteryStatus  = Inside Temperature
127 |                 consBatteryVoltage   = WS80-Temp/Wind
128 |                 heatingVoltage       = WH51-Soil
129 |                 supplyVoltage        = WH40-Rain
130 | 
131 | NOTE
132 | If you don't want to use the ecowitt_http_gateway, you can use the [Interceptor driver](https://github.com/matthewwall/weewx-interceptor) to sniff data of your GW1000, or you can use the [API broadcast methos driver](https://github.com/gjr80/weewx-gw1000) that uses the same protocol used by VSView, WeeWx must stay on the same network of the GW1000. 133 | # 134 | # ecowitt Meteotemplate plugin 135 | Simple plugin for [Meteotemplate](http://www.meteotemplate.com/), wonderful template developed by Jachym.

136 | Install this plugin if you don't want to install the previous gateway and weewx, or if you only need to update your Meteotemplate web site. You will not store any data locally in your network 137 | 138 | - Download it from the repository 139 | - Install it in the plugin directory of your template website, just like another plugin. (put in your plugins directory only the directory called ecowitt without the version number: Meteotemplate/ecowitt_x.x/ecowitt) 140 | - Go in the Plugin setup page, via Admin Panel of Meteotemplate 141 | - Configure it 142 | - Configure the GW1000 with the setup you read in the Plugin page. The web server port ususally is 80 143 | 144 | ![Example of plugin page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_plugin1.png) 145 | ![Example of plugin admin page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_plugin2.png) 146 | ![Example of plugin admin page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_plugin3.png) 147 | 148 | # 149 | # 150 | # ecowitt Meteotemplate blocks 151 | Remember to update the ecowitt Meteotemplate plugin to the latest version (or the index.php if you have your own webserver) 152 | ![Example of airquality block page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_block_airquality1.png) 153 | ![Example of airquality block page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_block_airquality2.png) 154 | 155 | ![Example of modules block page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_block_modules1.png) 156 | ![Example of modules block page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_block_modules2.png) 157 | ![Example of modules block page](https://raw.githubusercontent.com/iz0qwm/ecowitt_http_gateway/master/images/ecowitt_block_modules3.png) 158 | 159 | 160 | # 161 | # 162 | # NOTE from the issue forum 163 | 164 | Googling: https://fhem.de/ 165 | Is a server for home automation 166 | 167 | If you already have a Meteotemplate webserver you can use 3 mode of uploading mode: 168 | 169 | 1. **use the Meteotemplate plugin and configure GW1000 to send data to directly.**
170 | Follow only the section with title: _[ecowitt Meteotemplate plugin](https://github.com/iz0qwm/ecowitt_http_gateway/#ecowitt-meteotemplate-plugin)_
171 | example: http://www.kwos.org/meteotemplateweb/api.php
172 | Note: You have all extra sensors like soilmoisture, PM25 173 | 174 | 2. **have a raspberry at home, in the internal network, with a webserver where there is the index.php**
175 | Follow only the section with the title: _[ecowitt_http_gateway](https://github.com/iz0qwm/ecowitt_http_gateway/#ecowitt_http_gateway)_
176 | In this case you don't need the Meteotemplate plugin but you have to configure the index.php to send data via api to Meteotemplate.
177 | example: http//192.168.2.185/data/report/
178 | Note1: You have all extra sensors like soilmoisture, PM25 sent to Meteotemplate
179 | Note2: You can also send data to a weewx without extra sensors 180 | 181 | 4. **have a raspberry at home with weewx and weewx driver for GW1000.**
182 | Follow both the sections: _[ecowitt_http_gateway](https://github.com/iz0qwm/ecowitt_http_gateway/#ecowitt_http_gateway)_ and _[ecowitt WeeWX driver](https://github.com/iz0qwm/ecowitt_http_gateway/#ecowitt-weewx-driver)_
183 | Then configure weewx with the Meteotemplate plugin released here:
184 | https://github.com/matthewwall/weewx-meteotemplate
185 | Note: you don't have the extra sensors 186 | -------------------------------------------------------------------------------- /Meteotemplate/plugins/ecowitt/report/index.php: -------------------------------------------------------------------------------- 1 | 352.3 ) { 166 | $S = 352.3; 167 | } else { 168 | $S = $weather_data['solarradiation']; 169 | } 170 | 171 | if ( $S < $result_S_1 ) { 172 | if ( $result_S_1 < $result_S_2 ) { 173 | $as = $ashigh; 174 | } else { 175 | $as = $aslow; 176 | } 177 | } else { 178 | if ( $S < $result_S_2 ) { 179 | $as = $aslow; 180 | } else { 181 | $as = $asnormal; 182 | } 183 | } 184 | 185 | if ( ( $as == $ashigh ) || ( $as == $low ) ) { 186 | $diff_temp = $weather_data['tempc'] - $result_T_1; 187 | if ( $diff_temp > 0.3 ) { 188 | $as = $asultrahigh; 189 | } 190 | } 191 | 192 | if ( round($weather_data['solarradiation'], 2) < 145 ) { 193 | $as = $asultrahigh*2.5; 194 | } 195 | 196 | 197 | # Formula sections 198 | $sez1 = $as * $S; 199 | $sez2 = $u / $dm; 200 | $sez3 = sqrt($sez2); 201 | $sez4 = $cp * $K * $sez3; 202 | $sez5 = $sez1 / $sez4; 203 | $temp_corr = $weather_data['tempc'] - $sez5; 204 | 205 | # Original value of temperature from WS80 206 | @$weather_data['tempc_orig'] = $weather_data['tempc']; 207 | 208 | # Corrected value of temperature from WS80 209 | $diff_corr_temp = round($result_T_1, 2) - round($temp_corr, 2); 210 | if ( $diff_corr_temp > 0.7 ) { 211 | $temp_corr = $temp_corr+0.5; 212 | } 213 | if ( $diff_corr_temp < -0.7 ) { 214 | $temp_corr = $temp_corr-0.5; 215 | } 216 | 217 | # Corrected calue of temperature from WS80 218 | @$weather_data['tempc'] = round( $temp_corr, 2 ); 219 | 220 | 221 | } 222 | 223 | # Forward data to meteotemplate server 224 | if ( $forward_data == 1 ) 225 | { 226 | 227 | 228 | @$weather_data_forward['U'] = strtotime( $weather_data['dateutc'] ); 229 | @$weather_data_forward['PASS'] = $forward_server_password ; 230 | @$weather_data_forward['T'] = $weather_data['tempc'] ; 231 | @$weather_data_forward['H'] = $weather_data['humidity'] ; 232 | @$weather_data_forward['P'] = $weather_data['baromrelhpa'] ; 233 | @$weather_data_forward['W'] = $weather_data['windspeedkmh'] ; 234 | @$weather_data_forward['G'] = $weather_data['windgustkmh'] ; 235 | @$weather_data_forward['B'] = $weather_data['winddir'] ; 236 | @$weather_data_forward['R'] = $weather_data['dailyrainmm'] ; 237 | @$weather_data_forward['RR'] = $weather_data['rainratemm'] ; 238 | @$weather_data_forward['S'] = $weather_data['solarradiation'] ; 239 | @$weather_data_forward['UV'] = $weather_data['uv'] ; 240 | @$weather_data_forward['TIN'] = $weather_data['tempinc'] ; 241 | @$weather_data_forward['HIN'] = $weather_data['humidityin'] ; 242 | @$weather_data_forward['T1'] = $weather_data['temp1c'] ; 243 | @$weather_data_forward['H1'] = $weather_data['humidity1'] ; 244 | @$weather_data_forward['T2'] = $weather_data['temp2c'] ; 245 | @$weather_data_forward['H2'] = $weather_data['humidity2'] ; 246 | @$weather_data_forward['SM1'] = $weather_data['soilmoisture1'] ; 247 | @$weather_data_forward['SM2'] = $weather_data['soilmoisture2'] ; 248 | @$weather_data_forward['PP1'] = $weather_data['pm25_ch1'] ; 249 | @$weather_data_forward['L'] = $weather_data['lightning_num'] ; 250 | @$weather_data_forward['LD'] = $weather_data['lightning'] ; 251 | @$weather_data_forward['LT'] = $weather_data['lightning_time'] ; 252 | if (isset($weather_data['wh80batt'])) 253 | { 254 | @$weather_data_forward['WBAT'] = $weather_data['wh80batt'] ; 255 | } else { 256 | if ( $weather_data['wh65batt'] == 0 ) 257 | { 258 | @$weather_data_forward['WBAT'] = 3 ; 259 | } 260 | if ( $weather_data['wh65batt'] == 1 ) 261 | { 262 | @$weather_data_forward['WBAT'] = 1.4 ; 263 | } 264 | } 265 | @$weather_data_forward['RBAT'] = $weather_data['wh40batt'] ; 266 | @$weather_data_forward['LBAT'] = $weather_data['wh57batt'] ; 267 | @$weather_data_forward['SM1BAT'] = $weather_data['soilbatt1'] ; 268 | @$weather_data_forward['SM2BAT'] = $weather_data['soilbatt2'] ; 269 | @$weather_data_forward['PP1BAT'] = $weather_data['pm25batt1'] ; 270 | if ( $weather_data['batt1'] == 0 ) 271 | { 272 | @$weather_data_forward['T1BAT'] = OK ; 273 | } 274 | if ( $weather_data['batt1'] == 1 ) 275 | { 276 | @$weather_data_forward['T1BAT'] = LOW ; 277 | } 278 | if ( $weather_data['batt2'] == 0 ) 279 | { 280 | @$weather_data_forward['T2BAT'] = OK ; 281 | } 282 | if ( $weather_data['batt2'] == 1 ) 283 | { 284 | @$weather_data_forward['T2BAT'] = LOW ; 285 | } 286 | 287 | #@$weather_data['forward_url'] = "http://" . $forward_server . $_SERVER[REQUEST_URI]; 288 | @$weather_data_forward['forward_url'] = "http://" . $forward_server ; 289 | @$weather_data_forward['forward'] = file_get_contents($weather_data_forward['forward_url'] . "?" . "U=" . @$weather_data_forward['U'] . "&PASS=" . @$weather_data_forward['PASS'] . "&T=" . @$weather_data_forward['T'] . "&H=" . @$weather_data_forward['H'] ."&P=" . @$weather_data_forward['P'] . "&W=" . @$weather_data_forward['W'] . "&G=" . @$weather_data_forward['G'] . "&B=" . @$weather_data_forward['B'] . "&R=" . @$weather_data_forward['R'] . "&RR=" . @$weather_data_forward['RR'] . "&S=" . @$weather_data_forward['S'] . "&UV=" . @$weather_data_forward['UV'] . "&TIN=" . @$weather_data_forward['TIN'] . "&HIN=" . @$weather_data_forward['HIN'] . "&T1=" . @$weather_data_forward['T1'] . "&H1=" . @$weather_data_forward['H1'] . "&T2=" . @$weather_data_forward['T2'] . "&H2=" . @$weather_data_forward['H2'] . "&SM1=" . @$weather_data_forward['SM1'] . "&SM2=" . @$weather_data_forward['SM2'] . "&L=" . @$weather_data_forward['L'] . "&LD=" . @$weather_data_forward['LD'] . "<=" . @$weather_data_forward['LT'] . "&PP1=" . @$weather_data_forward['PP1'] . "&WBAT=" . @$weather_data_forward['WBAT'] . "&RBAT=" . @$weather_data_forward['RBAT'] . "&LBAT=" . @$weather_data_forward['LBAT'] . "&PP1BAT=" . @$weather_data_forward['PP1BAT'] . "&SM1BAT=" . @$weather_data_forward['SM1BAT'] . "&SM2BAT=" . @$weather_data_forward['SM2BAT'] . "&T1BAT=" . @$weather_data_forward['T1BAT'] . "&T2BAT=" . @$weather_data_forward['T2BAT']); 290 | } 291 | 292 | # Pack data into json format 293 | $weather_data_json = json_encode($weather_data); 294 | 295 | # Write json stream to logfile 296 | $json_data_logfile = $json_data_logdir . "/" . $device . ".json"; 297 | if ( $json_data_log == 1 ) 298 | { 299 | $file = fopen($json_data_logfile, 'w'); 300 | fwrite($file, $weather_data_json); 301 | fclose($file); 302 | } 303 | 304 | # Write stream to csvfile 305 | $txt_data_logfile = $txt_data_logdir . "/" . $device . "_" . $date_txt . ".csv"; 306 | if ($txt_data_log) 307 | { 308 | if (!file_exists($txt_data_logfile)) { 309 | $data = json_decode($weather_data_json); 310 | foreach($data as $key => $value) { 311 | $string .= $key . ','; 312 | } 313 | $string .= "\n"; 314 | file_put_contents($txt_data_logfile, $string, FILE_APPEND); 315 | } 316 | 317 | 318 | $file = fopen($txt_data_logfile, 'a'); 319 | fputcsv($file, $weather_data); 320 | fclose($file); 321 | } 322 | 323 | print("Success. Update done\n"); 324 | ?> 325 | -------------------------------------------------------------------------------- /Meteotemplate_Altervista/index.php: -------------------------------------------------------------------------------- 1 | 352.3 ) { 162 | $S = 352.3; 163 | } else { 164 | $S = $weather_data['solarradiation']; 165 | } 166 | 167 | if ( $S < $result_S_1 ) { 168 | if ( $result_S_1 < $result_S_2 ) { 169 | $as = $ashigh; 170 | } else { 171 | $as = $aslow; 172 | } 173 | } else { 174 | if ( $S < $result_S_2 ) { 175 | $as = $aslow; 176 | } else { 177 | $as = $asnormal; 178 | } 179 | } 180 | 181 | if ( ( $as == $ashigh ) || ( $as == $low ) ) { 182 | $diff_temp = $weather_data['tempc'] - $result_T_1; 183 | if ( $diff_temp > 0.3 ) { 184 | $as = $asultrahigh; 185 | } 186 | } 187 | 188 | if ( round($weather_data['solarradiation'], 2) < 145 ) { 189 | $as = $asultrahigh*2.5; 190 | } 191 | 192 | 193 | # Formula sections 194 | $sez1 = $as * $S; 195 | $sez2 = $u / $dm; 196 | $sez3 = sqrt($sez2); 197 | $sez4 = $cp * $K * $sez3; 198 | $sez5 = $sez1 / $sez4; 199 | $temp_corr = $weather_data['tempc'] - $sez5; 200 | 201 | # Original value of temperature from WS80 202 | @$weather_data['tempc_orig'] = $weather_data['tempc']; 203 | 204 | # Corrected value of temperature from WS80 205 | $diff_corr_temp = round($result_T_1, 2) - round($temp_corr, 2); 206 | if ( $diff_corr_temp > 0.7 ) { 207 | $temp_corr = $temp_corr+0.5; 208 | } 209 | if ( $diff_corr_temp < -0.7 ) { 210 | $temp_corr = $temp_corr-0.5; 211 | } 212 | 213 | # Corrected calue of temperature from WS80 214 | @$weather_data['tempc'] = round( $temp_corr, 2 ); 215 | 216 | 217 | } 218 | 219 | # Forward data to meteotemplate server 220 | if ( $forward_data == 1 ) 221 | { 222 | @$weather_data_forward['U'] = strtotime( $weather_data['dateutc'] ); 223 | @$weather_data_forward['PASS'] = $forward_server_password ; 224 | @$weather_data_forward['T'] = $weather_data['tempc'] ; 225 | @$weather_data_forward['H'] = $weather_data['humidity'] ; 226 | @$weather_data_forward['P'] = $weather_data['baromrelhpa'] ; 227 | @$weather_data_forward['W'] = $weather_data['windspeedkmh'] ; 228 | @$weather_data_forward['G'] = $weather_data['windgustkmh'] ; 229 | @$weather_data_forward['B'] = $weather_data['winddir'] ; 230 | @$weather_data_forward['R'] = $weather_data['dailyrainmm'] ; 231 | @$weather_data_forward['RR'] = $weather_data['rainratemm'] ; 232 | @$weather_data_forward['S'] = $weather_data['solarradiation'] ; 233 | @$weather_data_forward['UV'] = $weather_data['uv'] ; 234 | @$weather_data_forward['TIN'] = $weather_data['tempinc'] ; 235 | @$weather_data_forward['HIN'] = $weather_data['humidityin'] ; 236 | @$weather_data_forward['T1'] = $weather_data['temp1c'] ; 237 | @$weather_data_forward['H1'] = $weather_data['humidity1'] ; 238 | @$weather_data_forward['T2'] = $weather_data['temp2c'] ; 239 | @$weather_data_forward['H2'] = $weather_data['humidity2'] ; 240 | @$weather_data_forward['SM1'] = $weather_data['soilmoisture1'] ; 241 | @$weather_data_forward['SM2'] = $weather_data['soilmoisture2'] ; 242 | @$weather_data_forward['PP1'] = $weather_data['pm25_ch1'] ; 243 | @$weather_data_forward['L'] = $weather_data['lightning_num'] ; 244 | @$weather_data_forward['LD'] = $weather_data['lightning'] ; 245 | @$weather_data_forward['LT'] = $weather_data['lightning_time'] ; 246 | 247 | #@$weather_data['forward_url'] = "http://" . $forward_server . $_SERVER[REQUEST_URI]; 248 | @$weather_data_forward['forward_url'] = "http://" . $forward_server ; 249 | #@$weather_data_forward['forward'] = file_get_contents($weather_data_forward['forward_url'] . "?" . "U=" . @$weather_data_forward['U'] . "&PASS=" . @$weather_data_forward['PASS'] . "&T=" . @$weather_data_forward['T'] . "&H=" . @$weather_data_forward['H'] ."&P=" . @$weather_data_forward['P'] . "&W=" . @$weather_data_forward['W'] . "&G=" . @$weather_data_forward['G'] . "&B=" . @$weather_data_forward['B'] . "&R=" . @$weather_data_forward['R'] . "&RR=" . @$weather_data_forward['RR'] . "&S=" . @$weather_data_forward['S'] . "&UV=" . @$weather_data_forward['UV'] . "&TIN=" . @$weather_data_forward['TIN'] . "&HIN=" . @$weather_data_forward['HIN'] . "&T1=" . @$weather_data_forward['T1'] . "&H1=" . @$weather_data_forward['H1'] . "&T2=" . @$weather_data_forward['T2'] . "&H2=" . @$weather_data_forward['H2'] . "&SM1=" . @$weather_data_forward['SM1'] . "&SM2=" . @$weather_data_forward['SM2'] . "&L=" . @$weather_data_forward['L'] . "&LD=" . @$weather_data_forward['LD'] . "<=" . @$weather_data_forward['LT'] . "&PP1=" . @$weather_data_forward['PP1'] ); 250 | $weather_data_url = $weather_data_forward['forward_url'] . "?" . "U=" . @$weather_data_forward['U'] . "&PASS=" . @$weather_data_forward['PASS'] . "&T=" . @$weather_data_forward['T'] . "&H=" . @$weather_data_forward['H'] ."&P=" . @$weather_data_forward['P'] . "&W=" . @$weather_data_forward['W'] . "&G=" . @$weather_data_forward['G'] . "&B=" . @$weather_data_forward['B'] . "&R=" . @$weather_data_forward['R'] . "&RR=" . @$weather_data_forward['RR'] . "&S=" . @$weather_data_forward['S'] . "&UV=" . @$weather_data_forward['UV'] . "&TIN=" . @$weather_data_forward['TIN'] . "&HIN=" . @$weather_data_forward['HIN'] . "&T1=" . @$weather_data_forward['T1'] . "&H1=" . @$weather_data_forward['H1'] . "&T2=" . @$weather_data_forward['T2'] . "&H2=" . @$weather_data_forward['H2'] . "&SM1=" . @$weather_data_forward['SM1'] . "&SM2=" . @$weather_data_forward['SM2'] . "&L=" . @$weather_data_forward['L'] . "&LD=" . @$weather_data_forward['LD'] . "<=" . @$weather_data_forward['LT'] . "&PP1=" . @$weather_data_forward['PP1'] ; 251 | 252 | $ch = curl_init(); 253 | curl_setopt($ch, CURLOPT_URL, $weather_data_url ); 254 | curl_setopt($ch, CURLOPT_HEADER, false); 255 | $out = curl_exec($ch); 256 | curl_close($ch); 257 | #echo $out; 258 | 259 | #$weather_data_forward_json = json_encode($weather_data_forward); 260 | #$api_data_logfile = $json_data_logdir . "/" . $device . ".txt"; 261 | #$file2 = fopen($api_data_logfile, 'w'); 262 | #fwrite($file2, $weather_data_url); 263 | #fclose($file2); 264 | 265 | #$curl_data_logfile = $json_data_logdir . "/" . $device . "_curl.txt"; 266 | #$file3 = fopen($curl_data_logfile, 'w'); 267 | #fwrite($file3, $out); 268 | #fclose($file3); 269 | 270 | } 271 | 272 | # Pack data into json format 273 | $weather_data_json = json_encode($weather_data); 274 | 275 | 276 | # Write json stream to logfile 277 | $json_data_logfile = $json_data_logdir . "/" . $device . ".json"; 278 | 279 | 280 | if ( $json_data_log == 1 ) 281 | { 282 | $file = fopen($json_data_logfile, 'w'); 283 | fwrite($file, $weather_data_json); 284 | fclose($file); 285 | 286 | } 287 | 288 | # Write stream to csvfile 289 | $txt_data_logfile = $txt_data_logdir . "/" . $device . "_" . $date_txt . ".csv"; 290 | if ($txt_data_log) 291 | { 292 | if (!file_exists($txt_data_logfile)) { 293 | $data = json_decode($weather_data_json); 294 | foreach($data as $key => $value) { 295 | $string .= $key . ','; 296 | } 297 | $string .= "\n"; 298 | file_put_contents($txt_data_logfile, $string, FILE_APPEND); 299 | } 300 | 301 | 302 | $file = fopen($txt_data_logfile, 'a'); 303 | fputcsv($file, $weather_data); 304 | fclose($file); 305 | } 306 | 307 | print("Success. Update done\n"); 308 | ?> 309 | -------------------------------------------------------------------------------- /weewx/ecowitt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | # 5 | # Copyright 2019 Raffaello Di Martino 6 | # From a work of Matthew Wall on fileparser driver 7 | # 8 | # weewx driver that reads data from a file coming from ecowitt_gateway 9 | # https://github.com/iz0qwm/ecowitt_http_gateway/ 10 | # 11 | # This program is free software: you can redistribute it and/or modify it under 12 | # the terms of the GNU General Public License as published by the Free Software 13 | # Foundation, either version 3 of the License, or any later version. 14 | # 15 | # This program is distributed in the hope that it will be useful, but WITHOUT 16 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 | # FOR A PARTICULAR PURPOSE. 18 | # 19 | # See http://www.gnu.org/licenses/ 20 | 21 | # This driver will read data from a file generated by the https://github.com/iz0qwm/ecowitt_http_gateway/ 22 | # name=value pair, for example: 23 | # 24 | # outTemp=79.3 25 | # barometer=29.719 26 | # pressure=29.719 27 | # outHumidity=70 28 | # windSpeed=0.00 29 | # windDir=277 30 | # windGust=0.00 31 | # rainRate=0.000 32 | # rain_total=6.903 33 | # inTemp=79.7 34 | # inHumidity=76 35 | # radiation=0.00 36 | # UV=0 37 | # windchill= 38 | # dewpoint= 39 | # extraTemp1=78.44 40 | # extraHumid1=74 41 | # extraTemp2=78.51 42 | # extraHumid2=75 43 | # soilTemp1=0 44 | # txBatteryStatus= 45 | # rainBatteryStatus=1.6 46 | # outTempBatteryStatus=0 47 | # 48 | # The units must be in the weewx.US unit system: 49 | # degree_F, inHg, inch, inch_per_hour, mile_per_hour 50 | # 51 | # To use this driver, put this file in the weewx drivers directory (i.e. /usr/share/weewx/weewx/drivers ), then make 52 | # the following changes to weewx.conf: 53 | # 54 | # [Station] 55 | # station_type = ecowitt 56 | # [ecowitt] 57 | # poll_interval = 65 # number of seconds, just a little more the GW1000 update time 58 | # path = /var/log/ecowitt/weewx.txt # location of data file 59 | # driver = weewx.drivers.ecowitt 60 | # mode = normal # normal = use the ecowitt_http_gateway - server = without gateway, GW1000 configured to send data 61 | # to address:port 62 | # address = ip_address_of_weewx_server 63 | # port = 9999 64 | # 65 | # The variables in the file have the same names from those in the database 66 | # so you don't need a mapping section 67 | # 68 | # But if the variables in the file have names different from those in the database 69 | # schema, then create a mapping section called label_map. This will map the 70 | # variables in the file to variables in the database columns. For example: 71 | # 72 | # [ecowitt] 73 | # ... 74 | # [[label_map]] 75 | # temp = outTemp 76 | # humi = outHumidity 77 | # in_temp = inTemp 78 | # in_humid = inHumidity 79 | 80 | from __future__ import with_statement 81 | import syslog 82 | import time 83 | import BaseHTTPServer 84 | import SocketServer 85 | import re 86 | import Queue 87 | import threading 88 | import urlparse 89 | 90 | import weewx.drivers 91 | 92 | DRIVER_NAME = 'ecowitt' 93 | DRIVER_VERSION = '1.2' 94 | 95 | DEFAULT_ADDR = '' 96 | DEFAULT_PORT = 8000 97 | 98 | 99 | def logmsg(dst, msg): 100 | syslog.syslog(dst, 'ecowitt: %s' % msg) 101 | 102 | 103 | def logdbg(msg): 104 | logmsg(syslog.LOG_DEBUG, msg) 105 | 106 | 107 | def loginf(msg): 108 | logmsg(syslog.LOG_INFO, msg) 109 | 110 | 111 | def logerr(msg): 112 | logmsg(syslog.LOG_ERR, msg) 113 | 114 | 115 | def _obfuscate_passwords(msg): 116 | return re.sub(r'(PASSWORD|PASSKEY)=[^&]+', r'\1=XXXX', msg) 117 | 118 | 119 | def _get_as_float(d, s): 120 | v = None 121 | if s in d: 122 | try: 123 | v = float(d[s]) 124 | except ValueError as e: 125 | logerr("cannot read value for '%s': %s" % (s, e)) 126 | return v 127 | 128 | 129 | def loader(config_dict, engine): 130 | return ecowittDriver(**config_dict[DRIVER_NAME]) 131 | 132 | 133 | queue = Queue.Queue() 134 | 135 | 136 | class ecowittDriver(weewx.drivers.AbstractDevice): 137 | 138 | """weewx driver for ecowitt GW1000""" 139 | 140 | def __init__(self, **stn_dict): 141 | 142 | # where to find the data file 143 | 144 | self.path = stn_dict.get('path', '/var/log/ecowitt/weewx.txt') 145 | 146 | # how often to poll the weather data file, seconds 147 | 148 | self.poll_interval = float(stn_dict.get('poll_interval', 2.5)) 149 | 150 | # mapping from variable names to weewx names 151 | 152 | self.label_map = stn_dict.get('label_map', {}) 153 | self.last_rain = None 154 | self.mode = stn_dict.get('mode') 155 | self.address = stn_dict.get('address') 156 | self.port = stn_dict.get('port') 157 | 158 | loginf('data file is %s' % self.path) 159 | loginf('polling interval is %s' % self.poll_interval) 160 | loginf('label map is %s' % self.label_map) 161 | 162 | if self.mode == 'normal': 163 | loginf('mode is %s' % self.mode) 164 | elif self.mode == 'server': 165 | 166 | # self.genLoopPackets() 167 | 168 | loginf('mode is %s' % self.mode) 169 | loginf('address is %s' % self.address) 170 | loginf('port is %s' % self.port) 171 | 172 | handler = None 173 | 174 | self._server = self.TCPServer(self.address, self.port, 175 | handler) 176 | 177 | self._server_thread = \ 178 | threading.Thread(target=self.run_server) 179 | self._server_thread.setDaemon(True) 180 | self._server_thread.setName('ServerThread') 181 | self._server_thread.start() 182 | self._queue_timeout = int(stn_dict.pop('queue_timeout', 10)) 183 | else: 184 | 185 | raise Exception("unrecognized mode '%s'" % self.mode) 186 | 187 | def run_server(self): 188 | self._server.run() 189 | 190 | def stop_server(self): 191 | self._server.stop() 192 | self._server = None 193 | 194 | def get_queue(self): 195 | return queue 196 | 197 | class Server(object): 198 | 199 | def run(self): 200 | pass 201 | 202 | def stop(self): 203 | pass 204 | 205 | class Handler(BaseHTTPServer.BaseHTTPRequestHandler): 206 | 207 | def get_response(self): 208 | 209 | # default reply is a simple 'OK' string 210 | 211 | return 'OK' 212 | 213 | def reply(self): 214 | 215 | # standard reply is HTTP code of 200 and the response string 216 | 217 | response = bytes(self.get_response()) 218 | self.send_response(200) 219 | self.send_header('Content-Length', str(len(response))) 220 | self.end_headers() 221 | self.wfile.write(response) 222 | 223 | def do_POST(self): 224 | 225 | # get the payload from an HTTP POST 226 | 227 | length = int(self.headers['Content-Length']) 228 | data = str(self.rfile.read(length)) 229 | logdbg('POST: %s' % _obfuscate_passwords(data)) 230 | queue.put(data) 231 | self.reply() 232 | 233 | def do_PUT(self): 234 | pass 235 | 236 | def do_GET(self): 237 | 238 | # get the query string from an HTTP GET 239 | 240 | data = urlparse.urlparse(self.path).query 241 | logdbg('GET: %s' % _obfuscate_passwords(data)) 242 | queue.put(data) 243 | self.reply() 244 | 245 | # do not spew messages on every connection 246 | 247 | def log_message(self, _format, *_args): 248 | pass 249 | 250 | class TCPServer(Server, SocketServer.TCPServer): 251 | 252 | daemon_threads = True 253 | allow_reuse_address = True 254 | 255 | def __init__( 256 | self, 257 | address, 258 | port, 259 | handler, 260 | ): 261 | if handler is None: 262 | handler = ecowittDriver.Handler 263 | loginf('listen on %s:%s' % (address, port)) 264 | SocketServer.TCPServer.__init__(self, (address, int(port)), 265 | handler) 266 | 267 | def run(self): 268 | logdbg('start tcp server') 269 | self.serve_forever() 270 | 271 | def stop(self): 272 | logdbg('stop tcp server') 273 | self.shutdown() 274 | self.server_close() 275 | 276 | def genLoopPackets(self): 277 | while True: 278 | if self.mode == 'normal': 279 | 280 | # read whatever values we can get from the file 281 | 282 | data = {} 283 | try: 284 | with open(self.path) as f: 285 | for line in f: 286 | eq_index = line.find('=') 287 | name = line[:eq_index].strip() 288 | value = line[eq_index + 1:].strip() 289 | data[name] = value 290 | except Exception, e: 291 | logerr('read failed: %s' % e) 292 | 293 | # map the data into a weewx loop packet 294 | 295 | _packet = {'dateTime': int(time.time() + 0.5), 296 | 'usUnits': weewx.US} 297 | for vname in data: 298 | _packet[self.label_map.get(vname, vname)] = \ 299 | _get_as_float(data, vname) 300 | 301 | self._augment_packet(_packet) 302 | yield _packet 303 | time.sleep(self.poll_interval) 304 | elif self.mode == 'server': 305 | try: 306 | pkt = dict() 307 | data = self.get_queue().get(True, 308 | self._queue_timeout) 309 | logdbg('raw data: %s' % data) 310 | parts = data.split('&') 311 | for x in parts: 312 | if not x: 313 | continue 314 | if '=' not in x: 315 | loginf("unexpected un-assigned variable '%s'" 316 | % x) 317 | continue 318 | (n, v) = x.split('=') 319 | n = n.strip() 320 | v = v.strip() 321 | try: 322 | rain_total = None 323 | if n == 'tempf': 324 | pkt['outTemp'] = float(v) 325 | elif n == 'baromrelin': 326 | pkt['barometer'] = float(v) 327 | elif n == 'baromabsin': 328 | pkt['pressure'] = float(v) 329 | elif n == 'humidity': 330 | pkt['outHumidity'] = float(v) 331 | elif n == 'windspeedmph': 332 | pkt['windSpeed'] = float(v) 333 | elif n == 'windgustmph': 334 | pkt['windGust'] = float(v) 335 | elif n == 'winddir': 336 | pkt['winddir'] = float(v) 337 | elif n == 'rainratein': 338 | pkt['rainRate'] = float(v) 339 | elif n == 'totalrainin': 340 | pkt['rain_total'] = float(v) 341 | elif n == 'tempinf': 342 | pkt['inTemp'] = float(v) 343 | elif n == 'humidityin': 344 | pkt['inHumidity'] = float(v) 345 | elif n == 'solarradiation': 346 | pkt['radiation'] = float(v) 347 | elif n == 'uv': 348 | pkt['uv'] = float(v) 349 | elif n == 'dewptf': 350 | pkt['dewpoint'] = float(v) 351 | elif n == 'temp1f': 352 | pkt['extraTemp1'] = float(v) 353 | elif n == 'temp2f': 354 | pkt['extraTemp2'] = float(v) 355 | elif n == 'humidity1': 356 | pkt['extraHumid1'] = float(v) 357 | elif n == 'humidity2': 358 | pkt['extraHumid2'] = float(v) 359 | elif n == 'soilmoisture1': 360 | pkt['soilTemp1'] = float(v) 361 | elif n == 'wh80batt': 362 | pkt['consBatteryVoltage'] = float(v) 363 | if float(v) < 2.5: 364 | pkt['windBatteryStatus'] = 1.0 365 | if float(v) > 2.5: 366 | pkt['windBatteryStatus'] = 0.0 367 | elif n == 'wh40batt': 368 | pkt['supplyVoltage'] = float(v) 369 | if float(v) < 1.0: 370 | pkt['rainBatteryStatus'] = 1.0 371 | if float(v) > 1.0: 372 | pkt['rainBatteryStatus'] = 0.0 373 | elif n == 'batt1': 374 | pkt['outTempBatteryStatus'] = float(v) 375 | else: 376 | loginf("unknown element '%s' with value '%s'" 377 | % (n, v)) 378 | except (ValueError, IndexError) as e: 379 | logerr("decode failed for %s '%s': %s" 380 | % (n, v, e)) 381 | 382 | pkt['rain'] = \ 383 | weewx.wxformulas.calculate_rain(pkt['rain_total' 384 | ], self.last_rain) 385 | self.last_rain = pkt['rain_total'] 386 | 387 | pkt['windchill'] = 35.74 + 0.6215 * pkt['outTemp'] \ 388 | + (0.4275 * pkt['outTemp'] - 35.75) \ 389 | * pkt['windSpeed'] ** 0.16 390 | outTemp_c = (pkt['outTemp'] - 32) * 5 / 9 391 | dewpoint_c = (pkt['outHumidity'] / 100) ** 0.125 \ 392 | * (112 + 0.9 * outTemp_c) + 0.1 * outTemp_c \ 393 | - 112 394 | pkt['dewpoint'] = dewpoint_c * (9 / 5.0) + 32 395 | 396 | logdbg('raw packet: %s' % pkt) 397 | 398 | # map the data into a weewx loop packet 399 | 400 | _packet = { 401 | 'dateTime': int(time.time() + 0.5), 402 | 'usUnits': weewx.US, 403 | 'rain': pkt['rain'], 404 | 'outTemp': pkt['outTemp'], 405 | 'barometer': pkt['barometer'], 406 | 'pressure': pkt['pressure'], 407 | 'humidity': pkt['outHumidity'], 408 | 'windSpeed': pkt['windSpeed'], 409 | 'windGust': pkt['windGust'], 410 | 'windDir': pkt['winddir'], 411 | 'rainRate': pkt['rainRate'], 412 | 'inTemp': pkt['inTemp'], 413 | 'inHumidity': pkt['inHumidity'], 414 | 'radiation': pkt['radiation'], 415 | 'uv': pkt['uv'], 416 | 'windchill': pkt['windchill'], 417 | 'dewpoint': pkt['dewpoint'], 418 | 'extraTemp1': pkt['extraTemp1'], 419 | 'extraHumid1': pkt['extraHumid1'], 420 | 'extraTemp2': pkt['extraTemp2'], 421 | 'extraHumid2': pkt['extraHumid2'], 422 | 'soilTemp1': pkt['soilTemp1'], 423 | 'consBatteryVoltage': pkt['consBatteryVoltage' 424 | ], 425 | 'supplyVoltage': pkt['supplyVoltage'], 426 | 'windBatteryStatus': pkt['windBatteryStatus'], 427 | 'rainBatteryStatus': pkt['rainBatteryStatus'], 428 | 'outTempBatteryStatus': pkt['outTempBatteryStatus' 429 | ], 430 | } 431 | 432 | logdbg('decoded packet: %s' % _packet) 433 | 434 | yield _packet 435 | except Queue.Empty: 436 | 437 | logdbg('empty queue') 438 | 439 | time.sleep(self.poll_interval) 440 | else: 441 | raise Exception("unrecognized mode '%s'" % self.mode) 442 | 443 | def _augment_packet(self, packet): 444 | packet['rain'] = \ 445 | weewx.wxformulas.calculate_rain(packet['rain_total'], 446 | self.last_rain) 447 | self.last_rain = packet['rain_total'] 448 | 449 | @property 450 | def hardware_name(self): 451 | return 'ecowitt' 452 | 453 | 454 | # To test this driver, run it directly as follows: 455 | # PYTHONPATH=python /usr/share/weewx/weewx/drivers/ecowitt.py 456 | 457 | if __name__ == '__main__': 458 | import weeutil.weeutil 459 | driver = ecowittDriver() 460 | for packet in driver.genLoopPackets(): 461 | print weeutil.weeutil.timestamp_to_string(packet['dateTime']), \ 462 | packet 463 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2.5 ) 171 | { 172 | @$weather_data['windBatteryStatus'] = 0.0 ; 173 | } 174 | @$weather_data['consBatteryVoltage'] = $weather_data['wh80batt'] ; 175 | 176 | if ( $weather_data['wh40batt'] < 1.0 ) 177 | { 178 | @$weather_data['rainBatteryStatus'] = 1.0 ; 179 | } 180 | if ( $weather_data['wh40batt'] > 1.0 ) 181 | { 182 | @$weather_data['rainBatteryStatus'] = 0.0 ; 183 | } 184 | @$weather_data['supplyVoltage'] = $weather_data['wh40batt'] ; 185 | 186 | if ( $weather_data['soilbatt1'] < 1.0 ) 187 | { 188 | @$weather_data['txBatteryStatus'] = 1.0 ; 189 | } 190 | if ( $weather_data['soilbatt1'] > 1.0 ) 191 | { 192 | @$weather_data['txBatteryStatus'] = 0.0 ; 193 | } 194 | @$weather_data['heatingVoltage'] = $weather_data['soilbatt1'] ; 195 | 196 | @$weather_data['outTempBatteryStatus'] = $weather_data['batt1'] ; 197 | 198 | 199 | # WS80 temperature correction 200 | if ( $ws80_temperature_correction == 1 ) { 201 | # reading old data from files 202 | # 203 | # one value ago solar radiation 204 | # read old solar rad from file 205 | $read_S_1 = $txt_dir_weewx . "/last-1_solar_ws80.txt"; 206 | if (!file_exists($read_S_1)) { 207 | $result_S_1 = round($weather_data['solarradiation'], 2); 208 | } else { 209 | $file = fopen($read_S_1, 'r'); 210 | #while (!feof($file)){ 211 | $result_S_1 = fgets($file); 212 | $result_S_1 = round((double)$result_S_1, 2); 213 | #} 214 | fclose($file); 215 | } 216 | # two values ago solar radiation 217 | $read_S_2 = $txt_dir_weewx . "/last-2_solar_ws80.txt"; 218 | if (!file_exists($read_S_2)) { 219 | $result_S_2 = round($weather_data['solarradiation'], 2); 220 | } else { 221 | $file = fopen($read_S_2, 'r'); 222 | #while (!feof($file)){ 223 | $result_S_2 = fgets($file); 224 | $result_S_2 = round((double)$result_S_2, 2); 225 | #} 226 | fclose($file); 227 | } 228 | # one value ago temperature not corrected 229 | $read_T_1 = $txt_dir_weewx . "/last-1_temperature.txt"; 230 | if (!file_exists($read_S_2)) { 231 | $result_T_1 = round($weather_data['tempc'], 2); 232 | } else { 233 | $file = fopen($read_T_1, 'r'); 234 | #while (!feof($file)){ 235 | $result_T_1 = fgets($file); 236 | $result_T_1 = round((double)$result_T_1, 2); 237 | #} 238 | fclose($file); 239 | } 240 | # one value ago temperature corrected 241 | $read_corr_T_1 = $txt_dir_weewx . "/last-1_corr_temperature.txt"; 242 | if (!file_exists($read_corr_T_2)) { 243 | $result_corr_T_1 = round($weather_data['tempc'], 2); 244 | } else { 245 | $file = fopen($read_corr_T_1, 'r'); 246 | #while (!feof($file)){ 247 | $result_corr_T_1 = fgets($file); 248 | $result_corr_T_1 = round((double)$result_corr_T_1, 2); 249 | #} 250 | fclose($file); 251 | } 252 | 253 | 254 | 255 | # 256 | # Fixed constants 257 | # 258 | $dm = 0.0009; 259 | $K = 0.0984; 260 | $cp = 29.3; 261 | #$aslow = 0.270; 262 | $aslow = 0.300; 263 | $asnormal = 0.325; 264 | #$ashigh = 0.385; 265 | $ashigh = 0.335; 266 | #$asultrahigh = 0.452; 267 | $asultrahigh = 0.345; 268 | # Wind cannot be 0 269 | if ( $weather_data['windspeedms'] < 0.2 ) 270 | { 271 | $u = 0.2 ; 272 | } else { 273 | $u = $weather_data['windspeedms']; 274 | } 275 | # 276 | # as parameter estimation 277 | # 278 | if ( round($weather_data['solarradiation'], 2) < 1 ) 279 | { 280 | $S = 0.1; 281 | } elseif ( round($weather_data['solarradiation'], 2) > 352.3 ) { 282 | $S = 352.3; 283 | } else { 284 | $S = round($weather_data['solarradiation'], 2); 285 | } 286 | 287 | if ( $S < $result_S_1 ) { 288 | if ( $result_S_1 < $result_S_2 ) { 289 | $as = $ashigh; 290 | } else { 291 | $as = $aslow; 292 | } 293 | } else { 294 | if ( $S < $result_S_2 ) { 295 | $as = $aslow; 296 | } else { 297 | $as = $asnormal; 298 | } 299 | } 300 | 301 | if ( ( $as == $ashigh ) || ( $as == $low ) ) { 302 | $diff_temp = round($weather_data['tempc'], 2) - round($result_T_1, 2); 303 | if ( $diff_temp > 0.3 ) { 304 | $as = $asultrahigh; 305 | } 306 | } 307 | if ( round($weather_data['solarradiation'], 2) < 145 ) { 308 | $as = $asultrahigh*2.5; 309 | } 310 | 311 | # Formula sections 312 | $sez1 = $as * $S; 313 | $sez2 = $u / $dm; 314 | $sez3 = sqrt($sez2); 315 | $sez4 = $cp * $K * $sez3; 316 | $sez5 = $sez1 / $sez4; 317 | $temp_corr = round($weather_data['tempc'], 2) - $sez5; 318 | 319 | # Original value of temperature from WS80 320 | @$weather_data['tempc_orig'] = round($weather_data['tempc'], 2); 321 | 322 | 323 | # Corrected value of temperature from WS80 324 | $diff_corr_temp = round($result_corr_T_1, 2) - round($temp_corr, 2); 325 | if ( $diff_corr_temp > 0.7 ) { 326 | $temp_corr = $temp_corr+0.5; 327 | } 328 | if ( $diff_corr_temp < -0.7 ) { 329 | $temp_corr = $temp_corr-0.5; 330 | } 331 | 332 | # tempc is now corrected 333 | @$weather_data['tempc'] = round($temp_corr, 2); 334 | # tempf is now corrected 335 | @$weather_data['tempf'] = round( ( $temp_corr * 9/5 ) + 32, 2 ); 336 | 337 | 338 | # 339 | # Writing to files last values 340 | # 341 | 342 | $write_S_1 = $txt_dir_weewx . "/last-1_solar_ws80.txt"; 343 | $file = fopen($write_S_1, 'w'); 344 | $stringa = round($weather_data['solarradiation'], 2) . "\n"; 345 | fwrite($file, $stringa); 346 | fclose($file); 347 | 348 | # read old solar rad from file 349 | $read_S_1 = $txt_dir_weewx . "/last-1_solar_ws80.txt"; 350 | $file = fopen($read_S_1, 'r'); 351 | #while (!feof($file)){ 352 | $get_read_S_1 = fgets($file); 353 | $get_read_S_1 = round((double)$get_read_S_1, 2); 354 | #} 355 | fclose($file); 356 | 357 | # write old solar to new file 358 | $write_S_2 = $txt_dir_weewx . "/last-2_solar_ws80.txt"; 359 | $file = fopen($write_S_2, 'w'); 360 | $stringa = round((double)$get_read_S_1, 2) . "\n"; 361 | fwrite($file, $stringa); 362 | fclose($file); 363 | 364 | # write temp not corrected to file 365 | $write_T_1 = $txt_dir_weewx . "/last-1_temperature.txt"; 366 | $file = fopen($write_T_1, 'w'); 367 | $stringa = round($weather_data['tempc_orig'], 2) . "\n"; 368 | fwrite($file, $stringa); 369 | fclose($file); 370 | 371 | # write temp corrected to file 372 | $write_corr_T_1 = $txt_dir_weewx . "/last-1_corr_temperature.txt"; 373 | $file = fopen($write_corr_T_1, 'w'); 374 | $stringa = round($weather_data['tempc'], 2) . "\n"; 375 | fwrite($file, $stringa); 376 | fclose($file); 377 | 378 | 379 | } 380 | 381 | # Forward data to meteotemplate server 382 | if ( $forward_data == 1 ) 383 | { 384 | @$weather_data_forward['U'] = strtotime( $weather_data['dateutc'] ); 385 | @$weather_data_forward['PASS'] = $forward_server_password ; 386 | @$weather_data_forward['T'] = $weather_data['tempc'] ; 387 | @$weather_data_forward['H'] = $weather_data['humidity'] ; 388 | @$weather_data_forward['P'] = $weather_data['baromrelhpa'] ; 389 | @$weather_data_forward['W'] = $weather_data['windspeedkmh'] ; 390 | @$weather_data_forward['G'] = $weather_data['windgustkmh'] ; 391 | @$weather_data_forward['B'] = $weather_data['winddir'] ; 392 | @$weather_data_forward['R'] = $weather_data['dailyrainmm'] ; 393 | @$weather_data_forward['RR'] = $weather_data['rainratemm'] ; 394 | @$weather_data_forward['S'] = $weather_data['solarradiation'] ; 395 | @$weather_data_forward['UV'] = $weather_data['uv'] ; 396 | @$weather_data_forward['TIN'] = $weather_data['tempinc'] ; 397 | @$weather_data_forward['HIN'] = $weather_data['humidityin'] ; 398 | @$weather_data_forward['T1'] = $weather_data['temp1c'] ; 399 | @$weather_data_forward['H1'] = $weather_data['humidity1'] ; 400 | @$weather_data_forward['T2'] = $weather_data['temp2c'] ; 401 | @$weather_data_forward['H2'] = $weather_data['humidity2'] ; 402 | @$weather_data_forward['T3'] = $weather_data['temp2c'] ; 403 | @$weather_data_forward['H3'] = $weather_data['humidity2'] ; 404 | @$weather_data_forward['SM1'] = $weather_data['soilmoisture1'] ; 405 | @$weather_data_forward['SM2'] = $weather_data['soilmoisture2'] ; 406 | @$weather_data_forward['PP1'] = $weather_data['pm25_ch1'] ; 407 | @$weather_data_forward['L'] = $weather_data['lightning_num'] ; 408 | @$weather_data_forward['LD'] = $weather_data['lightning'] ; 409 | @$weather_data_forward['LT'] = $weather_data['lightning_time'] ; 410 | @$weather_data_forward['WBAT'] = $weather_data['wh80batt'] ; 411 | @$weather_data_forward['RBAT'] = $weather_data['wh40batt'] ; 412 | @$weather_data_forward['LBAT'] = $weather_data['wh57batt'] ; 413 | @$weather_data_forward['SM1BAT'] = $weather_data['soilbatt1'] ; 414 | @$weather_data_forward['SM2BAT'] = $weather_data['soilbatt2'] ; 415 | @$weather_data_forward['PP1BAT'] = $weather_data['pm25batt1'] ; 416 | if ( $weather_data['batt1'] == 0 ) 417 | { 418 | @$weather_data_forward['T1BAT'] = OK ; 419 | } 420 | if ( $weather_data['batt1'] == 1 ) 421 | { 422 | @$weather_data_forward['T1BAT'] = LOW ; 423 | } 424 | if ( $weather_data['batt2'] == 0 ) 425 | { 426 | @$weather_data_forward['T2BAT'] = OK ; 427 | } 428 | if ( $weather_data['batt2'] == 1 ) 429 | { 430 | @$weather_data_forward['T2BAT'] = LOW ; 431 | } 432 | 433 | #@$weather_data['forward_url'] = "http://" . $forward_server . $_SERVER[REQUEST_URI]; 434 | @$weather_data_forward['forward_url'] = "http://" . $forward_server ; 435 | @$weather_data_forward['forward'] = file_get_contents($weather_data_forward['forward_url'] . "?" . "U=" . @$weather_data_forward['U'] . "&PASS=" . @$weather_data_forward['PASS'] . "&T=" . @$weather_data_forward['T'] . "&H=" . @$weather_data_forward['H'] ."&P=" . @$weather_data_forward['P'] . "&W=" . @$weather_data_forward['W'] . "&G=" . @$weather_data_forward['G'] . "&B=" . @$weather_data_forward['B'] . "&R=" . @$weather_data_forward['R'] . "&RR=" . @$weather_data_forward['RR'] . "&S=" . @$weather_data_forward['S'] . "&UV=" . @$weather_data_forward['UV'] . "&TIN=" . @$weather_data_forward['TIN'] . "&HIN=" . @$weather_data_forward['HIN'] . "&T1=" . @$weather_data_forward['T1'] . "&H1=" . @$weather_data_forward['H1'] . "&T2=" . @$weather_data_forward['T2'] . "&H2=" . @$weather_data_forward['H2'] . "&T3=" . @$weather_data_forward['T3'] . "&H3=" . @$weather_data_forward['H3'] . "&SM1=" . @$weather_data_forward['SM1'] . "&SM2=" . @$weather_data_forward['SM2'] . "&L=" . @$weather_data_forward['L'] . "&LD=" . @$weather_data_forward['LD'] . "<=" . @$weather_data_forward['LT'] . "&PP1=" . @$weather_data_forward['PP1'] . "&WBAT=" . @$weather_data_forward['WBAT'] . "&RBAT=" . @$weather_data_forward['RBAT'] . "&LBAT=" . @$weather_data_forward['LBAT'] . "&PP1BAT=" . @$weather_data_forward['PP1BAT'] . "&SM1BAT=" . @$weather_data_forward['SM1BAT'] . "&SM2BAT=" . @$weather_data_forward['SM2BAT'] . "&T1BAT=" . @$weather_data_forward['T1BAT'] . "&T2BAT=" . @$weather_data_forward['T2BAT']); 436 | } 437 | 438 | # Pack data into json format 439 | $weather_data_json = json_encode($weather_data); 440 | 441 | # Converts array into string 442 | #$weather_data_txt = implode(";",$weather_data); 443 | 444 | # Write json stream to logfile 445 | $json_data_logfile = $json_data_logdir . "/" . $device . ".json"; 446 | if ( $json_data_log == 1 ) 447 | { 448 | $file = fopen($json_data_logfile, 'w'); 449 | fwrite($file, $weather_data_json); 450 | fclose($file); 451 | } 452 | 453 | # Write stream to csvfile 454 | $txt_data_logfile = $txt_data_logdir . "/" . $device . "_" . $date_txt . ".csv"; 455 | if ( $txt_data_log == 1 ) 456 | { 457 | if (!file_exists($txt_data_logfile)) { 458 | $data = json_decode($weather_data_json); 459 | foreach($data as $key => $value) { 460 | $string .= $key . ','; 461 | } 462 | $string .= "\n"; 463 | file_put_contents($txt_data_logfile, $string, FILE_APPEND); 464 | } 465 | 466 | 467 | $file = fopen($txt_data_logfile, 'a'); 468 | fputcsv($file, $weather_data); 469 | fclose($file); 470 | } 471 | 472 | # Write data to FHEM 473 | if ( $fhem_data_log == 1 ) 474 | { 475 | # Add settings, json and url string to array 476 | $weather_data['json'] = $weather_data_json; 477 | $weather_data['url'] = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; 478 | $weather_data['settings_device'] = $device; 479 | $weather_data['settings_convert_data'] = $convert_data; 480 | $weather_data['settings_json_data_log'] = $json_data_log; 481 | $weather_data['settings_json_data_logdir'] = $json_data_logdir; 482 | $weather_data['settings_json_data_logfile'] = $json_data_logfile; 483 | $weather_data['settings_fhem_data_log'] = $fhem_data_log; 484 | $weather_data['settings_forward_data'] = $forward_data; 485 | $weather_data['settings_forward_server'] = $forward_server; 486 | $weather_data['settings_FHEM_server'] = $FHEM_server; 487 | $weather_data['settings_FHEM_port'] = $FHEM_port; 488 | 489 | $FHEM_device = $device; 490 | 491 | $conn=fsockopen($FHEM_server,$FHEM_port); 492 | if($conn){ 493 | 494 | # Create FHEM device if not exists 495 | $FHEM_command = fputs($conn,"define $FHEM_device dummy".chr(10).chr(13)); 496 | 497 | # Write each value into seperate reading 498 | foreach ($weather_data as $reading => $value) { 499 | $FHEM_command = fputs($conn,"setreading $FHEM_device $reading $value".chr(10).chr(13)); 500 | } 501 | 502 | # Exit from FHEM interface 503 | $FHEM_command = fputs($conn,"exit".chr(10).chr(13)); 504 | fclose($conn); 505 | } 506 | } 507 | 508 | # Specifiche del file inviato dalla stazione al server Mnw formato file: file di testo con campi separati da ";" 509 | # nome file: nomestazione.txt (con nome stazione si intende il codice assegnato da mnw) separatore decimali: "." 510 | # separatore migliaia: nessuno 511 | # campi presenti nel file: 512 | # 1. Station - codice Stazione 513 | # 2. Date - Data rilevamento (gg/mm/aa) . 514 | # 3. Time - Ora rilevamento (hh:mm) 515 | # 4. TempOut - Temperatura esterna (°C) 516 | # 5. Pres - Pressione (Hpa) 517 | # 6. HumOut Umidita' relativa esterna (%) 518 | # 7. Wind - Velocità del vento (km/h) 519 | # 8. Dir - Direzione del vento (°) 520 | # 9. Gust - Massima raffica (km/h) 521 | # 10. RainRate - Rain rate (mm/h) 522 | # 11. Rain - Pioggia giornaliera (mm) 523 | # 12. DewPoint - DewPoint (°C) 524 | # 13. Software - Nome del software ( un nome generico ) 525 | # 14. Versione - Versione del software 526 | # 15. TempIn - Temperatura interna (°C) 527 | # 16. HumIn - Umidità interna (%) 528 | # 17. UVI - Radiazione solare (UVI) 529 | # 18. Radiazione Solare W/m2 530 | # dato non presente indicare “-99999”. Ultima riga in basso l’ultimo dato . Se non si puo’ mandare tutto l’archivio della giornata basta mandare solo l’ultimo dato , una riga sola . Di norma il file contiene i dati degli ultimi 2 giorni . 531 | # 532 | # vnt214;18/08/15;00:05;20.4;1010.2;90;0.0;180;3.2;0.0;0.0;18.7;WL02;0.1;-99999;-99999;-99999;-99999; 533 | 534 | if ( $txt_mnw == 1 ) 535 | { 536 | 537 | @$weather_data_mnw['Station'] = $station_mnw; 538 | @$weather_data_mnw['Date'] = gmdate("d-m-y"); 539 | @$weather_data_mnw['Time'] = gmdate("H:i"); 540 | @$weather_data_mnw['TempOut'] = $weather_data['tempc'] ; 541 | @$weather_data_mnw['Pres'] = $weather_data['baromrelhpa'] ; 542 | @$weather_data_mnw['HumOut'] = $weather_data['humidity'] ; 543 | @$weather_data_mnw['Wind'] = $weather_data['windspeedkmh'] ; 544 | @$weather_data_mnw['Dir'] = $weather_data['winddir'] ; 545 | @$weather_data_mnw['Gust'] = $weather_data['windgustkmh'] ; 546 | @$weather_data_mnw['RainRate'] = $weather_data['rainratemm'] ; 547 | @$weather_data_mnw['Rain'] = $weather_data['dailyrainmm'] ; 548 | @$weather_data_mnw['DewPoint'] = "-99999" ; 549 | @$weather_data_mnw['Software'] = "EcowittGate" ; 550 | @$weather_data_mnw['Versione'] = "XX" ; 551 | @$weather_data_mnw['TempIn'] = $weather_data['tempinc'] ; 552 | @$weather_data_mnw['HumIn'] = $weather_data['humidityin'] ; 553 | @$weather_data_mnw['SolarRad'] = $weather_data['solarradiation'] ; 554 | @$weather_data_mnw['UVI'] = $weather_data['uv'] ; 555 | 556 | $stringa = @$weather_data_mnw['Station'] . ";" . @$weather_data_mnw['Date'] . ";" . @$weather_data_mnw['Time'] . ";" . @$weather_data_mnw['TempOut'] . ";" . @$weather_data_mnw['Pres'] . ";" . @$weather_data_mnw['HumOut'] . ";" . @$weather_data_mnw['Wind'] . ";" . @$weather_data_mnw['Dir'] . ";" . @$weather_data_mnw['Gust'] . ";" . @$weather_data_mnw['RainRate'] . ";" . @$weather_data_mnw['Rain'] . ";" . @$weather_data_mnw['Rain'] . ";" . @$weather_data_mnw['DewPoint'] . ";" . @$weather_data_mnw['Software'] . ";" . @$weather_data_mnw['Versione'] . ";" . @$weather_data_mnw['TempIn'] . ";" . @$weather_data_mnw['HumIn'] . ";" . @$weather_data_mnw['SolarRad'] . ";" . @$weather_data_mnw['UVI'] . "\n"; 557 | 558 | $txt_mnw_logfile = $txt_dir_mnw . "/" . $station_mnw . ".txt"; 559 | $file = fopen($txt_mnw_logfile, 'w'); 560 | fwrite($file, $stringa); 561 | fclose($file); 562 | 563 | // set up basic connection 564 | $conn_id = ftp_connect($ftp_mnw); 565 | 566 | // login with username and password 567 | $login_result = ftp_login($conn_id, $ftp_user_mnw, $ftp_pass_mnw); 568 | $remote_file = $ftp_dir_mnw . $station_mnw . ".txt"; 569 | 570 | // turn passive mode on 571 | ftp_pasv($conn_id, true); 572 | 573 | // upload a file 574 | if (ftp_put($conn_id, $remote_file, $txt_mnw_logfile, FTP_ASCII)) { 575 | print "successfully uploaded $txt_mnw_logfile\n"; 576 | } else { 577 | print "There was a problem while uploading $txt_mnw_logfile\n"; 578 | } 579 | 580 | // close the connection 581 | ftp_close($conn_id); 582 | 583 | #print($stringa); 584 | 585 | } 586 | 587 | if ( $txt_weewx == 1 ) 588 | { 589 | @$weather_data_weewx['outTemp'] = $weather_data['tempf'] ; 590 | @$weather_data_weewx['barometer'] = $weather_data['baromrelin'] ; 591 | @$weather_data_weewx['pressure'] = $weather_data['baromabsin'] ; 592 | @$weather_data_weewx['outHumidity'] = $weather_data['humidity'] ; 593 | @$weather_data_weewx['windSpeed'] = $weather_data['windspeedmph'] ; 594 | @$weather_data_weewx['windDir'] = $weather_data['winddir'] ; 595 | @$weather_data_weewx['windGust'] = $weather_data['windgustmph'] ; 596 | @$weather_data_weewx['rainRate'] = $weather_data['rainratein'] ; 597 | @$weather_data_weewx['rain_total'] = $weather_data['totalrainin'] ; 598 | @$weather_data_weewx['inTemp'] = $weather_data['tempinf'] ; 599 | @$weather_data_weewx['inHumidity'] = $weather_data['humidityin'] ; 600 | @$weather_data_weewx['radiation'] = $weather_data['solarradiation'] ; 601 | @$weather_data_weewx['UV'] = $weather_data['uv'] ; 602 | @$weather_data_weewx['windchill'] = $weather_data['windchillf'] ; 603 | @$weather_data_weewx['dewpoint'] = $weather_data['dewptf'] ; 604 | @$weather_data_weewx['extraTemp1'] = $weather_data['temp1f'] ; 605 | @$weather_data_weewx['extraHumid1'] = $weather_data['humidity1'] ; 606 | @$weather_data_weewx['extraTemp2'] = $weather_data['temp2f'] ; 607 | @$weather_data_weewx['extraHumid2'] = $weather_data['humidity2'] ; 608 | @$weather_data_weewx['extraTemp3'] = $weather_data['temp3f'] ; 609 | @$weather_data_weewx['extraHumid3'] = $weather_data['humidity3'] ; 610 | @$weather_data_weewx['soilTemp1'] = $weather_data['soilmoisture1'] ; 611 | @$weather_data_weewx['windBatteryStatus'] = $weather_data['windBatteryStatus'] ; 612 | @$weather_data_weewx['rainBatteryStatus'] = $weather_data['rainBatteryStatus'] ; 613 | @$weather_data_weewx['outTempBatteryStatus'] = $weather_data['batt1'] ; 614 | @$weather_data_weewx['consBatteryVoltage'] = $weather_data['consBatteryVoltage'] ; 615 | @$weather_data_weewx['supplyVoltage'] = $weather_data['supplyVoltage'] ; 616 | @$weather_data_weewx['heatingVoltage'] = $weather_data['heatingVoltage'] ; 617 | @$weather_data_weewx['txBatteryStatus'] = $weather_data['txBatteryStatus'] ; 618 | 619 | $stringa = "outTemp=" . @$weather_data_weewx['outTemp'] . "\nbarometer=" . @$weather_data_weewx['barometer'] . "\npressure=" . @$weather_data_weewx['pressure'] . "\noutHumidity=" . @$weather_data_weewx['outHumidity'] . "\nwindSpeed=" . @$weather_data_weewx['windSpeed'] . "\nwindDir=" . @$weather_data_weewx['windDir'] . "\nwindGust=" . @$weather_data_weewx['windGust'] . "\nrainRate=" . @$weather_data_weewx['rainRate'] . "\nrain_total=" . @$weather_data_weewx['rain_total'] . "\ninTemp=" . @$weather_data_weewx['inTemp'] . "\ninHumidity=" . @$weather_data_weewx['inHumidity'] . "\nradiation=" . @$weather_data_weewx['radiation'] . "\nUV=" . @$weather_data_weewx['UV'] . "\nwindchill=" . @$weather_data_weewx['windchill'] . "\ndewpoint=" . @$weather_data_weewx['dewpoint'] . "\nextraTemp1=" . @$weather_data_weewx['extraTemp1'] . "\nextraHumid1=" . @$weather_data_weewx['extraHumid1'] . "\nextraTemp2=" . @$weather_data_weewx['extraTemp2'] . "\nextraHumid2=" . @$weather_data_weewx['extraHumid2'] . "\nextraTemp3=" . @$weather_data_weewx['extraTemp3'] . "\nextraHumid3=" . @$weather_data_weewx['extraHumid3'] . "\nsoilTemp1=" . @$weather_data_weewx['soilTemp1'] . "\nwindBatteryStatus=" . @$weather_data_weewx['windBatteryStatus'] . "\nrainBatteryStatus=" . @$weather_data_weewx['rainBatteryStatus'] . "\noutTempBatteryStatus=" . @$weather_data_weewx['outTempBatteryStatus'] . "\nconsBatteryVoltage=" . @$weather_data_weewx['consBatteryVoltage'] . "\nsupplyVoltage=" . @$weather_data_weewx['supplyVoltage'] . "\ntxBatteryStatus=" . @$weather_data_weewx['txBatteryStatus'] . "\nheatingVoltage=" . @$weather_data_weewx['heatingVoltage'] . "\n"; 620 | 621 | 622 | $txt_weewx_logfile = $txt_dir_weewx . "/weewx.txt"; 623 | $file = fopen($txt_weewx_logfile, 'w'); 624 | fwrite($file, $stringa); 625 | fclose($file); 626 | 627 | } 628 | 629 | 630 | print("success\n"); 631 | 632 | ?> 633 | -------------------------------------------------------------------------------- /Meteotemplate/update/apiSetup.php: -------------------------------------------------------------------------------- 1 | 98 | 99 | 100 | 101 | 102 | <?php echo $pageName?> 103 | 104 | 129 | 130 | 131 |
132 | 133 | 134 |
135 |
136 |
137 |

Extra Table Setup

138 |

Depending on which sensors you have and which software/update type you use, there might be more parameters available in the API file than what is included in the main alldata table.

139 |

This page allows you to set up an extra table in the database which will log the additional parameters. It is therefore necessary to first set up the normal database updates. This will create the API file with the current conditions with all the available parameters sent by whichever update type you use (Weather Display, Meteobridge, WeeWx, WeatherCat, NetAtmo, BloomSky, WeatherLink etc.).

140 |

Below is list of all the variables found in this file (these are available for you right now) and their current values. If in the future additional data is available, you should see it here and you can add new columns to the table. Only enable those which have sensible values. Also note! The values are shown in the default API units (degrees C, mm, hPa etc.), this is how they will be saved in the extra table, however, on the page you will see the numbers in whatever "display units" you or the user specifies.

141 |

142 |

API File

143 | 146 |

API FILE NOT FOUND, MAKE SURE YOU FIRST SET UP THE DATABASE UPDATES FOR THE MAIN TEMPLATE TABLE.

147 | 151 | 152 | 153 | 156 | 159 | 162 | 163 | 164 | 167 | 170 | 173 | 176 | 180 | 183 | 186 | 187 | 188 | 191 | 194 | 197 | 200 | 204 | 207 | 210 | 211 | 212 | 215 | 218 | 221 | 224 | 228 | 231 | 234 | 235 | 236 | 239 | 242 | 245 | 248 | 252 | 255 | 258 | 259 | 260 | 263 | 266 | 269 | 272 | 276 | 279 | 282 | 283 | 284 | 287 | 290 | 293 | 296 | 300 | 303 | 306 | 307 | 308 | 311 | 314 | 317 | 320 | 324 | 327 | 330 | 331 | 332 | 335 | 338 | 341 | 344 | 348 | 351 | 354 | 355 | 356 | 359 | 362 | 365 | 368 | 372 | 375 | 378 | 379 | 380 | 383 | 386 | 389 | 392 | 396 | 399 | 402 | 403 | 404 | 407 | 410 | 413 | 416 | 420 | 423 | 426 | 427 | 428 | 431 | 434 | 437 | 447 | 451 | 455 | 458 | 459 | 460 | 463 | 466 | 469 | 479 | 483 | 487 | 490 | 491 | 492 | 495 | 498 | 501 | 511 | 515 | 519 | 522 | 523 | 526 | 527 | 530 | 533 | 536 | 546 | 550 | 554 | 557 | 558 | 561 | 564 | 565 | 568 | 571 | 574 | 584 | 588 | 592 | 595 | 596 | 599 | 602 | 603 | 606 | 609 | 612 | 622 | 626 | 630 | 633 | 634 | 637 | 640 | 641 | 644 | 647 | 650 | 660 | 664 | 668 | 671 | 672 | 675 | 678 | 679 | 682 | 685 | 688 | 698 | 702 | 706 | 709 | 710 | 713 | 716 | 717 | 720 | 723 | 726 | 736 | 740 | 744 | 747 | 748 | 751 | 752 | 755 | 758 | 761 | 771 | 775 | 779 | 782 | 783 | 784 | 787 | 790 | 793 | 803 | 807 | 811 | 814 | 815 | 816 | 819 | 822 | 825 | 835 | 839 | 843 | 846 | 847 | 848 | 851 | 854 | 857 | 867 | 871 | 875 | 878 | 879 | 880 | 883 | 886 | 889 | 899 | 903 | 907 | 910 | 911 | 912 | 915 | 918 | 921 | 931 | 935 | 939 | 942 | 943 | 944 | 947 | 950 | 953 | 963 | 967 | 971 | 974 | 975 | 978 | 979 | 982 | 985 | 988 | 998 | 1002 | 1006 | 1009 | 1010 | 1013 | 1016 | 1017 | 1020 | 1023 | 1026 | 1036 | 1040 | 1044 | 1047 | 1048 | 1051 | 1054 | 1055 | 1058 | 1061 | 1064 | 1074 | 1078 | 1082 | 1085 | 1086 | 1089 | 1092 | 1093 | 1096 | 1099 | 1102 | 1112 | 1116 | 1120 | 1123 | 1124 | 1127 | 1130 | 1131 | 1134 | 1137 | 1140 | 1150 | 1154 | 1158 | 1161 | 1162 | 1165 | 1168 | 1169 | 1172 | 1175 | 1178 | 1188 | 1192 | 1196 | 1199 | 1200 | 1203 |
154 | Parameter 155 | 157 | Current value 158 | 160 | 161 |
165 | Air temperature 166 | 171 | °C 172 | 174 | included in main template table 175 | 181 | Not available 182 |
189 | Air humidity 190 | 195 | % 196 | 198 | included in main template table 199 | 205 | Not available 206 |
213 | Sea-level adjusted pressure 214 | 219 | hPa 220 | 222 | included in main template table 223 | 229 | Not available 230 |
237 | Wind speed 238 | 243 | km/h 244 | 246 | included in main template table 247 | 253 | Not available 254 |
261 | Wind gust 262 | 267 | km/h 268 | 270 | included in main template table 271 | 277 | Not available 278 |
285 | Wind direction 286 | 291 | ° 292 | 294 | included in main template table 295 | 301 | Not available 302 |
309 | Daily rain 310 | 315 | mm 316 | 318 | included in main template table 319 | 325 | Not available 326 |
333 | Rain rate 334 | 339 | mm/h 340 | 342 | included in main template table 343 | 349 | Not available 350 |
357 | Solar radiation 358 | 363 | W2 364 | 366 | included in main template table 367 | 373 | Not available 374 |
381 | Dew point 382 | 387 | °C 388 | 390 | included in main template table 391 | 397 | Not available 398 |
405 | Apparent temperature 406 | 411 | °C 412 | 414 | included in main template table 415 | 421 | Not available 422 |
429 | Indoor temperature 430 | 435 | °C 436 | 438 | 446 | 452 | Not available 453 | 454 |
461 | Indoor humidity 462 | 467 | % 468 | 470 | 478 | 484 | Not available 485 | 486 |
493 | UV 494 | 499 | 500 | 502 | 510 | 516 | Not available 517 | 518 |
528 | Extra temperature sensor 529 | 534 | °C 535 | 537 | 545 | 551 | Not available 552 | 553 |
566 | Extra humidity sensor 567 | 572 | % 573 | 575 | 583 | 589 | Not available 590 | 591 |
604 | Soil temperature 605 | 610 | °C 611 | 613 | 621 | 627 | Not available 628 | 629 |
642 | Soil moisture 643 | 648 | 649 | 651 | 659 | 665 | Not available 666 | 667 |
680 | Leaf wetness 681 | 686 | 687 | 689 | 697 | 703 | Not available 704 | 705 |
718 | Leaf temperature 719 | 724 | °C 725 | 727 | 735 | 741 | Not available 742 | 743 |
753 | Snowfall 754 | 759 | mm 760 | 762 | 770 | 776 | Not available 777 | 778 |
785 | Snow depth 786 | 791 | mm 792 | 794 | 802 | 808 | Not available 809 | 810 |
817 | Noise level 818 | 823 | dB 824 | 826 | 834 | 840 | Not available 841 | 842 |
849 | Ligthning 850 | 855 | 856 | 858 | 866 | 872 | Not available 873 | 874 |
881 | Ligthning distance 882 | 887 | 888 | 890 | 898 | 904 | Not available 905 | 906 |
913 | Ligthning time 914 | 919 | 920 | 922 | 930 | 936 | Not available 937 | 938 |
945 | Sunshine 946 | 951 | hours 952 | 954 | 962 | 968 | Not available 969 | 970 |
980 | CO2 sensor 981 | 986 | ppm 987 | 989 | 997 | 1003 | Not available 1004 | 1005 |
1018 | NO2 sensor 1019 | 1024 | ppm 1025 | 1027 | 1035 | 1041 | Not available 1042 | 1043 |
1056 | CO sensor 1057 | 1062 | ppm 1063 | 1065 | 1073 | 1079 | Not available 1080 | 1081 |
1094 | SO2 sensor 1095 | 1100 | ppb 1101 | 1103 | 1111 | 1117 | Not available 1118 | 1119 |
1132 | Ozone sensor 1133 | 1138 | ppb 1139 | 1141 | 1149 | 1155 | Not available 1156 | 1157 |
1170 | Particulate pollution 1171 | 1176 | ug/m3 1177 | 1179 | 1187 | 1193 | Not available 1194 | 1195 |
1204 | 1207 |
1208 |
1209 | 1210 |
1211 |

1212 |
1213 |
1214 | 1215 | 1277 | 1278 | 1279 | --------------------------------------------------------------------------------