torek, 20. oktober 2015

Generiranje QR kode v PL/SQL-u

Vse bolj pogosto "QR kodo", je mogoče generirati tudi s pomočjo PL/SQL-a na podatkovni bazi Oracle na kateri je nameščena vsaj Java verzija 1.5 navzgor.

Za delovanje je potrebno predhodno naložiti tri jar datoteke s pomočjo orodja Loadjava.
Jar datoteke dobite na tem naslovu: knjiznice.zip.
Datoteke odzipajte v neko mapo ter jih naložite v podatkovno bazo:


V pl/sql-u je nato potrebno napisati java sored "funkcijo" katera bo sprejemala tekst, ki ga bo qrkoda vsebovala ter vračala kodo kot GIF sličico shranjeno v BLOB podatkovnem tipu.

       
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "QRCodeBean" as
import oracle.sql.BLOB;  
import oracle.sql.*;  
import oracle.jdbc.driver.*;  
import java.sql.*;  
import javax.imageio.ImageIO;  
import java.awt.image.BufferedImage;  
import java.io.ByteArrayOutputStream;  
import java.io.File;  
import java.io.FileOutputStream;  
import java.io.OutputStream; 
import java.io.*;
import java.util.*;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType; 

public class QRCodeGenerator{  

public static BLOB getQrCode(String value) throws Exception  
{  
    OracleDriver ora = new OracleDriver();  
    Connection conn = ora.defaultConnection();  
    BLOB retBlob = BLOB.createTemporary(conn, true, oracle.sql.BLOB.DURATION_SESSION);  
  
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            out = net.glxn.qrgen.QRCode.from(value).to(ImageType.GIF).stream();
              
            try {  
                java.io.OutputStream outStr = retBlob.setBinaryStream(0);  
                outStr.write(out.toByteArray());  
                outStr.flush();  
            } finally {  
                out.close();  
            }  
           return retBlob;  
}  
}
/    
       

Poleg java stored procedure je potrebno napisati še funkcijo, ki bo klicala zgornjo kodo
       
CREATE OR REPLACE function INSURANCE2.getQRcode(p_text in varchar2) return BLOB as LANGUAGE JAVA  
NAME 'QRCodeGenerator.getQrCode(java.lang.String) return oracle.sql.BLOB';
/

S klicem funkcije se izvede generiranje QR kode.


več o QR kodah dobite tudi tukaj ;)


petek, 25. september 2015

FURS - Finančni urad Republike Slovenije - podpisovanje XML datotek v Javi - davčno potrjevanje računov

"Državni zbor RS je 15. julija 2015 sprejel  Zakon o davčnem potrjevanju računov, ki se bo začel uporabljati 2. januarja 2016.
Sprejet je sistem, v katerem bodo blagajne zavezancev preko spleta povezane s centralnim informacijskim sistemom Finančne uprave RS. Finančna uprava bo potrdila in shranila podatke o računih pri gotovinskem poslovanju v postopku njihove izdaje v realnem času. Postopek davčnega potrjevanja računov skupaj z veljavnima členoma 38. in 31. a  Zakona o davčnem postopku tvori sistem, ki bo omogočal sledljivost in učinkovitost nadzora nad izdanimi računi ter omejil sivo ekonomijo.
Zavezanec bo moral ob vsaki dobavi blaga in storitev za plačilo z gotovino izdati račun prek elektronske naprave, ki izpolnjuje predpisane pogoje in omogoča izvedbo postopka potrjevanja računa, in ga izročiti kupcu blaga oziroma naročniku storitve. Račun bo moral izdati najpozneje, ko je opravljena dobava in prejeto plačilo z gotovino."

Pri podpisovanju sem uporabil Java 1.6 verzijo, saj moram podpisovanje XML dokumentov omogočiti v podatkovni bazi Oracle preko Java stored procedur.

Za podpisovanje dokumenta je potrebno pridobiti testni nato pa produkcijski certifikat.
FURS na zahtevo izda testni certifikat v obliki p12.

!!! Opozorilo !!! V kolikor boste izhodni xml pregledovali v orodju kot je xmlspy ter ga nato poslali preko orodja soapui na FURS bo po vsej verjetnosti prišlo do napake ujemanja digitalnega potrdila. Zato je najbolje, da vzamete xml, ki nastane v izhodni datoteki  ter to pošljete preko SOAP-ui-ja.



