Vai al contenuto
PLC Forum


Aiuto openhab+arduino


claudio984

Messaggi consigliati

Ciao a tutti,

da qualche settimana ho iniziato a smanettare con openhab per realizzare un piccolo impianto di monitoraggio e gestione di sensori.. mi sono rivolto ad openhab in quanto mi pare di capire che sia facilmente integrabile con Arduino. E' proprio con quest ultimo che non riesco a sbloccarmi.

In pratica ciò che vorrei realizzare come primo approccio è semplicemente l'accensione di un led su arduino ma ho difficoltà con la comunicazione con arduino.

riporto il codice openhab:

ITEM:

Switch Luce1 "Luce 1" (gSolaio, gLuci) 
String Node1 "Nodo 1" (All) { serial="COM4", autoupdate="false" }

RULE:

rule "accensione luce" 
when 
Item Luce1 changed 
then 
sendCommand(Node1, "1") 
end

ARDUINO:

void setup() { 
// initialize digital pin 13 as an output. 
pinMode(13, OUTPUT); 
Serial.begin(9600); 
} 
void loop() { 
int ser=0; 
if (Serial.available() ) 
{ ser=Serial.read(); 
if(ser=='1') 
{ 
digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) 
Serial.println("ACCESO"); 
} 
else if (ser== '2') 
{ 
digitalWrite(13, LOW); // turn the LED off by making the voltage LOW 
Serial.println("SPENTO"); 
} 
}

ho provato il tutto su windows settando come porta la COM4 per l'item ma anche su linux settando la porta /dev/ttyACM0.

ho la sensazione che la stringa che invio ad arduino non arrivi nemmeno.

Qualcuno saprebbe aiutarmi?

Grazie in aticipo

 

 

 

Link al commento
Condividi su altri siti


C'è un forum ed una sezione dedicati ad Arduino, dove hò spsotato la discussione. Se si vogliono ottenere risposte pertinenti bisogna sempre aprire la discussione nella sezione più adatta.

Andiamo con ordine.

Scrivi lo sketch e lo scarichi sul target.

Se non ci sono errori di compilazione e di comunicazione in basso sulla finestra dello sketch compare la scritta in colore bianco che indica lì'occupazione di memoria ed il termine del caricamento del programma.

Questo indica che la comunicazione tra PC ed arduino è stabilita.

Poi premi "CTRL"+"Shift"+M e appare la finestra di monitor della seriale.

Scrivi "1"  nella riga di trasmissione e premi invio. nella finestra di ricezione dovrebbe comparirti la scritta di risposta.

 

Link al commento
Condividi su altri siti

Ciao Livio,

mi scuso per aver sbagliato sezione.

Forse non sono stato chiaro nell'esposizione del problema.

La comunicazione fra pc e arduino avviene correttamente perchè riesco tranquillamente a caricare lo sketch ma è la comunicazione fra openhab e arduino che temo non vada.

Infatti inserendo il carattere 1 sul monitor mi si accende il led e quindi tutto funziona a dovere ma ciò non accade quando provo ad inviare quella stringa da openhab.

Grazie

Link al commento
Condividi su altri siti

Prova a sostituire ON al posto di 1 nel sendCommand

e ad usare Switch al posto di string?

Modificato: da smoothhands
Link al commento
Condividi su altri siti

Allora il problema non è su Arduino ma su Openhab, anzi qausi certamente sui comandi che usi.

Se disponin di un programma di montior della seriale PC puoi usarlo come "sniffer" della comunicazione mettendo la seriale PC in parallelo sulla linea di comunicazione.

Link al commento
Condividi su altri siti

Potrebbe anche servire questo...

Note2: If you are using non standard serial ports you have to adapt start.sh to have the serial port included. the java command line should then include the following parameters:

-Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0

whereas ttyAMA0 is the path to your serial port. Please be aware to change all scripts you might use for startup (debug, automatic start in linus,...)

Link al commento
Condividi su altri siti

Grazie per i consigli ma non è che avreste qualche esempio funzionante?

Magri potrei sostituire interamente la cartella Configuration perchè comincio a pensare anche che il problema sia sul file openhab.cfg che va forse modificato ma non so come..

Link al commento
Condividi su altri siti

