Skocz do zawartości
SOYER

Arduino MEGA i BLYNK, LCD odchodzi do lamusa...

Pomocna odpowiedź

Bardzo ładnie - pomyśl o kilku wykresach jednocześnie (fajnie by było znać np. korelację temperatury i gęstości pyłu).

Odczytywanie głosowe zostaw screenreaderowi, tylko go poinformuj że tak trzeba. Do tego służy ARIA (czyli zestaw dodatkowych atrybutów rozumianych przez technologie wspomagające). Krótko i po polsku masz opisane tutaj: http://saccessibility.pl/aria-role-wlasciwosci/

Coś takiego jak div w którym ukazują różne ciekawe rzeczy jest w terminologii ARIA określane mianem "region".  Domyślnie czytana jest cała zawartość przy jakiejkolwiek zmianie treści, warto jedynie określić w jaki sposób będzie to czytane. Atrybut aria-live może przyjąć jedną z trzech możliwości:

"off" - nic nie będzie czytane. Dobre do różnego typu zegarkóœ, bannerów ze zmienną treścią i innych wydmuszek których odczytywanie po prostu by przeszkadzało;

"polite" - zmiana będzie odczytana wtedy, kiedy screenreader już powie co miał do powiedzenia.

"assertive" - zmiana będzie odczytana natychmiast.

W tym przypadku należy uzyć assertive, tak więc deklaracja diva wyświetlającego wyniki będzie wyglądać mniej więcej tak:

<div id="wyniki" role="region" aria-live="assertive">

Jeśli teraz zainstalujesz sobie na kompie np. NVDA zobaczysz, że po klepnięciu w link z czujnikiem NVDA odczyta pokazujący się w divie wynik.

Tu jedna uwaga: większość frameworków używa "display:none" lub "visibility:hidden" aby ukryć jakiś element (np. zwinięte menu). Niestety - taki zabieg ukrywa zawartość różnież przed screenreaderem, co raczej nie ułatwia nawigacji (użytkownik z reguły zaczyna przeglądanie strony od listy linków, a tych tam nie ma...). Jest na to sposób - poszukaj w sieci klasy screen-reader-text, która ukrywa element przed wzrokiem użytkownika a jednocześnie umożliwia screenreaderowi dostęp do treści. Oprócz różnych chowających się i pojawiających menu bardzo często stosuje się to w formularzach, np:

<label for="nazwisko" class="obowiazkowy">Nazwisko <span class="screen-reader-text">pole obowiązkowe</span></label>

W ten sposób widzący użytkownik zobaczy etykietę oznaczoną jako obowiązkowa (pewnie jakąś grafiką albo innym kolorem), niewidomy usłyszy "nazwisko pole obowiązkowe".

Fajne, nie? 🙂

A jak tam Twoje menu, screenreader wygra czy się podda?

 

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Siedzę dzisiaj nad impelmentacją tego kalendarzowego wybierania okresu i wartości max, min i srednia. 

Na razie kombinuję nad zapytaniami do bazy, bo raczej muszę to zrobić na nowym skrypcie PHP.

Takie zapytanie wydaje się działać, ale jest to na tyle zagnieżdżone, że wolę zapytać czy nie ma jakiegoś kardynalnego błędu w rozumowaniu:

SELECT czas, cisnienie FROM mega WHERE ((czas > "2019-02-02") && (czas < "2019-02-14") && (cisnienie = (SELECT min(cisnienie)))) order by czas desc limit 1
SELECT avg(cisnienie) FROM mega WHERE ((czas > "2019-02-02") && (czas < "2019-02-03"))

lub

SELECT czas, cisnienie FROM mega WHERE ((czas > DATE(DATE_SUB(NOW(), INTERVAL 7 DAY))) && (cisnienie = (SELECT MIN(cisnienie)))) order by czas desc limit 1
SELECT avg(cisnienie) FROM mega WHERE (czas > DATE(DATE_SUB(NOW(), INTERVAL 7 DAY)))

??

Edytowano przez SOYER

Udostępnij ten post


Link to post
Share on other sites

bez zagnieżdżania

select cisnienie, czas from mega where czas between t1 and t2 order by cisnienie, czas desc limit 1

to na minimum, na maximum przy ciśnieniu dasz desc w order by. zwróci ciśnienie i ostatni czas. oczywiście w miejsce t1 i t2 podstawiasz co trzeba (w apostrofach!!!).

twoje zapytanie nie będzie działać, jeśli minimalne ciśnienie było poza okresem (brak where w podzapytaniu).

przy okazji - between kompiluje się na taki sam kod jak dwa porównania, ale wygląda ładniej i jest krótsze 🙂

  • Pomogłeś! 1