import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.net.URL;

import java.security.*;
import java.security.cert.X509Certificate;
import java.util.*;
import javax.xml.XMLConstants;


import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.w3c.dom.*;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;


public class SignFileExample {

    
    

    public static void main(String[] args) throws Exception {
        String referenceURI = null;
        List transforms = null;

        String xml = "Tukaj vnesite vaš xml "
        String outputFile = "c:/podpisan.xml";

        // Instantiate the document to be signed
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        Document doc = (Document) dbFactory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));

        //podpišemo le določen node znotraj XML-ja
        Node node = doc.getElementsByTagName("fu:BusinessPremiseRequest").item(0);
     
        KeyStore p12 = KeyStore.getInstance("pkcs12");
        //iz diska naložimo certifikat v p12 obliki 
        p12.load(new FileInputStream("c:/cert/certifikatfursa.p12"), "GESLO".toCharArray());
        Enumeration e = p12.aliases();
        String alias = (String) e.nextElement();
        System.out.println("Alias certifikata:" + alias);
        Key privateKey = p12.getKey(alias, "GESLO".toCharArray());

        KeyStore.PrivateKeyEntry keyEntry
                = (KeyStore.PrivateKeyEntry) p12.getEntry(alias, new KeyStore.PasswordProtection("GESLO".toCharArray()));

        X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

        PublicKey publicKey = cert.getPublicKey();

        final XMLSignatureFactory sigFactory = XMLSignatureFactory.getInstance("DOM");
        Referenciramo se na Id="#data", ki je v <fu:BusinessPremiseRequest>
        Reference ref = sigFactory.newReference("#data",
                sigFactory.newDigestMethod(DigestMethod.SHA256, null),
                Collections.singletonList(sigFactory.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null)),
                null,
                null);
        SignedInfo si = sigFactory.newSignedInfo(sigFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec) null), sigFactory.newSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", null), Collections.singletonList(ref));

        // Create a KeyValue containing the RSA PublicKey 
        KeyInfoFactory keyInfoFactory = sigFactory.getKeyInfoFactory();
        X509IssuerSerial x509IssuerSerial = keyInfoFactory.newX509IssuerSerial(cert.getSubjectX500Principal().getName(), cert.getSerialNumber());

        List x509Content = new ArrayList();

        x509Content.add(cert.getSubjectX500Principal().getName());
        x509Content.add(x509IssuerSerial);

        KeyValue keyValue = keyInfoFactory.newKeyValue(publicKey);
        X509Data xd = keyInfoFactory.newX509Data(x509Content);

        KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(xd));

        DOMSignContext dsc = new DOMSignContext(
                privateKey,
                node
        );

        XMLSignature signature = sigFactory.newXMLSignature(si, keyInfo);

        signature.sign(dsc);

        
        OutputStream os = new FileOutputStream(outputFile);
        Transformer trans = TransformerFactory.newInstance()
                .newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));
       

    }

    private static void usage() {
        System.out.println("Usage: java SignFile   [id|path|whole]");
    }
}

nedelja, 14. junij 2015

Sinhronizator upljinačev po domače


Nastavitev ali sinhronizacija uplinjačev je eden ključnih elementov za pravilno delovanje motorja. Nepravilno nastavljeni uplinjači povzročajo nepravilno delovanje motorja. Posledica so večja poraba ter tresenje motorja.
Sam sem lastnik trinajst let starega izvenkrmnega motorja Yamaha F80, kateri vsebuje štiri uplinjače. Ne spomnem se točno ali je na servisu bila kdaj opravljena sinhronizacija uplinjačev zato sem se odločil, da sinhronizator izdelam sam in zadevo testiram ter sinhroniziram. Težava je tudi ta, da večina "mojstrov" zadevo nastavi na "uho"  (po občutku) vendar to ni to..

Pri svojem testiranju sem za potrebe sinhronizatorja izdelal tri sinhronizatorje vendar sem na koncu uporabil tretjega - najcenejšega.