Purtroppo queste cose vanno risolte per tentativi... almeno per ora.

Se è qualche settimana "sicuramente" avrai inserito il serial binding nella cartella addons di openHAB.

La seconda cosa da guardare è sicuramente la pagina con le informazioni del binding per i dispositivi seriali.

Il file openhab.cfg non mi pare abbia configurazioni da variare per il serial binding. Almeno la pagina del 

binding non riporta indicazioni e all'interno del file non ho trovato riferimenti.

 

Il file degli ITEMS e delle RULES sono corretti come li avevi postati manca solo quello della SITEMAP

che ti permette di inviare il comando allo Switch Luce1.

Una correzione che potresti fare alla rule è sicuramente:

rule "accensione luce" 
when 
    Item Luce1 changed 
then
    if (Luce1.state == ON)
        sendCommand(Node1, "1") 
    else
        sendCommand(Node1, "2") 
end

Così facendo puoi accendere e spegnere il led.

L'avevi inserito un file SITEMAP?

Comunque non è altro che una file test.sitemap del tipo...

sitemap test label="testlabel"
{
	Frame label="Test"  {
		Switch item=Luce1
	}
}

 

Modificato: da smoothhands
Link al commento
Condividi su altri siti

la condizione per farlo spegnere non l' ho messa ancora perchè volevo solo testre l'accesione e non mi ero posto ancora il problema di come farlo spegnere :smile:

Il sitemap non credo abbia problemi altrimenti non riuscirei nemmeno a vedere la webapp credo.

Hai dato un'occhiata allo sketch arduino? magari è li che ho fatto qualche errore..

Link al commento
Condividi su altri siti

a questo punto potrei fare un' altra prova, avendo a disposizione un ethernet shield per arduino vorrei provare a sfruttare quello quindi bypassando la seriale.

Mi sapreste indicare come vanno definiti gli item, rule, il file openhab.cfg e lo sketch arduino?

Link al commento
Condividi su altri siti

Prova a modificare lo sketch in questo modo...

void loop() { 
    int ser = 0; 
    while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    ser = Serial.parseInt();
    if (ser == 1) 
    { 
        digitalWrite(13, HIGH); // turn the LED on (HIGH is the voltage level) 
        Serial.println("ACCESO"); 
    } 
    else if (ser == 2) 
    { 
        digitalWrite(13, LOW); // turn the LED off by making the voltage LOW 
        Serial.println("SPENTO"); 
    }
    
    }
}

 

Modificato: da smoothhands
Link al commento
Condividi su altri siti

Ciao,

purtroppo per un bel pò di tempo non sono riuscito a dedicarmi all'accensione di questo benetto led :smile: alla fine però ci sono riuscito e ne approfitto anche per scusarmi se non ho aggiornato più il thread..

In realtà più che altro ho bypassato la porta seriale con il componente ethernet e tutto funziona alla grande :smile: 

Cliccando sullo switch invio una stringa ad arduino, questa se è uguale a http://192.168.1.200/?status=ON allora lo accende se uguale a http://192.168.1.200/?status=OFF lo spegne.

A questo punto mi piacerebbe spingermi oltre per poi passare agli altri sensori che necessitano di comunicazione da e verso arduino. In pratica mi piacerebbe capire come inviare da arduino una stringa.. per esempio supponiamo di aver acceso il led su arduino. Ciò che vorrei fare è inviare una stringa ad openhab per dirgli "Led acceso". Riporto un esempio di dove vorrei che mi comparisse la scritta led acceso (per es. quando avrò fatto pratica in questo senso utilizzando magari una sonda per la temperatura li mi aspetterò la temperatura).

34gpnwp.png

Per quanto riguarda l'item ho pensato di definirlo come stringa (non so se devo definire i parametri per il binding in realtà):

String StrLuce "Stato led [%s]" <keyring> (Diagnostic, TechnicView_Node0)

Per quanto riguarda le rule suppongo sia questo il modo di ricevere una stringa:

rule "ricevi stringa da arduino"
when
	Item Luce1 received command
then
val  result = sendHttpGetRequest("url")
    StrLuce.postUpdate(result.toString)
end

