Advertisement
jp112

HB-UNI-SenAct-8-8-RC_OhneTaster

Aug 19th, 2019
383
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //- -----------------------------------------------------------------------------------------------------------------------
  2. // AskSin++
  3. // 2016-10-31 papa Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
  4. // 2018-11-01 jp112sdl Creative Commons - http://creativecommons.org/licenses/by-nc-sa/3.0/de/
  5. //- -----------------------------------------------------------------------------------------------------------------------
  6.  
  7. // define this to read the device id, serial and device type from bootloader section
  8. // #define USE_OTA_BOOTLOADER
  9. // #define NDEBUG
  10. #define USE_WOR
  11.  
  12. #define EI_NOTEXTERNAL
  13. #include <EnableInterrupt.h>
  14. #include <AskSinPP.h>
  15. #include <LowPower.h>
  16. #include <MultiChannelDevice.h>
  17. #include <Switch.h>
  18.  
  19. //#define USE_BATTERY_MODE       // bei Batteriebetrieb
  20. #define LOWBAT_VOLTAGE     22    // Batterie-Leermeldung bei Unterschreiten der Spannung von U * 10
  21. #define RELAY1_PIN 14
  22. #define RELAY2_PIN 15
  23. #define RELAY3_PIN 16
  24. #define RELAY4_PIN 17
  25. #define RELAY5_PIN 7
  26. #define RELAY6_PIN 9
  27. #define RELAY7_PIN 6
  28. #define RELAY8_PIN 5
  29. #define RELAY_ON_STATE_INVERT true
  30.  
  31. #define REMOTE_PIN_1 0
  32. #define REMOTE_PIN_2 0
  33. #define REMOTE_PIN_3 0
  34. #define REMOTE_PIN_4 0
  35. #define REMOTE_PIN_5 0
  36. #define REMOTE_PIN_6 0
  37. #define REMOTE_PIN_7 0
  38. #define REMOTE_PIN_8 0
  39.  
  40. #define LED_PIN            4
  41. #define CONFIG_BUTTON_PIN  8
  42.  
  43. // number of available peers per channel
  44. #define PEERS_PER_SwitchChannel  3
  45. #define PEERS_PER_RemoteChannel  3
  46.  
  47. #ifdef USE_BATTERY_MODE
  48. #define battOp_ARGUMENT BatterySensor
  49. #define DEV_MODEL 0x39
  50. #else
  51. #define battOp_ARGUMENT NoBattery
  52. #define DEV_MODEL 0x38
  53. #endif
  54.  
  55. #define remISR(device,chan,pin) class device##chan##ISRHandler { \
  56.     public: \
  57.       static void isr () { device.remoteChannel(chan).irq(); } \
  58.   }; \
  59.   device.remoteChannel(chan).button().init(pin); \
  60.   if( digitalPinToInterrupt(pin) == NOT_AN_INTERRUPT ) \
  61.     enableInterrupt(pin,device##chan##ISRHandler::isr,CHANGE); \
  62.   else \
  63.     attachInterrupt(digitalPinToInterrupt(pin),device##chan##ISRHandler::isr,CHANGE);
  64.  
  65. // all library classes are placed in the namespace 'as'
  66.  
  67. using namespace as;
  68.  
  69. // define all device properties
  70. const struct DeviceInfo PROGMEM devinfo = {
  71.   {0xf3, DEV_MODEL, 0x01},// Device ID
  72.   "JPSENACT01",           // Device Serial
  73.   {0xf3, DEV_MODEL},      // Device Model
  74.   0x10,                   // Firmware Version
  75.   as::DeviceType::Switch, // Device Type
  76.   {0x01, 0x00}            // Info Bytes
  77. };
  78. /**
  79.    Configure the used hardware
  80. */
  81. typedef AvrSPI<10, 11, 12, 13> RadioSPI;
  82. typedef AskSin<StatusLed<LED_PIN>, battOp_ARGUMENT, Radio<RadioSPI, 2> > Hal;
  83. Hal hal;
  84.  
  85. DEFREGISTER(Reg0, MASTERID_REGS, DREG_INTKEY)
  86. class SwList0 : public RegList0<Reg0> {
  87.   public:
  88.     SwList0(uint16_t addr) : RegList0<Reg0>(addr) {}
  89.     void defaults() {
  90.       clear();
  91.       intKeyVisible(true);
  92.     }
  93. };
  94.  
  95. DEFREGISTER(RemoteReg1, CREG_LONGPRESSTIME, CREG_AES_ACTIVE, CREG_DOUBLEPRESSTIME)
  96. class RemoteList1 : public RegList1<RemoteReg1> {
  97.   public:
  98.     RemoteList1 (uint16_t addr) : RegList1<RemoteReg1>(addr) {}
  99.     void defaults () {
  100.       clear();
  101.       longPressTime(1);
  102.       // aesActive(false);
  103.       // doublePressTime(0);
  104.     }
  105. };
  106. class RemoteChannel : public Channel<Hal, RemoteList1, EmptyList, DefList4, PEERS_PER_RemoteChannel, SwList0>, public Button {
  107.   private:
  108.     uint8_t       repeatcnt;
  109.  
  110.   public:
  111.     typedef Channel<Hal, RemoteList1, EmptyList, DefList4, PEERS_PER_RemoteChannel, SwList0> BaseChannel;
  112.  
  113.     RemoteChannel () : BaseChannel() {}
  114.     virtual ~RemoteChannel () {}
  115.  
  116.     Button& button () {
  117.       return *(Button*)this;
  118.     }
  119.  
  120.     uint8_t status () const {
  121.       return 0;
  122.     }
  123.  
  124.     uint8_t flags () const {
  125.       return 0;
  126.     }
  127.  
  128.     virtual void state(uint8_t s) {
  129.       DHEX(BaseChannel::number());
  130.       Button::state(s);
  131.       RemoteEventMsg& msg = (RemoteEventMsg&)this->device().message();
  132.       //DPRINT("BATTERY IS LOW? "); DDECLN(this->device().battery().low());
  133.       msg.init(this->device().nextcount(), this->number(), repeatcnt, (s == longreleased || s == longpressed), this->device().battery().low());
  134.       if ( s == released || s == longreleased) {
  135.         this->device().sendPeerEvent(msg, *this);
  136.         repeatcnt++;
  137.       }
  138.       else if (s == longpressed) {
  139.         this->device().broadcastPeerEvent(msg, *this);
  140.       }
  141.     }
  142.  
  143.     uint8_t state() const {
  144.       return Button::state();
  145.     }
  146.  
  147.     bool pressed () const {
  148.       uint8_t s = state();
  149.       return s == Button::pressed || s == Button::debounce || s == Button::longpressed;
  150.     }
  151. };
  152.  
  153.  
  154. typedef SwitchChannel<Hal, PEERS_PER_SwitchChannel, SwList0>  SwChannel;
  155.  
  156. class MixDevice : public ChannelDevice<Hal, VirtBaseChannel<Hal, SwList0>, 16, SwList0> {
  157.   public:
  158.     VirtChannel<Hal, SwChannel, SwList0>     swChannel1,  swChannel2,  swChannel3,  swChannel4, swChannel5,  swChannel6,  swChannel7,  swChannel8;
  159.     VirtChannel<Hal, RemoteChannel, SwList0> remChannel9, remChannel10, remChannel11, remChannel12, remChannel13, remChannel14, remChannel15, remChannel16;
  160.   public:
  161.     typedef ChannelDevice<Hal, VirtBaseChannel<Hal, SwList0>, 16, SwList0> DeviceType;
  162.     MixDevice (const DeviceInfo& info, uint16_t addr) : DeviceType(info, addr) {
  163.       DeviceType::registerChannel(swChannel1, 1);
  164.       DeviceType::registerChannel(swChannel2, 2);
  165.       DeviceType::registerChannel(swChannel3, 3);
  166.       DeviceType::registerChannel(swChannel4, 4);
  167.       DeviceType::registerChannel(swChannel5, 5);
  168.       DeviceType::registerChannel(swChannel6, 6);
  169.       DeviceType::registerChannel(swChannel7, 7);
  170.       DeviceType::registerChannel(swChannel8, 8);
  171.  
  172.       DeviceType::registerChannel(remChannel9, 9);
  173.       DeviceType::registerChannel(remChannel10, 10);
  174.       DeviceType::registerChannel(remChannel11, 11);
  175.       DeviceType::registerChannel(remChannel12, 12);
  176.       DeviceType::registerChannel(remChannel13, 13);
  177.       DeviceType::registerChannel(remChannel14, 14);
  178.       DeviceType::registerChannel(remChannel15, 15);
  179.       DeviceType::registerChannel(remChannel16, 16);
  180.     }
  181.     virtual ~MixDevice () {}
  182.  
  183.     SwChannel& switchChannel (uint8_t num)  {
  184.       switch (num) {
  185.         case 1:
  186.           return swChannel1;
  187.           break;
  188.         case 2:
  189.           return swChannel2;
  190.           break;
  191.         case 3:
  192.           return swChannel3;
  193.           break;
  194.         case 4:
  195.           return swChannel4;
  196.           break;
  197.         case 5:
  198.           return swChannel5;
  199.           break;
  200.         case 6:
  201.           return swChannel6;
  202.           break;
  203.         case 7:
  204.           return swChannel7;
  205.           break;
  206.         case 8:
  207.           return swChannel8;
  208.           break;
  209.         default:
  210.           return swChannel1;
  211.           break;
  212.       }
  213.     }
  214.  
  215.     RemoteChannel& remoteChannel (uint8_t num)  {
  216.       switch (num) {
  217.         case 9:
  218.           return remChannel9;
  219.           break;
  220.         case 10:
  221.           return remChannel10;
  222.           break;
  223.         case 11:
  224.           return remChannel11;
  225.           break;
  226.         case 12:
  227.           return remChannel12;
  228.           break;
  229.         case 13:
  230.           return remChannel13;
  231.           break;
  232.         case 14:
  233.           return remChannel14;
  234.           break;
  235.         case 15:
  236.           return remChannel15;
  237.           break;
  238.         case 16:
  239.           return remChannel16;
  240.           break;
  241.         default:
  242.           return remChannel9;
  243.           break;
  244.       }
  245.     }
  246.  
  247.     virtual void configChanged () {
  248.     }
  249. };
  250. MixDevice sdev(devinfo, 0x20);
  251. ConfigButton<MixDevice> cfgBtn(sdev);
  252.  
  253. void initPeerings (bool first) {
  254.   // create internal peerings - CCU2 needs this
  255.   if ( first == true ) {
  256.     HMID devid;
  257.     sdev.getDeviceID(devid);
  258.     for ( uint8_t i = 1; i <= 8; ++i ) {
  259.       Peer ipeer(devid, i + 8);
  260.       sdev.switchChannel(i).peer(ipeer);
  261.     }
  262.     for ( uint8_t i = 1; i <= 8; ++i ) {
  263.       Peer ipeer(devid, i);
  264.       sdev.remoteChannel(i + 8).peer(ipeer);
  265.     }
  266.   }
  267. }
  268.  
  269. void setup () {
  270.   DINIT(57600, ASKSIN_PLUS_PLUS_IDENTIFIER);
  271.   bool first = sdev.init(hal);
  272.   sdev.switchChannel(1).init(RELAY1_PIN, RELAY_ON_STATE_INVERT);
  273.   sdev.switchChannel(2).init(RELAY2_PIN, RELAY_ON_STATE_INVERT);
  274.   sdev.switchChannel(3).init(RELAY3_PIN, RELAY_ON_STATE_INVERT);
  275.   sdev.switchChannel(4).init(RELAY4_PIN, RELAY_ON_STATE_INVERT);
  276.   sdev.switchChannel(5).init(RELAY5_PIN, RELAY_ON_STATE_INVERT);
  277.   sdev.switchChannel(6).init(RELAY6_PIN, RELAY_ON_STATE_INVERT);
  278.   sdev.switchChannel(7).init(RELAY7_PIN, RELAY_ON_STATE_INVERT);
  279.   sdev.switchChannel(8).init(RELAY8_PIN, RELAY_ON_STATE_INVERT);
  280.  
  281.   remISR(sdev, 9,  REMOTE_PIN_1);
  282.   remISR(sdev, 10, REMOTE_PIN_2);
  283.   remISR(sdev, 11, REMOTE_PIN_3);
  284.   remISR(sdev, 12, REMOTE_PIN_4);
  285.   remISR(sdev, 13, REMOTE_PIN_5);
  286.   remISR(sdev, 14, REMOTE_PIN_6);
  287.   remISR(sdev, 15, REMOTE_PIN_7);
  288.   remISR(sdev, 16, REMOTE_PIN_8);
  289.   buttonISR(cfgBtn, CONFIG_BUTTON_PIN);
  290.  
  291.   initPeerings(first);
  292. #ifdef USE_BATTERY_MODE
  293.   hal.activity.stayAwake(seconds2ticks(15));
  294.   hal.battery.low(LOWBAT_VOLTAGE);
  295.   // measure battery every 12 hours
  296.   hal.battery.init(seconds2ticks(60UL * 60 * 12 * 0.88), sysclock);
  297. #endif
  298.   sdev.initDone();
  299. }
  300.  
  301. void loop() {
  302.   bool worked = hal.runready();
  303.   bool poll = sdev.pollRadio();
  304.   if ( worked == false && poll == false ) {
  305. #ifdef USE_BATTERY_MODE
  306.     hal.activity.savePower<Sleep<> >(hal);
  307. #else
  308.     hal.activity.savePower<Idle<> >(hal);
  309. #endif
  310.   }
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement