I'm writing a program that converts OSC into MIDI, allowing OSC enabled applications (like touchOSC on my iPhone) to control MIDI enabled applications (Sibelius, Ableton Live and so on).
I'm using Python to create an OSC server and convert from OSC to MIDI. To get MIDI to the application in question, I'm outputting MIDI to the Apple IAC driver, which is then enabled as an input within the program in question.
Does anyone know of a means to programmatically configure Mac MIDI devices programmatically? In particular, I need to enable the IAC driver, which is disabled by default.
Using FileMon, I have observed that Audio Midi Setup.app modifies this file when enabling/disabling the IAC driver:
~/Preferences/ByHost/com.apple.MIDI.0017f2cxxxxx.plist
The number 0017f2cxxxxx is my system IOPlatformUUID. It's a simple XML property list, but I'm wary of writing to it directly. Even if I did, presumably I would need to cajole the midi server process into re-reading it somehow?
Finally, I'm becoming more and more aware that using the IAC driver at all is a pretty naff solution - for a start it only works on Mac! Ideally, I would write a loopback MIDI driver and all my problems would be solved...
Your hunch about writing directly to the plist is correct -- you probably shouldn't do it. I'm not 100% sure about this, but I have a feeling that the plist reflects the state of the MIDI device, but altering it will not open or close that MIDI device as you need.
To actually open the MIDI device, you could use something like pygame. I have used it for some audio-related projects, and the SDK is very straightforward and easy to work with. As python doesn't have great support for MIDI directly, this is probably your best bet (short of writing the python C module yourself, which would be rather painful).
As for IAC, it's a shame that other OS's don't come with virtual MIDI devices like this. IAC is very useful and good at what it does. So while relying on IAC for something like this would not be cross-platform, you could write an abstraction layer for manipulating the loopback device. For Windows users, you could recommend a free MIDI loopback device to be used with your software.
If you want to send OSC to MIDI then you're best off creating a Virtual Midi port in software rather trying to remotely configure an IAC. This virtual port will show up in Ableton etc so you can then have it control things programmatically.
You can do this using the rtmidi-python library (or older and slightly different pyrtmidi) - both based on the cross-platform rtmidi lib which provides for straightforward sending of MIDI Control and Notes:
import rtmidi_python as rtmidi
vmidi_out = rtmidi.MidiOut()
vmidi_out.open_virtual_port('My Virtual MIDI Output Port')
vmidi_out.send_message([0x90, 48, 100]) # Note on
vmidi_out.send_message([176, 7, 100]) # Control Change - Volume
PyGame itself uses PortMidi under the hood. If you don't need all PyGame library, maybe this can be useful for you.
Related
I want to establish a UART communication between an FPGA equipped with an FTD2232H chip and a PC, and for that, I am using the Python ftd2xx module. I do not know how to use the setBitMode function of this module to adjust the mode as UART.
I have written the following example code:
import ftd2xx as ftd
device = ftd.open(0)
device.setBaudRate(9600)
device.setBitMode(mask, enable)
device.write("01010101")
device.close()
How should the parameters mask and enable be chosen in order to have a UART communication?
The FT2232H defaults to a mode depending on if an EEPROM is present and the stored setup. If no EEPROM is present UART is the default. Else the setup stored in the EEPROM determins the mode. It can be UART or any other of the allowed modes. You can change the setup using FT_PROG.
If the FT2232H is in UART mode, there is no need to change anything via D2XX. Actually in that case the device can simply be opened as a com port if thethe Virtual Com Port (VCP) is loaded. The py_serial module is an easy solution to open the device in that case.
If you really want (or need) to use the ftd2xx module (note: the project page states "I don’t have time to maintain this project, so I am looking for a maintainer."), you can find the corresponding descripts in "D2XX Programmer's Guide" (Document Reference No.: FT_000071 ). However, you can only enter specific modes using the D2XX driver. If you entered one of them (e.g. to use an alternative protocol for a short time), you can issue a reset using mode = 0x0 to revert the device state to the EEPROM configurated mode. But this is a very specific use case which mostlikely does not apply here.
Since ftd2xx is simply a wrapper for the D2XX DLL from FTDI, you should consult the documentation for that.
I'm way outside my depth here, but am attempting to utilize the IOCTL interface to hardware on a windows machine using python (via ctypes). I've done quite a bit of reading, and the call signature asks for a file handle which can be opened via the CreateFileA (link) function in the windows file API. This takes a path for the file to be opened and can be passed a "Device Name" which seems to be a "MS-DOS Device Name".
The examples given are using the \\.\PhysicalDrive0 name which I am familiar with from using tools like DISM (windows imaging), but never really knew what they were exactly. I'd like to use the IOCTL interface with some completely unrelated to disk hardware, specifically some NFC hardware but have absolutely no idea how to find out what sort of device filename I should use to target the device! This the reference I would use to talk to the NFC chip built into my target platform (Surface Go).
Am I way off the rails here? Is what I am trying to do the wrong approach/not possible?
I have a dot-matrix printer LX-300 connected to my computer through the network. How do I send a raw string with ESCP characters directly to my printer in Python?
The computer is connected to the printer through another computer. I need to send a raw string because LX-300 image printing result is blurry.
The Problem
To send data down this route:
Client computer ---> Server (Windows machine) ---> printer (dot-matrix)
...and to not let Windows mess with the data; instead to send the raw data, including printer control codes, straight from the client computer.
My Solution
Here's how I solved a near-identical problem for a small in-house database application:
Step 1) Make the printer network-accessible without Windows getting its fingers in the data routed to it. I accomplished this by installing the printer using the "Generic/Text Only" driver, then installing
RawPrintServer on the Windows machine connected to the printer.
Step 2) Send raw data over the network to the TCP/IP port specified when you set up RawPrintServer (default is 9100). There are various ways to do that, here's what I did:
data = b"\x1B#A String To Print\x1B#" # be sure to use the right codes for your printer
ip_addr = 123.123.123.123 # address of the machine with the printer
port = 9100 # or whatever you set it to
s = socket.socket()
try:
s.connect((ip_addr, port))
s.send(data)
except:
# deal with the error
finally:
s.close()
Background
I thought about the problem in two parts:
Client machine: spitting out the data I need from Python with the correct formatting/control codes for my printer, and sending it across the network
Print server machine: transmitting the data to the locally connected printer
Number 1 is the easy part. There are actually some libraries in PyPI that may help with all the printer codes, but I found most of them are aimed at the little point-of-sale label printers, and were of limited use to me. So I just hard-coded what I needed into my Python program.
Of course, the way you choose to solve number 2 will effect how you send the data from Python. I chose the TCP/IP route to avoid dealing with Samba and Windows print issues.
As you probably discovered, Windows normally tries very hard to convert whatever you want to print to a bitmap and run the printer in graphics mode. We can use the generic driver and dump the data straight into the (local) printer port in order to prevent this.
The missing link, then, is getting from the network to the local printer port on the machine connected to the printer. Again, there are various ways to solve this. You could attempt to access the Windows printer share in some way. If you go the TCP/IP route like I did, you could write your own print server in Python. In my case, the RawPrintServer program "just worked" so I didn't investigate any further. Apparently all it does is grab incoming data from TCP port 9100 and shove it into the local printer port. Obviously you'll have to be sure the firewall isn't blocking the incoming connections on the print server machine. This method does not require the printer to be "shared" as far as Windows is concerned.
Depending on your situation (if you use DHCP), you might need to do some extra work to get the server's IP address in Python. In my case, I got the IP for free because of the peculiarity of my application.
This solution seems to be working out very well for me. I've got an old Panasonic printer running in Epson ESC/P compatibility mode connected to a Windows 7 machine, which I can print to from any other computer on the local network. Incidentally, this general idea should work regardless of what OS the client computer is running.
Ultimately, you will need and want to write your own wrapper/script to do this. And since you are using a distribution of Linux, this is relatively easy.
On a Linux OS, the simplest way to issue a print job is to open a subprocess to the lpr. Generally, using lpr lets you access the printer without the need to be logged in as root (being a superuser), which is desirable considering the amount of damage that can be done while logged in as a "superuser".
Code like the following:
import subprocess
lpr = subprocess.Popen("/usr/bin/lpr", stdin=subprocess.PIPE)
lpr.stdin.write(data_to_send_to_printer)
Should be a good jumping off point for you. Essentially, this code should allow you to accomplish what you need.
Be careful though; depending on your privilege levels, a call to open a subprocess might need root level/Superuser permissions.
Subprocesses generally inherit the User IDs and access rights by the user that is running the command. For example, if the subprocess is created by a root user, then you will need root user/Superuser rights to access that subprocess.
For more information, check out the hyperlinks I've included in the post.
Good luck!
is snmp really required to manage devices ?
i'd like to script something with python to manage devices (mainly servers), such as disk usage, process list etc.
i'm learning how to do and many article speak about snmp protocole.
I can't use, for example, psutil, or subprocess or os modules, and send information via udp ?
Thanks a lot
The SNMP is a standard monitoring (and configuration) tool used widely in managing network devices (but not only). I don't understand your question fully - is it a problem that you cannot use SNMP because device does not support it (what does it support then?) To script anything you have to know what interface is exposed to you (if not a MIB files then what?). Did you read about NETCONF?
No, it's not required, but your question is sort of like asking if you're required to use http to serve web pages. Technically you don't need it, but if you don't use it you're giving up interoperability with a lot of existing client software.
I am running a process on a S7-1200 plc and I need it to send a start signal to my python script, after the script is done running it needs to send something back to the plc to initiate the next phase. Oh, and it has to be done in ladder.
Is there a quick and dirty way to send things over profibus or am I better off using just a RS232 thing?
I would go with SNAP7 and python-snap7 libraries. Example on how to install it on a Raspberry pi found in this blog:
http://simplyautomationized.blogspot.com/2014/12/raspberry-pi-getting-data-from-s7-1200.html
Update:
Video walkthrough on how to set it up: https://youtu.be/yJNEsI5KJxs
After failing with libnodave and OPC, I created a TCON,TSEND and TRECV communication thing. It transmits a byte over TCP and it works.
I would use libnodave on PC side to change value of some M tag or a DB tag in a PLC. You can easily make a ladder rung which will monitor this tag and execute further actions. Although libnodave doesn't support Python natively, you can find a python wrapper here.
Well, a quick google of 'python rs232' turned up some site talking about doing robotics controls through rs232 using pySerial. So if you know how to hook your widget up to rs232, you could go that route.
There is a commercial library called "S7connector" by Rothenbacher GmbH (obviously it's not the "s7connector" on sourceforge).
It is for the .NET framework, so could be used with IronPython.
It does work with S7-1200 PLCs. You just have to make sure a DB you want to read from / write to is not an optimized S7-1200 style DB, but a S7-300/400 compatible one, an option which you can set when creating a DB in TIA portal.
This lib also allows to read and write all I/O ports - the "shadow registers" (not sure what they're called officially) and directly as well, overriding the former.
There are several Modbus TCP Clients available for Python, I have used pyModbusTCP successfully. TIA Portal the IDE for the S7-1200 has Modbus Server function that you can load to your PLC that will allow you to read and write directly to the PLC.
https://support.industry.siemens.com/cs/ww/en/view/83130159
Ther best way to communicate with S7-1200 PLC cpu's is with OPC UA or Classic OPC (ommonly known as OPC DA. ) Libnodave is made for S7-300 and S7-400 not for S71200 (2.x firmware).
If you use a third party solution to communicate with S7-1200 (or S7-1500) you have to decrease the security level at the PLC by allowing the put and get mechanism. Put and get are pure evil to use. You open the memory of the CPU for every process. Don’t use them anymore. Siemens should actually block this.
This applies for all firmware release for S7-1200.
Siemens pushes people you use OPC UA as default communication from PLC. What makes sense, because OPC UA is the protocol for industry 4.0 and IIoT.
Edit: rewrite everything. Info was heavily outdated.
If you use a firmware 2 or 3 1200, consider replacement or upgrade. These versions are no longer supported and contains the worm issue.