RFID moteino controled access system [FINISHED]

Started by luisr320, May 29, 2014, 08:54:29 PM

luisr320

I'm reading the COM port directly trough a script. It is the standard COM handler script that starts with Homesser and I just added what to look for coming trough the COM port, the same COM port to which the Gateway Moteino is attached, a USB port on my Homeseer computer. This way I can deal with all the traffic coming to my Gateway.
I can send you a copy of the script. It works for both HS2 and HS3.

WhiteHare

@luisr320:  If you would either post your HS script or PM it to me, that would be great.  Thanks!

luisr320

I will post the script as soon as I get back home, which should be next Sunday.

luisr320

Here are the two required scripts to make HS3 work with your Moteinos.
The first one is the comport_open.txt:

' com port script to send/receive data to/from a COM port
' this script registers a callback script named com_event.txt
' when data is received on the COM port the com_event.txt script is called and the
' data can be processed there
' this script only needs to be called once as the com port will stay open

sub main()

	dim e
	dim comport
		
	comport = hs.DeviceValue(230)

	hs.writelog "COM PORT","Opening COM PORT" & comport & "..."
	e=hs.OpenComPort(comport,"115200,n,8,1",1,"com_event.txt","main")
	if e <> "" then
		hs.writelog "COM PORT","Error opening COM PORT " & comport,e
	else
		hs.writelog "COM PORT", "COM PORT " & comport & " correctly OPEN."
	end if

end sub


I have a virtual device, number 230, that holds the COM port number, so that I can change the com number if necessary without having to edit this script again.
This script fires the com_event.txt every time some data comes trough the COM port, and pushed the incoming data through a variable called "data", which is the argument of the main() function of com_event.txt.
My com_event.txt has the following content:

sub main(data)' when opencomport mode is a 1, data is complete string

Dim posNode_init
Dim posNode_end
Dim nodeNumber
Dim posTag_init
Dim posTag_end
Dim tagNumber
Dim infoResult
Dim tagDir
Dim posTemp_init
Dim posTemp_end
Dim posPerc_init
Dim posPerc_end
Dim tempValue
Dim fuelPercent
Dim gatePos_init
Dim gatePos_end
Dim gatePos
Dim posComandId_init
Dim posComandId_end
Dim comandId
Dim virt_device
Dim prev_result
Dim e
Dim comport

comport = hs.DeviceValue(230)


	' process the com port data here

	' hs.writelog "COM DATA",data


'=============================================================
'        Check if incoming data is from RFID reader
'=============================================================

	if instr(1,data,"TAGID") then
		posTag_init = instr(1,data,"Data 1:")+8
		posTag_end = instr(1,data,"Data 2:")-1
		'msgbox (Mid(data,posTag_init,posTag_end - posTag_init))		
		tagNumber = Mid(data,posTag_init,posTag_end - posTag_init)
		hs.RunScriptFunc "rfid_tag_processing.vb","Main",tagNumber,False,True
	end If

'=============================================================
'        Check if incoming data is from the Boiler
'=============================================================

	if instr(1,data,"BOILR") then
	
		'#################### Get Temperature #################
		posTemp_init = instr(1,data,"Data 2:")+8
		posTemp_end = instr(1,data,"Data 3:")-1
		tempValue = Mid(data,posTemp_init,posTemp_end - posTemp_init)
		
		virt_device = "135"

		'Check if value changed
		prev_result = hs.DeviceString(virt_device)

		'if value changed, update the value and string on the virtu_device
 		if tempValue<>prev_result then
			hs.SetDeviceString virt_device,tempValue & "ºC",true
			hs.SetDeviceValueByRef virt_device,Cint(tempValue),true
		end if	

		'##################### Get Fuel Level ##################
		posPerc_init = instr(1,data,"Data 3:")+8
		posPerc_end = instr(1,data,"- ACK")-1
		fuelPercent = Mid(data,posPerc_init,posPerc_end - posPerc_init)
		
		virt_device="136"
		
		'Check if value changed
		prev_result=hs.DeviceString(virt_device)
		
		'if value changed, update the value and string on the virtu_device

 		if Abs(cInt(fuelPercent)-cInt(instr(1,prev_result,"%")-1))<100  and fuelPercent<>prev_result then
			hs.SetDeviceString virt_device,fuelPercent & "%",true
			hs.SetDeviceValueByRef virt_device,cInt(fuelPercent),true
		end if

		
	end if

