Does anybody know of a USB Postage Scale that's Linux compatible? - linux

I'm looking for a postage scale that already has linux support (drivers, etc) for a shipping system that I'm working on. I'm planning to use Ubuntu 9.04, but I am willing to switch distro's for compatibility.
Does anybody know of any scales that currently work? Is there an open source project that's working on scale drivers or similar?
Thanks!

I use the 5lb stamps.com scale. You can pick it up for $10 if you sign up for an account with them and then cancel it.
To read from it in linux, get this script: http://gist.github.com/503896
Edit the script file to set the proper hidraw device path. You can find the path by running dmesg after you've plugged the scale in. You will see something like "/dev/hidraw2".
After setting the hidraw path in the script, add execute permission and then run it as root:
chmod +x usbscale.pl
sudo ./usbscale.pl
Place an object on the scale and it will print the weight.

Update:
I've created a newer version of my earlier script that mattismyname linked. It's written in C, and you can find it at https://github.com/erjiang/usbscale
To use it, just download the source code and run (inside its directory):
sudo aptitude install libusb-1.0-0-dev
make
./usbscale
You might need to copy the 50-usb-scales.rules to your /etc/udev/rules.d (or run as root, haha) if you run into a permissions error.

Exponent value is passed as signed integer, and weight is passed in little endian byte order. Other answers do not properly account for these factors. See a more comprehensive example here.
<?php
$binary = fread(fopen('/dev/hidraw3', 'r'), 7);
$data = (object) unpack('Creport/Cstatus/Cunit/cexponent/vweight', $binary);
if ($data->report == 0x03 && $data->status == 0x04) {
$data->weight = $data->weight * pow(10, $data->exponent);
if ($data->unit == 0x0B) {
// convert ounces to grams
$data->weight *= 28.349523125;
// and unit to grams
$data->unit = 0x02;
}
if ($data->unit == 0x02) {
echo "{$data->weight} g\n";
} else {
echo "{$data->weight} in other unit\n";
}
}

Related