Ma per quanto riguarda lo sketch su arduino non saprei proprio come fare, questo è quello che utilizzo attualmente per accedere il led:

#include <EtherCard.h>

static byte mymac[] = {0xDD,0xDD,0xDD,0x00,0x00,0x01};
static byte myip[] = {192,168,1,200};
byte Ethernet::buffer[700];

const int ledPin = 9;  //per settare il led sul piedino 9
boolean ledStatus;

char* on = "ON";
char* off = "OFF";
char* statusLabel;
char* buttonLabel;

void setup () {
 
  Serial.begin(57600);
  Serial.println("WebLed Demo");
 
  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    Serial.println( "Failed to access Ethernet controller");
 else
   Serial.println("Ethernet controller initialized");
 
  if (!ether.staticSetup(myip))
    Serial.println("Failed to set IP address");

  Serial.println();
  
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  ledStatus = false;
}
  
void loop() {
 
  word len = ether.packetReceive();
  word pos = ether.packetLoop(len);


  if(pos) {
    
    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=ON") != 0) {
      Serial.println("Received ON command");
      ledStatus = true;
    }

    if(strstr((char *)Ethernet::buffer + pos, "GET /?status=OFF") != 0) {
      Serial.println("Received OFF command");
      ledStatus = false;
    }
    
    if(ledStatus) {
      digitalWrite(ledPin, HIGH);
      statusLabel = on;
      buttonLabel = off;
    } else {
      digitalWrite(ledPin, LOW);
      statusLabel = off;
      buttonLabel = on;
    }
      
    BufferFiller bfill = ether.tcpOffset();
    bfill.emit_p(PSTR("HTTP/1.0 200 OK\r\n"
      "Content-Type: text/html\r\nPragma: no-cache\r\n\r\n"
      "<html><head><title>WebLed</title></head>"
      "<body>LED Status: $S "
      "<a href=\"/?status=$S\"><input type=\"button\" value=\"$S\"></a>"
      "</body></html>"      
      ), statusLabel, buttonLabel, buttonLabel);
    ether.httpServerReply(bfill.position());
  }
}

Spero di non avervi annoiato.

Grazie ancora per la disponibilità

Modificato: da claudio984
Link al commento
Condividi su altri siti

Ciao claudio984, ben tornato.

Stavo scherzando.

 

Purtroppo Java non va molto d'accordo con le seriali.

 

L'item String va bene però non ho trovato nelle Actions 

se la sendHttpGetRequest restituisce qualcosa.

Mi sa che devi utilizzare il binding http.

 

Link al commento
Condividi su altri siti

Ciao smoothhands,

in realtà sta cercando proprio di capire come utilizzare il binding http ed è proprio li che ho un pò di difficoltà.

Ho capito finalmente che posso sfruttare in uscita il binding http in due modi:

1 - aggiungendo alla fine dell'item una stringa tipo(quella in rosso):

Switch Luce1 "Luce 1" <light> (gSolaio, gLuci) { http=">[ON:CURL:http://192.168.1.200/]"} 

2 - posso definire l'item allo stesso modo dell'esempio sopa ma eliminando la stringa rossa e definendo una regola tipo questa dove gli si dice che quando cambia lo stato dello switch deve inviare la stringa "http://192.168.1.200/?status=ON" ad arduino

 

rule "accensione luce"
when
    Item Luce1 changed
then
    if(Luce1.state == ON)  sendHttpGetRequest("http://192.168.1.200/?status=ON")
    else sendHttpGetRequest("http://192.168.1.200/?status=OFF")
end

 

Fin qui tutto bene il led risponde alla grande :-)

Il problema purtroppo nasce quando vorrei riceve info in senso opposto.. cioè quando voglio comunicare da arduino ad openhab.

Per es. una volta acceso il led mi piacerebbe che arduino inviasse una stringa, sempre sfruttando il binding http, con scritto ACCESO/SPENTO in modo che possa poi visualizzare tale valore sull'app openhan. Un es. che potrebbe chiarire ulteriormente ciò che vorrei realizzare potrebbe essere per es un sensore di temperatura installato su arduino, che dovrebbe comunicare il valore di temperatura ad oh tramite una stringa.