'=============================================================
'        Check if incoming data is from the Car Remote
'=============================================================

	if instr(1,data,"CARMO") then

		posComandId_init = instr(1,data,"Data 1:")+8
		posComandId_end = instr(1,data,"Data 2:")-1
		comandId = Mid(data,posComandId_init,posComandId_end - posComandId_init)
		'msgbox (comandId)
		
		if comandId = 1 then 'se o comando for 1, abre o portão de fora
			hs.writelog "CARMO", "A abrir o Portão Grande" ' faz um log da abertura do portão grande
			hs.SendToComPort comport,"#5/1/" ' abre o portão
		elseIf comandId = 2 then 'se o comando for 2, fecha o portão grande da rua
			hs.writelog "CARMO", "A fechar o Portão Grande" ' faz um log da abertura do portão grande
			hs.SendToComPort comport,"#5/2/" ' fecha o portão
		elseIf comandId = 3 then 'se o comando for 3, abre/fecha o Portão da Garagem
			hs.writelog "CARMO", "A abrir/fechar o Portão da Garagem" ' faz um log da abertura do portão da garagem
			hs.SendToComPort comport,"#4/1/" ' abre o portão da garagem
		end if
	end if

'=============================================================
'        Check if incoming data is a Garage Door Position!
'=============================================================

	if instr(1,data,"GDOR!") then

		gatePos_init = instr(1,data,"Data 1:")+8
		gatePos_end = instr(1,data,"Data 2:")-1
		gatePos = Mid(data,gatePos_init,gatePos_end - gatePos_init)

		virt_device="195"
		
		'Check if value changed
		prev_result=hs.DeviceString(virt_device)
		'if value changed, update the value and string on the virtu_device	
 		if Abs(cInt(gatePos)-cInt(instr(1,prev_result,"%")-1))<100 and gatePos<>prev_result then
			hs.SetDeviceString virt_device,gatePos & "%",true
			hs.SetDeviceValueByRef virt_device,cInt(gatePos),true
		end if	

	end if

'=============================================================
'        Check if incoming data is a PING!
'=============================================================

	if instr(1,data,"PING!") then

		posNode_init = instr(1,data,"[")+1
		posNode_end = instr(1,data,"]")
		nodeNumber = Mid(data,posNode_init,posNode_end - posNode_init)
		hs.writelog "PING!", "A Ping was received from node " & nodeNumber 
	end if

end Sub


Both this files are  in the scripts folder of HS3.

(cont...)

luisr320

(...cont)

As you can see, once the com port connected to the Moteino is open, all you have to do to send a command to the Gateway Moteino is hs.SendToComPort comport,"XXXXX", being the XXXXX the instruction Moteino "understands". Is is read in the main loop(). You can do this through a script or from the comport_event.txt script to automate the response to any data received trough the com port on HS,

Here is what I have on my Gateway Moteino code:

