BIM Workbench Beta

- 1 min read

This is a beta version of a BIM Workbench for Autodesk Revit. It is a Vue frontend and a Node.js backend. The backend is a simple REST API that communicates with the Revit API. The frontend is a simple Vue.js app that allows the user to create a new project, upload a Revit file, and get the project information.

Portera

- 2 mins read

portera 🚀

portera🚀 provides remote logs for you node apps with an awesome style :).

portera has two parts, a library that wrap your console object by default, redirecting the output to portera server, its receive your data and serve a web page where you can display an awesome output, just like that

Sample Web

Installation

github

Motivation

These days I spent more time at home by corona quarantine, time to practice and learn new things. I began to do a sample project in node for the company where I work, it was something that I had have in my mind time ago. The project its a middleware between our different management programs and third part applications, this middleware should contain all bussiness logic necesary by thrird part systems.

NEngine is a skeleton project that I use to start new projects where I need to use SQL Server for the database and JWT tokens for authentication. The project is available on GitHub

It is necessary to have a SQL Server database with stored procedures to authenticate the user and generate the JWT token. The stored procedures are:

{
  "CHECK_EMAIL": "DATABASE.dbo.checkEmail @email = @email",
  "SAVE_USER": "DATABASE.dbo.saveUser @email = @email, @password = @password",
  "LIST_USERS": "DATABASE.dbo.listUsers",
  "CHECK_PASSWORD": "DATABASE.dbo.checkPassword @email = @email, @password = @password",
  "CHECK_PASSWORD1": "DATABASE.dbo.checkPassword"
}

Stored Procedures