Premesso che queste dovrebbero essere le regole da aggiungere agli item sia per l'input che per l'output in/verso openhab, comincio a pensare che il grosso problema è lo sketch su arduino.

input =>       http:"<[<url>:<refreshintervalinmilliseconds>:<transformationrule>]"
output =>      http:">[<command>:<httpmethod>:<url>]"

E' qui che vi chiedo aiuto.

Considerando che non ho lo shield ufficiale ma il componente che va collegato con i fisi ai pin, questo per intenderci:

607138974861101208220947-116318-700_700.

Link al commento
Condividi su altri siti

Il meccanismo del binding serve ad openHAB come scambio bidirezionale

tra l'event bus (meccanismo alla base del sistema) e i vari sistemi esterni che

si ha intenzione di integrare con openHAB.

Il sistema esterno può essere un vero è proprio hardware domotico oppure

come in questo caso un servizio di rete.

 

Quote

Ho capito finalmente che posso sfruttare in uscita il binding http in due modi:

1 - aggiungendo alla fine dell'item una stringa tipo(quella in rosso):

Switch Luce1 "Luce 1" <light> (gSolaio, gLuci) { http=">[ON:CURL:http://192.168.1.200/]"} 

2 - posso definire l'item allo stesso modo dell'esempio sopa ma eliminando la stringa rossa e definendo una regola tipo questa dove gli si dice che quando cambia lo stato dello switch deve inviare la stringa "http://192.168.1.200/?status=ON" ad arduino

 

Il primo è l'utilizzo del binding... ovvero tutto ciò che è tra le parentesi graffe

Il secondo invece è il meccanismo delle Actions... pezzi software direttamente accedibili dalle rules.

Posso anche realizare nuove Actions e aggiungere come un qualsiasi altro addon.

 

Se ho capito bene il meccanismo della Action sendHttpGetRequest non ritorna valori: o per lo meno

non ne ho trovato cenno nel wiki del sito.

 

Tramite il binding http invece posso trattare quanto restituito dal sito (nel tuo caso l'arduino) tramite

regole di trasformazione che possono essere 

- XSLT-transformation

- JSON-transformation

- altro...

 

Il tuo scopo è trovare la combinazione giusta tra la trasformation del binding e quanto fai restituire da arduino.

 

Per fare il polling altro non ti serve che il parametro <refreshintervalinmilliseconds> del bind in input

http:"<[<url>:<refreshintervalinmilliseconds>:<transformationrule>]"
Link al commento
Condividi su altri siti

Se usi il binding http però secondo me nella definizione dell'Item va usato...

{ http = ">[ON:GET:http://192.168.1.200/?status=ON] >[OFF:GET:http://192.168.1.200/?status=OFF]" }

a questo punto la rule non ti serve più.

Quella qui sopra è la definizione utilizzata per i comandi.

 

Diverso è il discorso di come ricevere informazioni dall'arduino.

In ogni caso openHAB ha il ruolo di client e Arduino quello di server.

E' come se avessi un servizio REST al quale richiedi un valore.

Io farei rispondere ad Arduino con una stringa JSON dove restituisco

ad openHAB tutti i valori della risorsa interrogata.

 

Nella definizione dell'Item a questo punto va impostato un binding del tipo

{ http = "<[http://192.168.1.200/sensor/temperature:2000:JS(getValue.js)]" }

ovvero ogni 2 secondi vado a richiedere informazioni a /sensor/temperature

Nel file getValue.js contenuto nella directory <openhab>/configuration/transform inserisco

JSON.parse(input).temperature;
Link al commento
Condividi su altri siti

Resta da capire come formattare il testo restituito da Arduino.

Dovresti guardare come risponde un server con un servizio REST.

Oltre alla risposta del server 

HTTP/1.0 200 OK\r\n

 

va aggiunto il corretto content-type che dovrebbe essere 

application/json

 

poi il contenuto come stringa json

{
    status : "success",
    sensor : { "temperature" : 22.3 }
}
Link al commento
Condividi su altri siti

  • 2 years later...

Ciao a tutti, ho provato a capire cosa non andasse nella prima parte elaborata da Claudio984, ho trovato il problema della seriale usb, bisognava semplicemente aggiungere all'utente il gruppo openhab, riavviare il pc ed eureka!!!!

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...