Prva izvedba sinhronizatorja je bila iz pvc cevk notranjega premera 5mm ter zunanjega premera 8mm. Potreboval sem dva T člena ter okrog pet metrov pvc cevi.
Za pričvrstitev PVC cevk na kolektor motorja sem v merkurju kupil varilne šobe, ki imajo navoj M6 te pa sem nato privil v kolektor (slika spodaj označena s puščicami).
Na varilne šobe sem nato nataknil konce pvc cevi.

Prostor na kolektorju kamor privijemo šobe

Prvotna izvedba sinhronizatorja je nekakšna "U" vaga (vaser vaga), ki deluje na principu podtlaka, ki ga ustvarjajo bati v motorju, ko sesajo mešanico goriva.
Različno nastavljeni uplinjači posledično povzročajo večji ali manjši dotok goriva in s tem večji ali manjši podtlak.
Neenakomerno nastavljeni uplinjač bo tako povzročil neenakomerno delovanje motorja, kar bo povzročalo tresljaje.
Kadar so uplinjači pravilno nastavljeni takrat je podtlak na vseh štirih uplinjačih približno enak in tekočina v pvc ceveh bo takrat v ravnovesju kar pomeni, da bo tudi motor enakomerno deloval.

1.) Prva izvedba sinhronizatorja izgleda takšna:
Sinhronizator s pomočjo pvc cevi v katerih je hidravlično olje

Slabost pri takšnem sinhronizatorju je ta, da v kolikor so uplinjači slabo nastavljeni nam bo hitro v  motoro po eni izmed cevk potegnilo olje. S tem instrumentom nisem uspel ustrezno nastaviti uplinjača zato sem ga kmalu opustil.

2.) Druga izvedba uplinjača je bila ideja o analogno digitalnem pretvorniku. Za ta projekt sem uporabil DCDuino Mega 2560 ,štiri A/D pretvornike podtlaka ter modul za blue tooth.
Cena takšnega projekta je okrog 60 eur kar pa je cenovno že kar velik strošek. Sestavil sem provizorično vezje ter spisal program v orodju za Arduino. Program je enostaven. Uporablja se 10 bitni A/D pretvornik, ki v neskončni zanki beleži digitalne vrednosti vsakega senzorja ter po prebranih 50 meritvah izračuna povprečje podtlaka ter podatke po RS232 ali BlueTooth pošlje v zunanjo napravo.
Grafični vmesnik sem razvil za Android telefon saj sem imel v mislih takšno napravo, da bi jo lahko držal v rokah medtem ko bi z drugo roko nastavljal posamezni uplinjač. 
Inspiracijo za to sem imel že prej v glavi vendar sem tudi na spletu opazil podoben projekt, vendar je program napisan le za PC platformo (http://www.instructables.com/id/Arduino-Throttle-Body-Syncronization-Shield/) . 

DCDuino, 4 A/D pretvorniki podtlaka + Bluetooth modul
Aplikacija za prikaz podtlaka na android telefonu
3.) Tretja izvedba je podobna prvi vendar narejena iz štirih stekleničk za olivno olje, štirih gumijastih zamaškov, štirih T členov ter nekaj metrov PVC cevi premera 5/8 mm. Strošek takšnega sinhronizatorja je minimalem (okrog 10-13 EUR).
Stekleničke cca 0.5 litra
Potek izdelave je sledeč:
Na leseno deščico postavimo štiri stekleničke ter označimo položaj le teh.

Na mesta kamor bomo postavili stekleničke iztisnemo nekaj silikona


Stekleničke pričvrstimo na lepilo 
Ko se lepilo posuši moramo v vsak gumijast zamašek narediti po dve luknje premera 8mm v katere potem vtaknemo po dve pvc cevki. Daljša pvc cevka je na vrhu preko T člena spojena z drugo stekleničko vse dokler na koncu preko T člena povežemo zadnjo stekleničko s prvo. 
Cevka, ki je na vrhu zamaška je spojena na kolektor izvenkrmnega motorja. Cevka je na samem vrhu zamaška zaradi tega, da motor nebi mogel potegniti tekočine v sam motor. 
Takšna naprava je nekakšna "vaser vaga". Različni podtlaki bodo povzročili različne podtlake v stekleničkah in posledično se bo tekočina v enih dvignila v drugih spustila.
Narejeni sinhronizator
Da bi lažje videl sem za tekočino tokrat uporabil kar ledeni čaj. Ta je lepe rdeče barve in je na dnevni svetlobi lepo viden..
Ledeni čaj je pravšnji za take reči
Šobe za varjenje z navojem M6 so privijačene v kolektor motorja
Na kolektor, kjer so privijačene šobe moramo sedaj natakniti cevke našega sinhronizatorja

