somfy.lua 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. -- Somfy module example (beside somfy module requires also CJSON module)
  2. -- The rolling code number is stored in the file somfy.cfg. A cached write of the somfy.cfg file is implemented in order to reduce the number of write to the EEPROM memory. Together with the logic of the file module it should allow long lasting operation.
  3. config_file = "somfy."
  4. -- somfy.cfg looks like
  5. -- {"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}
  6. local tmr_cache = tmr.create()
  7. local tmr_delay = tmr.create()
  8. pin = 4
  9. gpio.mode(pin, gpio.OUTPUT, gpio.PULLUP)
  10. function deepcopy(orig)
  11. local orig_type = type(orig)
  12. local copy
  13. if orig_type == 'table' then
  14. copy = {}
  15. for orig_key, orig_value in next, orig, nil do
  16. copy[deepcopy(orig_key)] = deepcopy(orig_value)
  17. end
  18. setmetatable(copy, deepcopy(getmetatable(orig)))
  19. else -- number, string, boolean, etc
  20. copy = orig
  21. end
  22. return copy
  23. end
  24. function readconfig()
  25. local cfg, ok, ln
  26. if file.exists(config_file.."cfg") then
  27. print("Reading config from "..config_file.."cfg")
  28. file.open(config_file.."cfg", "r+")
  29. ln = file.readline()
  30. file.close()
  31. else
  32. if file.exists(config_file.."bak") then
  33. print("Reading config from "..config_file.."bak")
  34. file.open(config_file.."bak", "r+")
  35. ln = file.readline()
  36. file.close()
  37. end
  38. end
  39. if not ln then ln = "{}" end
  40. print("Configuration: "..ln)
  41. config = cjson.decode(ln)
  42. config_saved = deepcopy(config)
  43. end
  44. function writeconfighard()
  45. print("Saving config")
  46. file.remove(config_file.."bak")
  47. file.rename(config_file.."cfg", config_file.."bak")
  48. file.open(config_file.."cfg", "w+")
  49. local ok, cfg = pcall(cjson.encode, config)
  50. if ok then
  51. file.writeline(cfg)
  52. else
  53. print("Config not saved!")
  54. end
  55. file.close()
  56. config_saved = deepcopy(config)
  57. end
  58. function writeconfig()
  59. tmr.stop(tmr_cache)
  60. local savenow = false
  61. local savelater = false
  62. --print("Config: "..cjson.encode(config))
  63. --print("Config saved: "..cjson.encode(config))
  64. local count = 0
  65. for _ in pairs(config_saved) do count = count + 1 end
  66. if count == 0 then
  67. config_saved = readconfig()
  68. end
  69. for remote,cfg in pairs(config_saved) do
  70. savelater = savelater or not config[remote] or config[remote].rc > cfg.rc
  71. savenow = savenow or not config[remote] or config[remote].rc > cfg.rc + 10
  72. end
  73. savelater = savelater and not savenow
  74. if savenow then
  75. print("Saving config now!")
  76. writeconfighard()
  77. end
  78. if savelater then
  79. print("Saving config later")
  80. tmr.alarm(tmr_cache, 65000, tmr.ALARM_SINGLE, writeconfighard)
  81. end
  82. end
  83. --======================================================================================================--
  84. function down(remote, cb, par)
  85. par = par or {}
  86. print("down: ".. remote)
  87. config[remote].rc=config[remote].rc+1
  88. somfy.sendcommand(pin, config[remote].address, somfy.DOWN, config[remote].rc, 16, function() wait(100, cb, par) end)
  89. writeconfig()
  90. end
  91. function up(remote, cb, par)
  92. par = par or {}
  93. print("up: ".. remote)
  94. config[remote].rc=config[remote].rc+1
  95. somfy.sendcommand(pin, config[remote].address, somfy.UP, config[remote].rc, 16, function() wait(100, cb, par) end)
  96. writeconfig()
  97. end
  98. function downStep(remote, cb, par)
  99. par = par or {}
  100. print("downStep: ".. remote)
  101. config[remote].rc=config[remote].rc+1
  102. somfy.sendcommand(pin, config[remote].address, somfy.DOWN, config[remote].rc, 2, function() wait(300, cb, par) end)
  103. writeconfig()
  104. end
  105. function upStep(remote, cb, par)
  106. par = par or {}
  107. print("upStep: ".. remote)
  108. config[remote].rc=config[remote].rc+1
  109. somfy.sendcommand(pin, config[remote].address, somfy.UP, config[remote].rc, 2, function() wait(300, cb, par) end)
  110. writeconfig()
  111. end
  112. function wait(ms, cb, par)
  113. par = par or {}
  114. print("wait: ".. ms)
  115. if cb then tmr.alarm(tmr_delay, ms, tmr.ALARM_SINGLE, function () cb(unpack(par)) end) end
  116. end
  117. --======================================================================================================--
  118. if not config then readconfig() end
  119. if #config == 0 then -- somfy.cfg does not exist
  120. config = cjson.decode([[{"window1":{"rc":1,"address":123},"window2":{"rc":1,"address":124}}]])
  121. config_saved = deepcopy(config)
  122. end
  123. down('window1',
  124. wait, {60000,
  125. up, {'window1',
  126. wait, {9000,
  127. downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1', downStep, {'window1'
  128. }}}}}}}}}})