radiacode_docker_usb/webserver.html
2023-07-05 16:14:47 +03:00

301 lines
13 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html>
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-GBWL3K2WMQ"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());
gtag('config', 'G-GBWL3K2WMQ');
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Київ неРадіоактивний! Проект dead.guru</title>
<meta name="description" content="неРадіоактивна ситуація в Києві в реальному часі. Спектр, події, радіаційний фон.">
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-apexcharts"></script>
<link rel="shortcut icon" href="https://kmr.gov.ua/sites/default/files/favicon-kyiv.ico"
type="image/vnd.microsoft.icon" />
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.4/css/bulma.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.15.4/js/all.js"
integrity="sha384-rOA1PnstxnOBLzCLMcre8ybwbTmemjzdNlILg8O7z1lUkLXozs4DHonlDtnE7fpc"
crossorigin="anonymous"></script>
<style>
#app>div {
margin: 5px auto;
width: 80%;
}
#app fieldset {
display: inline-block;
border: 0;
padding: 0;
margin-left: 20px;
}
#app>.notification {
border: none;
}
#map {
height: 180px;
width: 80%;
margin: 5px auto;
}
</style>
</head>
<body>
<section class="section">
<div class="container">
<div id="app">
<nav class="navbar is-transparent">
<div class="navbar-brand">
<a class="navbar-item" href="https://kyiv.dead.guru">
<img src="https://assada.dead.guru/storage/images/logo.png" alt="Bulma: a modern CSS framework based on Flexbox" width="112" height="28">
<div><span style="opacity: .9; color: #17914a; font-size: x-small;">не</span><span
style="font-size: x-small;">Радіоактивний!</span></div>
</a>
<div class="navbar-burger" @click="showNav = !showNav" :class="{ 'is-active': showNav }">
<span></span>
<span></span>
<span></span>
</div>
</div>
<div class="navbar-menu" :class="{ 'is-active': showNav }">
<div class="navbar-start">
<a class="navbar-item" href="https://www.saveecobot.com/radiation-maps">
Мапа датчиків
</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#nav">
Корисні посилання
</a>
<div class="navbar-dropdown is-boxed">
<a class="navbar-item" href="https://www.windy.com/?50.321,30.504,9">
Мапа вітрів
</a>
<a class="navbar-item" href="https://bit.ly/3efbPmc">
Мапа укриттів
</a>
</a>
<a class="navbar-item" href="https://alerts.in.ua/">
Мапа тривог
</a>
<a class="navbar-item" href="https://bit.ly/3egOosD">
Поради від РНБО
</a>
<a class="navbar-item"
href="https://dmbk.kyivcity.gov.ua/content/dii-u-vypadku-zagrozy-vynyknennya-avarii-z-vykydom-rozlyvom-radioaktyvnyh-rechovyn.html">
Поради від департаменту муніципальної безпеки
</a>
</div>
</div>
</div>
<div class="navbar-end">
<div class="navbar-item">
<div class="field is-grouped">
<p class="control">
<a class="bd-tw-button button" data-social-network="Twitter" data-social-action="tweet"
data-social-target="https://bulma.io" target="_blank"
href="https://twitter.com/intent/tweet?text=Київ неРадіоактивний! Перевірити можна на &amp;hashtags=КиївНеРадіоактивний&amp;url=https://kyiv.dead.guru">
<span class="icon">
<i class="fab fa-twitter"></i>
</span>
<span>
Tweet
</span>
</a>
</p>
</div>
</div>
</div>
</div>
</nav>
<div v-if="al" class="notification is-warning">
<button class="delete" @click="al = !al"></button>
Використовуйте ландшафтну орієнтацію екрану для зручного перегляду. Ще краще — планшет чи комп'ютер.
</div>
<div style="text-align: center;">
<apexchart type="line" height="350" :options="ratesChartOptions" :series="rates_series"></apexchart>
<button @click="rates_autoupdate = !rates_autoupdate" class="button">Автооновлення: {{ rates_autoupdate ?
"ВКЛ" : "ВИКЛ" }}</button>
</div>
<div class="notification">
<strong>До 0,3 мк3в/г — нормальний радіаційний фон.</strong>
<p>
Швидкість дози в мікрозівертах на годину вказує, скільки мікрозівертів (одиниця виміру еквівалентної дози)
радіації поглинається організмом або матеріалом за одну годину. Ця величина може використовуватися для
оцінки рівня радіаційного впливу на людей, а також для моніторингу і контролю радіаційної безпеки в
радіаційних зонах, ядерних установках або природному середовищі.
</p>
<p>
Наприклад, якщо швидкість дози становить 10 μSv/h, це означає, що організм або матеріал отримує дозу 10
мікрозівертів радіації за кожну годину. Це може вказувати на наявність джерела радіації в цьому місці або на
необхідність заходів з радіаційного захисту.
</p>
</div>
<div style="text-align: center;">
<apexchart type="bar" height="350" :options="spectrumChartOptions" :series="spectrum_series"></apexchart>
<div>
<fieldset>
<label class="checkbox" for="spectrum_x_accum"><input type="checkbox" id="spectrum_x_accum"
v-model="spectrum_accum"> Акумульований</label>
</fieldset>
<fieldset class="control">
<label class="radio" for="spectrum_x_channel"><input type="radio" id="spectrum_x_channel"
v-bind:value="false" v-model="spectrum_energy"> Канал</label>
<label class="radio" for="spectrum_x_energy"><input type="radio" id="spectrum_x_energy"
v-bind:value="true" v-model="spectrum_energy"> Енергія</label>
</fieldset>
<fieldset class="control">
<label class="radio" for="spectrum_linear"><input type="radio" id="spectrum_linear" v-bind:value="false"
v-model="spectrum_logarithmic"> Лінійне</label>
<label class="radio" for="spectrum_log"><input type="radio" id="spectrum_log" v-bind:value="true"
v-model="spectrum_logarithmic"> Логарифмічне</label>
</fieldset>
</div>
<button @click="updateSpectrum" class="button">Оновити спектр</button>
</div>
</div>
<div id="map"></div>
</div>
</section>
<footer class="footer">
<div class="content has-text-centered">
<p>Важливо зазначити що явище радіоактивності не можна застосувати(вживати в контексті) до міста. Прочитати більше можна на <a href="https://uk.wikipedia.org/wiki/%D0%A0%D0%B0%D0%B4%D1%96%D0%BE%D0%B0%D0%BA%D1%82%D0%B8%D0%B2%D0%BD%D1%96%D1%81%D1%82%D1%8C">Вікі</a>!</p>
<p>
Частина проекту <a href="https://dead.guru/"><strong>dead.guru</strong></a>. Код ліцензований
<a href="http://opensource.org/licenses/mit-license.php">MIT</a>. Вміст сайту
має ліцензію <a href="http://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY NC SA 4.0</a>.
</p>
</div>
</footer>
<script>
const common_options = {
chart: {
animations: { enabled: false },
zoom: { autoScaleYaxis: true },
},
tooltip: { intersect: false },
grid: { xaxis: { lines: { show: true } } },
dataLabels: { enabled: false },
};
var app = new Vue({
el: '#app',
components: {
apexchart: VueApexCharts,
},
data: function () {
return {
ws: null,
spectrum_duration: 0,
rates_autoupdate: true,
al: true,
showNav: false,
rates_series: [],
spectrum_accum: false,
spectrum_series: [],
spectrum_coef: [0, 0, 0],
spectrum_logarithmic: true,
spectrum_energy: true,
ratesChartOptions: {
...common_options,
title: { text: 'Активнсть подій (подій в секунду) і доза' },
xaxis: { type: 'datetime' },
yaxis: [
{ seriesName: 'Подій', title: { text: 'ПНС' }, labels: { formatter: (v) => v.toFixed(2) + ' ПНС' } },
{ seriesName: 'Доза', title: { text: 'мк3в/г' }, labels: { formatter: (v) => v.toFixed(4) + ' мк3в/г' }, opposite: true },
],
},
};
},
watch: {
spectrum_accum() {
this.updateSpectrum();
},
al(newAl) {
localStorage.al = newAl === true ? "ok!" : "no";
}
},
computed: {
spectrumChartOptions() {
const a0 = this.spectrum_coef[0], a1 = this.spectrum_coef[1], a2 = this.spectrum_coef[2];
const fmt = this.spectrum_energy ? ((c) => (a0 + a1 * c + a2 * c * c).toFixed(0)) : undefined;
const title = this.spectrum_energy ? 'кеВ' : 'канал';
return {
...common_options,
title: { text: `Спектр, ${this.spectrum_duration} секунд` },
xaxis: { type: 'numeric', title: { text: title }, tickAmount: 25, labels: { formatter: fmt } },
yaxis: { logarithmic: this.spectrum_logarithmic, decimalsInFloat: 0 },
plotOptions: { bar: { columnWidth: '95%' } },
};
},
},
created() {
this.ws = new WebSocket('wss://' + window.location.host + '/ws')
this.ws.onmessage = this.onmessage;
this.updateSpectrum();
var map = L.map('map').setView([50.51847778550632, 30.508852993206236], 10);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 10,
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
}).addTo(map);
var circle = L.circle([50.51847778550632, 30.508852993206236], {
color: '#164299',
weight: 1,
opacity: 0.7,
fillColor: '#256FFF',
fillOpacity: 0.2,
radius: 5000
}).addTo(map);
circle.bindPopup("Зона виміру");
},
beforeDestroy: function () {
this.ws.close();
},
mounted() {
if (localStorage.al) {
this.al = localStorage.al === "ok!";
}
},
methods: {
onmessage(ev) {
if (!this.rates_autoupdate) {
return;
}
const d = JSON.parse(ev.data);
this.rates_series = d.series;
},
updateSpectrum() {
fetch(`/spectrum?accum=${this.spectrum_accum}`)
.then(response => response.json())
.then(data => (this.spectrum_duration = data.duration, this.spectrum_coef = data.coef, this.spectrum_series = data.series));
},
},
});
</script>
</body>
</html>