void loop() {
 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                        PROCESS DATA COMMING FROM COM PORT                               //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
  if (Serial.available()>0)//Is there a byte coming trough the com port?
  {
    inByte = Serial.read();//Load the first incoming byte in inByte variable
    if (inByte == '#')//# marks the beginning of a new packet. Is it the beginning of a new packet?
    {
      serialData = 0;//Reset serialData variable
      while (inByte != '/')//Continue to read the next bytes until the "/" separator is found
      {
        inByte = Serial.read(); 
        if (inByte > 0 && inByte != '/')//Read inByte content and do the following loop until the first "/" is found
        {
          serialData = serialData * 10 + inByte - '0';//Keep building the node number into serialData
        }
      }
      inByte = 0;//Reset inByte variable
      destinationNode = serialData;//Assign the node number to destinationNode
      //Serial.print("destinationNode:");Serial.println(destinationNode);//Show the node number for debug purpose only
      
      //Now keep on reading the data packet and look for the next "/" data separator
      serialData = 0;//Reset serialData variable
      while (inByte != '/')//Continue to read the next bytes until the "/" separator is found
      {
        inByte = Serial.read(); 
        if (inByte > 0 && inByte != '/')//Read inByte content and do the following loop until the first "/" is found
        {
          serialData = serialData * 10 + inByte - '0';
        }
      }
      inByte = 0;//Reset inByte variable
      data = serialData;//Assign the command number to the data variable to be send to the node
      //Serial.print("Data:");Serial.println(data);//Show the node command number for debug purpose only
    }
data = 2;
    //Serial.flush();
    if (radio.sendWithRetry(destinationNode, (const void*)&data, 1, 5, ACK_TIME))//Send the data via radio and wait for the ACK to be received
    {
      Serial.println("ACK Received!");//If the sent packet was delivered and an ACK received, send this message to the serial monitor
      delay(3);// Allow the the radio to switch to receive mode
    }
    destinationNode = 0;
    data = 0;
    Serial.flush();
  }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                      PROCESS DATA COMMING FROM THE RADIO               //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////

  if (radio.receiveDone())//If some packet was received by the radio, wait for all its contents to come trough
  {
    if (radio.TARGETID == 1)//Check if the packet destination is this radio (NODE 1)
    {
      //Display a message on the serial monitor showing the packet origin radio NODE number
      Serial.print('[');Serial.print(radio.SENDERID, DEC);Serial.print("] ");
            
      //If the radio Promiscuous mode is ON, show the packet destination radio NODE number on the serial monitor
      /*if (promiscuousMode)
      {
        Serial.print("to [");Serial.print(radio.TARGETID, DEC);Serial.print("] ");
      }*/
      
      in_theData = *(in_Payload*)radio.DATA; //assume radio.DATA actually contains our struct and not something else 
      //Add the transmission signal level to the message to be displayed on the serial monitor 
      Serial.print("[RX_RSSI:");Serial.print(radio.RSSI);Serial.print("] ");
      Serial.print("Data packet size: ");Serial.print(sizeof(in_theData));
      Serial.print(" Type: ");
      Serial.print(in_theData.in_dataType);
      Serial.print(" Data 1: ");
      Serial.print(in_theData.in_data1);
      Serial.print(" Data 2: ");
      Serial.print(in_theData.in_data2);
      Serial.print(" Data 3: ");
      Serial.print(in_theData.in_data3);
      delay(30);//Wait for all data to go trough the com port

      //If an ACK (acknowledge) was requested by the data packet transmitter radio, send the ACK back to it and display "ACK sent" on the serial monitor
      if (radio.ACKRequested())
      {
        radio.sendACK();
        Serial.println(" - ACK sent!");
        Serial.println();
        Blink(LED,100);
      }
    }
  }
}


My data have a "/" to separate the different type of messages that can be sent.

If you need any further assistance just let me know.



luisr320


WhiteHare

luisr320,

Thanks for your posts.  I meant to reply earlier, but I got sidetracked figuring out some Moteino details that that I've been posting about lately and that I'd like to iron out before moving on to HomeSeer integration.  If I had to guess I would estimate I'll be looping back to your homeseer scripts on this thread in about a month or so.  I don't have hard deadlines, so rate of progress is less important than just getting things implemented correctly the first time so that I (hopefully) don't have to change much, if anything, later.

Once again, thank you very much for posting your homeseer script.