Ruby 物联网编程闲话

简介: Ruby 物联网编程闲话

首先从硬件本身聊起。

硬件领域基本都是 C 语言或者汇编语言的天下,其他语言基本上也就是划划水的存在。

大家都知道,ruby 除了我们常用的 CRuby 版本外,还有 JRuby 等等各种实现版本,估计比较少人知道的是mruby

直接使用mruby 还是有点难的,下面的下面会介绍一下。

Arduino

Arduino 系列是针对硬件爱好者的开发的,通过这个项目mruby-arduino 可以用 Ruby 开发。

曾经试了一下,因为 Arduino 本身提供的语法也很简单,所以基本上就相当于玩了一下而已。

ESP

ESP 系列本身在工业领域用的比较多,现在也有一些类似于玩具一样的产品,比如说 ESP-EYE 等,可玩性很强。可以运行 TensorFlow Lite,实现离线人脸识别,除了速度慢没别的缺点。

有个开源的项目,mrubyc-esp32-arduino 可以实现在 ESP 系列硬件上用 ruby 编程,不过环境安装在国内实在是费劲。

但是 ESP 系列的可玩性很强,有个 micro-python 的项目,和 Ruby 相比起来更有优势。

micro:bit

另外还有针对BBC micro:bit v2的项目。

再说说物联网的协议

现在比较流行的有 NB-IoT 和 Lora 两种,当然还有其他的,有兴趣的可以自行百度一下。

NB-IoT

NB-IoT,全称是 Narrow Band Internet of Things,窄带物联网,它的原型是 2014 年 5 月华为和沃达丰联合提出的 NB M2M 技术,随后在 2015 年 5 月与高通提出的 NB OFDMA 技术融合成为 NB-CIOT 技术,之后又于 2015 年 9 月与爱立信公司提出的 NB-LTE 技术融合,形成了我们现在认识的 NB-IoT,并在 3GPP 上正式立项。至 2016 年 6 月,NB-IoT 核心标准冻结,但相关特性仍在持续演进中。

NB-IoT 的优点是不需要自己组网,直接依托运营商网络就可以。缺点就很显然,数据都到了运营商手里了,当然也可以自行对数据进行加密。之前在一家公司负责和华强北对接,他们就对自己的数据进行了封装,运营商如果没有协议是很难自行破解的(其实也很简单,估计就是数据没什么价值,因为除了自定义协议外并没有进行数据加密)。

和华强北合作的项目用的是电信的 NB-IoT 平台,可以通过 REST 接口拉取,也可以用 Apache Pulsar Client SDK 自行拉取。

很多城市的电动车防盗就是通过 NB-IoT 实现的,利润你懂得~

国家准备在未来几年,健全 NB-IoT 网络,覆盖城乡农村,加强在农业等领域应用。

Lora 也是流行的一种物联网协议。

Lora 的好处是 Lora 所用的无线电频率连业余频率都不是,所以组建 Lora 网络不需要相关部门批准。缺点就是自己组网成本较高。

一台 Lora 发射器成本不到一千元,可以覆盖大约空旷地带 10 公里的范围,实际上受建筑物的影响,可能每层都需要一台中继,所以实现的成本还是很高的。

目前在燃气抄表等领域,都有应用 Lora 的案例,和 NB-IoT 相比应用比较小。

优点是完全自主可控。

4G/5G/Wifi直连

这没啥好说的

Ruby 物联网实现

我们使用的是EventMachine,好像之前停了一段时间之后又活了。

核心的原理就是物联网硬件通过 TCP Socket 发送到指定服务器,服务器通过 Nginx 做了一个负载均衡

因为物联网硬件是通过 4G 网络连接的,所以物联网硬件的 IP 是动态的。为了保持服务器和硬件之间的连接,需要定时发送心跳。

屏幕截图 2023-09-06 114408.png

然后通过EventMachine来保存连接,需要的时候发送指令等。

以下的代码好久没看了,仅供参考:)

require 'eventmachine'
class SaleServer < EM::Connection
  include Wanfeng
  extend Wanfeng
  @@connections = {}
  @@logger = Logger.new("#{Rails.root}/log/vending_machines.log")
  def initialize
    @@last_heart  = Time.zone.now
  end
  def self.connections
    @@connections
  end
  def self.deliver_goods_data(machine, row, column, count, password="111111")
    sale(machine, rand(100), row, column, count, password).pack("C*")
  end
  def post_init
    @@logger.info "connected  "
  end
  def receive_data data
    @received_data = data.unpack('H*').first
    if valid_imei?
      add_clients
      log_received_data
      show_connections
      reply_heart
    end
  end
  def unbind
    @@connections.delete(self)
    @@logger.info "#{imei} disconnected\n"
  end
 private
 def imei
   get_machine_code(@received_data)
 end
 def valid_imei?
   !!(imei =~ /\A\d+\z/) && (imei&.size == 15)
 end
 def add_clients
   $redis.hmset('vending_machines', imei, Time.zone.now )
   @@connections[imei] = self
 end
 def log_received_data
   last_time =  "#{Time.now - @@last_heart} seconds"
   @@last_heart = Time.now
   @@logger.info "Received:\t#{last_time}\t#{@received_data}"
 end
 def reply_heart
   unless imei.present?
     @@connections[imei].send_data(heart(imei, "111111").pack("C*"))
   end
 end
 def show_connections
   @@connections.each do |k, v|
     @@logger.info "Connection: #{k}: #{v} "
   end
 end
end

这个是一段控制售货机的代码,出货指令是通过ActiveJob 实现的:

class AutosaleJob < ApplicationJob
  queue_as :default
  def perform(machine, row, column, count)
    SaleServer.connections[machine].send_data(
      SaleServer.deliver_goods_data(machine, row, column, count)
    )
  end
end

如果用的是 Passenger 的话,需要在config/application.rb 中这样启动EventMachine,没有这个if defined?(PhusionPassenger)逻辑会报什么错,我已经忘了 :

# config/application.rb
    ...
    config.after_initialize do
      if defined?(PhusionPassenger)
        PhusionPassenger.on_event(:starting_worker_process) do |forked|
          if forked && EM.reactor_running?
            EM.stop
          end
          Thread.new {
            EM.run {
              EM.start_server '0.0.0.0', 4000, SaleServer
            }
          }
          Signal.trap("INT")  { EM.stop }
          Signal.trap("TERM") { EM.stop }
        end
      end
    end
   ....

出货调用逻辑:

AutosaleJob.perform_now(params[:code], row, column, amount)

这样你就能在夏天喝上王老吉了:)

总结

在开发单片机原型的时候,用 Ruby 快速验证是可以的,不过你必须要懂点 C 才行,不然寸步难行。

在服务器开发方面,用 Ruby 实现是没有问题,而且运行也非常稳定。

服务器性能优化,最重要的是找到影响性能的瓶颈。

曾经做过一个中国全海域风能评估的项目,绝大部分代码是用 Ruby 写的,只有统计的一小点用的是 C。