Udostępnij ten post


Link to post
Share on other sites

ok, 

28 minut temu, ethanak napisał:

twoje zapytanie nie będzie działać, jeśli minimalne ciśnienie było poza okresem (brak where w podzapytaniu).

czyli jeśliby stosować mój przykład to powinno być tak:

SELECT czas, cisnienie FROM mega WHERE ((czas > DATE(DATE_SUB(NOW(), INTERVAL 7 DAY))) && (cisnienie = (SELECT MIN(cisnienie)where czas > DATE(DATE_SUB(NOW(), INTERVAL 7 DAY))))) orderby czas desc limit 1

 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

nie jestem pewien (ślepowaty jestem i liczenie nawiasów na telefonie absolutnie nie jest moim hobby) ale coś podobnego powinno zadziałać.

problem taki, że ty dwa razy przeszukujesz okres (okres jest co prawda wyznaczony przez indeksy, ale ciśnienie już nie) a ja tylko raz.

sprawdź co powie explain w obu przypadkach.

Edytowano przez ethanak

Udostępnij ten post


Link to post
Share on other sites

Działać działa, bo sprawdzam na bieżąco, po prostu próbuję zrozumiec zależności....

Udostępnij ten post


Link to post
Share on other sites

do tego właśnie służy explain.

"sprawdzam na bieżąco" to takie trochę mylące, bo sprawdzasz, działa, implementujesz, a potem się okazuje że działa ale tylko czasami (z reguły przy sprawdzaniu).

Udostępnij ten post


Link to post
Share on other sites

a co to ten explain... co tłumaczy;)? 

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

tłumaczy to co robi planer (czyli takie cóś, co w sql-owych bazach układa sobie plan wykonania twojego zapytania).

po prostu w konsoli zamiast "select cośtam" wpisz "explain select cośtam".

tu masz:

https://x-coding.pl/blog/developers/mysql-explain-uzywac-czytac/

Edytowano przez ethanak

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Zrobiłem ten max min i srednią. Najwięcej czasu zajęło mi opanowanie pokolorowania wkładanych przez jquery zmiennych, tak by podświetlały się na czerwono....

ach te nawiasy i przecinki...

Zrobilem kolejne trzy skrypty php z zapytaniami:

$sqlOdczyt="SELECT min(${czujnik}) FROM ${base} WHERE czas > DATE(DATE_SUB(NOW(), INTERVAL ${okres} DAY))";
$sqlOdczyt="SELECT max(${czujnik}) FROM ${base} WHERE czas > DATE(DATE_SUB(NOW(), INTERVAL ${okres} DAY))";
if($polaczenie->connect_errno!=0){
    die("Error: ".$polaczenie->connect_errno."Opis: ".$polaczenie->connect_error);
}
      $typ = $polaczenie->real_escape_string($typ);
      $sqlOdczyt="SELECT avg(${czujnik}) FROM ${base} WHERE czas > DATE(DATE_SUB(NOW(), INTERVAL ${okres} DAY))";
      $odczyt=$polaczenie->query($sqlOdczyt);
      while($row = $odczyt->fetch_row()){
      $result[] = $row;
      }
      
    echo json_encode($result);
?>

ten ostatni to średnia, jak sprawić by wartość przesyłana miała tylko np. dwa miejsca po przecinku?

EDIT: funkcja round() w kwerendzie chyba będzie najlepszym rozwiązaniem. 

skrypt od wykresów i wartości max/min/srednia:

function okresCzujnik() {
  var okres = $( "#okres" ).val();
  var czujnik = $( "#czujnik" ).val();
  
    if (czujnik == "cisnienie"){var m = "hPa";var b = "mega";}
    else if (czujnik == "wilgZew"){var m = "%RH";var b = "mega";}
    else if ((czujnik == "tempZew")||(czujnik == "tempGrunt")||(czujnik == "tempSlonce")){var m = "°C";var b = "mega";}
    else if((czujnik == "pm1") || (czujnik == "pm2") || (czujnik == "pm10")){ var b = "pms";var m = "µg/m³";}
  
 $.ajax({url: "getMin.php", dataType: 'json', data:{b: b, c: czujnik, o: okres}, success: function(res){
            $("#min").html('Wartość <span style="color:red;">minimalna</span> dla wybranego okresu i parametru wynosi: <span style="color:red;font-weight:bold;">'+res+' '+m+'</span>');
            
            }});
$.ajax({url: "getSred.php", dataType: 'json', data:{b: b, c: czujnik, o: okres}, success: function(res){
            $("#srednia").html('Wartość <span style="color:red;">średnia</span> dla wybranego okresu i parametru wynosi: <span style="color:red;font-weight:bold;">'+res+' '+m+'</span>');
            }});
$.ajax({url: "getMax.php", dataType: 'json', data:{b: b, c: czujnik, o: okres}, success: function(res){
            $("#max").html('Wartość <span style="color:red;">maksymalna</span> dla wybranego okresu i parametru wynosi: <span style="color:red;font-weight:bold;">'+res+' '+m+'</span>');
            }});
 
 $.ajax({url: "getChart.php", dataType: 'json', data:{b: b, c: czujnik, o: okres}, success: function(res){
                wykres(res, "Wykres "+okres+"-dniowy", '#wykresy', m);
            }});
}
$( "select" ).change(okresCzujnik);

 