Motor vžgemo in preko čoka nastavimo na cca 1000 obratov na minuto.
Po nekaj sekundah delovanja opažam, da mi četrti uplinjač preveč "vleče" kar se vidi po temu, da se je tekočina v četrti steklenički dvignila.
Slabo nastavljen uplinjač
Po skoraj uri in pol preciznega nastavljanja na vijaku za zrak vsakega uplinjača posebej sem nekako dosegel, da so vsi štirje uplinjači delovali skoraj isto.

V zimskem času se bom lotil demontaže vseh štirih karburatorjev ker se je verjetno v trinajstih letih nabral tudi bencinski kamen v šobah - dizah kar ima za posledico tudi nepravilno delovanje. Za enkrat sem dosegel ravnovesje in motor lepo deluje (mirno) kar pa brez sinhronizatorja nisem mogel doseči, saj gre tukaj kot sem napisal za "precizno" nastavljanje vsake uplinjača posebej. Motor tako deluje na 900 obratov ko je na minimumu in preskok v brzino ne povzroči, da bi motor "crknil".

Video prispevek si lahko ogledate tudi tukaj kjer za razliko sinhronizirajo uplinjač na cestnem motorju (princip je identičen)


Primer sinhronizatorjev, ki jih dobimo na internetu stanejo pa od 60-150 EUR.
Sinhronizator na manometre s pripadajočimi nastavki

Sinhronizator na vodni stolpec s pripadajočimi nastavki

ponedeljek, 20. april 2015

Sonarji z bočnim delovanjem

Po dooolgoletnem študiju, ki je poleg študija vseboval še izredno posvetitev prostega časa v namene podvodnega ribolova (2002-2010) ter kasneje ustvarjanju družine sem svojo pot na fakulteti za pomorstvo in promet smer ladijsko strojništvo zaključil. Tema diplomske naloge so seveda sonarji z bočnim delovanjem. V nadaljevanju si lahko ogledate diplomsko delo.

Sonarji_z_bocnim_delovanjem.pdf

sreda, 21. januar 2015

Garmin Echomap 70 - Sidevu - Downwu

Garmin Echomap70
Gre za povsem novo napravo, ki je v osnovi zasnovana kot navigacijski prikazalnik in opremljena z 2D–sonarjem, ki omogoča zajem klasične 2D sonarske slike pod plovilom s frekvenco 50/200 kHz. Posebnost naprave je, da na njej ne zasledimo gumbov za upravljanje, ampak le gumb za vklop
in izklop. Napravo upravljamo s pomočjo zaslona, občutljivega na dotik.
Sama naprava ima zaslon velikosti 7 palcev, ki pa je izredno dobro viden na direktni sončni svetlobi. Poudariti moram, da je Garmin svoje naprave po novem opremil tudi z izredno hitrim GPS-sprejemnikom, saj se pozicija v napravi osvežuje 10-krat na sekundo (v primerjavi s starejšimi napravami se je pozicija osveževala vsaj 1-krat na sekundo). Ta opcija je izredno dobrodošla pri podvodnem ribolovu, saj lahko na zelo enostaven in hiter način določimo natančno pozicijo. Ker so se v zadnjih letih na tržišču pojavili različni proizvajalci s tehnologijo bočnega sondiranja, je v svojih zadnjih napravah tudi Garmin omogočil bočni zajem sonarske slike oziroma SideVu, kot jo imenuje Garmin.
Dražje in večje Garminove naprave imajo modul za bočni zajem slike že vgrajen v samo napravo, medtem ko je za manjše in nekatere starejše modele naprav Garmin izdelal dodatni modul z imenom GCV 10. Modul za bočno sondiranje je opremljen z dodatno ultrazvočno sondo, ki je v osnovi večja kot pri sonarjih konkurenčnih znamk (Humminbird ali Lowrance).
Posebnost Garminove ultrazvočne sonde je zmožnost sočasnega operiranja na dveh frekvenčnih področjih (455 kHz ter 800 kHz) ter boljša ločljivost, ki je razvidna iz pregledovanja sonarskega zapisa.

