Example #1
0
        private void GetParametersWriteInfo(
            IEnumerable <WriteParameter> parameters, out Dictionary <byte, SlaveWriteInfo> infos)
        {
            infos = new Dictionary <byte, SlaveWriteInfo>();
            int index = -1;

            foreach (WriteParameter parameter in parameters)
            {
                ++index;
                var   regex = new Regex(DevicePattern);
                Match match = regex.Match(parameter.Address);
                if (!match.Success)
                {
                    throw new Exception(parameter.Address + " is not a valid device address");
                }

                #region Get slave address

                byte   slaveAddress = _defaultAddress;
                string match1       = match.Groups[1].ToString();
                if (!string.IsNullOrEmpty(match1) && match1.Length > 1)
                {
                    int i;
                    if (int.TryParse(match1.Substring(0, match1.Length - 1), out i))
                    {
                        if (i >= byte.MinValue && i <= byte.MaxValue)
                        {
                            slaveAddress = (byte)i;
                        }
                        else
                        {
                            throw new Exception(parameter.Address + ": slave address incorrect");
                        }
                    }
                }

                #endregion Get slave address

                #region Get device address

                ushort deviceAddress;
                if (!ushort.TryParse(match.Groups[3].ToString(), out deviceAddress) || deviceAddress == 0)
                {
                    throw new Exception(parameter.Address + ": device index not supported");
                }
                deviceAddress -= 1;
                string match2 = match.Groups[2].ToString();
                int?   length;
                if (parameter.Value is bool)
                {
                    if (match2 != "0" && match2 != "1")
                    {
                        throw new Exception("Type " + parameter.Value.GetType().Name +
                                            " is not supported for " + parameter.Address);
                    }
                    length = 1;
                }
                else
                {
                    if (match2 != "3" && match2 != "4")
                    {
                        throw new Exception("Type " + parameter.Value.GetType().Name +
                                            " is not supported for " + parameter.Address);
                    }
                    length = TypeToRegistersCount(parameter.Value.GetType());
                    if (length == null)
                    {
                        throw new Exception("Type " + parameter.Value.GetType().Name +
                                            " is not supported for " + parameter.Address);
                    }
                }

                #endregion Get device address

                #region Check device index

                int deviceLength = length.Value;
                if (deviceLength + deviceAddress - 1 > ushort.MaxValue)
                {
                    throw new Exception(parameter.Address + ": device index is out of range");
                }

                #endregion Check device index

                #region WriteInfo

                SlaveWriteInfo writeInfo;
                if (!infos.TryGetValue(slaveAddress, out writeInfo))
                {
                    writeInfo = new SlaveWriteInfo();
                    infos.Add(slaveAddress, writeInfo);
                }

                #endregion WriteInfo

                #region Fill WriteInfo

                switch (match2)
                {
                case "0":
                    var coil = new CoilWriteInfo {
                        Address        = deviceAddress,
                        Index          = index,
                        WriteParameter = parameter
                    };
                    writeInfo.Coils.Add(coil);
                    break;

                case "4":
                    var hr = new HoldingRegisterWriteInfo {
                        Address        = new KeyValuePair <ushort, int>(deviceAddress, deviceLength),
                        Index          = index,
                        WriteParameter = parameter
                    };
                    writeInfo.HoldingRegisters.Add(hr);
                    break;
                }

                #endregion Fill WriteInfo
            }
        }
Example #2
0
        public void WriteOnce(WriteParameter[] writeParameters)
        {
            if (writeParameters == null)
            {
                return;
            }
            var result = new bool[writeParameters.Count()];

            Dictionary <byte, SlaveWriteInfo> writeInfos;

            GetParametersWriteInfo(writeParameters, out writeInfos);

            foreach (var slaveWriteInfo in writeInfos)
            {
                byte           slaveAddress = slaveWriteInfo.Key;
                SlaveWriteInfo writeInfo    = slaveWriteInfo.Value;
                SortWriteInfoDevices(writeInfo);
                for (var i = 0; i < writeInfo.Coils.Count; ++i)
                {
                    CoilWriteInfo coil      = writeInfo.Coils[i];
                    ushort        address   = coil.Address;
                    const int     maxLength = MaxWriteBytesLength * 8;
                    var           bools     = new List <bool>(maxLength)
                    {
                        coil.WriteParameter.Value as bool? == true
                    };
                    for (var j = 1; j < maxLength && i + j < writeInfo.Coils.Count; ++j)
                    {
                        CoilWriteInfo c = writeInfo.Coils[i + j];
                        if (c.Address == address + j)
                        {
                            bools.Add(c.WriteParameter.Value as bool? == true);
                        }
                        else
                        {
                            break;
                        }
                    }

                    if (_mb.WriteCoils(slaveAddress, address, BoolsToBytes(bools), bools.Count))
                    {
                        for (int j = i; j < bools.Count + i; ++j)
                        {
                            result[writeInfo.Coils[j].Index] = true;
                        }
                    }
                    i += bools.Count - 1;
                }

                for (var i = 0; i < writeInfo.HoldingRegisters.Count; ++i)
                {
                    HoldingRegisterWriteInfo hr = writeInfo.HoldingRegisters[i];
                    var       address           = hr.Address;
                    const int maxLength         = MaxWriteBytesLength / 2;
                    var       bytes             = new byte[MaxWriteBytesLength];
                    int       length            = address.Value;
                    var       valueBytes        = GetBytes(hr.WriteParameter.Value);
                    valueBytes = _bytesToRegistersConverter.GetBytes(valueBytes, 0, hr.Address.Value);
                    for (var j = 0; j < valueBytes.Length; ++j)
                    {
                        bytes[j] = valueBytes[j];
                    }
                    int oldI = i;
                    for (var j = 1; i + j < writeInfo.HoldingRegisters.Count; ++j)
                    {
                        HoldingRegisterWriteInfo h = writeInfo.HoldingRegisters[i + j];
                        if (h.Address.Key <= address.Key + length)
                        {
                            int newLength = h.Address.Key + h.Address.Value - address.Key;
                            if (newLength < maxLength)
                            {
                                var vBytes = GetBytes(h.WriteParameter.Value);
                                vBytes = _bytesToRegistersConverter.GetBytes(vBytes, 0, h.Address.Value);
                                for (var k = 0; k < vBytes.Length; ++k)
                                {
                                    bytes[k + (h.Address.Key - address.Key) * 2] = vBytes[k];
                                }
                                if (newLength > length)
                                {
                                    length = newLength;
                                }
                                ++i;
                                continue;
                            }
                        }

                        break;
                    }

                    var byteList = new List <byte>(length * 2);
                    for (var j = 0; j < length * 2; ++j)
                    {
                        byteList.Add(bytes[j]);
                    }
                    if (_mb.WriteHoldingRegisters(slaveAddress, address.Key, byteList, length))
                    {
                        for (int j = oldI; j <= i; ++j)
                        {
                            result[writeInfo.HoldingRegisters[j].Index] = true;
                        }
                    }
                }
            }
        }