Taking Screenshot's using python using the Virtualbox API - python

I'm trying to take screenshots from my guest Virtualbox session using a python script running in the host. From the research I did the best way of doing this is accessing the VirtualBox API and using COM constants in order to make a screenshot. However, every time I try to run the script I get an attribute error:
Traceback (most recent call last):
File "D:\computer_vision_scripts\take_screenshot.py", line 29, in <module>
take_screenshot('Windows 10 Pro')
File "D:\computer_vision_scripts\take_screenshot.py", line 16, in take_screenshot
machine.LockMachine(session, constants.LockType_Shared)
File "C:\Users\me\AppData\Roaming\Python\Python39\site-packages\win32com\client\__init__.py", line 180, in __getattr__
raise AttributeError(a)
AttributeError: LockType_Shared
The script I am using comes from https://floatingoctothorpe.uk/2018/automating-virtualbox-screenshots-with-python.html
And looks like this when seen in the file version:
import win32com.client
from win32com.client import constants
def take_screenshot(vm_name, screenshot_path='screenshot.png'):
"""Create a VM Screenshot for a given VM"""
vbox = win32com.client.Dispatch("VirtualBox.VirtualBox")
session = win32com.client.Dispatch("VirtualBox.Session")
machine = vbox.FindMachine(vm_name)
machine.LockMachine(session, constants.LockType_Shared)
display = session.Console.Display
width, height, _, _, _, _ = display.GetScreenResolution(0)
screenshot = display.TakeScreenShotToArray(0, width, height,
constants.BitmapFormat_PNG)
session.UnlockMachine()
with open(screenshot_path, 'wb') as output_png:
output_png.write(screenshot.tobytes())
if __name__ == '__main__':
take_screenshot('Windows 10 Pro')
Does anyone know what I should do in order to make it work?

I faced the same issue.
Solved it like this:
Add this:
import virtualbox
from virtualbox import library
Change
machine.LockMachine(session, constants.LockType_Shared)
by
machine.LockMachine(session, virtualbox.library.LockType.shared)
and
screenshot = display.TakeScreenShotToArray(0, width, height,constants.BitmapFormat_PNG)
by
screenshot = display.TakeScreenShotToArray(0, width, height, virtualbox.library.BitmapFormat.png)
Found this solution here:
https://github.com/sethmlarson/virtualbox-python/blob/master/tests/test_test_vm.py

Related

Flink Python Datastream API Kafka Consumer