这样既满足了需求,也大大提高了开发的速度和效率。

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
4月前
|
网络协议 Ruby
|
19天前
|
SQL 自然语言处理 安全
探索研究Ruby CGI 编程
【9月更文挑战第1天】
41 6
|
19天前
|
开发者 Android开发 UED
打造流畅应用:深入探索如何在Xamarin项目中选择并实现最佳UI/UX设计的实践指南
【8月更文挑战第31天】在数字化时代,UI/UX设计成为应用成功的关键。Xamarin以高效开发和强大兼容性著称,其设计理念“一次编写,处处运行”需充分适应多平台特性,提供一致体验。选择Xamarin.Forms或结合Xamarin.Native可实现跨平台UI设计;遵循各平台设计指南,保持布局一致性和简洁性;通过用户测试不断优化。最终,结合技术和用户需求,打造美观实用的应用,脱颖而出。
27 0
|
19天前
|
开发者 编解码
界面适应奥秘:从自适应布局到图片管理,Xamarin响应式设计全解析
【8月更文挑战第31天】在 Xamarin 的世界里,构建灵活且适应性强的界面是每位开发者的必修课。本文将带您探索 Xamarin 的响应式设计技巧,包括自适应布局、设备服务协商和高效图片管理,帮助您的应用在各种设备上表现出色。通过 Grid 和 StackLayout 实现弹性空间分配,利用 Device 类检测设备类型以加载最优布局,以及使用 Image 控件自动选择合适图片资源,让您轻松应对不同屏幕尺寸的挑战。掌握这些技巧,让您的应用在多变的市场中持续领先。
25 0
|
19天前
|
开发者 数据库 虚拟化
Xamarin 应用性能优化策略大揭秘,从代码到界面再到数据访问,全面提升应用性能,快来围观!
【8月更文挑战第31天】在 Xamarin 跨平台移动应用开发中,性能优化至关重要。代码优化是基础,应避免不必要的计算与内存分配,如减少循环中的对象创建及合理使用数据结构。界面设计上需注意简化布局、减少特效并启用虚拟化以提升响应速度。数据访问方面,优化数据库查询和网络请求可显著改善性能。Xamarin Profiler 等工具还可帮助开发者实时监控并优化应用表现,从而打造流畅高效的用户体验。
37 0
|
19天前
|
开发者 测试技术 Android开发
Xamarin 开发者的五大常见问题及解决方案:从环境搭建到性能优化,全面解析高效跨平台应用开发的技巧与代码实例
【8月更文挑战第31天】Xamarin 开发者常遇问题及解决方案覆盖环境搭建至应用发布全流程,助新手克服技术难关。首先需正确安装配置 Visual Studio 及 Xamarin 支持,设置 iOS/Android 测试环境。利用 Xamarin.Forms 和 XAML 实现高效跨平台开发,共享 UI 和业务逻辑代码。针对性能优化,采取减少 UI 更新、缓存计算结果等措施,复杂问题则借助 Xamarin Profiler 分析。
31 0
|
20天前
|
API 数据库 Ruby
Ruby自动化魔法:揭秘日常任务的脚本编程秘籍
【8月更文挑战第31天】使用Ruby编写自动化脚本是一种高效且直观的方式。首先确保已安装Ruby环境,然后创建`auto_script.rb`文件开始编写。Ruby语法简洁优雅,内置及第三方库丰富,便于处理文件操作、网络请求和数据库交互等任务。通过`FileUtils`可轻松复制、删除或移动文件;利用`net/http`库可与网络API交互;`whenever`库帮助定时执行任务;而`mail`库则方便发送邮件。Ruby的强大功能和活跃社区支持,使自动化任务变得简单有趣。
31 0
|
20天前
|
测试技术 程序员 开发者
Ruby事件驱动编程的奥秘:如何打造响应式设计,让你的应用程序飞起来?
【8月更文挑战第31天】在现代编程领域,事件驱动编程已成为构建响应式与高并发应用的重要范式,尤其在动态、面向对象的Ruby语言中表现突出。本文深入探讨了Ruby中的事件驱动编程,包括概念介绍、核心机制(如回调函数与事件循环)及常用库(如EventMachine)。通过示例代码展示了如何使用EventMachine实现事件驱动的设计,并提出了合理使用回调、优化事件处理等最佳实践,助力开发者构建高效、灵敏的应用程序。
22 0
|
4月前
|
存储 JavaScript 编译器
这款国产中文编程火了!通过文言文编译生成Python、JS、Ruby代码!
这款国产中文编程火了!通过文言文编译生成Python、JS、Ruby代码!
240 0
|
4月前
|
移动开发 网络协议 Ruby