Translate

sábado, 30 de abril de 2016

Arduino Web - Página Web Controlando Hardware Arduino

Descrevo neste post Projeto completo de interface gráfica (web) controlando placa Arduino, acionando o servo motor, colocando mensagens no LCD e ajustando cor de Led RGB, atuando sobre uma porta ligada a um relé para acender lâmpada, etc.


A Aplicação consiste numa página Web rodando sob um servidor GlassFish.

Esta envia/recebe comandos de uma aplicação Java RMI (RMIServer) que se comunica com a placa Arduino.



Abaixo, projeto completo, incluindo código para o hardware e as bibliotecas RTXcomm.jar para comunicação serial com o Arduino.






terça-feira, 26 de abril de 2016

Banco Oracle - Verificando Tempo Transcorrido


Podemos eventualmente, necessitar contar o tempo transcorrido entre dois valores de campos distintos de uma tabela (DATA_FINAL - DATA_INICIAL) ou determinado tempo passado até a data atual.

No Banco Oracle podemos utilizar de alguns artifícios para conseguirmos esta solução.

Utilizarei as tabelas e dados criados no post anterior:

Banco Oracle - Adicionando valores de tempo em Datas TIMESTAMP


Observação: Utilize o comando abaixo para ajustar o formato de hora para a sessão, a fim de evitarmos problemas de conversão:

--necessario alterar a sessao, utilizo aqui o formato 'DD/MM/YYYY HH24:MI:SS'
       ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';

Baseando-se que já tenhamos uma tabela e uma pequena massa de dados na mesma, podemos executar a seguinte consulta, calculando a subtração do tempo transcorrido entre a data atual (SYSTIMESTAMP) e a data registrada no campo DATA1:


--demonstra valor de data 1 e suas diferencas                         
SELECT ID_TESTE
      ,SYSTIMESTAMP AS DATA_ATUAL
      ,DATA1
      ,(SYSTIMESTAMP --DATA ATUAL
        -
        DATA1
        ) AS DIFERENCA_ENTRE_DATAS
            FROM TESTES_COM_DATA;  


Obtendo um resultado semelhante ao demonstrado na figura:










Observe o campo DIFERENCA_ENTRE_DATAS. É demonstrado, dias/horas/minutos/segundos.

Mas e se desejarmos saber apenas os minutos transcorridos?

Podemos usar a cláusula WITH e a partir de um sub-query semelhante à demonstrada acima, extrair os valores desejados, no caso, os minutos transcorridos desde a hora atual até o momento da execução da consulta:
--SELECIONA MINUTOS TRANSCORRIDOS
        WITH DIFERENCA AS (
        --SELECIONA DIFERENCAS ENTRE A DATA ATUAL 
        -- E A DATA REGISTRADA NA TABELA
         SELECT (
              SYSTIMESTAMP --DATA ATUAL ou por ex.:TO_TIMESTAMP('22/04/2016 13:00:00', 'DD/MM/YYYY HH24:MI:SS') 
              -
              DATA1
              ) AS DIFERENCA_ENTRE_DATAS
                  FROM TESTES_COM_DATA                                    
                         )
          --EXTRAI OS MINUTOS
          SELECT (( EXTRACT (DAY FROM (DIFERENCA_ENTRE_DATAS)) *24*60*60 
               + EXTRACT (HOUR FROM (DIFERENCA_ENTRE_DATAS)) *60*60 
               + EXTRACT (MINUTE FROM (DIFERENCA_ENTRE_DATAS)) *60 
               + EXTRACT (SECOND FROM (DIFERENCA_ENTRE_DATAS)) )/60) AS TOTAL
          FROM DIFERENCA;

Observe o resultado


Podemos, através da função  ROUND(<valor>,<casas_decimais>) arredondar este valor: 