Edytowano przez SOYER

Udostępnij ten post


Link to post
Share on other sites
(edytowany)
 if (czujnik == "cisnienie"){var m = "hPa";var b = "mega";}
    else if (czujnik == "wilgZew"){var m = "%RH";var b = "mega";}
    else if ((czujnik == "tempZew")||(czujnik == "tempGrunt")||(czujnik == "tempSlonce")){var m = "°C";var b = "mega";}
    else if((czujnik == "pm1") || (czujnik == "pm2") || (czujnik == "pm10")){ var b = "pms";var m = "µg/m³";}

Wywal to i w ogóle wszystkie informacje o bazie danych z javascriptu (nie wspominałem przypadkiem o tym?) i wrzuć do skryptu w PHP. Poza tym zamiast bandy nieczytelnych ifów zrób tablicę (nie wspominałem przypadkiem o tym?). Przesyłasz jeden parametr czujnik.

Tak przy okazji: przecież przesyłasz dane o całym okresie - po co jeszcze liczysz min/max/średnia w bazie, kiedy masz wszystko co pozwoli policzyć to w javascripcie? Rozumiem, że gdyby to było jedno zapytanie ajaxowe to jeszcze ujdzie. Ale cztery??? Zrób to porządnie, jednym wywołaniem skryptu który zwraca obiekt zawierający wszystko co potrzebne.

A przy okazji: do formatowania liczb (i nie tylko) w PHP służy... no zgaduj... zgaduj... o właśnie, sprintf! 🙂

Edytowano przez ethanak

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Do strony internetowej jeszcze wrócę. Napiszę tylko, że jestem zmuszony rozbudować mój system o monitoring poziomu paliwa w zasobniku pieca przy pomocy kursowego czujnika ultradźwiękowego, oraz uruchomić regulator pokojowy tegoż pieca na moim systemie. Regulator już działa... tak jak standardowy prosty regulator pokojowy, porównuje temperaturę zadaną z pokojową, bierze poprawkę na histetezę i steruje wejściem zwarciowym w sterowniku kotła, obniżając w razie potrzeby temperaturę wody w instalacji. Do czujnika poziomu paliwa i temperatur "około piecowych" zrobiona kabelkologia, zostało programowanie;). 

No i zrobiłem też sterowanie bramą wjazdową, plus krańcówkaz z powiadomieniem o otwarciu, plus Google Assistant. 

 

Edytowano przez SOYER
  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites

Skończyłem dzisiaj sprawę czujnika poziomu węgla. Działa:). Pozostała mi sprawa stabilizacji odczytów czujników TMP36 i podłączenie w innym miejscu czujnika salonowego. 

Fotki czujnika poziomu paliwa :

IMG_20190517_182902.jpg IMG_20190517_182914.jpg IMG_20190517_195748.jpg

IMG_20190517_195548.jpg IMG_20190517_195602.jpg

Screenshot_20190517-195628.jpg Screenshot_20190517-200056.jpg

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Mała errata do czujnika poziomu węgla. Przy pełnym zbiorniku czujnikowi zdarzało się mieć pewien rozrzut w odczytach, jeśli węgiel był w odległości 2-3 cm nawet wariacje... Pomyślałem, że może problemem jest kształt i struktura brył, które dziwnie odbijają ultradźwięki i czujnik łapie echo po kilku "rykoszetach". Chyba miałem rację, bo rozwiązaniem okazała się... kartka papieru położona na węglu. Teraz odczyty pewne i stabilne. 

  • Lubię! 1

Udostępnij ten post


Link to post
Share on other sites

Ładnie 🙂 

Te najtańsze czujniki ultradźwiękowe działają niby od 2 cm, ale to jest dość optymistyczne założenie - często przy małej odległości jest spory rozrzut w pomiarach. Jednak w tym wypadku, tak jak sam napisałeś, największym problemem jest pewnie kształt węgla i ogólny fakt pomiaru w małej komorze.

Udostępnij ten post


Link to post
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »

×