-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
370 lines (340 loc) · 23.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:url" content="https://cwop.rest" />
<meta property="og:type" content="website" />
<meta property="og:title" content="cwop.rest" />
<meta property="og:description" content="An easy way to submit weather reports to the NOAA Citizen's Weather Observer Program." />
<meta property="og:image" content="https://cwop.rest/img/social.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta property="twitter:domain" content="cwop.rest" />
<meta property="twitter:url" content="https://cwop.rest" />
<meta name="twitter:title" content="cwop.rest" />
<meta name="twitter:description" content="An easy way to submit weather reports to the NOAA Citizen's Weather Observer Program." />
<meta name="twitter:image" content="https://cwop.rest/img/social.png" />
<link rel="icon" type="image/png" sizes="512x512" href="https://cwop.rest/img/512.png" />
<link rel="icon" type="image/png" sizes="192x192" href="https://cwop.rest/img/192.png" />
<link rel="icon" type="image/x-icon" href="https://cwop.rest/img/favicon.ico" />
<title>cwop.rest — An easy way to submit weather reports to CWOP</title>
<meta name="description" content="An easy way to submit weather reports to the NOAA Citizen's Weather Observer Program." />
<meta name="keywords" content="CWOP, NOAA, NWS, How To, Weather, Weather Station, PWS, Software, JavaScript, Open Source, Ham Radio, Amateur Radio, APRS" />
<meta name="author" content="Leo Herzog | herzog.tech" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.colors.min.css" />
<style>
code,
pre {
color: var(--pico-contrast);
}
.secondary {
color: var(--pico-secondary);
}
.pico-color-red-contrast {
color: var(--pico-color-red-600);
}
[data-theme='dark'] .pico-color-red-contrast {
color: var(--pico-color-red-200);
}
.pico-color-orange-contrast {
color: var(--pico-color-orange-600);
}
[data-theme='dark'] .pico-color-orange-contrast {
color: var(--pico-color-orange-200);
}
.pico-color-pumpkin-contrast {
color: var(--pico-color-pumpkin-600);
}
[data-theme='dark'] .pico-color-pumpkin-contrast {
color: var(--pico-color-pumpkin-200);
}
.pico-color-green-contrast {
color: var(--pico-color-green-600);
}
[data-theme='dark'] .pico-color-green-contrast {
color: var(--pico-color-green-200);
}
.pico-color-jade-contrast {
color: var(--pico-color-jade-600);
}
[data-theme='dark'] .pico-color-jade-contrast {
color: var(--pico-color-jade-200);
}
.pico-color-blue-contrast {
color: var(--pico-color-blue-600);
}
[data-theme='dark'] .pico-color-blue-contrast {
color: var(--pico-color-blue-200);
}
.pico-color-indigo-contrast {
color: var(--pico-color-indigo-600);
}
[data-theme='dark'] .pico-color-indigo-contrast {
color: var(--pico-color-indigo-200);
}
.pico-color-purple-contrast {
color: var(--pico-color-purple-600);
}
[data-theme='dark'] .pico-color-purple-contrast {
color: var(--pico-color-purple-200);
}
.pico-color-slate-contrast {
color: var(--pico-color-slate-600);
}
[data-theme='dark'] .pico-color-slate-contrast {
color: var(--pico-color-slate-200);
}
</style>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon='{"token": "445b2b84397047588632863154eb739d"}'></script>
</head>
<body>
<div style="position: absolute; top: 0px; left: 8px; cursor: pointer">
<span id="theme" style="font-size: 16px" aria-label="Toggle light and dark mode">☀️</span>
</div>
<div style="position: absolute; top: 0px; right: 8px">
<a href="https://github.com/leoherzog/cwop.rest" class="contrast" aria-label="cwop.rest GitHub repository">
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512" height="20px">
<path
fill="currentColor"
d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"></path>
</svg>
</a>
</div>
<header class="container" style="margin-top: 10vh; margin-bottom: 20vh">
<hgroup>
<h1 style="font-size: 400%">
<svg style="width: 5%; max-width: 50px" aria-label="A light blue logo of a lightning bolt whose top form an arrow pointing up" xmlns="http://www.w3.org/2000/svg" zoomAndPan="magnify" viewBox="0 0 127.5 352.5" preserveAspectRatio="xMidYMid" xmlns:v="https://vecta.io/nano">
<defs>
<clipPath id="A">
<path d="M129.832 23.031h124.324v337.98H129.832zm0 0" clip-rule="nonzero" />
</clipPath>
<clipPath id="B">
<path d="M129.832 23.246h115.016v337.766H129.832zm0 0" clip-rule="nonzero" />
</clipPath>
</defs>
<g transform="matrix(1.025544 0 0 1.042972 -133.14849 -24.020943)">
<g clip-path="url(#A)">
<path fill="#5ce1e6" d="M210.266 83.168l-80.598 139.918h50.254l-46.977 137.922 121.211-181.16-58.883.102 30.609-96.781h13.934L245 23.031l-.148.16.055-.16-.172.293-53.328 59.844h18.859" />
</g>
<g clip-path="url(#B)">
<path fill="#0097b2" d="M132.945 361.008l76.152-160.719h-42.48l78.117-176.965-53.328 59.844h18.859l-80.598 139.918h50.254l-46.977 137.922" />
</g>
</g>
</svg>
cwop.rest
</h1>
<h2>
An easy way to submit weather reports to the NOAA
<a href="https://en.wikipedia.org/wiki/Citizen_Weather_Observer_Program" target="_blank" class="secondary">Citizen's Weather Observer Program</a>.
</h2>
</hgroup>
</header>
<main class="container">
<article id="getting-started">
<h2>Getting Started</h2>
<p>To submit your current readings to CWOP, send an HTTP GET or POST request to <mark>send.cwop.rest</mark>.</p>
<h3>GET</h3>
<p>For example, send a single GET request like so:</p>
<p>
<mark style="word-break: break-all"
><!--
--><span>https://send.cwop.rest/</span
><!--
-->?<a style="text-decoration: none" href="https://madis.ncep.noaa.gov/cwop_signup.shtml" target="_blank"><span class="pico-color-red-contrast" style="cursor: pointer" data-tooltip="Required. Your CWOP or Ham Radio ID. Click for more info.">id=CW0001</span></a
><!--
-->&<span class="pico-color-orange-contrast" data-tooltip="Required. Your weather station's latitude in decimal degrees.">lat=38.892954</span
><!--
-->&<span class="pico-color-pumpkin-contrast" data-tooltip="Required. Your weather station's longitude in decimal degrees.">long=−‌77.0328578</span
><!--
-->&<span class="pico-color-green-contrast" data-tooltip=" Required. The time that your weather reading was taken in ISO Date or Epoch (milliseconds) format.">time=<span class="timevalue">1672531200000</span></span
><!--
-->&<span class="pico-color-jade-contrast" data-tooltip="Required. The temperature in degrees fahrenheit.">tempf=<span class="tempfvalue">73</span></span
><!--
-->&<span class="pico-color-blue-contrast" data-tooltip="Required. The wind speed in miles per hour.">windspeedmph=<span class="windspeedmphvalue">1.5</span></span
><!--
-->&<span class="pico-color-indigo-contrast" data-tooltip="Required. The wind gust in miles per hour.">windgustmph=<span class="windgustmphvalue">2.7</span></span
><!--
-->&<span class="pico-color-purple-contrast" data-tooltip="Required. The direction that the wind is coming from, 0–359 degrees.">winddir=<span class="winddirvalue">270</span></span
><!--
-->&<span class="pico-color-slate-contrast" data-tooltip="Optional. The barometer pressure in Hectopascals/Millibars.">pressure=<span class="pressurevalue">980.0</span></span
><!--
-->&<span class="pico-color-red-contrast" data-tooltip="Optional. The relative humidity from 0 to 100 percent.">humidity=<span class="humidityvalue">42</span></span
><!--
-->&<span class="pico-color-orange-contrast" data-tooltip="Optional. The solar radiation in W/m².">solarradiation=<span class="solarradiationvalue">170</span></span
><!--
-->&<span class="pico-color-pumpkin-contrast" data-tooltip="Optional. The amount of rain that has fallen over the past hour in inches.">rainin=<span class="raininvalue">0</span></span
><!--
-->&<span class="pico-color-green-contrast" data-tooltip="Optional. The amount of rain that has fallen since midnight in inches.">dailyrainin=<span class="dailyraininvalue">1.5</span></span
><!--
-->&<span class="pico-color-jade-contrast" data-tooltip="Optional. The amount of rain that has fallen over the past 24 hours in inches.">last24hrrainin=<span class="last24hrraininvalue">2.5</span></span
><!--
--></mark>
</p>
<h3>POST</h3>
<p>Or, POST a request with the following body:</p>
<pre>{
"id": "CW0001", <span class="secondary">// Required. <a href="https://madis.ncep.noaa.gov/cwop_signup.shtml" target="_blank" class="secondary">Your CWOP or Ham Radio ID.</a></span>
"lat": 38.892954, <span class="secondary">// Required. Your weather station's latitude in decimal degrees.</span>
"long": -77.0328578, <span class="secondary">// Required. Your weather station's longitude in decimal degrees.</span>
"time": "<span class="timevalue">1672531200000</span>", <span class="secondary">// Required. The time that your weather reading was taken in ISO Date or Epoch (milliseconds) format.</span>
"tempf": <span class="tempfvalue">73</span>, <span class="secondary">// Required. The temperature in degrees fahrenheit.</span>
"windspeedmph": <span class="windspeedmphvalue">1.5</span>, <span class="secondary">// Required. The wind speed in miles per hour.</span>
"windgustmph": <span class="windgustmphvalue">2.7</span>, <span class="secondary">// Required. The wind gust in miles per hour.</span>
"winddir": <span class="winddirvalue">270</span>, <span class="secondary">// Required. The direction that the wind is coming from, 0–359 degrees.</span>
"pressure": <span class="pressurevalue">980.0</span>, <span class="secondary">// Optional. The barometer pressure in Hectopascals/Millibars.</span>
"humidity": <span class="humidityvalue">42</span>, <span class="secondary">// Optional. The relative humidity from 0 to 100 percent.</span>
"solarradiation": <span class="solarradiationvalue">170</span>, <span class="secondary">// Optional. The solar radiation in W/m².</span>
"rainin": <span class="raininvalue">0</span>, <span class="secondary">// Optional. The amount of rain that has fallen over the past hour in inches.</span>
"dailyrainin": <span class="dailyraininvalue">1.5</span> <span class="secondary">// Optional. The amount of rain that has fallen since midnight in inches.</span>
"last24hrrainin": <span class="last24hrraininvalue">2.5</span> <span class="secondary">// Optional. The amount of rain that has fallen over the past 24 hours in inches.</span>
}</pre>
</article>
<article id="faq">
<details>
<summary>What is CWOP?</summary>
<p>I'll let the National Weather Service explain:</p>
<blockquote>
<p>Do you have a well-placed personal weather station at your home or business? Would you like to share your data with the world? You can if you send your data to the Citizen Weather Observing Program (CWOP)!</p>
<p>
CWOP is a volunteer-based network that allows owners of personal weather stations to share their station’s live data with the National Weather Service, emergency managers, wild land fire fighters, and Universities worldwide. There are several options to getting your data online —
inexpensive (even free) software programs, and extremely reliable, energy-efficient 'internet devices.' If you have a well-sited home weather station, and a broadband internet connection, you’re just a few steps away from contributing your data to CWOP.
</p>
<footer>
<cite>— <a href="https://www.weather.gov/cle/CWOP" target="_blank" class="secondary">https://www.weather.gov/cle/CWOP</a></cite>
</footer>
</blockquote>
<blockquote>
<p>CWOP is a public-private partnership with three goals:</p>
<ol>
<li>To collect weather data contributed by citizens.</li>
<li>To make these data available for weather services and homeland security.</li>
<li>To provide feedback to the data contributors so they have the tools to check and improve their data quality.</li>
</ol>
<p>CWOP has been sending data to MADIS (the Meteorological Assimilation Data Ingest System) since MADIS started on July 1, 2001.</p>
<footer>
<cite>— <a href="https://madis.ncep.noaa.gov/madis_cwop.shtml" target="_blank" class="secondary">https://madis.ncep.noaa.gov/madis_cwop.shtml</a></cite>
</footer>
</blockquote>
</details>
<hr />
<details>
<summary>Why does this site in particular exist?</summary>
<p>
Submitting your weather station data to CWOP is a pain, technologically. Most weather station reporting services use a simple HTTP GET request with URL parameters to submit data. By requiring a direct TCP connection, it is difficult to submit your weather data to CWOP from many contexts.
This service allows you to submit from any device that can make an HTTP request.
</p>
<p>Scattered about the official website are the instructions:</p>
<blockquote>
<p>
Each TCP connection to port 14580 will begin with receiving at least one text line from the APRS server (terminated with cr/lf). This line identifies the server software you just connected to which you can safely ignore. A line is sent from the server upon connection and upon receiving
that line, your client will send a login line. Suppose your CWOP identifier is EW9876. Your login line would be:
</p>
<p>user EW9876 pass -1 vers YourSoftwareName 1.0</p>
<p>
The CWOP identifier is the user name, the passcode is -1 (minus one), and the software identifier is your software name (no spaces) followed by the version number (containing no spaces). There is a single space between each keyword and each value. Once that is entered (terminate with
cr/lf), you will receive an acknowledgement line from the server and it can be safely ignored. After receiving the login acknowledgement, the server is ready to take the single APRS "packet" with the weather data. After the packet is sent, your client can safely disconnect from the
server. There will be no acknowledgement of the packet being received at the server (the acknowledgement is handled by the TCP underlying protocol). The APRS "packet" is also terminated by cr/lf. The APRS "packet" is a weather position packet with a very specific header:
</p>
<p>EW9876>APRS,TCPIP*:rest of packet</p>
<p>The first "callsign" is the CWOP station identifier for that station as shown. The next item is TCPIP followed by an asterisk. All capital letters must be used for the packet header. The rest of the packet follows the format specified...</p>
<footer>
<cite>— <a href="http://wxqa.com/faq.html" target="_blank" class="secondary">http://wxqa.com/faq.html</a></cite>
</footer>
</blockquote>
<p>and</p>
<blockquote>
<p>Use a server designator of "cwop.aprs.net" to send to servers (CWOP1, CWOP2, CWOP3, CWOP4) designated for CWOP non-ham use. These servers do not require a validation code or password.</p>
<p>
Use a server designator of "rotate.aprs.net" to send to the APRS Core servers (FIRST, SECOND, THIRD) or "rotate.aprs2.net" to send to the Tier 2 servers. Note that these servers require a validation code which currently licensed amateur radio operators can obtain from cwop-support at
noaa dot gov.
</p>
<p>Use port 14580 first; but if that does not work, try port 23.</p>
<footer>
<cite>— <a href="http://wxqa.com/servers2use.html" target="_blank" class="secondary">http://wxqa.com/servers2use.html</a></cite>
</footer>
</blockquote>
<p>This website abstracts all of that out, so all you have to worry about is one HTTP request.</p>
</details>
<hr />
<details>
<summary>Are you related to CWOP, Findu, or the NWS/NOAA?</summary>
<p>
Nope! This was a service I built for myself (to integrate into my
<a href="https://github.com/leoherzog/WundergroundStationForwarder" target="_blank">Apps Script Weather Station Forwarder</a>) and I thought it might be useful to others.
</p>
</details>
<hr />
<details>
<summary>How do I see my CWOP report(s) once I start sending data?</summary>
<p>Your reports will show up (with some delay) in several places:</p>
<p>
<a href="https://findu.com/" target="_blank"><button>FindU</button></a>
<a href="https://aprs.fi/weather/" target="_blank"><button>APRS.fi</button></a>
<a href="https://madis-data.ncep.noaa.gov/MadisSurface/" target="_blank"><button>MADIS Surface Data Visualizer</button></a>
<a href="https://madis.ncep.noaa.gov/" target="_blank"><button>Data Requests from the MADIS API</button></a>
</p>
</details>
<hr />
<details>
<summary>How does send.cwop.rest work? How can I trust you?</summary>
<p>This website, and the <mark>send.cwop.rest</mark> service, are open source and powered by Cloudflare Pages and Cloudflare Workers. You are free to inspect the code, or copy it into your own Cloudflare Worker and run your own instance.</p>
<a href="https://github.com/leoherzog/cwop.rest" role="button" class="">See the Source Code</a>
</details>
<hr />
<details>
<summary>I already have an APRS packet assembled from my software. Can I just submit it?</summary>
<p>
Sure! Instead of using parameters for each reading, just use a
<code>packet</code> URL parameter in your GET request or <code>packet</code> key in your JSON POST payload and we will send it along.
</p>
</details>
<hr />
<details>
<summary>What if I am using my Ham Radio callsign and have a validation code?</summary>
<p>Just include a <code>validation</code> URL parameter in your GET request or <code>validation</code> key in your JSON POST payload and we will send your packet to the correct Ham-only CWOP server using your validation code.</p>
</details>
<hr />
<details>
<summary>What if I want to submit to a custom CWOP server, such as the "Tier 2 servers" or one specific CWOP server?</summary>
<p>Just include a <code>server</code> URL parameter in your GET request or <code>server</code> key in your JSON POST payload and we will send your packet to your specified server instead of the defaults.</p>
</details>
</article>
</main>
<script>
function getRandomNumber(min, max, decimalPlaces) {
return Number((Math.random() * (max - min) + min).toFixed(decimalPlaces));
}
document.addEventListener('DOMContentLoaded', function () {
document.documentElement.dataset.theme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
document.getElementById('theme').innerText = document.documentElement.dataset.theme === 'dark' ? '☀️' : '🌙';
document.getElementById('theme').addEventListener('click', (e) => {
document.documentElement.dataset.theme = document.documentElement.dataset.theme === 'dark' ? 'light' : 'dark';
e.srcElement.innerText = document.documentElement.dataset.theme === 'dark' ? '☀️' : '🌙';
});
let time = Math.random() > 0.5 ? new Date().toISOString() : new Date().getTime();
let tempf = getRandomNumber(0, 100, 0);
let windspeedmph = getRandomNumber(0, 10, 1);
let windgustmph = windspeedmph + getRandomNumber(0, 10, 0);
let winddir = getRandomNumber(0, 359, 0);
let pressure = getRandomNumber(970, 1050, 1);
let humidity = getRandomNumber(10, 100, 0);
let solarradiation = getRandomNumber(0, 1000, 0);
let rainin = getRandomNumber(0, 2, 1);
let dailyrainin = Number(getRandomNumber(0, 10, 1) + Number(rainin)).toFixed(1);
let last24hrrainin = Number(getRandomNumber(0, 10, 1) + Number(dailyrainin)).toFixed(1);
Array.from(document.getElementsByClassName('timevalue')).forEach((x) => (x.innerText = time));
Array.from(document.getElementsByClassName('tempfvalue')).forEach((x) => (x.innerText = tempf));
Array.from(document.getElementsByClassName('windspeedmphvalue')).forEach((x) => (x.innerText = windspeedmph));
Array.from(document.getElementsByClassName('windgustmphvalue')).forEach((x) => (x.innerText = windgustmph));
Array.from(document.getElementsByClassName('winddirvalue')).forEach((x) => (x.innerText = winddir));
Array.from(document.getElementsByClassName('pressurevalue')).forEach((x) => (x.innerText = pressure));
Array.from(document.getElementsByClassName('humidityvalue')).forEach((x) => (x.innerText = humidity));
Array.from(document.getElementsByClassName('solarradiationvalue')).forEach((x) => (x.innerText = solarradiation));
Array.from(document.getElementsByClassName('raininvalue')).forEach((x) => (x.innerText = rainin));
Array.from(document.getElementsByClassName('dailyraininvalue')).forEach((x) => (x.innerText = dailyrainin));
Array.from(document.getElementsByClassName('last24hrraininvalue')).forEach((x) => (x.innerText = last24hrrainin));
});
</script>
</body>
</html>