--SELECIONA MINUTOS TRANSCORRIDOS
        WITH DIFERENCA AS (
        --SELECIONA DIFERENCAS ENTRE A DATA ATUAL 
        -- E A DATA REGISTRADA NA TABELA
         SELECT (
             SYSTIMESTAMP --DATA ATUAL ou por ex.:TO_TIMESTAMP('22/04/2016 13:00:00', 'DD/MM/YYYY HH24:MI:SS') 
              -
              DATA1
              ) AS DIFERENCA_ENTRE_DATAS
                  FROM TESTES_COM_DATA                                    
                         )
          --EXTRAI OS MINUTOS
          SELECT ROUND((( EXTRACT (DAY FROM (DIFERENCA_ENTRE_DATAS)) *24*60*60 
               + EXTRACT (HOUR FROM (DIFERENCA_ENTRE_DATAS)) *60*60 
               + EXTRACT (MINUTE FROM (DIFERENCA_ENTRE_DATAS)) *60 
               + EXTRACT (SECOND FROM (DIFERENCA_ENTRE_DATAS)) )/60)
               ,0) AS TOTAL_ARREDONDADO -- 0 CASAS DECIMAIS
          FROM DIFERENCA;

Obtendo o resultado em Minutos, como desejávamos:




domingo, 24 de abril de 2016

Banco Oracle - Adicionando valores de tempo em Datas TIMESTAMP


Neste post procurarei utilizar exemplos de como inserir valores de datas, (campos TIMESTAMP) incrementando, minutos, segundos, etc, a partir da data atual.

Para começar, vamos criar uma tabela de exemplo, com campo identificador (ID_TESTE) dois campos (DATA1 e DATA2) representando as datas atuais e a data acrescida respectivamente.

Há também a criação (opcional) de uma sequence (TESTE_COM_DATA_SEQ) para facilitar a inserção de valores únicos o campo ID_TESTE.

--criação da tabela de testes
CREATE TABLE TESTES_COM_DATA(

ID_TESTE          INTEGER,
DATA1             TIMESTAMP(6),
DATA2             TIMESTAMP(6),

PRIMARY KEY (ID_TESTE)

);

--criação de sequence (opcional) para atribuição de 
--valores do campo ID_TESTE
CREATE SEQUENCE TESTES_COM_DATA_SEQ
  MINVALUE 1
  START WITH 1
  INCREMENT BY 1
  CACHE 20;


Para começarmos, temos que alterar o formato de exibição de TIMESTAMP para a sessão atual do usuário. Esta alteração não é permanente e é cancelada quando encerramos a sessão.

Observação: Sempre que formos utilizar este tipo de tratativas com datas, temos que utilizar o comando abaixo:

--necessario alterar a sessao, utilizo aqui o formato 'DD/MM/YYYY HH24:MI:SS'
       ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';

Feito isso, vamos estudar os códigos para incremento dos valores de Horas, Minutos e Segundos




 --TIMESTAMP ADICIONADO HORAS
        SELECT SYSTIMESTAMP AS DATA_ATUAL
                            , TO_TIMESTAMP(
                              SYSTIMESTAMP + (
                              2 --QUANTIDADE DE HORAS ADICIONADAS
                              /24)
                              , 'DD/MM/YYYY HH24:MI:SS') 
                              AS DATA_SOMADA_HORAS
                            FROM DUAL;      
      
       --TIMESTAMP ADICIONADO MINUTOS
       SELECT SYSTIMESTAMP AS DATA_ATUAL
                            , TO_TIMESTAMP(
                              SYSTIMESTAMP + (
                              5 --QUANTIDADE DE MINUTOS ADICIONADOS
                              /(24*60))
                              , 'DD/MM/YYYY HH24:MI:SS') 
                              AS DATA_SOMADA_MINUTOS
                            FROM DUAL;
                            
       --TIMESTAMP ADICIONADO SEGUNDOS
        SELECT SYSTIMESTAMP AS DATA_ATUAL
                            , TO_TIMESTAMP(
                              SYSTIMESTAMP + (
                              25 --QUANTIDADE DE SEGUNDOS ADICIONADOS
                              /24/60/60)
                              , 'DD/MM/YYYY HH24:MI:SS') 
                              AS DATA_SOMADA_SEGUNDOS
                            FROM DUAL;  


