2014-01-04 2 views
4

У меня проблема с петлями, таблица в Lua здесь таблица с переменной knx (теперь это статическая)Lua цикл для создания переменных в таблице

regTable = { 
     { RegEddr=3027, count=2, regType="float", knx="1/1/1"}, 
     { RegEddr=3029, count=2, regType="float", knx="1/1/2"}, 
     { RegEddr=3031, count=2, regType="float", knx="1/1/3"}, 
     { RegEddr=2999, count=2, regType="float", knx="1/1/4"}, 
     { RegEddr=3001, count=2, regType="float", knx="1/1/5"}, 
     { RegEddr=3003, count=2, regType="float", knx="1/1/6"}, 
     { RegEddr=3109, count=2, regType="float", knx="1/1/7"}, 
     { RegEddr=3083, count=2, regType="float", knx="1/1/8"}, 
     { RegEddr=3059, count=2, regType="float", knx="1/1/9"}, 
     { RegEddr=3203, count=4, regType="int64", knx="1/1/10"}, 
    } 

    function readRegisters() 

    for idx, register in pairs(regTable) do 
     if register.regType=="int" then 
     valueInt = mb:readregisters(register.RegEddr) 
     grp.write(register.knx, valueInt) 




      elseif register.regType=="float" then 
        value1, value2 = mb:readregisters(register.RegEddr,register.count) 

      if value1 then 
        valueFloat = bit.lshift(value1, 16) + value2 
        valueFloat = lmcore.inttohex(valueFloat, 4) 
        valueFloat = knxdatatype.decode(valueFloat, dt.float32) 
      grp.write(register.knx, valueFloat) 
       end 

      elseif register.regType=="int64" then 
      valueInt1, valueInt2, valueInt3, valueInt4 = mb:readregisters(register.RegEddr,register.count) 
      if valueInt4 then 
      valueInt64 = valueInt4 
       log(valueInt64) 
       grp.write(register.knx, valueInt64) 
      end 




     end 

     end  --end for 

    end --end function 

из другого сценария я называю функцию readRegisters() поэтому у меня есть список адресов, но я не знаю, сколько адресов потребуется пользователю. если 10 или 100. Это причина, почему это не оптимально иметь список адресов, но динамический список с +1 шагом

1/1/1 
1/1/2 
... 
1/1/255 

это возможно, чтобы помочь мне, как составить динамически добавлять адреса переменных knx в эту таблицу?

+0

Не понимаю, что это означает: «как динамически добавлять адреса переменной knx' в эту таблицу» – Schollii

ответ

1

Вам нужна функция распределения регистров, которая учитывает адрес и размер последнего регистра. Этот распределитель будет динамически создавать новые регистры по мере их запроса.

local startAddr = 3000 
local sizes = {float = 2, int = 2, int64 = 4} 
local registers = {} 

local function allocRegister(type) 
    if sizes[type] == nil then 
    error'invalid register type' 
    end 

    local n = #registers 
    local addr 

    if n == 0 then -- If this is the first register, use the starting address. 
    addr = startAddr 
    else -- Determine the next starting address based on the last register's address & size. 
    addr = registers[n].addr + registers[n].count 
    end 

    table.insert(registers, { addr = addr, count = sizes[type], type = type, knx = '1/1/' .. n + 1 }) 
end 

-- Example usage: 
allocRegister'float' 
allocRegister'int64' 
allocRegister'int' 
-- Resulting table: 
{ 
    { addr = 3000, count = 2, knx = "1/1/1", type = "float" }, 
    { addr = 3002, count = 4, knx = "1/1/2", type = "int64" }, 
    { addr = 3006, count = 2, knx = "1/1/3", type = "int" } 
} 

Вы можете использовать эту функцию в цикле точно так же, тоже. Следующий цикл создаст таблицу регистров, очень похожую на таблицу в вашем вопросе.

for i=1, 9 do allocRegister'float' end 
allocRegister'int64' 

Edit: Следующий код должен быть достаточно иллюстративными, чтобы показать вам, как решить вашу проблему.

local sizes = {float = 2, int = 2, int64 = 4} 
local registers = {} 
local usedSpace = {} 

local function allocRegisters(t) 
    for i=1, #t do 
    local addr, size = t[i].addr, sizes[t[i].type] 

    if size == nil then 
     error('invalid register type: ' .. t[i].type) 
    end 

    -- Check if there's free space for this register. 
    for j=addr, addr+size-1 do 
     if usedSpace[j] then 
     error('address already in use: ' .. addr) 
     end 
    end 

    -- Mark the space for this register as used. 
    for j=addr, addr+size-1 do 
     usedSpace[j] = true 
    end 

    -- Copy the register into the registers table, setting knx by using the length of the table. 
    table.insert(registers, { addr = addr, count = size, type = t[i].type, knx = '1/1/' .. #registers + 1}) 
    end 
end 

-- Example usage: 
allocRegisters { 
    { addr = 3000, type = 'float' }, 
    { addr = 3003, type = 'int' }, 
    { addr = 3009, type = 'int64' } 
} 
+0

Спасибо за ответ Райан. То, что вы пишете, должно использоваться для чтения всех регистров. – user3159120

+0

@RaynStein Спасибо за ответ Райан. То, что вы пишете, должно использоваться для чтения всех регистров. Но у меня есть конкретный список регистров, который не один за другим ... см. 3003, 3009. Таким образом, адреса и тип вводятся пользователем, и на основе этого я хотел бы создать regTable с автоматически добавленными адресами от 1/1/1 к числу регистров, которые я читал. – user3159120

+0

Таким образом, вашим пользователям нужно будет сделать что-то вроде 'allocRegister ('float', 3003)' where '' float'' является типом, а '3003' - адресом, куда должен идти новый регистр? –

0

Так что вы хотите динамически создавать regTable, с KNX быть динамически, как «1/1/п» где п есть порядок создания. Предположительно, вы также хотите, чтобы счет автоматически вычислялся на основе типа регистра. Похоже, что адреса могут быть назначены в любом порядке, но они должны соответствовать размеру регистра. Так как об этом:

local counts = {float = 2, int = 2, int64 = 4} 
local regTable = {} 

local function newRegister(addr, regType) 
    local count = counts[regType] 
    if count == nil then 
    error 'invalid register type' 
    end 

    checkAddrVsCount(addr, count) -- verify that addr is ok 

    local tableSize = #regTable 
    knx = '1/1/' .. (tableSize+1) 
    regTable.insert {RegEddr=addr, count=count, regType=regType, knx=knx} 
end 

В checkAddrVsCount(addr, count) проверяет, является ли действительным адр. Для например,

  • если regTable содержит запись, которая имеет RegEddr=addr, ошибка (адрес уже в таблице)
  • еще найти запись, которая находится ближе всего меньше RegEddr в адр, и убедитесь, что зазор по крайней мере пунктам [type] для типа найденной записи (не тип новой записи)
Смежные вопросы