Im new to pyflink. Im tryig to write a python program to read data from kafka topic and prints data to stdout. I followed the link Flink Python Datastream API Kafka Producer Sink Serializaion. But i keep seeing NoSuchMethodError due to version mismatch. I have added the flink-sql-kafka-connector available at https://repo.maven.apache.org/maven2/org/apache/flink/flink-sql-connector-kafka_2.11/1.13.0/flink-sql-connector-kafka_2.11-1.13.0.jar. Can someone help me in with a proper example to do this? Following is my code
import json
import os
from pyflink.common import SimpleStringSchema
from pyflink.datastream import StreamExecutionEnvironment
from pyflink.datastream.connectors import FlinkKafkaConsumer
from pyflink.common.typeinfo import Types
def my_map(obj):
json_obj = json.loads(json.loads(obj))
return json.dumps(json_obj["name"])
def kafkaread():
env = StreamExecutionEnvironment.get_execution_environment()
env.add_jars("file:///automation/flink/flink-sql-connector-kafka_2.11-1.10.1.jar")
deserialization_schema = SimpleStringSchema()
kafkaSource = FlinkKafkaConsumer(
topics='test',
deserialization_schema=deserialization_schema,
properties={'bootstrap.servers': '10.234.175.22:9092', 'group.id': 'test'}
)
ds = env.add_source(kafkaSource).print()
env.execute('kafkaread')
if __name__ == '__main__':
kafkaread()
But python doesnt recognise the jar file and throws the following error.
Traceback (most recent call last):
File "flinkKafka.py", line 31, in <module>
kafkaread()
File "flinkKafka.py", line 20, in kafkaread
kafkaSource = FlinkKafkaConsumer(
File "/automation/flink/venv/lib/python3.8/site-packages/pyflink/datastream/connectors.py", line 186, in __init__
j_flink_kafka_consumer = _get_kafka_consumer(topics, properties, deserialization_schema,
File "/automation/flink/venv/lib/python3.8/site-packages/pyflink/datastream/connectors.py", line 336, in _get_kafka_consumer
j_flink_kafka_consumer = j_consumer_clz(topics,
File "/automation/flink/venv/lib/python3.8/site-packages/pyflink/util/exceptions.py", line 185, in wrapped_call
raise TypeError(
TypeError: Could not found the Java class 'org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer'. The Java dependencies could be specified via command line argument '--jarfile' or the config option 'pipeline.jars'
What is the correct location to add the jar file?
I see that you downloaded flink-sql-connector-kafka_2.11-1.13.0.jar, but the code loades flink-sql-connector-kafka_2.11-1.10.1.jar.
May be you can have a check
just need to check the path to flink-sql-connector jar
You should add jar file of flink-sql-connector-kafka, it depends on your pyflink and scala version. If versions are true, check your path in add_jars function if the jar package is here.

I'm using VS Code to program an EV3 with python but I'm having trouble getting my infrared sensor to work

The code I'm using is:
#!/usr/bin/env python3
from ev3dev2.motor import LargeMotor, MoveSteering, OUTPUT_B, OUTPUT_C, SpeedDPS
from ev3dev2.sensor.lego import InfraredSensor
from sys import stderr
from time import sleep
motorB = LargeMotor(OUTPUT_B)
steer_pair = MoveSteering(OUTPUT_B, OUTPUT_C)
ir = InfraredSensor()
wf = 1
motorB.position = 0
steer_pair.on(steering=0, speed=SpeedDPS(265))
while motorB.position*0.612 < 640:
if ir.proximity * 0.7 < 23:
motorB.position = 0
print(motorB.position*0.612, ir.proximity * 0.7, file = stderr)
sleep(0.1)
steer = 28
rots = -1
steer_pair.on_for_rotations(steering=0, speed=25, rotations=0.5*wf)
steer_pair.on_for_rotations(steering=steer, speed=15, rotations=rots*wf)
steer_pair.on_for_rotations(steering=-steer, speed=15, rotations=rots*wf)
steer_pair.on_for_rotations(steering=0, speed=25, rotations=0.7*wf)
When I run the code I get the following error:
Traceback (most recent call last):
File "/home/robot/part3/self_park_ir.py", line 9, in <module>
ir = InfraredSensor()
File "/usr/lib/python3/dist-packages/ev3dev2/sensor/lego.py", line 838, in __init__
super(InfraredSensor, self).__init__(address, name_pattern, name_exact, driver_name='lego-ev3-ir', **kwargs)
File "/usr/lib/python3/dist-packages/ev3dev2/sensor/__init__.py", line 78, in __init__
super(Sensor, self).__init__(self.SYSTEM_CLASS_NAME, name_pattern, name_exact, **kwargs)
File "/usr/lib/python3/dist-packages/ev3dev2/__init__.py", line 223, in __init__
chain_exception(DeviceNotFound("%s is not connected." % self), None)
File "/usr/lib/python3/dist-packages/ev3dev2/__init__.py", line 54, in chain_exception
raise exception from cause
ev3dev2.DeviceNotFound: InfraredSensor is not connected.
I have tried to use different ports and wires, as this was the fix for another problem I had, but that did not work this time. Anyone know how to fix this?
I think you should assign an Input port for infrared sensor like this:
from ev3dev2.sensor import INPUT 1
ir = InfraredSensor(INPUT 1)
Also, some hardware tips for accuracy.
Don't 'Hot Plug' any sensors
This is where you plug it in once the device is already on.
Ensure you import the right modules
Make sure you have the shebang line and the right modules imported
Make sure your EV3DEV code is up to date with the new EV3DEV 2 code and you have the correct OS image flashed onto the microSD card.
Otherwise, the code won't run smoothly

Error on Python serial import

When I try to import the serial I get the following error:
Traceback (most recent call last):
File "C:\Documents and Settings\eduardo.pereira\workspace\thgspeak\tst.py", line 7, in <module>
import serial
File "C:\Python27\lib\site-packages\serial\__init__.py", line 27, in <module>
from serial.serialwin32 import Serial
File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 15, in <module>
from serial import win32
File "C:\Python27\lib\site-packages\serial\win32.py", line 182, in <module>
CancelIoEx = _stdcall_libraries['kernel32'].CancelIoEx
File "C:\Python27\lib\ctypes\__init__.py", line 375, in __getattr__
func = self.__getitem__(name)
File "C:\Python27\lib\ctypes\__init__.py", line 380, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'CancelIoEx' not found
I have installed the latest version of pySerial, Python 2.7 runing on a WinXP laptop. Tried everywhere and found no similar problem. Is there any solution for that?
Thanks in advance...
The version of pySerial that you're using is trying to call a function that's only available in Windows Vista, whereas you're running Windows XP.
It might be worth experimenting with using an older version of pySerial.
The code in question was added to pySerial on 3 May 2016, so a version just prior to that might be a good start.
Older versions seem unavailable. But, this worked for me (assuming nanpy version 3.1.1):
open file \lib\site-packages\serial\serialwin32.py
delete methods _cancel_overlapped_io(), cancel_read(), cancel_write() in lines 436-455 nearly at the botton of the file
change method _close() als follows:
(Python)
def _close(self):
"""internal close port helper"""
if self._port_handle is not None:
# Restore original timeout values:
win32.SetCommTimeouts(self._port_handle, self._orgTimeouts)
# Close COM-Port:
if self._overlapped_read is not None:
win32.CloseHandle(self._overlapped_read.hEvent)
self._overlapped_read = None
if self._overlapped_write is not None:
win32.CloseHandle(self._overlapped_write.hEvent)
self._overlapped_write = None
win32.CloseHandle(self._port_handle)
self._port_handle = None
Additionally, create a non-default serial connection when starting the communication, otherwise you'll be bound to some linux device:
a = ArduinoApi(SerialManager("COM5:"))
for i in range(10):
a.pinMode(13, a.OUTPUT)
a.digitalWrite(13, a.HIGH)
# etc.
And in serial\win32.py comments
#CancelIoEx = _stdcall_libraries['kernel32'].CancelIoEx
#CancelIoEx.restype = BOOL
#CancelIoEx.argtypes = [HANDLE, LPOVERLAPPED]
There is no obvious reason why CancelIO was replaced with the cross-thread version CancelIOex, which allows code in one thread to cancel IO in another thread. Certainly cpython 2.x is single threaded.
To get pySerial to run on python 2.7 on Win2K, I just changed CancelIOex in serial back to CancelIO.

AttributeError: 'DocsClient' object has no attribute 'GetDocumentListFeed'

I'm currently trying to build a Script that interacts with Google's API's, but I keep getting an Attribute error:
Traceback (most recent call last):
File "service_catalog_automation.py", line 18, in <module>
feed = client.GetDocumentListFeed()
AttributeError: 'DocsClient' object has no attribute 'GetDocumentListFeed'
This is the code I'm trying to use
import gdata.gauth
import gdata.docs.client
import sys
def sys_print(text):
sys.stdout.write(str(text))
sys.stdout.flush()
CONSUMER_KEY = 'domain.com'
CONSUMER_SECRET = 'abcde1234'
requestor_id = 'myuser#domain.com'
client = gdata.docs.client.DocsClient(source='my-script-v1')
client.auth_token = gdata.gauth.TwoLeggedOAuthHmacToken(
CONSUMER_KEY, CONSUMER_SECRET, requestor_id)
# Retrieve user's list of Google Docs
feed = client.GetDocumentListFeed()
for entry in feed.entry:
sys_print(entry.title.text)
sys_print('\n')
I've pulled client.getDocumentListFeed() portion of code from their sample code here and have even tried a bare minimum approach using their sample code under the 2LeggedOAuth section here. (I also have tried GetDocList() from that example with the same error)
I have downloaded Google's gdata-python-client to a linux vm's home directory and installed it by running python setup.py install and ran the test python all_tests.py with no errors.
Any help would be greatly apperciated
In the first example, they're assigning their client object as the return of gdata.docs.service.DocsService().
The second example also returns the client object as a DocsService type:
client = gdata.docs.service.DocsService(source='yourCompany-YourAppName-v1')
This would seem to imply that gd_client is of type DocsService, not DocsClient

Adding new portgroups to vmware virtual switches using pysphere

I'm trying to automate the addition of new portgroups to ESXi hosts using pysphere. I'm using the following code fragment:
from pysphere import MORTypes
from pysphere import VIServer, VIProperty
from pysphere.resources import VimService_services as VI
s = VIServer()
s.connect(vcenter, user, password)
host_system = s.get_hosts().keys()[17]
prop = VIProperty(s, host_system)
propname = prop.configManager._obj.get_element_networkSystem()
vswitch = prop.configManager.networkSystem.networkInfo.vswitch[0]
network_system = VIMor(propname, MORTypes.HostServiceSystem)
def add_port_group(name, vlan_id, vswitch, network_system):
request = VI.AddPortGroupRequestMsg()
_this = request.new__this(network_system)
_this.set_attribute_type(network_system.get_attribute_type())
request.set_element__this(_this)
portgrp = request.new_portgrp()
portgrp.set_element_name(name)
portgrp.set_element_vlanId(vlan_id)
portgrp.set_element_vswitchName(vswitch)
portgrp.set_element_policy(portgrp.new_policy())
request.set_element_portgrp(portgrp)
s._proxy.AddPortGroup(request)
However, when I attempt to run it, I get the following error:
>>> add_port_group(name, vlan_id, vswitch, network_system)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 12, in add_port_group
File "/usr/lib/python2.6/site-packages/pysphere-0.1.8- py2.6.egg/pysphere/resources/VimService_services.py", line 4344, in AddPortGroup
response = self.binding.Receive(AddPortGroupResponseMsg.typecode)
File "/usr/lib/python2.6/site-packages/pysphere-0.1.8- py2.6.egg/pysphere/ZSI/client.py", line 545, in Receive
return _Binding.Receive(self, replytype, **kw)
File "/usr/lib/python2.6/site-packages/pysphere-0.1.8- py2.6.egg/pysphere/ZSI/client.py", line 464, in Receive
raise FaultException(msg)
pysphere.ZSI.FaultException: The object has already been deleted or has not been completely created
I've attempted to swap in different values for "vswitch" and "network_system", but I haven't had any success. Has anyone attempted to do something similar with pysphere successfully?
I can accomplish what I need through Powershell, which demonstrates that it isn't a vmware issue, but I don't want to use Powershell in this particular case.
I tried your code on one of our vSpheres.
It seems you are passing the object to set_element_vswitchName rather than the name. Maybe this will help:
vswitch = prop.configManager.networkSystem.networkInfo.vswitch[0].name

Categories

Resources