What does it mean to invoke `make -f` with a target that appears to be setting a variable? (And why isn't it working for me?)

Summary
I am trying to understand a complicated chain of Makefiles, in order to get a build to succeed. I narrowed down my problem to this bit in our build script:
INF_RL=`make -f $BUILD_ROOT/Makefile BUILD_ROOT_MAKEFILE= show__BUILD_INF_RL`
$INF_RL/$BUILD_UTILS_RELDIR/BuildAll.sh
$INF_RL is being set to an empty string (or not being set). If I replace the first line with
INF_RL=/foo_rel_linx86/infrastructure_release/v8.0.14
in order to hardcode what I know $INF_RL is supposed to be, then the build goes smoothly. But I want to know how to fix this the proper way.
What I've Tried / Thought
My first thought was that make -f is failing. So I tried it in my shell:
% make -f $BUILD_ROOT/Makefile BUILD_ROOT_MAKEFILE= show__BUILD_INF_RL
% setenv | grep BUILD_ROOT
BUILD_ROOT=/userhome/andrew.cheong/TPS
Indeed, it returned an empty string. But what conclusion could I draw from this? I wasn't sure if the shell was the same thing as the environment / scope in which Make was chaining together its Makefiles. I abandoned this investigation.
Next, I looked into show__BUILD_INF_RL, which seemed to be defined in $BUILD_ROOT/Makefile:
BUILD_ROOT_MAKEFILE = 1
MAKE_DIRS = src
CASE_KITS = tpsIn tpsOut
REQUIRED_VERSIONS = "case.v$(INF_VS)"
all:
## These next 3 rules allows any variable set in this makefile (and therefore
## the included makefile.include to have it's value echoed from the command
## "make show_<variableName>"
## NOTE: the "disp" target is vital as it allows the show_% implicit rule to be
## recognised as such - implicit rules *must* have a target.
show_% := DISPLAY_MACRO = $(#:show_%=%)
show_% : disp
# echo $($(DISPLAY_MACRO))
disp:
include $(BUILD_ROOT)/makefile.include
Here, I faced more questions:
What is BUILD_ROOT_MAKEFILE for? Why is it set to 1, then seemingly something else in the make -f command?
In the make -f command, is BUILD_ROOT_MAKEFILE= its own argument? If so, what kind of target or rule is that? Otherwise, why is it being set to the macro?
In $BUILD_ROOT, there is another file, makefile.LINUX_X86.include:
BUILD_INF_RL = /foo_rel_linx86/infrastructure_release/v$(INF_VS)
$(warning $(BUILD_INF_RL))
BUILD_UTILS = $(BUILD_INF_RL)/build-utils_LINUX_X86
Though a completely ignorant guess, I think BUILD_INF_RL is being set here, and intended to be extracted into the build script's variable INF_RL when the macro show__BUILD_INF_RL is invoked. I added the middle line to see if it was indeed being set, and indeed, I get this output when running the build script:
/userhome/andrew.cheong/TPS/makefile.LINUX_X86.include:3: /foo_rel_linx86/infrastructure_release/v8.0.14
i.e. Looks like what I've hardcoded way above! But why doesn't it make it into INF_RL? There is yet another file, makefile.include, also in $BUILD_ROOT:
#
# INCLUDE THIS FILE AS THE LAST LINE IN THE LOCAL MAKEFILE
#
# makefile.include - use this file to define global build settings
# e.g. infrastructure version and location, or third-party
#
# supported macros in addition to build-utils-makefile.include
#
# BUILD_INF_RL : optional, specification of infrastructure release location
# defaults to vdev_build area
#
include $(BUILD_ROOT)/../../makefile.include.$(BUILD_ARCH).Versions
#include $(BUILD_UTILS)/makefile.archdef.include
include $(BUILD_ROOT)/makefile.$(BUILD_ARCH).include
$(warning $(BUILD_INF_RL))
_BUILD_INF_RL = $(BUILD_INF_RL)
# place the results at the root of the infdemo tree
BUILD_DEST = $(BUILD_ROOT)
INCLUDE_DIRS += $(BUILD_INF_RL)/core/$(BUILD_TARGET)/include
LINK_DIRS += $(BUILD_INF_RL)/core/$(BUILD_TARGET)/lib
# libraries required for a typical fidessa app, including OA and DB access
FIDEVMAPP_LIBS = FidApp FidInf FidCore Fidevm
include $(BUILD_UTILS)/makefile.include
That $(warning ...) is again mine, and when running the build script, I get:
/userhome/andrew.cheong/TPS/makefile.include:18: /foo_rel_linx86/infrastructure_release/v8.0.14
The Question
The fact that both $(warning ...)s show up when I run the build script that's calling the make -f ... show__BUILD_INF_RL, tells me that those Makefiles are being included. Then what is causing the macro to fail and return an empty string instead of the correct INF_RL path?
Historical Notes
These build scripts were written at a time when we were only compiling for Solaris. (The scripts were based on templates written by an infrastructure team that loosely accounted for both Solaris and Linux, but we never ran the Linux branch, as it was unnecessary.) We are now fully migrating to Linux, and hitting this issue. The reason I'm skeptical of it being a Linux versus Solaris issue is that we have at least four other products that use a similar Makefile chain and have been migrated with no issues. Not sure why this one in particular is behaving different.
Your question got very long and complex so I didn't read it all... for SO it's often better if you just ask a specific targeted question that you want to know the answer to, with a simple repro case.
I can't say why different makefiles behave differently, but this line:
show_% := DISPLAY_MACRO = $(#:show_%=%)
seems really wrong to me. This is (a) setting the variable show_%, which don't actually use anywhere, (b) to the simply expanded string DISPLAY_MACRO = because at this point in the makefile the variable $# is not set to any value.
Maybe you wanted this line to be this instead:
show_% : DISPLAY_MACRO = $(#:show_%=%)
(note : not :=) so that it's a pattern-specific variable assignment, not a simple variable assignment?

Determine what exactly returns parameter

In some OS, like Ubuntu, Debian, etc. cal return current calendar with highlighting of today. And cal -h turns off highlighting of today:
But in some OS, like Arch Linux -h param displays the help of a calendar.
I'm doing a small script with Lua:
function foo()
local f, err = io.popen('cal -h', 'r')
if f then
local s = f:read("*all")
f:close()
return s
else
return err
end
end
And my main question - how do I determine exactly what specifically returned parameter -h?
Execute cal -h and parse the output for the word "help". If the word is found, the "-h" is for help. If word not found it is likely used to mean highlight but there is no sure way of knowing (a way that will work on all flavors of Linux). Most likely you will need some code to read environment var that identifies platform so you can issue correct command and rely on users of different Linux flavors to report when default fails and report to you the correct command line parameters. OTOH you could limit supprt to only those platforms you have access to. Or combination of these approaches.
Another solution.
Arch Linux cal have -V param, which returns the UTIL_LINUX_VERSION.
It this case, after call cal -V in Arch Linux you will likely receive exit code 0, but Ubuntu don't have -V param and return 64 :)
So, if cal -V returns exit code 0, -h return help

GPIO output value not changing

I am trying to setup up a output GPIO pin on my Nitrogen6X board, but I can't change the file value. I navigated to /sys/class/gpio/ and I exported my pin (GPIO18) with echo 18 > export. I was then able to change direction with the command echo out > direction and it seems like I should be able to change the value file the same way, with echo 1 > value, but this doesn't seem to be working. I am logged in as root and the permissions on both the direction file and the value file are the same: -rw-r--r-- 1 root root.
Does anyone have an idea why this would not be writing to this file?
Thanks so much for all of your help!
The commands that you have listed should work, if the gpio number is correct. While I have not worked with Nitrogen6X in particular, I have found out that Linux GPIO pin numbers often do not match the labels on the board. I advice trying to find out the proper mapping experimentally by watching all possible GPIOs:
cd /sys/class/gpio
for x in `seq 1 128`; do echo $x > export; done
ground the pin in question via 10k resistor, run:
grep . gpio*/value > /tmp/values0
connect the pin in question to Vcc via 10k resistor, run:
grep . gpio*/value > /tmp/values1
diff the files, and pay attention which pin has changed.

How do I script a "yes" response for installing programs?

I work with Amazon Linux instances and I have a couple scripts to populate data and install all the programs I work with, but a couple of the programs ask:
Do you want to continue [Y/n]?
and pause the install. I want to auto answer "Y" in all cases, I'm just now sure how to do it.
The 'yes' command will echo 'y' (or whatever you ask it to) indefinitely. Use it as:
yes | command-that-asks-for-input
or, if a capital 'Y' is required:
yes Y | command-that-asks-for-input
If you want to pass 'N' you can still use yes:
yes N | command-that-asks-for-input
echo y | command should work.
Also, some installers have an "auto-yes" flag. It's -y for apt-get on Ubuntu.
You might not have the ability to install Expect on the target server.
This is often the case when one writes, say, a Jenkins job.
If so, I would consider something like the answer to the following on askubuntu.com:
https://askubuntu.com/questions/338857/automatically-enter-input-in-command-line
printf 'y\nyes\nno\nmaybe\n' | ./script_that_needs_user_input
Note that in some rare cases the command does not require the user to press enter after the character. in that case leave the newlines out:
printf 'yyy' | ./script_that_needs_user_input
For sake of completeness you can also use a here document:
./script_that_needs_user_input << EOF
y
y
y
EOF
Or if your shell supports it a here string:
./script <<< "y
y
y
"
Or you can create a file with one input per line:
./script < inputfile
Again, all credit for this answer goes to the author of the answer on askubuntu.com, lesmana.
You just need to put -y with the install command.
For example: yum install <package_to_install> -y
Although this may be more complicated/heavier-weight than you want, one very flexible way to do it is using something like Expect (or one of the derivatives in another programming language).
Expect is a language designed specifically to control text-based applications, which is exactly what you are looking to do. If you end up needing to do something more complicated (like with logic to actually decide what to do/answer next), Expect is the way to go.
If you want to just accept defaults you can use:
\n | ./shell_being_run

Compressing the core files during core generation

Is there way to compress the core files during core dump generation?
If the storage space is limited in the system, is there a way of conserving it in case of need for core dump generation with immediate compression?
Ideally the method would work on older versions of linux such as 2.6.x.
The Linux kernel /proc/sys/kernel/core_pattern file will do what you want: http://www.mjmwired.net/kernel/Documentation/sysctl/kernel.txt#191
Set the filename to something like |/bin/gzip -1 > /var/crash/core-%t-%p-%u.gz and your core files should be saved compressed for you.
For an embedded Linux systems, following script change perfectly works to generate compressed core files in 2 steps
step 1: create a script
touch /bin/gen_compress_core.sh
chmod +x /bin/gen_compress_core.sh
cat > /bin/gen_compress_core.sh #!/bin/sh exec /bin/gzip -f - >"/var/core/core-$1.$2.gz"
ctrl +d
step 2: update the core pattern file
cat > /proc/sys/kernel/core_pattern |/bin/gen_compress_core.sh %e %p ctrl+d
As suggested by other answer, the Linux kernel /proc/sys/kernel/core_pattern file is good place to start: http://www.mjmwired.net/kernel/Documentation/sysctl/kernel.txt#141
As documentation says you can specify the special character "|" which will tell kernel to output the file to script. As suggested you could use |/bin/gzip -1 > /var/crash/core-%t-%p-%u.gz as name, however it doesn't seem to work for me. I expect that the reason is that on my system kernel doesn't treat the > character as a output, rather it probably passes it as a parameter to gzip.
In order to avoid this problem, like other suggested you can create your file in some location I am using /home//crash/core.sh, create it using the following command, replacing with your user. Alternatively you can also obviously change the entire path.
echo -e '#!/bin/bash\nexec /bin/gzip -f - >"/home/<username>/crashes/core-$1-$2-$3-$4-$5.gz"' > ~/crashes/core.sh
Now this script will take 5 input parameters and concatenate them and add to core-path. The full paths must be specified in the ~/crashes/core.sh. Also the location of this script can be specified. Now lets tell kernel to use tour executable with parameters when generating file:
sudo sysctl -w kernel.core_pattern="|/home/<username>/crashes/core.sh %e %p %h %t"
Again should be replaced (or entire path to match location and name of core.sh script). Next step is to crash some program, lets create example crashing cpp file:
int main (){
int * a = nullptr;
int b = *a;
}
After compiling and running there are 2 options, either we will see:
Segmentation fault (core dumped)
Or
Segmentation fault
In case we see the latter, there are few possible reasons.
ulimit is not set, ulimit -c should specify what is limit for cores
apport or your distro core dump collector is not running, this should be investigated further
there is an error in script we wrote, I suggest than checking some basic dump path to check if the other things aren't reason the below should create /tmp/core.dump:
sudo sysctl -w kernel.core_pattern="/tmp/core.dump"
I know there is already an answer for this question however it wasn't obvious for me why it isn't working "out of the box" so I wanted to summarize my findings, hope it helps someone.

Resources