Finalmente, podemos aplicar os conceitos aprendidos dentro de cláusulas de INSERT na tabela do banco:
--inserindo diferença de duas horas
INSERT INTO TESTES_COM_DATA (  
                              ID_TESTE
                              ,DATA1
                              ,DATA2)
        VALUES(
        TESTES_COM_DATA_SEQ.NEXTVAL --busca proximo valor para a sequence
        ,SYSTIMESTAMP               --data/hora atual
        ,(TO_TIMESTAMP(
                       SYSTIMESTAMP + (
                       2 --QUANTIDADE DE HORAS ADICIONADAS
                       /24)
                       , 'DD/MM/YYYY HH24:MI:SS') 
                       )  --inserção de SYSTIMESTAMP + 2 Horas        
        );


--inserindo diferença de quinze minutos
INSERT INTO TESTES_COM_DATA (  
                              ID_TESTE
                              ,DATA1
                              ,DATA2)
        VALUES(
        TESTES_COM_DATA_SEQ.NEXTVAL --busca proximo valor para a sequence
        ,SYSTIMESTAMP               --data/hora atual
        ,(TO_TIMESTAMP(
                       SYSTIMESTAMP + (
                       15 --QUANTIDADE DE MINUTOS ADICIONADOS
                        /(24*60))
                      , 'DD/MM/YYYY HH24:MI:SS')--inserção de SYSTIMESTAMP + 15 mins        
          )
        );


        INSERT INTO TESTES_COM_DATA (  
                              ID_TESTE
                              ,DATA1
                              ,DATA2)
        VALUES(
        TESTES_COM_DATA_SEQ.NEXTVAL --busca proximo valor para a sequence
        ,SYSTIMESTAMP               --data/hora atual
        ,(TO_TIMESTAMP(
                       SYSTIMESTAMP + (
                       30 --QUANTIDADE DE SEGUNDOS ADICIONADOS
                       /24/60/60)
                       , 'DD/MM/YYYY HH24:MI:SS')--inserção de SYSTIMESTAMP + 30 segs        
          )
        );   

Resultado final das linhas inseridas:




Podemos também adicionar simultaneamente HORAS/MINUTOS/SEGUNDOS à data atual, como no exemplo abaixo:

      --inserindo diferenca de HORAS/MINUTOS/SEGUNDOS
        INSERT INTO TESTES_COM_DATA (  
                              ID_TESTE
                              ,DATA1
                              ,DATA2)
        VALUES(
        TESTES_COM_DATA_SEQ.NEXTVAL --busca proximo valor para a sequence
        ,SYSTIMESTAMP               --data/hora atual
        ,(TO_TIMESTAMP(
                              SYSTIMESTAMP + (
                              2 --QUANTIDADE DE HORAS ADICIONADAS
                              /24)
                               +(
                              10 --QUANTIDADE DE MINUTOS ADICIONADOS
                              /(24*60))
                              +
                              (
                              30 --QUANTIDADE DE SEGUNDOS ADICIONADOS
                              /24/60/60)   --inserção de SYSTIMESTAMP + 30 segundos        
             )
          )
        );   

Resultando em:




sexta-feira, 22 de abril de 2016

Banco Oracle - Desbloquear Usuários com senhas Expiradas ORA-28001

Eventualmente, por padrão, o banco de dados Oracle expira a senha de usuários.

Para reverter esta situação execute as linhas a seguir, com usuário SYS , e atribuição SYSDBA:
--desbloqueie o usuário
ALTER USER TESTES_LOCAIS ACCOUNT UNLOCK;

--atribua uma nova senha
ALTER USER TESTES_LOCAIS IDENTIFIED BY 123456;

--verifique a próxima data de expiração (EXPIRY_DATE)
SELECT USERNAME, ACCOUNT_STATUS, EXPIRY_DATE FROM DBA_USERS 
WHERE USERNAME='TESTES_LOCAIS';

Se for de seu desejo que as contas de usuário nunca mais expirem, execute os comandos a seguir, também com usuário SYS , e atribuição SYSDBA:
--alterando perfil para não expirar mais
ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_TIME UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME  UNLIMITED;


--verifique se não há mais data de expiração (EXPIRY_DATE)
SELECT USERNAME, ACCOUNT_STATUS, EXPIRY_DATE FROM DBA_USERS
WHERE USERNAME='TESTES_LOCAIS';