Testiranje naprave in izkušnje s terena
Modul za bočni zajem slike GCV 10
Omenjeni napravi sem namestil na leseno deščico ter vse skupaj povezal s priloženimi kabli. Pomožni nosilec sem pričvrstil na zrcalo čolna, nanj pa dve ultrazvočni sondi. Prva sonda je del naprave echoMAP 70s in se uporablja za zajem sonarske slike pod plovilom v 2D-tehnologiji (stožec). Druga ultrazvočna sonda je del modula GCV 10, ki skrbi za bočni zajem sonarske slike. Ob zagonu GPS-a oziroma sonarja sem bil prijetno presenečen. Celotni uporabniški vmesnik se nahaja na samem zaslonu, s pomočjo ponujenih opcij pa izbiramo med različnimi funkcijami naprave (nastavitve,navigacija, instrumenti, sonar itd.). Poleg tega je napravo mogoče uporabiti kot brezžični
usmerjevalnik. To pomeni, da se lahko povežemo s pametnim telefonom ali tablico in tako tudi
tam spremljamo podatke (podatke lahko denimo spremljamo na krmi plovila, napravo pa imamo
nameščeno v kabini). Napravo sem med poletnim dopustom testiral za iskanje novih pozicij pri ribolovu. Pohvaliti moram izredno natančno kartografijo (blue chart), ki omogoča več različnih prikazov pomorske karte (karta za navigacijo, ribiška karta ...).
Primer bočnega zajema - sidevu
Med iskanjem pozicij sem večinoma uporabljal bočni zajem sonarske slike. Naprava se krmili s prsti preko zaslona. Izbrani del sonarske slike tako povečamo s pomočjo prstov, kot bi to naredili na pametnem telefonu. V primeru, da smo našli zanimiv podvodni objekt, lahko z daljšim pritiskom omogočimo zajem GPS-pozicije. Sonarsko sliko lahko shranimo na dve mikro SD pomnilniški kartici, zapis pa kasneje pregledujemo v Garminovem programu HomePort.Omeniti moram tudi enostavnost pri samih nastavitvah sonarja.
Večina parametrov se nastavlja s pomočjo tako imenovanega drsnika (sliderja) preko zaslona in to uporabniku omogoča hitrejši pregled nad spremembami v delovanju sonarja.
Primer bočnega zajema slike - sidevu
Garmin omogoča sočasni prikaz več podatkov na enem zaslonu, kot npr. bočni zajem, klasični 2D-zajem (z različnimi frekvencami) ter navigacijsko karto. Seveda moramo v zakup vzeti tudi velikost zaslona, saj bo na majhnem 7-palčnem zaslonu sočasni prikaz več različnih podatkov malce težje berljiv (to velja posebej za sonarski prikaz).





Prednosti naprave: vse na enem mestu
Garminov program za upravljanje z napravo in sonarskim zapisom
Homeport 
Garmin je poskrbel tudi za izredno dober programski paket za upravljanje s samo napravo, kartografijo ter sonarskim zapisom. Imenuje se HomePort in je programski paket za računalnike
PC ter Apple. Z njegovo pomočjo lahko na izredno enostaven način pregledujemo shranjene GPS-pozicije, pregledujemo navigacijsko karto in na njej s pomočjo miške določamo pozicije (waypointe), lahko oblikujemo rute, izvažamo pozicije v zunanje programe, kot je recimo Google Earth. Poleg tega nam omenjeni program omogoča tudi pregled sonarskega zapisa. Kot sem napisal že v prejšnjem prispevu lahko tudi pri Garminu pregledujemo sonarski zapis na večjem zaslonu in tako lažje lociramo za nas pomembne podmorske objekte. Sam program omogoča tudi ažuriranje naprave preko spleta, tako da lahko naprave sproti posodabljamo z zadnjo različico programske opreme.