USE [DemoDB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER PROCEDURE [dbo].[checkEmail] (@email VARCHAR(50))
AS
BEGIN
	SELECT * from DemoUser WHERE email = @email	
END

ALTER PROCEDURE [dbo].[checkPassword] (@email NVARCHAR(50), @password NVARCHAR(60))
AS
BEGIN
 SELECT email, password from DemoUser WHERE email = @email	AND password = @password
 --IF @@ROWCOUNT = 0 BEGIN
 --	select 'none' as email, 'none' as password   
 --END 
END

ALTER PROCEDURE [dbo].[saveUser] (@email VARCHAR(50), @password VARCHAR(10))
AS
BEGIN
	INSERT INTO DemoUser(email, password) VALUES (@email, @password)
END

ALTER PROCEDURE [dbo].[listUsers]
AS
BEGIN
	SELECT * from DemoUser 
END

SSH

- 1 min read

SSH related

ssh-copy-id windows -> linux

cat ~/.ssh/id_rsa.pub | ssh root@agora "cat >> ~/.ssh/authorized_keys"

github

ssh-keygen -t ed25519 -C "[email protected]"
ssh-keygen -t rsa -b 4096 -C "[email protected]" (old)

github config ~/.ssh/config

Host github.com
      Hostname github.com
      PreferredAuthentications publickey
      IdentityFile ~/.ssh/gh

ssh-agent

$ eval "$(ssh-agent -s)"
> Agent pid 59566

add key to agent

ssh-add ~/.ssh/id_ed25519 

Windows ssh-agent

Set-Service ssh-agent -StartupType Manual
Start-Service ssh-agent

Arduino car

- 2 mins read

I have been working on a project that involves controlling a car with an Arduino board. The car is made of a chassis, two motors, and a battery. The motors are connected to the Arduino board through a motor driver, which allows the Arduino to control the speed and direction of the motors using a wii nunchuck as a remote control.

#include <math.h>
#include "Wire.h"
#include "WiiChuck.h"
#include <Servo.h>
#include <RHMotor.h>

WiiChuck chuck = WiiChuck();

int joyX = 0;
int joyY = 0;

#define MOVING_MARGIN  50
#define ROTATE_MARGIN  50

int left_motor_pin = 7;
int right_motor_pin = 6;

RHMotor motor(left_motor_pin, right_motor_pin);

void setup()
{

  Serial.begin(9600);
  Serial.flush();

  Serial.println("Initialize chuck engine.");

  chuck.begin(1000);
  chuck.update();

  delay(1000);

  Serial.println("Completed.");
  Serial.println("Initialize motor engine.");

  motor.start(300);

  delay(1000);
  motor.stop();

  Serial.println("Completed.");
}

void loop()
{

  chuck.update();

  joyX = chuck.readJoyX();
  joyY = chuck.readJoyY();
  //Serial.print(joyX);
  //Serial.print(" ");
  //Serial.print(joyY);
  //Serial.println();

  if (millis()%1000 == 0)
    Serial.print(".");

  if (chuck.zPress() == 1) {
      Serial.println("Z Pressed");
      motor.stop();
  }

  if (joyY > MOVING_MARGIN)     {
    Serial.println("Fwd");
    motor.forward();
  } else if (joyY < 0-MOVING_MARGIN) {
    Serial.println("Bwd");
    motor.backward();
  }

  if (joyX > ROTATE_MARGIN){
    Serial.println("Right");
    motor.right(300);
  } else if (joyX < 0-ROTATE_MARGIN) {     
    Serial.println("Left");      
    motor.left(300);
  }

  if (chuck.cPress()) {
    int left = motor.getLeftServo().readMicroseconds();
    int right = motor.getRightServo().readMicroseconds();
    Serial.print(left);
    Serial.print(" ");
    Serial.println(right);
  }

  joyX = 0;
  joyY = 0;

  delay(20);
}

This is a sort video of the car in action:

Servo calibration

- 1 min read

Este experimento es para tratar de calibrar los servos que se van a usar como motores.

Este paso es importante ya que hay que encontrar el punto en el que el servo queda detenido.

Material -Un servo de rotación continua

Conexiones - Usar para el servo una salida con PWM

#include <Servo.h>
#define SERVO_PIN  6

Servo servo;
int velocity;
void setup()
{

    Serial.begin(9600);
    Serial.flush();

    // Initialize
    velocity = 0;

    servo.attach(SERVO_PIN);
}

void loop()
{
    // commands
    if ( Serial.available()) {
      char ch = Serial.read();
      switch(ch) {
        case 's':
          servo.write(0);
          servo.write(velocity);
          break;

        case 'a':
          velocity += 10;
          break;      
        case 'd':
          velocity -= 10;
          break; 
        case 'z':
          velocity += 1;
          break;      
        case 'x':
          velocity -= 1;
          break;   
        case 'f':
          servo.detach();
          servo.attach(SERVO_PIN);
          break;
        case 'q':
          velocity = 0;
          servo.write(velocity);
          break;
        case 'w':
          velocity = 90;
          servo.write(velocity);
          break;
        case 'e':
          velocity = 180;
          servo.write(velocity);
          break; 
      }
       Serial.print("> ");
       Serial.print(ch);
       Serial.print(" ");
       Serial.print(velocity);
       Serial.print(" ");
       Serial.print(servo.readMicroseconds());
       Serial.println();
  }
}

Resultados

Servo A

Stop 86 (momento en que el servo deja de meter ruidito)

Servo B

Stop 83

acts_as_role

- 2 mins read

= acts_as_role

This is a minimalist implementation of roles using a database column to store the roles in plain text. You can specify the role values and a default role that should be used when model is initialized.

  class User < ActiveRecord::Base
    acts_as_role :role, :values = %w(admin owner user), :default => :user
  end

Use role field to store the user roles.

  user = User.new
  user.role => "user"
  user.has_role?(:user) => true 

Test roles using has_#{role_column.singularize}? or has_#{role_column.pluralize}?

  user.has_roles?(:user, :admin) => false

  user.add_roles :owner
  user.has_roles?(:user, :owner) => true

Roles are stored using plain text

GPS Arduino

- 3 mins read

La cosa es que en cierta ocasión había abierto este GPS y me había llamado la atención los agujeritos de conexión que hay dentro, de modo que me puse a buscar información al respecto y di con esta página (de un tal xam) en la que vi una foto en donde se actualizaba el software por medio de los agujeritos… http://xamweb2.dyndns.org/wordpress/2008/02/20/fortuna-clipon-flashing/ http://xamweb2.dyndns.org/wordpress/2007/09/20/innenleben-von-sirf2-gps-mausen-2/

Información

Mi GPS es parecido al de la primera foto pero distin del de la segunda, en vez de tener 12 agujeritos tiene 7