Test your home made controller with MockMySensors (w/ tutorial)



  • Hi Folks,

    While building my custom controller i've run into a problem of not having enough arduinos/material to produce each type of supported sensors.

    So in order to create visualizations for each sensor I've decided to create an arduino sketch to fake sensors and send dummy data.

    Of course I'm running out of Global/Local variable space half way through (about 12 sensors, even with debug off) but plan to comment/uncomment the sersors to fake.

    Also I havent had a proper chance to test this.

    Is anyone interested in this?
    Want to give it a go?
    Check it on MySensors Github

    Usual stuff, open source, as is, terrible code, blá blá blá, have fun!

    Cheers


  • Admin

    Very cool. I think the appropriate term would be "mock" sensors as is common in software where one mock objects for testing.



  • Guys

    No pun intended.

    I admire and appreciate your work with my sensors library

    Cheers



  • Hi Folks

    Did a major refactor on this thing and was able to do some preliminery testing.

    Due to memory limitations on the Arduino, you now can comment/uncomment the sensors you would like to test. I was able to test about 12 sensors at a time (if i turn off the MySensor library debug).

    It is able to fake/mock the 24 sensors on the 1.4.1 MySensors Library.

    Nest steps will be:

    • remove the read/write from the eprom

    • include the extra sensors supported by library version 1.5.

    • Implement a way to request sensor information (where it makes sense)

    Not necessarily in this order...

    With this I now have plenty of information to use in my controller HAALL

    It has also made a very good exercise in creating MySensors code.

    By the way I would like some advice from the arduino experts here....

    As I mentioned you can comment/uncomment the sensors declarations on the beginning, I use a lot of #ifdef in the code.

    My question is: Is there a more elegant solution for this?

    e.g. for the dimmer sensor:

    //declaration
    #define ID_S_DIMMER                   5
    ---
    //Message
    #ifdef ID_S_DIMMER
      MyMessage msg_S_DIMMER(ID_S_DIMMER,V_DIMMER);
    #endif
    ---
    //set up - presentation
    #ifdef ID_S_DIMMER
        Serial.println("  S_DIMMER");
        gw.present(ID_S_DIMMER,S_DIMMER);
        gw.wait(SHORT_WAIT);
      #endif
    ---
    // loop
    #ifdef ID_S_DIMMER
        dimmer();
      #endif
    ---
    // read function
    #ifdef ID_S_DIMMER
    void dimmer(){
    
      int dimmerVal = gw.loadState(ID_S_DIMMER);
      
      Serial.print("Dimmer is set to: " );
      Serial.println(dimmerVal);
      
      gw.send(msg_S_DIMMER.set(dimmerVal));
    
    }
    #endif
    ---
    // incoming message switch
    #ifdef ID_S_DIMMER
        case V_DIMMER:
              if ((message.getInt()<0)||(message.getInt()>100)) {
                Serial.println( "V_DIMMER data invalid (should be 0..100)" );
                break;
              }
              gw.saveState(ID_S_DIMMER, message.getInt());
              Serial.print("Incoming change for ID_S_DIMMER:");
              Serial.print(message.sensor);
              Serial.print(", New status: ");
              Serial.println(message.getInt());
        break;
        #endif
    

    Also, suggestions to remove the read/write from the eprom are welcome.

    For those who are building custom controllers, the comments on the v1.5 library help to clarify a few things.

    For example, there is no formal relation between the sensor type and the message type (and to me it wasn't always obvious), however that relation is somewhat establshed in the comments of lib 1.5.

    Thanks guys.

    As always, feedback is very welcome!!!!

    Cheers



  • Hi Folks,

    Though i give out an update on the MockMySensors thing...

    Here is a pic

    sensors.png

    Cheers


  • Hero Member

    Nice work and great idea.

    When I was getting started I too didn't have enough arduinos/radios to test different bits with it was a pain...or wanting to try out Hek's latest and greatest sensor/sketch to see what it looks like in Vera/Imperihome... but I never thought to create a sketch to just pretend it had the hardware...great thinking!

    Q: What GUI is that?



  • @gregl

    I'm one of the crazy ones who decided to build it own controller (see here: Meet HAALL)

    Still very much work in progress, but I needed this MockMySensors to get it going.

    Cheers


  • Hero Member

    Wow - nice work again! Im in bed with Vera and looking at OpenHAB, but what you have created looks very nice and a good start!


  • Hero Member

    Very good idea! Thanks a lot!
    I've tested it against my OH2 binding and it works like a charm.

    One thing didn't work though, for S_DIMMER there is a value of 255 submitted, which was read from the eeprom. At this point OH2 grumbles because the value is >100%. 😉


  • Hero Member

    @barduino said:

    My question is: Is there a more elegant solution for this?

    Not very elegant, but just a different idea. Ability to extend it to more then 24 sensors and 1.5. I built it to test my own controller script. Not complete yet...I doubt it will ever be 😉

    /*
     PROJECT: MySensors
     PROGRAMMER: AWI
     DATE: 10 august 2015
     FILE: AWI_Universal_Test_50.ino
     LICENSE: Public domain
       -in conjunction with MySensors
      
     SUMMARY:
    	multisensor for controller (sensor)testing
    	
     Setup: sends values for al sensor specified in setup array 
      
     */
    #include <MySensor.h>  
    #include <SPI.h>
    
    const int NODE_ID = 50;  		  		// fixed MySensors node ID
    const int NoSensors = 36; 
    const int NoTests = 40; 
    
    // Sensor array: defines the sensors { Sensor_type (S_LIGHT) }, index number = sensor_id minus 1
    byte MySensorList[NoSensors]={
    	S_DOOR, // Door sensor, V_TRIPPED, V_ARMED
    	S_MOTION,  // Motion sensor, V_TRIPPED, V_ARMED 
    	S_SMOKE,  // Smoke sensor, V_TRIPPED, V_ARMED
    	S_BINARY, // Binary light or relay, V_STATUS (or V_LIGHT), V_WATT (same as S_LIGHT)
    	S_DIMMER, // Dimmable light or fan device, V_STATUS (on/off), V_DIMMER (dimmer level 0-100), V_WATT
    	S_COVER, // Blinds or window cover, V_UP, V_DOWN, V_STOP, V_DIMMER (open/close to a percentage)
    	S_TEMP, // Temperature sensor, V_TEMP
    	S_HUM, // Humidity sensor, V_HUM
    	S_BARO, // Barometer sensor, V_PRESSURE, V_FORECAST
    	S_WIND, // Wind sensor, V_WIND, V_GUST
    	S_RAIN, // Rain sensor, V_RAIN, V_RAINRATE
    	S_UV, // Uv sensor, V_UV
    	S_WEIGHT, // Personal scale sensor, V_WEIGHT, V_IMPEDANCE
    	S_POWER, // Power meter, V_WATT, V_KWH
    	S_HEATER, // Header device, V_HVAC_SETPOINT_HEAT, V_HVAC_FLOW_STATE
    	S_DISTANCE, // Distance sensor, V_DISTANCE
    	S_LIGHT_LEVEL, // Light level sensor, V_LIGHT_LEVEL (uncalibrated in percentage),  V_LEVEL (light level in lux)
    	S_ARDUINO_NODE, // Used (internally) for presenting a non-repeating Arduino node
    	S_ARDUINO_REPEATER_NODE, // Used (internally) for presenting a repeating Arduino node 
    	S_LOCK, // Lock device, V_LOCK_STATUS
    	S_IR, // Ir device, V_IR_SEND, V_IR_RECEIVE
    	S_WATER, // Water meter, V_FLOW, V_VOLUME
    	S_AIR_QUALITY, // Air quality sensor, V_LEVEL
    	S_CUSTOM, // Custom sensor 
    	S_DUST, // Dust sensor, V_LEVEL
    	S_SCENE_CONTROLLER, // Scene controller device, V_SCENE_ON, V_SCENE_OFF. 
    	S_RGB_LIGHT, // RGB light. Send color component data using V_RGB. Also supports V_WATT 
    	S_RGBW_LIGHT, // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT
    	S_COLOR_SENSOR,  // Color sensor, send color information using V_RGB
    	S_HVAC, // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COLD, V_HVAC_FLOW_STATE, V_HVAC_FLOW_MODE
    	S_MULTIMETER, // Multimeter device, V_VOLTAGE, V_CURRENT, V_IMPEDANCE 
    	S_SPRINKLER,  // Sprinkler, V_STATUS (turn on/off), V_TRIPPED (if fire detecting device)
    	S_WATER_LEAK, // Water leak sensor, V_TRIPPED, V_ARMED
    	S_SOUND, // Sound sensor, V_TRIPPED, V_ARMED, V_LEVEL (sound level in dB)
    	S_VIBRATION, // Vibration sensor, V_TRIPPED, V_ARMED, V_LEVEL (vibration in Hz)
    	S_MOISTURE, // Moisture sensor, V_TRIPPED, V_ARMED, V_LEVEL (water content or moisture in percentage?) 
    };
    
    // sensor data types
    // typedef enum {P_STRING, P_BYTE, P_INT16, P_UINT16, P_LONG32, P_ULONG32, P_CUSTOM, P_FLOAT32 } MyTypes ;
    /*
    */
    
    // Test array: defines the sensor test patterns
    // { sensorId ; sensorMessage ; type (MyTypes) ; lowValue(byte) ; highValue(byte) ; step }
    // integer values take normal step, float values take reciproke step
    int myTestData[NoTests][6]={
     {0, V_TRIPPED, P_BYTE, 30, 50, 2}, // DOOR
     {1, V_TRIPPED, P_BYTE, 30, 40, 2},  // MOTION
     {2, V_TRIPPED, P_BYTE, 30, 30, 2},  // SMOKE
     {3, V_STATUS, P_BYTE, 30, 40, 2},  // BINARY
     {4, V_PERCENTAGE, P_BYTE, 30, 30, 2},  // DIMMER
     {5, V_PERCENTAGE, P_BYTE, 30, 40, 2},  // COVER 
     {6, V_TEMP, P_FLOAT32, 30, 30, 2},  // TEMP
     {7, V_HUM, P_FLOAT32, 30, 40, 2},  // HUM
     {8, V_PRESSURE, P_FLOAT32, 30, 30, 2},  // BARO
     {9, V_WIND, P_BYTE, 30, 40, 2},  // WIND
     {10, V_RAIN, P_BYTE, 30, 30, 2}, // RAIN
     {11, V_UV, P_BYTE, 30, 40, 2}, // UV
     {12, V_WEIGHT, P_BYTE, 30, 30, 2}, // WEIGHT
     {13, V_KWH, P_FLOAT32, 30, 40, 2}, // POWER
     {13, V_WATT, P_FLOAT32, 30, 40, 2}, // POWER
     {14, V_HEATER, P_BYTE, 30, 30, 2}, // HEATER
     {15, V_DISTANCE, P_BYTE, 30, 40, 2}, // DISTANCE
     {16, V_LIGHT_LEVEL, P_BYTE, 30, 50, 2}, // LIGHT_LEVEL
     {19, V_LOCK_STATUS, P_BYTE, 30, 40, 2}, // LOCK
     {20, V_IR_SEND, P_BYTE, 30, 30, 2}, // IR
     {20, V_IR_RECEIVE, P_BYTE, 30, 30, 2}, // IR
     {21, V_VOLUME, P_BYTE, 30, 40, 2}, // WATER
     {22, V_LEVEL, P_FLOAT32, 30, 30, 2}, // AIR QUALITY
     {23, V_STATUS, P_BYTE, 30, 40, 2}, // CUSTOM
     {24, V_LEVEL, P_BYTE, 30, 30, 2}, // DUST
     {25, V_SCENE_ON, P_BYTE, 30, 40, 2},  // SCENE
     {25, V_SCENE_OFF, P_BYTE, 30, 40, 2},  // SCENE
     {26, V_RGB, P_ULONG32, 30, 30, 2},  // RGB
     {27, V_RGBW, P_BYTE, 30, 40, 2},  // RGBW
     {28, V_RGB, P_BYTE, 30, 30, 2},  // COLOR
     {29, V_HVAC_SETPOINT_HEAT, P_BYTE, 30, 40, 2},  // HVAC
     {30, V_VOLTAGE, P_BYTE, 30, 30, 2},  // MULTIMETER
     {30, V_CURRENT, P_BYTE, 30, 30, 2},  // MULTIMETER
     {30, V_IMPEDANCE, P_BYTE, 30, 30, 2},  // MULTIMETER
     {31, V_STATUS, P_BYTE, 30, 40, 2},  // SRINKLER
     {32, V_TRIPPED, P_BYTE, 30, 50, 2},  // WATER_LEAK
     {33, V_TRIPPED, P_BYTE, 30, 40, 2},  // SOUND
     {34, V_TRIPPED, P_BYTE, 30, 30, 2},  // VIBRATION
     {35, V_TRIPPED, P_BYTE, 30, 40, 2},  // MOISTURE
    };
    
    
    // initialize MySensors
    MyTransportNRF24 transport(7, 8); // Ceech board, 3.3v (7,8)  (pin default 9,10)
    MySensor gw(transport); 	      			
    // Initialize messages, not used here
    MyMessage Msg;                    // instantiate message to fill "on the fly
    
    // storage of last values - if you onlys want to send changes (I don't)
    float lastHum, lastTemp, lastPressure, lastLux ;
    unsigned long SLEEP_PERIOD = 1000 ;   // Sleep period in ms)  
    unsigned long loopDelay = 1000 ;      // Sleep period in ms)  
    
    void setup() {
      Serial.println("\n  Stress test for Mysensors network (201508).\n");
      gw.begin(incomingMessage, NODE_ID); 											// start MySensors, manual set node ID
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("AWI Universal test 50", "1.0");
      // Register all sensors to gw (they will be created as child devices)
      for (int i = 0; i < NoSensors ; i++) { 
        gw.present(i+1,MySensorList[i] ); // present all sensors in list
        gw.wait(loopDelay);
      }
    }
    
    void loop()
    {
      gw.process();           // check if message from controller
      for (int i = 0; i < NoTests ; i++) { 
        Msg.setSensor(myTestData[i][0]);    // set the sensor number, byte 0
        Msg.setType(myTestData[i][1]);      // set the sensor type, byte 1
        switch (myTestData[i][2]) {         // determine type of data for test and use in send
          case P_BYTE:
            for (byte j = myTestData[i][3]; i < myTestData[i][4] ; j += myTestData[i][5])
            {
              gw.send(Msg.set(i, true ));
              gw.sleep(SLEEP_PERIOD);
            }
          break;
          case P_INT16:
            for (int j = myTestData[i][3]; i < myTestData[i][4] ; j += myTestData[i][5])
            {
              gw.send(Msg.set(i, true ));
              gw.sleep(SLEEP_PERIOD);
            }
            break;
          case P_UINT16:
            for (unsigned int j = myTestData[i][3]; i < myTestData[i][4] ; j += myTestData[i][5])
            {
              gw.send(Msg.set(i, true ));
              gw.sleep(SLEEP_PERIOD);
            }
          break;
          case P_ULONG32:
            for (unsigned long j = myTestData[i][3]; i < myTestData[i][4] ; j += myTestData[i][5])
            {
              gw.send(Msg.set(i, true ));
              gw.sleep(SLEEP_PERIOD);
            }
          break;
          case P_FLOAT32:
            for (float j = myTestData[i][3]; i < myTestData[i][4] ; j += 1/myTestData[i][5])  // reciproke step for float
            {
              gw.send(Msg.set(i, true ));
              gw.sleep(SLEEP_PERIOD);
            }
          break;
          default: 
            // do nothing
        gw.sleep(SLEEP_PERIOD);
        }
      }
    }
    
    void incomingMessage(const MyMessage &message) {
     Serial.print("Incoming Message");
     // We wait for V_... value
    // if (message.type == V_DISTANCE) {
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(" (type : ");
         Serial.print(message.type);
         Serial.print(")");
         Serial.print(", status: ");
         Serial.println(message.getInt());
     //}
    }
    


  • @TimO
    Yes, it still has the init value of the eprom...
    Good feed back, i'll initialize it to 0 or something.
    Thanks



  • @AWI
    Very interesting and compacts, probably avoids the memory limitations on UNO.
    Great feedback, thanks!



  • @barduino

    Please excuse newness and ignorance (which go hand-in-hand.) Do I understand correctly that this sketch replaces a serial gateway? If so, what changes might be required to make this work for an ethernet gateway? Or, perhaps, do I have this all completely wrong?

    I'm wanting to check out an ethernet connection between a Vera controller (or equivalent) and a Uno, on which I plan to run an internet gateway when I have built some sensors. Not yet having connected a radio, can I use this to mock up some sensors sending data to the Vera gateway plugin, just from an ethernet connected Uno?

    Any help appreciated.



  • @akbooer

    Hi, this sketch does not replace a gateway. It simulates a node with many sensors.

    So its like having an arduino with 24 sensors connected to it (all fake, done by software) it still needs the gateway and radios, etc.

    Some folks here in the forum have made experiences in creating sensors directly on a gateway, not sure if it is supported.

    If so, it might be possible to Mock sensors in the gatway using such a technique...

    Food for thought/investigation,

    Cheers



  • OK and thanks for the quick response!
    I knew I knew nothing.

    So, just to be sure, I run this on an Arduino with a radio, but not sensors. This is going to talk to my Arduino gateway, with radio, and either serial or ethernet connection to the controller, whichever I choose.



  • @akbooer

    That is correct.

    Also, because i'm having some issues updating the source code in git hub here is the latest version (lib 1.5) MockMySensors.ino and l(lib 1.4) FakeMySensorsOrig.ino

    Cheers



  • Thanks so much.



  • all sensors present good but when finish i get a loop sended:

    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0

    im use (lib 1.5) MockMySensors.ino



  • @ch3b7

    Very interesting.
    I was not able to repruduce what you are describing above.

    According to your message we have:

    • Node 50 sending to node 0

    • Child sensor id 0

    • Message type 1 : SET

    • MessageSub Type 16: V_TRIPPED

    • Payload type 7: P_CUSTOM

    • Payload length 5

    Which is very strange.
    In MockMySensors there is no childid=0, the first sensor is #define ID_S_DOOR 1 and the node ID is set to 254 (but perhpas you have changed this)
    Also V_TRIPPED should be sending a bolean value...

    Could you upload your scetch?

    here is my log: SetUP

    send: 254-254-0-0 s=255,c=0,t=17,pt=0,l=3,sg=0,st=ok:1.5
    send: 254-254-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    read: 0-0-254 s=255,c=3,t=6,pt=0,l=1,sg=0:M
    sensor started, id=254, parent=0, distance=1
    GW Started
    Send Sketch Info: send: 254-254-0-0 s=255,c=3,t=11,pt=0,l=14,sg=0,st=ok:MockMySensors 
    send: 254-254-0-0 s=255,c=3,t=12,pt=0,l=4,sg=0,st=ok:v0.3
    MockMySensors v0.3
    Get Config: Metric
    Presenting Nodes
    ________________
      S_DOOR
    send: 254-254-0-0 s=1,c=0,t=0,pt=0,l=0,sg=0,st=ok:
      S_MOTION
    send: 254-254-0-0 s=2,c=0,t=1,pt=0,l=0,sg=0,st=ok:
      S_SMOKE
    send: 254-254-0-0 s=3,c=0,t=2,pt=0,l=0,sg=0,st=ok:
      S_LIGHT
    send: 254-254-0-0 s=4,c=0,t=3,pt=0,l=0,sg=0,st=ok:
      S_DIMMER
    send: 254-254-0-0 s=5,c=0,t=4,pt=0,l=0,sg=0,st=ok:
      S_COVER
    send: 254-254-0-0 s=6,c=0,t=5,pt=0,l=0,sg=0,st=ok:
      S_TMEP
    send: 254-254-0-0 s=7,c=0,t=6,pt=0,l=0,sg=0,st=ok:
      S_HUM
    send: 254-254-0-0 s=8,c=0,t=7,pt=0,l=0,sg=0,st=ok:
      S_BARO
    send: 254-254-0-0 s=9,c=0,t=8,pt=0,l=0,sg=0,st=ok:
      S_WIND
    send: 254-254-0-0 s=10,c=0,t=9,pt=0,l=0,sg=0,st=ok:
      S_RAIN
    send: 254-254-0-0 s=11,c=0,t=10,pt=0,l=0,sg=0,st=ok:
      S_UV
    send: 254-254-0-0 s=12,c=0,t=11,pt=0,l=0,sg=0,st=ok:
      S_WEIGHT
    send: 254-254-0-0 s=13,c=0,t=12,pt=0,l=0,sg=0,st=ok:
      S_POWER
    send: 254-254-0-0 s=14,c=0,t=13,pt=0,l=0,sg=0,st=ok:
      S_DISTANCE
    send: 254-254-0-0 s=16,c=0,t=15,pt=0,l=0,sg=0,st=ok:
      S_LIGHT_LEVEL
    send: 254-254-0-0 s=17,c=0,t=16,pt=0,l=0,sg=0,st=ok:
      S_LOCK
    send: 254-254-0-0 s=18,c=0,t=19,pt=0,l=0,sg=0,st=ok:
      S_IR
    send: 254-254-0-0 s=19,c=0,t=20,pt=0,l=0,sg=0,st=ok:
      S_WATER
    send: 254-254-0-0 s=20,c=0,t=21,pt=0,l=0,sg=0,st=ok:
      S_AIR_QUALITY
    send: 254-254-0-0 s=21,c=0,t=22,pt=0,l=0,sg=0,st=ok:
      S_SCENE_CONTROLLER
    send: 254-254-0-0 s=23,c=0,t=25,pt=0,l=0,sg=0,st=ok:
      S_CUSTOM
    send: 254-254-0-0 s=24,c=0,t=23,pt=0,l=0,sg=0,st=ok:
    ________________
    

    And the loop section

    ########################
    RandomNumber:76
    Send Battery Level
    send: 254-254-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:76
    Request Time
    send: 254-254-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    read: 0-0-254 s=255,c=3,t=1,pt=0,l=10,sg=0:1439720967
    Time value received: 1439720967
    Motion is: Quiet
    send: 254-254-0-0 s=2,c=1,t=16,pt=2,l=2,sg=0,st=ok:0
    Smoke is: Quiet
    send: 254-254-0-0 s=3,c=1,t=16,pt=2,l=2,sg=0,st=ok:0
    Light is: On
    send: 254-254-0-0 s=4,c=1,t=2,pt=2,l=2,sg=0,st=ok:1
    Dimmer is set to: 255
    send: 254-254-0-0 s=5,c=1,t=3,pt=2,l=2,sg=0,st=ok:255
    Cover is : Idle
    send: 254-254-0-0 s=6,c=1,t=31,pt=2,l=2,sg=0,st=ok:31
    Temperature is: 34
    send: 254-254-0-0 s=7,c=1,t=0,pt=4,l=4,sg=0,st=ok:34
    Humitidty is: 76
    send: 254-254-0-0 s=8,c=1,t=1,pt=4,l=4,sg=0,st=ok:76
    Atmosferic Pressure is: 103363
    send: 254-254-0-0 s=9,c=1,t=4,pt=4,l=4,sg=0,st=ok:103363
    Weather forecast: unstable
    send: 254-254-0-0 s=9,c=1,t=5,pt=0,l=8,sg=0,st=ok:unstable
    Wind Speed is: 76
    send: 254-254-0-0 s=10,c=1,t=8,pt=4,l=4,sg=0,st=ok:76
    Wind Gust is: 86
    send: 254-254-0-0 s=10,c=1,t=9,pt=4,l=4,sg=0,st=ok:86
    Wind Direction is: 272
    send: 254-254-0-0 s=10,c=1,t=10,pt=4,l=4,sg=0,st=ok:272
    Rain ammount  is: 76
    send: 254-254-0-0 s=11,c=1,t=6,pt=4,l=4,sg=0,st=ok:76
    Rain rate  is: 1
    send: 254-254-0-0 s=11,c=1,t=7,pt=7,l=5,sg=0,st=ok:1.0
    Ultra Violet level is: 11
    send: 254-254-0-0 s=12,c=1,t=11,pt=4,l=4,sg=0,st=ok:11
    Weight is: 113
    send: 254-254-0-0 s=13,c=1,t=12,pt=4,l=4,sg=0,st=ok:113
    Impedance is: 113
    send: 254-254-0-0 s=14,c=1,t=14,pt=4,l=4,sg=0,st=ok:113
    Watt is: 113
    send: 254-254-0-0 s=14,c=1,t=17,pt=4,l=4,sg=0,st=ok:113
    KWH is: 113
    send: 254-254-0-0 s=14,c=1,t=18,pt=4,l=4,sg=0,st=ok:113
    Voltage is: 113
    send: 254-254-0-0 s=14,c=1,t=38,pt=4,l=4,sg=0,st=ok:113
    Current is: 113
    send: 254-254-0-0 s=14,c=1,t=39,pt=4,l=4,sg=0,st=ok:113
    Distance is: 113
    send: 254-254-0-0 s=16,c=1,t=13,pt=4,l=4,sg=0,st=ok:113
    Light is: 113
    send: 254-254-0-0 s=17,c=1,t=23,pt=4,l=4,sg=0,st=ok:113
    Lock is: On
    send: 254-254-0-0 s=18,c=1,t=36,pt=2,l=2,sg=0,st=ok:1
    Infrared is: 255
    send: 254-254-0-0 s=19,c=1,t=32,pt=2,l=2,sg=0,st=ok:255
    Water flow is: 113
    send: 254-254-0-0 s=20,c=1,t=34,pt=4,l=4,sg=0,st=ok:113
    Water volume is: 113
    send: 254-254-0-0 s=20,c=1,t=35,pt=4,l=4,sg=0,st=ok:113
    Air Quality is: 76
    send: 254-254-0-0 s=21,c=1,t=24,pt=4,l=4,sg=0,st=ok:76
    Scene is: On
    send: 254-254-0-0 s=23,c=1,t=19,pt=2,l=2,sg=0,st=ok:1
    Custom value is: 76
    send: 254-254-0-0 s=24,c=1,t=25,pt=4,l=4,sg=0,st=ok:76
    send: 254-254-0-0 s=24,c=1,t=26,pt=4,l=4,sg=0,st=ok:76
    send: 254-254-0-0 s=24,c=1,t=27,pt=4,l=4,sg=0,st=ok:76
    send: 254-254-0-0 s=24,c=1,t=28,pt=4,l=4,sg=0,st=ok:76
    send: 254-254-0-0 s=255,c=3,t=0,pt=1,l=1,sg=0,st=ok:76
    #########################
    


  • @barduino

    sorry your sketch work good! the problem im have is with the @AWI example!

    @AWI

    all sensors present good but when finish i get a loop sended:

    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0
    send: 50-50-0-0 s=0,c=1,t=16,pt=7,l=5,sg=0,st=ok:0.0


  • Hero Member

    @ch3b7 Sorry to have confused you but my sketch was meant for inspiration and as an alternative method to "stress test" the controller and network.
    The version I published is firing an enormous amount of messages at the controller for each sensor. The test data is in myTestData in the format {sensor, V_type, Dataformat, start_value, end_value, stepsize} You can fill the array with anything you want (also "not allowed" combinations).
    I suggest you remove the "ack" which is sent with each message at firtst {gw.send(Msg.set(i, false ))};



  • @AWI, @ch3b7
    The loop may be caused by a bug in the source code :

     for (int i = 0; i < NoTests ; i++) { 
        [...]
            for (byte j = myTestData[i][3]; i < myTestData[i][4] ; j += myTestData[i][5])
            {
              gw.send(Msg.set(i, true ));
    

    Isn't there a mix between 'i' and 'j' ? Shouldn't it be

     for (int i = 0; i < NoTests ; i++) { 
        [...]
            for (byte j = myTestData[i][3]; j < myTestData[i][4] ; j += myTestData[i][5])
            {
              gw.send(Msg.set(j, true ));
    

    Sorry, cannot test it right now...


  • Hero Member

    @rene_2k2 you're right, thanks



  • @awi can you upload the fixed SKETCH ?? pls! thank you!!



  • I'm most grateful for your work on this sketch - I've used it to exercise my gateway as I developed and debugged my Vera emulation environment called 'openLuup'. I now have a controller for MySensors running on Vera, BeagleBone Black, and an Arduino Yun, all running the ALTUI interface, so it looks like the attached.

    Many thanks for the code and the initial explanations.

    MySensors on openLuup.jpg



  • @akbooer let me tell you...
    It looks fanastic!



  • Well, thank you. But I have to say that the L&F is all down to the amazing ALTUI plugin produced by @amg0 on the Vera BB. I just do the behind-the-scenes bits which make it work on platforms other than Vera.


  • Hero Member

    A "new" version of a stress test or "Fake sensor". As mentioned in a previous post it will never be complete. But I gave it an update to make it easier to work with.

    This version (MySensors 1.5) will take an array of test values ; present them to the gateway/controller and spit out a range of values for each sensor in the testArray.

    Version below is fixed node 50, 9 sensors and sends data every 0.1 sec.

    /*
     PROJECT: MySensors
     PROGRAMMER: AWI
     DATE: 10 august 2015, update 4 september 2015
     FILE: AWI_Universal_Test_50.ino
     LICENSE: Public domain
       -in conjunction with MySensors
     
     STATUS: never finished, MySensors 1.5
     KNOWN ISSUES: no text message yet
     
     SUMMARY:
    	multisensor for controller stress test
    	1. Presents sensors to controller
    	2. Sends (per sensor) values in defined range
    	repeat
    	
     Setup: sends values for al sensor specified in setup array 
      
     Update: 20150904: Changed structure and type definitions (makes is easier to read)
     */
    #include <MySensor.h>  
    #include <SPI.h>
    
    const int NODE_ID = 50;  		  		// fixed MySensors node ID
    const bool testAck = false ;			// set to true if you want all tests to be acknowledged 
    
    // reference: typedef enum {P_STRING, P_BYTE, P_INT16, P_UINT16, P_LONG32, P_ULONG32, P_CUSTOM, P_FLOAT32 } mysensor_payload ; // MySensor types
    
    typedef	union {							// MySensor Payload types (only p_String used in this sketch)
    	char p_String[10] ; 				// reduce characters to limit RAM size
    	int16_t p_Int16 ;
    	uint16_t p_Uint16 ;
    	int32_t p_Int32 ;
    	uint32_t p_Uint32 ;
    	byte p_Byte ;
    	float p_Float32 ;
    	} payLoadType ;
    
    // data type for tests
    typedef struct {
    	int s_type ;						// S_ type of the sensor number (only for init)
    	char s_name[10] ;					// sensor name (max 9 char) 						
    	int v_type ;						// data V_ type to be sent
    	mysensor_payload dataType ;			// data type identifier (uses MySensors MyTypes definition)
    	payLoadType testStartValue ;		// start value for test
    	payLoadType testEndValue ;			// end value for test
    	float testIncrement;				// test increment (different behaviour for each datatype)
    	} testDataType ;
    
    
    // TESTDATA: testdata & initialization, change to adapt to your needs
    const int noSensors = 9 ; 				// number of active sensors in node
    const int noTests = noSensors ;			// noTests == noSensors for now
    
    // testData index determines child_no
    testDataType testData[noSensors] = { 									// size determined by noSensors constant
    	{S_MOISTURE, "Moist1" , V_LEVEL, P_BYTE, "40", "50", 1 },			// start & end values in text for convenience, are converted later
    	{S_MOISTURE, "Moist2" , V_LEVEL, P_BYTE, "60", "70", 1 },
    	{S_MOISTURE, "Moist3" , V_LEVEL, P_BYTE, "80", "90", 1 },
    	{S_MULTIMETER, "Multi1", V_VOLTAGE, P_FLOAT32, "30.2", "50.0", 2},  // MULTIMETER
    	{S_MULTIMETER, "Multi2", V_CURRENT, P_FLOAT32, "1.3", "5.6", 1},  
    	{S_MULTIMETER, "Multi3", V_IMPEDANCE, P_FLOAT32, "300", "900", 50},  
    	{S_TEMP, "Temp1", V_TEMP, P_FLOAT32, "1.1", "20.3", 2},				// Temperature
    	{S_TEMP, "Temp2", V_TEMP, P_FLOAT32, "10.3", "50.6", 3}, 
    	{S_TEMP, "Temp3", V_TEMP, P_FLOAT32, "300", "900", 50}
    	};
    // END TESTDATA
    	
    	
    // initialize MySensors
    MyTransportNRF24 transport(9, 10); // Ceech board, 3.3v (7,8)  (pin default 9,10)
    MySensor gw(transport); 	      			
    // Initialize messages (only generic message here)
    MyMessage Msg;                    // instantiate message to fill "on the fly
    
    unsigned long SLEEP_PERIOD = 100 ;   // Period between individual tests in ms  
    unsigned long loopDelay = 1000 ;      // Sleep period in ms)  
    
    void setup() {
      Serial.println("\n  Stress test for Mysensors network (20150904).\n");
      gw.begin(incomingMessage, NODE_ID); 								// start MySensors, fixed node ID
      // Send the sketch version information to the gateway and Controller
      gw.sendSketchInfo("AWI Universal test 50", "1.1");
     
      for (int i = 0; i < noSensors ; i++) {  							// Register al sensors (they will be created as child devices)
        gw.present(i , testData[i].s_type, testData[i].s_name ); 		// present all sensors in list (sensor_no, sensor_type, sensor_name)
        gw.wait(loopDelay);
      }
    }
    
    void loop()
    {
      gw.process();           											// check if message from controller
      for (int i = 0; i < noTests ; i++) { 
        Msg.setSensor(i);				    							// set the sensor number, byte 0
        Msg.setType(testData[i].v_type);      							// set the sensor type, byte 1
        switch (testData[i].dataType) {         						// data type determines test format
          case P_BYTE:
            for (byte j = atoi(testData[i].testStartValue.p_String) ; j < atoi(testData[i].testEndValue.p_String) ; j += testData[i].testIncrement)
            {
              gw.send(Msg.set(j), testAck);
              gw.wait(SLEEP_PERIOD);
            }
          break;
          case P_INT16:
            for (int j = atoi(testData[i].testStartValue.p_String) ; j < atoi(testData[i].testEndValue.p_String) ; j += testData[i].testIncrement)
            {
              gw.send(Msg.set(j), testAck);
              gw.wait(SLEEP_PERIOD);
            }
            break;
          case P_UINT16:
            for (unsigned int j = atoi(testData[i].testStartValue.p_String) ; j < atoi(testData[i].testEndValue.p_String) ; j += testData[i].testIncrement)
            {
              gw.send(Msg.set(j), testAck);
              gw.wait(SLEEP_PERIOD);
            }
          break;
          case P_ULONG32:
            for (unsigned long j = atol(testData[i].testStartValue.p_String) ; j < atol(testData[i].testEndValue.p_String) ; j += testData[i].testIncrement)
            {
              gw.send(Msg.set(j), testAck);
              gw.wait(SLEEP_PERIOD);
            }
          break;
          case P_FLOAT32:
            for (float j = atof(testData[i].testStartValue.p_String) ; j < atof(testData[i].testEndValue.p_String) ; j += testData[i].testIncrement)  
            {
              gw.send(Msg.set(j,3), testAck );
              gw.wait(SLEEP_PERIOD);
            }
          break;
          default: 
            // do nothing
        gw.wait(loopDelay);
        }
      }
    }
    
    void incomingMessage(const MyMessage &message) {
     Serial.print("Incoming Message");
         Serial.print("Incoming change for sensor:");
         Serial.print(message.sensor);
         Serial.print(" (type : ");
         Serial.print(message.type);
         Serial.print(")");
         Serial.print(", status: ");
         Serial.println(message.getInt());
     //}
    }
    
    
    /*	IGNORE: For reference only
    	S_DOOR, // Door sensor, V_TRIPPED, V_ARMED
    	S_MOTION,  // Motion sensor, V_TRIPPED, V_ARMED 
    	S_SMOKE,  // Smoke sensor, V_TRIPPED, V_ARMED
    	S_BINARY, // Binary light or relay, V_STATUS (or V_LIGHT), V_WATT (same as S_LIGHT)
    	S_DIMMER, // Dimmable light or fan device, V_STATUS (on/off), V_DIMMER (dimmer level 0-100), V_WATT
    	S_COVER, // Blinds or window cover, V_UP, V_DOWN, V_STOP, V_DIMMER (open/close to a percentage)
    	S_TEMP, // Temperature sensor, V_TEMP
    	S_HUM, // Humidity sensor, V_HUM
    	S_BARO, // Barometer sensor, V_PRESSURE, V_FORECAST
    	S_WIND, // Wind sensor, V_WIND, V_GUST
    	S_RAIN, // Rain sensor, V_RAIN, V_RAINRATE
    	S_UV, // Uv sensor, V_UV
    	S_WEIGHT, // Personal scale sensor, V_WEIGHT, V_IMPEDANCE
    	S_POWER, // Power meter, V_WATT, V_KWH
    	S_HEATER, // Header device, V_HVAC_SETPOINT_HEAT, V_HVAC_FLOW_STATE
    	S_DISTANCE, // Distance sensor, V_DISTANCE
    	S_LIGHT_LEVEL, // Light level sensor, V_LIGHT_LEVEL (uncalibrated in percentage),  V_LEVEL (light level in lux)
    	S_ARDUINO_NODE, // Used (internally) for presenting a non-repeating Arduino node
    	S_ARDUINO_REPEATER_NODE, // Used (internally) for presenting a repeating Arduino node 
    	S_LOCK, // Lock device, V_LOCK_STATUS
    	S_IR, // Ir device, V_IR_SEND, V_IR_RECEIVE
    	S_WATER, // Water meter, V_FLOW, V_VOLUME
    	S_AIR_QUALITY, // Air quality sensor, V_LEVEL
    	S_CUSTOM, // Custom sensor 
    	S_DUST, // Dust sensor, V_LEVEL
    	S_SCENE_CONTROLLER, // Scene controller device, V_SCENE_ON, V_SCENE_OFF. 
    	S_RGB_LIGHT, // RGB light. Send color component data using V_RGB. Also supports V_WATT 
    	S_RGBW_LIGHT, // RGB light with an additional White component. Send data using V_RGBW. Also supports V_WATT
    	S_COLOR_SENSOR,  // Color sensor, send color information using V_RGB
    	S_HVAC, // Thermostat/HVAC device. V_HVAC_SETPOINT_HEAT, V_HVAC_SETPOINT_COLD, V_HVAC_FLOW_STATE, V_HVAC_FLOW_MODE
    	S_MULTIMETER, // Multimeter device, V_VOLTAGE, V_CURRENT, V_IMPEDANCE 
    	S_SPRINKLER,  // Sprinkler, V_STATUS (turn on/off), V_TRIPPED (if fire detecting device)
    	S_WATER_LEAK, // Water leak sensor, V_TRIPPED, V_ARMED
    	S_SOUND, // Sound sensor, V_TRIPPED, V_ARMED, V_LEVEL (sound level in dB)
    	S_VIBRATION, // Vibration sensor, V_TRIPPED, V_ARMED, V_LEVEL (vibration in Hz)
    	S_MOISTURE, // Moisture sensor, V_TRIPPED, V_ARMED, V_LEVEL (water content or moisture in percentage?) 
    };
    
    // sensor data types
    // typedef enum {P_STRING, P_BYTE, P_INT16, P_UINT16, P_LONG32, P_ULONG32, P_CUSTOM, P_FLOAT32 } MyTypes ;
    
    sTypes[V_TEMP] =  P_FLOAT32; // S_TEMP
    sTypes[V_HUM] =P_FLOAT32; // S_HUM
    sTypes[V_STATUS] = P_UINT16; //  S_LIGHT, S_DIMMER, S_SPRINKLER, S_HVAC, S_HEATER. Used for setting binary (on/off) status. 1=on, 0=off  
    sTypes[V_LIGHT] = P_UINT16; // Same as V_STATUS
    sTypes[V_PERCENTAGE] = P_UINT16; // S_DIMMER. Used for sending a percentage value (0-100). 
    sTypes[V_DIMMER] = P_UINT16; // S_DIMMER. Same as V_PERCENTAGE.  
    sTypes[V_PRESSURE] = P_FLOAT32; // S_BARO
    sTypes[V_FORECAST] = P_FLOAT32; // S_BARO
    sTypes[V_RAIN] = P_FLOAT32; // S_RAIN
    sTypes[V_RAINRATE] = P_FLOAT32;  // S_RAIN
    sTypes[V_WIND] = P_FLOAT32; // S_WIND
    sTypes[V_GUST] = P_FLOAT32; // S_WIND
    sTypes[V_DIRECTION] = P_FLOAT32; // S_WIND 
    sTypes[V_UV] = P_FLOAT32; // S_UV
    sTypes[V_WEIGHT] = P_FLOAT32; // S_WEIGHT
    sTypes[V_DISTANCE] = P_FLOAT32; // S_DISTANCE
    sTypes[V_IMPEDANCE] = P_FLOAT32; // S_MULTIMETER, S_WEIGHT
    sTypes[V_ARMED]= P_FLOAT32; // S_DOOR, S_MOTION, S_SMOKE, S_SPRINKLER
    sTypes[V_TRIPPED]= P_FLOAT32; // S_DOOR, S_MOTION, S_SMOKE, S_SPRINKLER (for sprinklers with fire detection)
    sTypes[V_WATT]= P_FLOAT32; // S_POWER, S_LIGHT, S_DIMMER
    sTypes[V_KWH]= P_FLOAT32; // S_POWER
    sTypes[V_SCENE_ON]= P_FLOAT32; // S_SCENE_CONTROLLER
    sTypes[V_SCENE_OFF]= P_FLOAT32; // S_SCENE_CONTROLLER
    sTypes[V_HEATER]= P_FLOAT32; // Deprecated. Use V_HVAC_FLOW_STATE instead.
    sTypes[V_HVAC_FLOW_STATE] = P_UINT16; // HVAC flow state ("Off", "HeatOn", "CoolOn", or "AutoChangeOver"). S_HEATER, S_HVAC 
    sTypes[V_HVAC_SPEED]= P_FLOAT32; // HVAC/Heater fan speed ("Min", "Normal", "Max", "Auto") 
    sTypes[V_LIGHT_LEVEL]= P_UINT16; // Used for sending light level in uncalibrated percentage. See also V_LEVEL (light level in lux). S_LIGHT_LEVEL
    sTypes[V_VAR1] = P_FLOAT32;
    sTypes[V_VAR2] = P_FLOAT32;
    sTypes[V_VAR3] = P_FLOAT32;
    sTypes[V_VAR4] = P_FLOAT32;
    sTypes[V_VAR5] = P_FLOAT32;
    sTypes[V_UP] = P_FLOAT32; // S_COVER
    sTypes[V_DOWN] = P_FLOAT32; // S_COVER
    sTypes[V_STOP] = P_FLOAT32; // S_COVER
    sTypes[V_IR_SEND] = P_FLOAT32; // S_IR
    sTypes[V_IR_RECEIVE] = P_FLOAT32; // S_IR
    sTypes[V_FLOW] = P_FLOAT32; // S_WATER
    sTypes[V_VOLUME] = P_FLOAT32; // S_WATER
    sTypes[V_LOCK_STATUS] = P_FLOAT32; // S_LOCK
    sTypes[V_LEVEL] = P_UINT16; // S_DUST, S_AIR_QUALITY, S_SOUND (dB), S_VIBRATION (hz), S_LIGHT_LEVEL (lux)
    sTypes[V_VOLTAGE] = P_FLOAT32; // S_MULTIMETER 
    sTypes[V_CURRENT] = P_FLOAT32; // S_MULTIMETER
    sTypes[V_RGB] = P_ULONG32; 	// S_RGB_LIGHT, S_COLOR_SENSOR. 
    					// Used for sending color information for multi color LED lighting or color sensors. 
    					// Sent as ASCII hex: RRGGBB (RR=red, GG=green, BB=blue component)
    sTypes[V_RGBW] = P_ULONG32; // S_RGBW_LIGHT
    					// Used for sending color information to multi color LED lighting. 
    					// Sent as ASCII hex: RRGGBBWW (WW=while component)
    sTypes[V_ID] = P_FLOAT32; // S_TEMP
    					// Used for sending in sensors hardware ids (i.e. OneWire DS1820b). 
    sTypes[V_UNIT_PREFIX] = P_STRING; // Allows sensors to send in a string representing the 
    								 // unit prefix to be displayed in GUI, not parsed by controller! E.g. cm, m, km, inch.
    								 // Can be used for S_DISTANCE or gas concentration (S_DUST, S_AIR_QUALITY)
    sTypes[V_HVAC_SETPOINT_COOL] = P_UINT16; // HVAC cool setpoint (Integer between 0-100). S_HVAC
    sTypes[V_HVAC_SETPOINT_HEAT] = P_UINT16; // HVAC/Heater setpoint (Integer between 0-100). S_HEATER, S_HVAC
    sTypes[V_HVAC_FLOW_MODE] = P_UINT16; // Flow mode for HVAC ("Auto", "ContinuousOn", "PeriodicOn"). S_HVAC
    */
    

  • Hero Member

    @akbooer , just curious to know, what version of AltUI do you have? Did you adjust anything into the mySensors plugin json?

    I'm asking that because, my plugin display a bit different:

    Picture1.png



  • @rvendrame

    Yes, I made a mod to the Arduino plugin. The changes are on GitHub:

    https://github.com/akbooer/Vera/blob/features-for-altui/L_Arduino.lua

    I'm hoping to get this merged with the master branch in due course, but I've not finished.


  • Hero Member

    @akbooer , thanks a lot!



  • Hi Folks,

    @GizMoCuz just commited a new version of MockMySensors and I'm about to commit another (MockMySensors.ino) (need to merge with his changes).

    This will complete the 1.4 lib sensors and Giz has already started adding more.

    In the mean time here is a picture of MockMySensors running on the MYSController

    20150906_MYSController.png

    And here is how it look on the HAALL controller

    20150906_Dashboard.png

    If you have used this skecth in other controller would you mind posting screen shots of it here?

    Cheers



  • Hello, is it possible to MockMySensors without physical radio on the gateway?
    I ordered/received wrong radios and I am now waiting (most likely a month) for the new ones, but I would like to setup the controller without actual sensors. How can I mock them, or somehow simulate sensors without the radio?
    Thanks


  • Admin

    @dakipro

    Depending on what you want to run your controller on, and your own experience level with hacking stuff, you can use node-red to simulate sensors, and inject fake sensors into the controller of your choice. (Not all controllers support this though)

    head over to http://forum.mysensors.org/topic/1965/nodered-injected-between-domoticz-and-mysensors for more info on setup..



  • @dakipro

    I use nodeJS to read from the serial gatweay and send the information to my my controller HAALL, similar to what @tbowmo is suggesting.

    Now depending on how your controller accepts information you might pull this off with some hacking. (In HAALL case it accepts via REST service). I've attached my nodeJS example for convenience.

    Cheers



  • Thank you. I installed MajorDoMo controller on a old laptop, just because it is written in php - which I do professionally so that I could optimize or debug it. And it looks decent too 🙂
    I just started with the MySensors and Arduino so I guess it will take me some time to get familiar with how everything works.

    My initial idea was to just use mockMySensors without radio and other sensors, but when I try initiate MySensors lib on the arduino I get "radio init fail" which is expected as I do not have the radio attached (it will arrive soon).
    I messed a bit inside MySensors library, trying to comment out the part that initializes the radio but then I get some other messages. I guess it is never needed in practice to turn off radio portion of MySensors.

    Maybe my question is more related to Network Stress test thread http://forum.mysensors.org/topic/2000/mysensors-network-stress-test on which I also get the same "radio init fail" message, as again radio is missing.

    If I find the time I will try to make some software emulation for sensors, based on your NodeJS example. That could be useful for prepping the Controller before even making new sensors, also for simulating scenarios and test how would controller react in certain situations (how different scenes work etc).


  • Admin

    The mock example is written to use radio communications. Can be pretty hairy to fix it. Suggest you run the development branch which allows sensors to be attached to gateway. It should run twith the mock example if you configure it as a serial gateway (radio disabled).. See Serial Gateway example for how to activate gateway.

    Here is a couple of nodejs modules that might be helpful:
    http://forum.mysensors.org/topic/2208/node-js-modules-for-mysensors



  • @dakipro

    arghhh of course, it will be very dificult geting pass the radio init fail...

    Sorry, I pointed you in the wrong direction.



  • Hi Folks,

    The guys at MySensors were kind to convert this to 1.6 lib.

    So being back in Europe for the holidays I decided to create a post with some explanations/tutorial about the code.

    This example MockMySensors from the MySensors examples actually combines 30 sensors in a single node.

    It may have a poor architecture but it will give you an idea of how to combine sensors and with some feedback we can always improve on the architecture.

    It has been designed for you to customize it for the sensor you want to test by uncomment the initial lines.

    This line defines your NODE ID, you can always change it to AUTO or to your specification

    #define MY_NODE_ID 254
    

    This part of the code defines the sensors you want to work with and their ids

    #define ID_S_ARMED             0  // dummy to controll armed stated for several sensors
    #define ID_S_DOOR              1
    //#define ID_S_MOTION            2
    //#define ID_S_SMOKE             3
    //#define ID_S_LIGHT             4
    //#define ID_S_DIMMER            5
    //#define ID_S_COVER             6
    //#define ID_S_TEMP              7
    //#define ID_S_HUM               8
    //#define ID_S_BARO              9
    ... code lines snipped ...
    //#define ID_S_MOISTURE          33
    //
    //#define ID_S_CUSTOM            99
    

    This part of the code defines the messages you want to instantiate to work with your sensors

    #ifdef ID_S_DOOR // V_TRIPPED, V_ARMED
      MyMessage msg_S_DOOR_T(ID_S_DOOR,V_TRIPPED);
      MyMessage msg_S_DOOR_A(ID_S_DOOR,V_ARMED);
    #endif
    
    #ifdef ID_S_MOTION // V_TRIPPED, V_ARMED
      MyMessage msg_S_MOTION_A(ID_S_MOTION,V_ARMED);
      MyMessage msg_S_MOTION_T(ID_S_MOTION,V_TRIPPED);
    #endif
    
    #ifdef ID_S_SMOKE  // V_TRIPPED, V_ARMED
      MyMessage msg_S_SMOKE_T(ID_S_SMOKE,V_TRIPPED);
      MyMessage msg_S_SMOKE_A(ID_S_SMOKE,V_ARMED);
    #endif
    
    #ifdef ID_S_LIGHT
      MyMessage msg_S_LIGHT(ID_S_LIGHT,V_LIGHT);
      bool isLightOn=0;
    #endif
    ... code lines snipped ...
    #ifdef ID_S_MOISTURE
    // To be implemented
    #endif
    

    On the presentation section, you have all the sensors being presented, along with some debugging

    void presentation()  {
    #ifdef ID_S_DOOR
        Serial.println("  S_DOOR");
        present(ID_S_DOOR,S_DOOR,"Outside Door");
        wait(SHORT_WAIT);
      #endif
      
      #ifdef ID_S_MOTION
        Serial.println("  S_MOTION");
        present(ID_S_MOTION,S_MOTION,"Outside Motion");
        wait(SHORT_WAIT);
      #endif
      
      #ifdef ID_S_SMOKE
        Serial.println("  S_SMOKE");
        present(ID_S_SMOKE,S_SMOKE,"Kitchen Smoke");
        wait(SHORT_WAIT);
      #endif
      ... code lines snipped ...
      #ifdef ID_S_CUSTOM
        Serial.println("  S_CUSTOM");
        present(ID_S_CUSTOM,S_CUSTOM,"Other Stuff");
        wait(SHORT_WAIT);
      #endif
    

    On the loop section you have methods which will trigger each sensor to report. This will happen periodically on the SLEEP_TIME, 15 minutes by default

    void loop()[ 
      //Read Sensors
      #ifdef ID_S_DOOR 
        door(); 
      #endif
      
      #ifdef ID_S_MOTION
        motion();
      #endif
      
      #ifdef ID_S_SMOKE
        smoke();
      #endif
    
      ... code lines snipped ...
    
      #ifdef ID_S_CUSTOM
        custom();
      #endif
    

    Lets take a look at one of them, the dimmer. As you can see its just reporting the dimmerVal which was declared as a global variable.
    Sometimes these values are saved in the EPROM, for this example I wanted to avoid that.

       #ifdef ID_S_DIMMER
    	void dimmer(){
    
      	Serial.print("Dimmer is set to: " );
      	Serial.println(dimmerVal);
      
      	send(msg_S_DIMMER.set(dimmerVal));
    
    	}
    	#endif
    

    Finally the incoming message section.

    void receive(const MyMessage &message) {
    ... code lines snipped ...
    	#ifdef ID_S_DIMMER
        case V_DIMMER:
              if ((message.getInt()<0)||(message.getInt()>100)) {
                Serial.println( "V_DIMMER data invalid (should be 0..100)" );
                break;
              }
              dimmerVal= message.getInt();
              Serial.print("Incoming change for ID_S_DIMMER:");
              Serial.print(message.sensor);
              Serial.print(", New status: ");
              Serial.println(message.getInt());
              dimmer();// temp ack
        break;
        #endif
    ... code lines snipped ...
    

    The temp ack mean I'm just forcing the sensor to report back the new value to the controller.

    And this is basically what it takes to combine sensors in the MySensors library.

    One node can have many sensors and each sensor can receive any number or combinations of messages.

    So for the dimmer example

    #define ID_S_DIMMER            5
    ... code lines snipped ...
    #ifdef ID_S_DIMMER
      MyMessage msg_S_DIMMER(ID_S_DIMMER,V_DIMMER);
      int dimmerVal=100;
    #endif
    ... code lines snipped ...
    
    void presentation()  {
    ... code lines snipped ...
    #ifdef ID_S_DIMMER
    	Serial.println("  S_DIMMER");
        present(ID_S_DIMMER,S_DIMMER,"Living room dimmer");
        wait(SHORT_WAIT);
    #endif
    ... code lines snipped ...
    

    There is nothing stoping me to add another message type to the dimmer. So for example if the dimmer does have an on/off button I could add

    MyMessage msg_S_DIMMER_BUTTON(ID_S_DIMMER,V_STATUS)
    

    Note that your controller might not be expecting all this freedom of combinations of messages.

    So although I could report a temperature on a dimmer sensor using

    MyMessage msg_S_DIMMER_BUTTON(ID_S_DIMMER,V_TEMP)
    

    Your controller might not like it.

    As always feddback is welcome

    Cheers


Log in to reply
 

Suggested Topics

  • 2
  • 48
  • 2
  • 482
  • 4
  • 10

8
Online

11.4k
Users

11.1k
Topics

112.7k
Posts