Universal gateway for 315/433Mhz devices
-
Hallo everybody!
I've recently come by, through Radio Shack closing and an Amazon sale, 3 sets of SecureSam wireless security sensors (5 door/window open and 1 PIR motion each) and 6 433Mhz remote controlled outlets. I had a couple odd 315/433Mhz sensors added individually already, but now I'm feeling like there's got to be an easier way.
My goal is to make a MySensors device with both a transmitter and receiver which simply forwards all received (valid) codes straight to OpenHAB without having to have them pre-programmed and allow OpenHAB to send codes which the node then blindly transmits. This way, new devices can be added within the rules and items definitions without having to reprogram the radio node.
I'm using the V_VAR1 data type and seemingly have come up with a node sketch which successfully sends the received code to the gateway./* MySensors node sketch for adding 315/433Mhz radios to OpenHAB transparently */ #include <RCSwitch.h> #include <MySensor.h> #include <SPI.h> #define NODE_ID 105 MySensor gw; #define CHILD_ID_CODE 0 unsigned long readwait = 1000; //time to wait before transmitting the same code again unsigned long lastread = 0; //last millis() value code was read long lastcode; //store last transmitted code RCSwitch mySwitch = RCSwitch(); MyMessage msgCode(CHILD_ID_CODE, V_VAR1); //using VAR1 data type (24) lacking a better option for passing a string to the gateway void setup() { mySwitch.enableReceive(1); // Receiver on inerrupt 1 => that is pin #3 // Initialize library and add callback for incoming messages gw.begin(incomingMessage, NODE_ID, true); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("ASK Transmit/Receive", "1.0"); //Register to gateway gw.present(CHILD_ID_CODE, S_CUSTOM); //315MHz radio initialize // Transmitter is connected to Arduino Pin #7 mySwitch.enableTransmit(7); // Optional set pulse length. mySwitch.setPulseLength(200); // Optional set protocol (default is 1, will work for most outlets) mySwitch.setProtocol(1); // Optional set number of transmission repetitions. mySwitch.setRepeatTransmit(2); } void loop() { gw.process(); if (mySwitch.available()) { int value = mySwitch.getReceivedValue(); //used by check function long code = mySwitch.getReceivedValue(); //int value doesn't end up containing the code so we read it again into a long //Make sure we don't spam the gateway for devices which transmit multiple times per trigger //Allow unique IDs through even if the wait isn't over so we don't miss out on other devices if ((lastread + readwait) <= millis() || lastcode != code) { if (value == 0) { Serial.print("Unknown encoding"); } else { Serial.print("Received "); Serial.print( mySwitch.getReceivedValue() ); Serial.print(" / "); Serial.print( mySwitch.getReceivedBitlength() ); Serial.print("bit "); Serial.print("Protocol: "); Serial.println( mySwitch.getReceivedProtocol() ); Serial.print("Time: "); Serial.println(millis()); //watch the time between retransmits to fine-tune the wait value gw.send(msgCode.set(code)); //send the successfully read code to the gateway lastread = millis(); //reset last read time lastcode = code; //store last code } } mySwitch.resetAvailable(); } } void incomingMessage(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_VAR1) { // Transmit code mySwitch.send(message.sensor, 24); // Write some debug info Serial.print("Incoming code to transmit:"); Serial.print(message.sensor); } }
My problem now is that I can't quite wrap my head around getting OpenHAB to read the strings and do something. I'm using TimO's tutorial for serial gateway and a hash map for my various nodes. The initial plan was to use something like that to map a code to an item, but my rule-fu is still weak and I'm not having much luck adapting that tutorial to this. I've got my table for mapping a code to an item:
var HashMap<String, String> CodeToItemsMap = NewLinkedHashMap( "7793834;" -> "Laundry_Room_PIR", "Laundry_Room_PIR" -> "7793834;", "4555512;" -> "2_outlet_ON", "2_outlet_ON" -> "4555512;", "4541876;" -> "2_outlet_OFF", "2_outlet_OFF" -> "4541876;", "6710453;" -> "Front_Door_Trip", "Front_Door_Trip" -> "6710453;",
and I'm guessing I need to make a new "IF" statement under the V_DIMMER and V_LIGHT ones
if (subType == V_VAR1){ postUpdate(CodeToItemsMap.get( nodeId + ";" + childId + ";"), msg) println ("Dimmer item: " + CodeToItemsMap.get( nodeId + ";" + childId + ";") + " Dimmer: " + msg ) }
But I'm not having good luck finding a good how-to for the syntax here and every time I futz it up I have to wait 2 solid minutes for my RaspberryPi to reload my rules, so I figured I'd see if anyone has any input.
Am I over(or under)thinking this and there's a simple solution? Seemingly this could be a handy addition to both MySensors and OpenHAB since it would make adding the thousands of readily/cheaply available switched outlets and basic wireless home security devices already on the market nearly effortless.
Thanks in advance for any help I can get, or even a referral in the right direction!
-
Ok, so I've made some more progress. I'm not much of a programmer, so I didn't realize that HashMap was a java thing and not an OpenHAB thing. After a couple quick tutorials I've got this:
var HashMap<String, String> CodeToItemsMap = NewLinkedHashMap( "7793834;" -> "Laundry_Room_PIR", "Laundry_Room_PIR" -> "7793834;", "4555512;" -> "2_outlet_ON", "2_outlet_ON" -> "4555512;", "4541876;" -> "2_outlet_OFF", "2_outlet_OFF" -> "4541876;", "6710453;" -> "Front_Door_Trip", "Front_Door_Trip" -> "6710453;", var HashMap<String, String> CodeToActionMap = newLinkedHashMap( "4555512;" -> "ON", "ON" -> "4555512;", "4541876;" -> "OFF", "OFF" -> "4541876;", "6710453;" -> "OPEN", "OPEN" -> "6710453;", if (subType == V_VAR1){ println (msg) postUpdate(CodeToItemsMap.get( msg + ";"), CodeToActionMap.get( msg + ";")) println ("Item updated: " + CodeToItemsMap.get( msg + ";") + " State: " + CodeToActionMap.get( msg + ";") ) }
This works! The couple codes I've added to my hashmap update the appropriate items despite not being programmed into the MySensors node at all. Keys that haven't been added don't really do anything. OpenHAB shows an error about "Null" not existing, which I assume is the code not being in the map, but it doesn't seem to be harmful so I don't necessarily see a need to do anything about that.
New problem, though. I can only have one of each type of sensor in the action map or I get an error upon reloading the rules file to the effect "duplicate key". Eg, can't have more than one code resolve to "Open" or "ON". I believe there's a java method for multi-key mapping, so I guess I'll work on that. I'll keep posting with progress, though I'd love some feedback, so at least there's an archive of this so maybe it'll help someone at some point if I actually get it figured out!
-
Is there anyway to use directly 433 with openhab --- serial gateway will be 433 receiver and transmitter (without mysensors lib and devices)
@static418 Thank you for your idea.
Create 2 maps, if one is null then get other map.
I removed ";" things because i dont need them.
var HashMap<String, String> CodeToItemsMapOn = newLinkedHashMap( "14013452"->"SOKET_1", "SOKET_1"->"14013452" ) var HashMap<String, String> CodeToItemsMapOff = newLinkedHashMap( "14013443"->"SOKET_1", "SOKET_1"->"14013443" ) var HashMap<String, String> CodeToActionMap = newLinkedHashMap( //nothing important because there is no duplicate "14013452"->"ON", "ON"->"14013452", "14013443"->"OFF", "OFF"->"14013443" ) //remember hashmaps must be out of the rule rule "Arduino sends to Openhab" when Item Arduino received update then ......... if(subType==V_VAR1){ var myOrder=CodeToItemsMapOn.get(msg) //1.map if(myOrder==null){myOrder=CodeToItemsMapOff.get(msg)} //2.map postUpdate(myOrder,CodeToActionMap.get(msg)) //make you job } ....... end
This code is only for updating the openhab screen (receiving), i will work for transmit.
You can find more on https://github.com/openhab/openhab/wiki/Taking-Rules-to-New-Heights
There is another problem with CodeToActionMap; If i got a lot of outlets this means many on and off commands ..
rule "MY ON" when Item SOKET_1 received command ON then sendCommand(Arduino, "105;105;1;0;24;" + 14013452 + "\n") end rule "MY OFF" when Item SOKET_1 received command OFF then sendCommand(Arduino, "105;0;1;0;24;" + 14013443 + "\n") end`
These rules for TRANSMIT didnt work any idea???
-
@C.r.a.z.y.
I'm sure there's a way to use it without the MySensors stuff, but that's a little bit out of my scope. I'd imagine it would just involve writing up an Arduino sketch for a device with a 433Mhz transmitter and receiver and have it listen for serial commands. OpenHAB can send whatever you want to serial.
As for transmitting, it seems to work with the arduino sketch I posted earlier, but I still need to put some kind of protection in place to prevent a feedback loop since it also listens for codes. When I make it transmit, it gets stuck sending and receiving the same code to itself.
A basic example of testing the transmit (I'd unplug the receiver if you haven't fixed the loop issue) would be:rule "two-outlet ON update" when Item two_outlet_ON received update if(two_outlet_ON.state==ON) { sendCommand(Arduino, "105;0;1;0;24;" + CodeToItemsMap.get("two_Outlet_ON") + "\n") OUTLET1.state = ON } end
This isn't as clean as I'd like, since I'm still basically defining the command with the exception of the code itself. But it does work!