sáng tạo

Xây dựng hệ thống cho mượn thiết bị đơn giản trong công ty

0. Khởi nguồn

  • Tôi nghĩ rằng việc tạo ra các sản phẩm từ ý tưởng của cá nhân và đem lại lợi ích cho mọi người luôn là điều đáng được hoan nghênh, khen ngợi nhất. Tuy nhiên do nhiều yếu tố, các thành viên thường ít khi triển khai và đưa những ý tưởng của mình vào giai đoạn thực hiện. Hy vọng thông qua bài viết này sẽ giúp mọi người có sự tự tin nhiều hơn, chia sẻ suy nghĩ, tìm các đối tác để chung tay tạo ra sản phẩm tốt, không tốn quá nhiều công sức cũng như tiền bạc, mà vẫn đem lại lợi ích cho rất nhiều người.
  • Cảm ơn anh Taihei đã chia sẻ bài viết này, ngoài ra truyền cảm hứng để mình có thể dịch và mong muốn cộng tác với anh em trong công ty tạo ra các sản phẩm có ích như thế này trong tương lai.

1. Source

社内の備品貸出にTSUTAYAのレジ風システムを導入した

2. Sơ lược

Tôi đã tạo ra một hệ thống giống với chuỗi cửa hàng cho thuê băng đĩa nổi tiếng TSUTAYA, cho phép người sử dụng có thể thuê hay cho thuê một cách dễ dàng chỉ bằng cách scan thiết bị của công ty (chủ yếu là smartphone hay laptop..) qua app.

Tên của nó là 「ネコレジ」(Nekoreji)

( Neko có nghĩa là mèo, Reji là viết tắt của register - máy thanh toán )
Đây là sản phẩm thứ 2 trong chuỗi Neko của tôi, bên cạnh tool trợ giúp OSS test 「Chibineko

3. Cấu trúc hệ thống Nekoreji

5463d32b-17a0-abfd-ddf7-51f447240446.png

4. Cơ chế nhận diện thiết bị

Tôi đã quyết dịnh sử dụng QR code để phân biệt các thiết bị.
Với mỗi thiết bị, chúng tôi đều dán 1 mã QR code đã ẩn trong đó ID duy nhất. Bên phía reader - máy đọc (client app) có thể sử dụng ID này để phân biệt.
5d50ce20-ad57-76a3-e5db-c0d95a65555c.jpeg

Chúng tôi sử dụng テプラPRO SR5900P cho việc in ấn QR code.
Thiết bị tuyệt vời này có hỗ trợ kết nối LAN cho phép trực tiếp in ấn được từ iPhone.

Phòng của chúng tôi quản lý tới hơn 1000 thiết bị và chúng tôi đã phải toát mồ hôi hột để dán lên toàn bộ.

5. Thẻ thành viên (tên thường gọi Nekoca)

(Neko - mèo, Ca - card. Người Nhật ưa thích việc gọi tắt như thế này để dễ nhớ)

Tôi cũng sử dụng QR code để quản lý việc nhận diện các user, và ngoài ra để tiết kiệm chi phí, tôi quyết định làm bằng tay không quá cầu kỳ.

In thẻ thành viên lên một bìa cứng cỡ như 1 tấm thiệp, tiếp theo sử dụng máy cắt để lấy ra kích cỡ thích hợp. Tiếp theo, nếu để nguyên vuông vắn như thế này thì các góc cạnh sẽ rất dễ bị quăn queo, tôi đã sử dụng máy cắt chuyên dụng để làm bo tròn các góc, tăng độ bền cho sản phẩm. Cuối cùng ép plastic cho nó để đẹp và sử dụng được lâu dài hơn.

Hình ảnh về sản phầm Nekoca

23d4a013-8612-c697-8e82-66878b8073fb.jpeg

[Vật dụng cần thiết]

Tính trung bình mỗi một chiếc thẻ tốn khoảng 1200 đồng để làm. Với giá rẻ thế này thì chúng ta thoải mái mà triển khai thôi đúng không?

6. Client app (QR code reader - máy đọc QR code)

Tôi đã viết 1 iOS app (swift) để tạo ra 1 reader đọc được QR code từ "thiết bị có gắn QR code" và "thẻ thành viên" ở trên, hỗ trợ cho iphone (cầm tay) và iPad (đặt trên mặt bàn để sử dụng).

f2f51574-113e-26a7-65a3-4ec4b0308617.png

Đoạn code để đọc QR code như sau: (môi trường Xcode 7.3, Swift 2.2, iOS 8.3)

import UIKit
import AVFoundation

class ViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        let session = AVCaptureSession()
        let devices = AVCaptureDevice.devices()
        var device: AVCaptureDevice!
        let devicePosition = AVCaptureDevicePosition.Back  // Sử dụng camera phía sau

        // Lấy camera
        for d in devices {
            if d.position == devicePosition {
                device = d as! AVCaptureDevice
                break
            }
        }

        // Cài đặt camera lấy được là Input
        do {
            let deviceInput = try AVCaptureDeviceInput(device: device)
            if session.canAddInput(deviceInput) {
                session.addInput(deviceInput)
            }
        } catch let error as NSError {
            print(error)
        }

        // Cài đặt Output vào QR code
        let metadataOutput = AVCaptureMetadataOutput()

        if session.canAddOutput(metadataOutput) {
            session.addOutput(metadataOutput)
            metadataOutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
            metadataOutput.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
        }

        // Chuẩn bị View cho vùng đọc dữ liệu
        let videoLayer = AVCaptureVideoPreviewLayer(session: session)
        videoLayer.frame = self.view.bounds
        videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        self.view.layer.addSublayer(videoLayer)

        session.startRunning()
    }

    // Delegate được gọi lúc chụp
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        if metadataObjects.count > 0 {
            let metaData = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
            print("\(metaData.type)")
            print("\(metaData.stringValue)")
        }
    }
}

Đây là lần đầu tiên tôi sử dụng Swift để viết chương trình, tuy nhiên do iOS đã được chuẩn bị sẵn lib dùng để đọc QR code cho nên việc implement cũng hết sức đơn giản.

Ngoài ra, camera của iphone có độ chính xác của autofocus rất tốt cho nên tốc độ đọc QR code nhanh đến mức đáng kinh ngạc, việc sử dụng app có cảm giác rất thoải mái. (hãy tham khảo video sau đây)

Bên cạnh đó tôi cũng cho phép có thể thay đổi được tiếng lúc chụp QR code, cho nên mọi người thử tưởng tượng mỗi lần chụp QR code sẽ có tiếng như kiểu Mario nhảy (tưng tưng..), nếu có ai mượn một lúc nhiều thiết bị sẽ có cảm giác như đang chơi game vậy - rất thú vị.

8b1cf2ec-cbf5-d7a8-44ce-61c638357e40.png

Chú ý: Chỉ có những người nào biết về chế độ ẩn này mới có thể di chuyển đến màn hình này và thay đổi cài đặt được.

7. Server

Trước khi đưa Nekoreji vào sử dụng, việc quản lý mượn thiết bị toàn bộ được thực hiện trên hệ thống web của công ty. Tuy nhiên với mỗi lần muốn mượn hay muốn trả thì lại phải khởi động browser rồi cho xử lý rất mất thời gian.
Chính vì thế tôi đã tạo ra "Nekoreji" - client của hệ thống quản lý mượn thiết bị này, tuy nhiên sự liên kết giữa hệ thống vốn có này và Nekoreji không được tốt đẹp như mơ.

Cũng bởi lý do này, việc xử lý liên kết giữa app và web service phải thực hiện thông qua WebAPI thông thường (interface giao tiếp với data), tuy nhiên tại hệ thống quản lý mượn thiết bị này do không có API cho nên từ app không thể lấy được request đơn giản như vậy.

Để giải quyết vấn đề này, tại Nekoreji cần implement một API riêng.

Mặc dù nói implement một API riêng nghe có vẻ to tát nhưng thực sự rất đơn giản, đầu tiên là scraping web page rồi sau đó tạo 1 service trả về dưới dạng JSON, mục tiêu là một API server đơn sơ nhất.

Nếu có cơ hội tôi sẽ giới thiệu kỹ hơn với các bạn, tuy nhiên tôi đã sử dụng lib riêng tự chế có tên "Bengal" - hỗ trợ việc chỉ định CSS selector mong muốn là có thể GET/POST API một cách đơn giản.

Ví dụ: khi access vào https://{address của API server}/api/users/:id, API trả về thông tin user.

require \'bengal\'

namespace \'/api\' do
  # API lấy thông tin user
  get \'/users/:id\' do
    Bengal::Element.get(
      url: "https://example.com/users/#{params[:id]}",
      contents: [
        { name: "id", css: "#userid" },
        { name: "name", css: "#username" },
      ],
    ).to_json
  end
end

Kết quả API

{
  id: "25"
  name: "猫 太郎"
}

Rất mong bài viết đã truyền được cảm hứng cho các bạn tạo ra những sản phẩm tốt từ những ý tưởng tưởng chừng đơn giản nhất.

Registration Login
Sign in with social account
or
Lost your Password?
Registration Login
Sign in with social account
or
A password will be send on your post
Registration Login
Registration