_ENCRYPT_=0    --LUA脚本加密

--数据类型定义
VT_LW = 1    --变量地址
VT_RW = 2    --FLASH存储
VT_0x = 10    --线圈
VT_1x = 11    --输入点
VT_3x = 12    --输入寄存器
VT_4x = 13    --保持寄存器

function set_valbit(data, bitmask, state)
    print('-----------------------------------')
    print('set_valbit1('..data..','.. bitmask..','.. state..')')
    bitmask  = (1 << bitmask) & 0xFFFF

    data = (state == 0) and (data & (~bitmask)) or (data | bitmask)
    print('set_valbit2('..data..','.. bitmask..','.. state..')')
    return data
end


--读取线圈
function mb_read_coil_01(slave, addr)

    local onlineState = get_uint16(VT_LW,0x01A3)
    
    if ((onlineState >> slave) & 0x01) == 0x01
    then
        select_slave(slave)
        return get_bit(VT_0x, addr)
    else
        return false
    end
end

--读取离散输入
function mb_read_input_02(slave, addr)

    local onlineState = get_uint16(VT_LW,0x01A3)
    
    if ((onlineState >> slave) & 0x01) == 0x01
    then
        select_slave(slave)
        return get_bit(VT_1x, addr)
    else
        return false
    end
end

--读取保存寄存器
function mb_read_reg_03(slave, addr)

    local onlineState = get_uint16(VT_LW,0x01A3)
    
    if ((onlineState >> slave) & 0x01) == 0x01
    then
        select_slave(slave)
        return get_uint16(VT_4x, addr)
    else
        return false
    end
end

--读取输入寄存器
function mb_read_input_reg_04(slave, addr)

    local onlineState = get_uint16(VT_LW,0x01A3)
    
    if ((onlineState >> slave) & 0x01) == 0x01
    then
        select_slave(slave)
        return get_uint16(VT_3x, addr)
    else
        return false
    end
end

--写单个线圈
function mb_write_coil_05 (slave,addr,value)

    local onlineState = get_uint16(VT_LW,0x01A3)

    if ((onlineState >> slave) & 0x01) == 0x01
    then
        feed_dog()
        select_slave(slave)
        set_bit(VT_0x, addr, value)
        return true
    else
        return false
    end
end

--写单个保存寄存器
function mb_write_reg_06(slave, addr, value)

    local onlineState = get_uint16(VT_LW,0x01A3)

    if ((onlineState >> slave) & 0x01) == 0x01
    then
        feed_dog()
        select_slave(slave)
        set_uint16(VT_4x, addr, value)
        return true
    else
        return false
    end

end

--批量写多个线圈
function mb_write_coil_15 (slave,addr,coils)

    if ((addr + #coils) > 0xFFFF ) or (#coils > 120) or (#coils <= 0)
    then
        return
    end

    local onlineState = get_uint16(VT_LW,0x01A3)
    if ((onlineState >> slave) & 0x01) == 0x01
    then
        feed_dog()
        select_slave(slave)
        local cnt = (#coils // 16) + (((#coils % 16) >= 0 ) and 1 or 0) -- 总共个数,16个线圈对齐
        local all = cnt*16
        local idx = (#(coils) + 1)

        if all > 120 --标准modbus 最大读写连续寄存器<=120
        then
            return
        end
        
        for i = idx, all
        do
            local ret = mb_read_coil_01(slave, ((addr + i) - 1))
            if ret == false
            then
                return false
            end
            coils[#coils + 1] = ret
       end

        local val = {}
        for i = 1, cnt
        do
            val[i] = 0x0000
            for j = 0, 15
            do
                 val[i] = set_valbit(val[i], j, coils[(i - 1)*16 + j + 1])
            end
        end
        set_array(VT_0x, addr, val)

        return true
    else
        return false
    end

end

--批量写多个保存寄存器
function mb_write_reg_16 (slave,addr,regs)

    local onlineState = get_uint16(VT_LW,0x01A3)

    if ((onlineState >> slave) & 0x01) == 0x01
    then
        feed_dog()
        select_slave(slave)
        print('select_slave('..slave..')')
        set_array(VT_4x, addr, regs)
        return true
    else
        return false
    end

end

function on_init()

    set_uint16(VT_LW, 0x1005, 100) --保存码
    set_uint16(VT_LW, 0x1006, 1) --标定系数
    set_uint16(VT_LW, 0x1007, 1) --保存码

    set_auto_read(0)

    select_slave(0)
    start_read(1,VT_4x, 0x0000, 3)
    start_read(2,VT_0x, 0x0000, 16)
    redraw()

    select_slave(1)
    start_read(3,VT_4x, 0x0000, 3)
    start_read(4,VT_4x, 0x1000, 7)
    redraw()
end

function on_run(screen)

    local Energy1 = mb_read_reg_03(0, 0x0000)
    local Energy2 = mb_read_reg_03(1, 0x0000)
    if Energy1 ~= false and Energy2 ~= false
    then
        set_uint16(VT_LW, 0x1000, Energy1 + Energy2)
    end

    local vol1 = mb_read_reg_03(0, 0x0001)
    local vol2 = mb_read_reg_03(1, 0x0001)
    if vol1 ~= false and vol2 ~= false
    then
        set_uint16(VT_LW, 0x1001, vol1 + vol2)
    end
end

function on_update(slave,vtype,addr)

    if vtype == VT_LW
    then
        if addr == 0x1004
        then
            local val = get_uint16(VT_LW,  0x1003) -- 校准

            if val == 0
            then
                mb_write_reg_06(0, 0x0002, 57)

            elseif val == 1
            then
                --实重 = 砝码重量
                local weightVal = get_uint16(VT_LW, 0x1005) -- A秤砝码重量
                mb_write_reg_06(0, 0x0002, weightVal)

            elseif val == 2
            then
                --if (标定系数>0) && (保存码>0) 
                --then
                --    实重=标定系数*砝码重量 // 保存码
                --end
                local coeffi   = get_uint16(VT_LW, 0x1006) --标定系数
                local saveCode = get_uint16(VT_LW, 0x1007) --保存码

                if coeffi > 0 and saveCode > 0
                then
                    local weightVal = get_uint16(VT_LW, 0x1005) -- 砝码重量
                    mb_write_reg_06(0, 0x0002, (saveCode*weightVal)//coeffi )
                end
            end
        
        elseif addr == 0x2000
        then
            local val = get_uint16(VT_LW,  0x2000) -- 批量写
            print('val = '..val)
            if val == 1
            then
                --批量写入0x0000~0x000D, 14个寄存器  5B1A
                mb_write_coil_15(0, 0x0000, {1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0 })

            elseif val == 2
            then
                --批量写入0x1000~0x1006, 7个寄存器
                mb_write_reg_16(1, 0x1000, {0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007})
            end
        end
    end

end

function on_draw(screen_id,control_id)
end

