2010-08-07 52 views
4

我发现使用modbus读取64个连续内存位置(元素)是使用rmodbus库通过Modbus检索信息的最有效方法。将Modbus记录器插入数据库和阵列处理策略

我的目标是将读取的信息记录在一个简单的数据库中,该数据库可以被挖掘以在网页上生成数据图表和表格,并将最新值存储在实例变量中。

数据被rmodbus库读入数组,其中每个元素的索引代表元素的地址。但是,我想将索引转换为八进制,因为这与用户已经熟悉的元素寻址方案相对应,并且在界面中更容易引用。

编辑添加细节和细化:在这个时间点,我用下面的模式工作:

create_table "elements", :force => true do |t| 
    t.string "name" 
    t.integer "modbus_connection_id" 
    t.string "address" 
    t.string "eng_unit" 
    t.integer "base" 
    t.string "wiring" 
    t.text  "note" 
    t.boolean "log" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "events", :force => true do |t| 
    t.integer "element_id" 
    t.string "value" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

    create_table "modbus_connections", :force => true do |t| 
    t.string "name" 
    t.string "ip_address" 
    t.integer "port" 
    t.integer "client" 
    t.text  "note" 
    t.datetime "created_at" 
    t.datetime "updated_at" 
    end 

的想法将是一个后台进程可能会轮询通过Modbus和比较在仅记录已更改且被要求记录的元素之前针对其自身进行更改。元素应该可以存储在数据库和变量已经缩放,所以前端不必担心它。未记录的那些仍然保存在实例变量中,用于半实时抬头显示类型监视。然后,只有在UI请求时,才会为其图表和表格中的记录元素进行解析。

第一个问题:(最后!)它使更多的意义与数据生活在一个阵列和应用,处理转换指数层,(和它发生相应的元素值,以及我用v.collect{|i| i.to_s(16)}转换)还是更好地将所有内容都转换成哈希表,索引和值可以以最有用的形式永远幸福地生活在一起?

首先问编辑:鉴于我对采伐问题唯一变化的数据到一个简单的SQLite数据库的判定/演变,我需要跟踪的元素的变化,以确定哪些MODBUS之间改变读取,数组或哈希是否更有效地进行比较?我应该关心吗?

第二个问题:在Rails中,假设一分钟记录间隔,将大约一千个数据点可以更好地在独立的领域举行的,或者我应该留在他们64元块和解析的道路上的信息,界面?

第二个问题编辑:将大量未改变的数据运行到数据库的一分钟'行'看起来非常平坦。另外,它不允许轻松动态选择要记录的元素。使“记录器”事件基于而不是基于间隔为基础似乎更为合适。这很好,意味着第一个问题在这里更重要,因为它也可能成为国家检查机制。

我在猜测我不必要地重新发明了一个带有这种启示的轮子,因为它变得和现有的“伐木工”非常相似。对SO进行阅读显示,登录DB和FS是一个古老的问题。由于日志本身是应用程序的基础,因此我倾向于登录到数据库,最有可能的情况是给出了我读过的sqlite。

第二个问题再次编辑:现在这是一个规范化问题,我读的所有内容都表明“可伸缩性”往往需要非规范化。我记录的“Events”表格将会相对简单,时间戳,值和元素ID。它是否也可以从Elements表内反规格化最常见的属性,或者在这个相对较小的范围内是否可以连接?

任何人都有任何最喜欢的Ruby日志框架/宝石/捆绑/插件/什么?

+0

看起来好像我正在想办法在这里“平坦”。我会适当地编辑问题。 – arriflex 2010-08-08 18:20:34

+0

好的,既然我提出的问题已经在别处得到解答,或者我已经为自己找到了答案,我将完全改变第二个问题。 – arriflex 2010-08-15 04:05:19

+0

这开始变得比我预想的更笨重一点。我认为是时候学习如何使用GIT,这样我就可以实现更少的破坏性实验了! – arriflex 2010-08-15 22:02:39

回答

1

我不认为这个问题已被其他地方回答:)你可能是唯一使用Rails和Modbus的人。我拥有Rails和Modbus的经验,除了我的Modbus经验是在.net精简框架上使用nmodbus。我不知道我对你有任何明确的答案,但我可以分享我使用的方法。

当我们轮询设备时,我们立即对数据应用任何解析,缩放或转换(但我们没有1000个值)。数据然后被记录到数据库中。现在任何想要使用数据库的客户端都不了解modbus,他们并不在意;问题从了解modbus转移到应用程序真正关心的问题(电压!)。在你的场景中,我会尝试从你的Rails应用中完全分离这个轮询应用。

现在为什么可能无法解耦 - 1000个数据点。这是一个问题。即使你能够将这些数据标准化为50个表格,为了参数的缘故,那就是50个表格,每个表格有20列...... yuck。我不知道一个简单的方法来记录1000个数据点,但构建基本上是持久散列表的方法可能无法解决。

关于要求Rails知道如何解析寄存器值的一个不好的部分是,现在你的Rails应用程序掌握了Modbus的知识(不是在读取寄存器级别,而是在解析级别)。另外,如果您想使用Rails以外的客户端,那么该应用程序也需要解析知识。也许这就是你的Rails应用程序的全部意义? Rails应用程序知道如何切分和切分Modbus读数,并为用户/客户提供一个很好的UI/Web服务。

这些都是很好的问题,但如果没有更多的知识,就很难提供具体的建议。至于正常化 - 试错。试试这两种方法。我不能说像“如果你的sqlite表中有超过40列将会分崩离析” - 像你必须碰到的东西...

+1

非常有趣。随着我的进化,你的想法与我的想法是平行的。 当我考虑只记录更改而不是冗余值时,1000个数据点的问题变得更加困难。我可能并不清楚这一点,就像我刚刚提到的那样,认为收集和存储的解耦是必要的。绝对最多只有一百个值可能在一秒钟内发生变化,将它们存储为日志风格应该很容易。将它留给Rails解析以显示速度并不太重要的地方。 很高兴我并不完全孤单!谢谢。 – arriflex 2010-08-15 21:37:55

0

回应OP问题编号2。我使用了一个简单的算法来获得最佳数量的传输请求,而不是使用64个字块。

该算法非常简单,从地址1开始(假设您使用的是PLC),然后在该情况下查找是否需要轮询该寄存器,将其用作起始地址并将其长度增加至125(这是modbus max)。如果不是,则转到下一个元素,看看是否需要轮询并重复该过程。